001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Anton Avtamonov
019: * @version $Revision$
020: */package javax.swing.tree;
021:
022: import java.awt.Rectangle;
023: import java.util.Enumeration;
024:
025: import javax.swing.event.TreeModelEvent;
026:
027: import org.apache.harmony.x.swing.internal.nls.Messages;
028:
029: public class FixedHeightLayoutCache extends AbstractLayoutCache {
030: public FixedHeightLayoutCache() {
031: setRowHeight(1);
032: }
033:
034: public void setRowHeight(final int rowHeight) {
035: if (rowHeight <= 0) {
036: throw new IllegalArgumentException(Messages
037: .getString("swing.97")); //$NON-NLS-1$
038: }
039: super .setRowHeight(rowHeight);
040: }
041:
042: public int getRowCount() {
043: return getRowCountImpl();
044: }
045:
046: public void invalidatePathBounds(final TreePath path) {
047: }
048:
049: public void invalidateSizes() {
050: if (getStateRoot() != null) {
051: getStateRoot().invalidateSubtree();
052: }
053: }
054:
055: public boolean isExpanded(final TreePath path) {
056: return getExpandedState(path);
057: }
058:
059: public Rectangle getBounds(final TreePath path,
060: final Rectangle placeIn) {
061: if (nodeDimensions == null || !isRoot(path) && !isVisible(path)) {
062:
063: return null;
064: }
065:
066: return getFixedHeightBoundsImpl(path, placeIn);
067: }
068:
069: public TreePath getPathForRow(final int row) {
070: if (row < 0 || row >= getRowCount()) {
071: return null;
072: }
073:
074: int currentRow = isRootVisible() ? 0 : -1;
075: StateNode parent = getStateRoot();
076: while (true) {
077: if (currentRow == row) {
078: return parent.getModelPath();
079: }
080: if (parent.isLeaf()) {
081: Object modelChildNode = parent.getModelChildNode(row
082: - currentRow - 1);
083: return parent.getModelPath().pathByAddingChild(
084: modelChildNode);
085: }
086:
087: int previousModelIndex = 0;
088: currentRow++;
089: for (int i = 0; i < parent.getChildCount(); i++) {
090: StateNode child = parent.get(i);
091: int childModelIndex = parent.getModelIndexOfChild(child
092: .getModelNode());
093: int rowIncrement = childModelIndex - previousModelIndex;
094: previousModelIndex = childModelIndex;
095: if (row < currentRow + rowIncrement) {
096: Object modelChildNode = parent
097: .getModelChildNode(childModelIndex
098: - (currentRow + rowIncrement - row));
099: return parent.getModelPath().pathByAddingChild(
100: modelChildNode);
101: }
102: if (row == currentRow + rowIncrement) {
103: return child.getModelPath();
104: }
105: currentRow += rowIncrement;
106: if (row > currentRow
107: && row <= currentRow
108: + child.getTotalChildrenCount()) {
109: parent = child;
110: break;
111: }
112:
113: currentRow += child.getTotalChildrenCount();
114:
115: if (i + 1 == parent.getChildCount()) {
116: Object modelChildNode = parent
117: .getModelChildNode(childModelIndex + row
118: - currentRow);
119: return parent.getModelPath().pathByAddingChild(
120: modelChildNode);
121: }
122: }
123: }
124: }
125:
126: public int getRowForPath(final TreePath path) {
127: if (!isVisible(path)) {
128: return -1;
129: }
130:
131: int result = -1;
132: StateNode correspondingNode = getStateNodeForPath(path);
133: StateNode parent = correspondingNode != null ? correspondingNode
134: .getParent()
135: : getStateNodeForPath(path.getParentPath());
136: Object modelNode = path.getLastPathComponent();
137:
138: while (parent != null) {
139: int modelIndex = parent.getModelIndexOfChild(modelNode);
140: for (int i = 0; i < parent.getChildCount(); i++) {
141: StateNode sibling = parent.get(i);
142: int siblingModelIndex = parent
143: .getModelIndexOfChild(sibling.getModelNode());
144: if (siblingModelIndex >= modelIndex) {
145: break;
146: }
147: result += sibling.getTotalChildrenCount();
148: }
149: result += modelIndex + 1;
150:
151: modelNode = parent.getModelNode();
152: parent = parent.getParent();
153: }
154:
155: return isRootVisible() ? result + 1 : result;
156: }
157:
158: public TreePath getPathClosestTo(final int x, final int y) {
159: return getFixedHeightPathClosestToImpl(x, y);
160: }
161:
162: public int getVisibleChildCount(final TreePath path) {
163: return getVisibleChildCountImpl(path);
164: }
165:
166: public Enumeration<TreePath> getVisiblePathsFrom(final TreePath path) {
167: return getVisiblePathsFromImpl(path);
168: }
169:
170: public void setExpandedState(final TreePath path,
171: final boolean isExpanded) {
172: setExpandedStateImpl(path, isExpanded);
173: }
174:
175: public boolean getExpandedState(final TreePath path) {
176: return getExpandedStateImpl(path);
177: }
178:
179: public void treeNodesChanged(final TreeModelEvent e) {
180: treeNodesChangedImpl(e);
181: }
182:
183: public void treeNodesInserted(final TreeModelEvent e) {
184: treeNodesInsertedImpl(e);
185: }
186:
187: public void treeNodesRemoved(final TreeModelEvent e) {
188: treeNodesRemovedImpl(e);
189: }
190:
191: public void treeStructureChanged(final TreeModelEvent e) {
192: treeStructureChangedImpl(e);
193: }
194:
195: class FixedHeightStateNode extends StateNode {
196: public FixedHeightStateNode(final StateNode parent,
197: final TreePath path) {
198: super (parent, path);
199: }
200:
201: public void invalidateTreePartBelow() {
202: invalidate();
203: }
204:
205: protected void validateData() {
206: super .validateData();
207: if (!isExpanded()) {
208: totalChildrenCount = 0;
209: return;
210: }
211:
212: totalChildrenCount = getModelChildCount();
213: for (int i = 0; i < getChildCount(); i++) {
214: StateNode child = get(i);
215: totalChildrenCount += child.getTotalChildrenCount();
216: }
217: }
218: }
219:
220: StateNode createStateNode(final StateNode parent,
221: final TreePath path) {
222: return new FixedHeightStateNode(parent, path);
223: }
224: }
|