Frames | No Frames |
1: /* AbstractLayoutCache.java -- 2: Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.tree; 40: 41: import java.awt.Rectangle; 42: import java.util.Enumeration; 43: 44: import javax.swing.event.TreeModelEvent; 45: 46: /** 47: * class AbstractLayoutCache 48: * 49: * @author Andrew Selkirk 50: */ 51: public abstract class AbstractLayoutCache 52: implements RowMapper 53: { 54: /** 55: * class NodeDimensions 56: */ 57: public abstract static class NodeDimensions 58: { 59: /** 60: * Creates <code>NodeDimensions</code> object. 61: */ 62: public NodeDimensions() 63: { 64: // Do nothing here. 65: } 66: 67: /** 68: * Get the node dimensions. The NodeDimensions property must be set (unless 69: * the method is overridden, like if {@link FixedHeightLayoutCache}. If the 70: * method is not overridden and the property is not set, the InternalError is 71: * thrown. 72: * 73: * @param value the last node in the path 74: * @param row the node row 75: * @param depth the indentation depth 76: * @param expanded true if this node is expanded, false otherwise 77: * @param bounds the area where the tree is displayed 78: */ 79: public abstract Rectangle getNodeDimensions(Object value, int row, 80: int depth, boolean expanded, 81: Rectangle bounds); 82: } 83: 84: /** 85: * nodeDimensions 86: */ 87: protected NodeDimensions nodeDimensions; 88: 89: /** 90: * treeModel 91: */ 92: protected TreeModel treeModel; 93: 94: /** 95: * treeSelectionModel 96: */ 97: protected TreeSelectionModel treeSelectionModel; 98: 99: /** 100: * rootVisible 101: */ 102: protected boolean rootVisible; 103: 104: /** 105: * rowHeight 106: */ 107: protected int rowHeight; 108: 109: /** 110: * Constructor AbstractLayoutCache 111: */ 112: public AbstractLayoutCache() 113: { 114: // Do nothing here. 115: } 116: 117: /** 118: * setNodeDimensions 119: * 120: * @param dimensions TODO 121: */ 122: public void setNodeDimensions(NodeDimensions dimensions) 123: { 124: nodeDimensions = dimensions; 125: } 126: 127: /** 128: * getNodeDimensions 129: * 130: * @return NodeDimensions 131: */ 132: public NodeDimensions getNodeDimensions() 133: { 134: return nodeDimensions; 135: } 136: 137: /** 138: * Get the node dimensions. The NodeDimensions property must be set 139: * (unless the method is overridden, like if 140: * {@link FixedHeightLayoutCache}. If the method is not overridden and 141: * the property is not set, the InternalError is thrown. 142: * 143: * @param value the last node in the path 144: * @param row the node row 145: * @param depth the indentation depth 146: * @param expanded true if this node is expanded, false otherwise 147: * @param bounds the area where the tree is displayed 148: */ 149: protected Rectangle getNodeDimensions(Object value, int row, int depth, 150: boolean expanded, Rectangle bounds) 151: { 152: Rectangle d = null; 153: if (nodeDimensions != null) 154: d = nodeDimensions.getNodeDimensions(value, row, depth, expanded, 155: bounds); 156: return d; 157: } 158: 159: /** 160: * Sets the model that provides the tree data. 161: * 162: * @param model the model 163: */ 164: public void setModel(TreeModel model) 165: { 166: treeModel = model; 167: } 168: 169: /** 170: * Returns the model that provides the tree data. 171: * 172: * @return the model 173: */ 174: public TreeModel getModel() 175: { 176: return treeModel; 177: } 178: 179: /** 180: * setRootVisible 181: * 182: * @param visible <code>true</code> if root should be visible, 183: * <code>false</code> otherwise 184: */ 185: public void setRootVisible(boolean visible) 186: { 187: rootVisible = visible; 188: } 189: 190: /** 191: * isRootVisible 192: * 193: * @return <code>true</code> if root is visible, 194: * <code>false</code> otherwise 195: */ 196: public boolean isRootVisible() 197: { 198: return rootVisible; 199: } 200: 201: /** 202: * setRowHeight 203: * 204: * @param height the row height 205: */ 206: public void setRowHeight(int height) 207: { 208: rowHeight = height; 209: invalidateSizes(); 210: } 211: 212: /** 213: * getRowHeight 214: * 215: * @return the row height 216: */ 217: public int getRowHeight() 218: { 219: return rowHeight; 220: } 221: 222: /** 223: * setSelectionModel 224: * 225: * @param model the model 226: */ 227: public void setSelectionModel(TreeSelectionModel model) 228: { 229: if (treeSelectionModel != null) 230: treeSelectionModel.setRowMapper(null); 231: treeSelectionModel = model; 232: if (treeSelectionModel != null) 233: treeSelectionModel.setRowMapper(this); 234: 235: } 236: 237: /** 238: * getSelectionModel 239: * 240: * @return the model 241: */ 242: public TreeSelectionModel getSelectionModel() 243: { 244: return treeSelectionModel; 245: } 246: 247: /** 248: * Get the sum of heights for all rows. This class provides a general not 249: * optimized implementation that is overridded in derived classes 250: * ({@link VariableHeightLayoutCache}, {@link FixedHeightLayoutCache}) for 251: * the better performance. 252: */ 253: public int getPreferredHeight() 254: { 255: int height = 0; 256: int n = getRowCount(); 257: Rectangle r = new Rectangle(); 258: for (int i = 0; i < n; i++) 259: { 260: TreePath path = getPathForRow(i); 261: height += getBounds(path, r).height; 262: } 263: return height; 264: } 265: 266: /** 267: * Get the maximal width. This class provides a general not 268: * optimized implementation that is overridded in derived classes 269: * ({@link VariableHeightLayoutCache}, {@link FixedHeightLayoutCache}) for 270: * the better performance. 271: * 272: * @param rect the rectangle that is used during the method work 273: */ 274: public int getPreferredWidth(Rectangle rect) 275: { 276: int maximalWidth = 0; 277: Rectangle r = new Rectangle(); 278: int n = getRowCount(); 279: for (int i = 0; i < n; i++) 280: { 281: TreePath path = getPathForRow(i); 282: r.setBounds(0, 0, 0, 0); 283: r = getBounds(path, r); 284: if (r.x + r.width > maximalWidth) 285: maximalWidth = r.x + r.width; 286: // Invalidate the cached value as this may be the very early call 287: // before the heigth is properly set (the vertical coordinate may 288: // not be correct). 289: invalidatePathBounds(path); 290: } 291: return maximalWidth; 292: } 293: /** 294: * isExpanded 295: * 296: * @param value0 TODO 297: * 298: * @return boolean 299: */ 300: public abstract boolean isExpanded(TreePath value0); 301: 302: /** 303: * getBounds 304: * 305: * @param value0 TODO 306: * @param value1 TODO 307: * 308: * @return Rectangle 309: */ 310: public abstract Rectangle getBounds(TreePath value0, Rectangle value1); 311: 312: /** 313: * getPathForRow 314: * 315: * @param row the row 316: * 317: * @return the tree path 318: */ 319: public abstract TreePath getPathForRow(int row); 320: 321: /** 322: * getRowForPath 323: * 324: * @param path the tree path 325: * 326: * @return the row 327: */ 328: public abstract int getRowForPath(TreePath path); 329: 330: /** 331: * getPathClosestTo 332: * 333: * @param value0 TODO 334: * @param value1 TODO 335: * 336: * @return the tree path 337: */ 338: public abstract TreePath getPathClosestTo(int value0, int value1); 339: 340: /** 341: * getVisiblePathsFrom 342: * 343: * @param path the tree path 344: * 345: * @return Enumeration 346: */ 347: public abstract Enumeration<TreePath> getVisiblePathsFrom(TreePath path); 348: 349: /** 350: * getVisibleChildCount 351: * 352: * @param path the tree path 353: * 354: * @return int 355: */ 356: public abstract int getVisibleChildCount(TreePath path); 357: 358: /** 359: * setExpandedState 360: * 361: * @param value0 TODO 362: * 363: * @param value1 TODO 364: */ 365: public abstract void setExpandedState(TreePath value0, boolean value1); 366: 367: /** 368: * getExpandedState 369: * 370: * @param path the tree path 371: * 372: * @return boolean 373: */ 374: public abstract boolean getExpandedState(TreePath path); 375: 376: /** 377: * getRowCount 378: * 379: * @return the number of rows 380: */ 381: public abstract int getRowCount(); 382: 383: /** 384: * invalidateSizes 385: */ 386: public abstract void invalidateSizes(); 387: 388: /** 389: * invalidatePathBounds 390: * 391: * @param path the tree path 392: */ 393: public abstract void invalidatePathBounds(TreePath path); 394: 395: /** 396: * treeNodesChanged 397: * 398: * @param event the event to send 399: */ 400: public abstract void treeNodesChanged(TreeModelEvent event); 401: 402: /** 403: * treeNodesInserted 404: * 405: * @param event the event to send 406: */ 407: public abstract void treeNodesInserted(TreeModelEvent event); 408: 409: /** 410: * treeNodesRemoved 411: * 412: * @param event the event to send 413: */ 414: public abstract void treeNodesRemoved(TreeModelEvent event); 415: 416: /** 417: * treeStructureChanged 418: * 419: * @param event the event to send 420: */ 421: public abstract void treeStructureChanged(TreeModelEvent event); 422: 423: /** 424: * Get the tree row numbers for the given pathes. This method performs 425: * the "bulk" conversion that may be faster than mapping pathes one by 426: * one. To have the benefit from the bulk conversion, the method must be 427: * overridden in the derived classes. The default method delegates work 428: * to the {@link #getRowForPath(TreePath)}. 429: * 430: * @param paths the tree paths the array of the tree pathes. 431: * @return the array of the matching tree rows. 432: */ 433: public int[] getRowsForPaths(TreePath[] paths) 434: { 435: int[] rows = null; 436: if (paths != null) 437: { 438: rows = new int[paths.length]; 439: for (int i = 0; i < rows.length; i++) 440: rows[i] = getRowForPath(paths[i]); 441: } 442: return rows; 443: } 444: 445: /** 446: * Returns true if this layout supposes that all rows have the fixed 447: * height. 448: * 449: * @return boolean true if all rows in the tree must have the fixed 450: * height (false by default). 451: */ 452: protected boolean isFixedRowHeight() 453: { 454: return rowHeight > 0; 455: } 456: }