API Overview API Index Package Overview Direct link to this page
JDK 1.6
  javax.swing.tree. AbstractLayoutCache View Javadoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514

/*
 * @(#)AbstractLayoutCache.java	1.18 05/11/17
 *
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package javax.swing.tree;

import javax.swing.event.TreeModelEvent;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.Enumeration;

/**
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @version 1.18 11/17/05
 * @author Scott Violet
 */

public abstract class AbstractLayoutCache implements RowMapper {
    /** Object responsible for getting the size of a node. */
    protected NodeDimensions     nodeDimensions;

    /** Model providing information. */
    protected TreeModel          treeModel;

    /** Selection model. */
    protected TreeSelectionModel treeSelectionModel;

    /**
     * True if the root node is displayed, false if its children are
     * the highest visible nodes.
     */
    protected boolean            rootVisible;

    /**
      * Height to use for each row.  If this is <= 0 the renderer will be
      * used to determine the height for each row.
      */
    protected int                rowHeight;


    /**
     * Sets the renderer that is responsible for drawing nodes in the tree
     * and which is threfore responsible for calculating the dimensions of
     * individual nodes.
     *
     * @param nd a <code>NodeDimensions</code> object
     */
    public void setNodeDimensions(NodeDimensions nd) {
	this.nodeDimensions = nd;
    }

    /**
     * Returns the object that renders nodes in the tree, and which is 
     * responsible for calculating the dimensions of individual nodes.
     *
     * @return the <code>NodeDimensions</code> object
     */
    public NodeDimensions getNodeDimensions() {
	return nodeDimensions;
    }

    /**
     * Sets the <code>TreeModel</code> that will provide the data.
     *
     * @param newModel the <code>TreeModel</code> that is to
     *		provide the data
     */
    public void setModel(TreeModel newModel) {
        treeModel = newModel;
    }

    /**
     * Returns the <code>TreeModel</code> that is providing the data.
     *
     * @return the <code>TreeModel</code> that is providing the data
     */
    public TreeModel getModel() {
        return treeModel;
    }

    /**
     * Determines whether or not the root node from
     * the <code>TreeModel</code> is visible.
     *
     * @param rootVisible true if the root node of the tree is to be displayed
     * @see #rootVisible
     * @beaninfo
     *        bound: true
     *  description: Whether or not the root node
     *               from the TreeModel is visible.
     */
    public void setRootVisible(boolean rootVisible) {
        this.rootVisible = rootVisible;
    }

    /**
     * Returns true if the root node of the tree is displayed.
     *
     * @return true if the root node of the tree is displayed
     * @see #rootVisible
     */
    public boolean isRootVisible() {
        return rootVisible;
    }

    /**
     * Sets the height of each cell.  If the specified value
     * is less than or equal to zero the current cell renderer is
     * queried for each row's height.
     *
     * @param rowHeight the height of each cell, in pixels
     * @beaninfo
     *        bound: true
     *  description: The height of each cell.
     */
    public void setRowHeight(int rowHeight) {
        this.rowHeight = rowHeight;
    }

    /**
     * Returns the height of each row.  If the returned value is less than
     * or equal to 0 the height for each row is determined by the
     * renderer.
     */
    public int getRowHeight() {
        return rowHeight;
    }

    /**
     * Sets the <code>TreeSelectionModel</code> used to manage the
     * selection to new LSM.
     *
     * @param newLSM  the new <code>TreeSelectionModel</code>
     */
    public void setSelectionModel(TreeSelectionModel newLSM) {
	if(treeSelectionModel != null)
	    treeSelectionModel.setRowMapper(null);
	treeSelectionModel = newLSM;
	if(treeSelectionModel != null)
	    treeSelectionModel.setRowMapper(this);
    }

    /**
     * Returns the model used to maintain the selection.
     *
     * @return the <code>treeSelectionModel</code>
     */
    public TreeSelectionModel getSelectionModel() {
	return treeSelectionModel;
    }

    /**
     * Returns the preferred height.
     *
     * @return the preferred height
     */
    public int getPreferredHeight() {
	// Get the height
	int           rowCount = getRowCount();

	if(rowCount > 0) {
	    Rectangle     bounds = getBounds(getPathForRow(rowCount - 1),
					     null);

	    if(bounds != null)
		return bounds.y + bounds.height;
	}
	return 0;
    }

    /**
     * Returns the preferred width for the passed in region.
     * The region is defined by the path closest to
     * <code>(bounds.x, bounds.y)</code> and
     * ends at <code>bounds.height + bounds.y</code>.
     * If <code>bounds</code> is <code>null</code>,
     * the preferred width for all the nodes
     * will be returned (and this may be a VERY expensive
     * computation).
     *
     * @param bounds the region being queried
     * @return the preferred width for the passed in region
     */
    public int getPreferredWidth(Rectangle bounds) {
	int           rowCount = getRowCount();

	if(rowCount > 0) {
	    // Get the width
	    TreePath      firstPath;
	    int           endY;

	    if(bounds == null) {
		firstPath = getPathForRow(0);
		endY = Integer.MAX_VALUE;
	    }
	    else {
		firstPath = getPathClosestTo(bounds.x, bounds.y);
		endY = bounds.height + bounds.y;
	    }

	    Enumeration   paths = getVisiblePathsFrom(firstPath);

	    if(paths != null && paths.hasMoreElements()) {
		Rectangle   pBounds = getBounds((TreePath)paths.nextElement(),
						null);
		int         width;

		if(pBounds != null) {
		    width = pBounds.x + pBounds.width;
		    if (pBounds.y >= endY) {
			return width;
		    }
		}
		else
		    width = 0;
		while (pBounds != null && paths.hasMoreElements()) {
		    pBounds = getBounds((TreePath)paths.nextElement(),
					pBounds);
		    if (pBounds != null && pBounds.y < endY) {
			width = Math.max(width, pBounds.x + pBounds.width);
		    }
		    else {
			pBounds = null;
		    }
		}
		return width;
	    }
	}
	return 0;
    }

    //
    // Abstract methods that must be implemented to be concrete.
    //

    /**
      * Returns true if the value identified by row is currently expanded.
      */
    public abstract boolean isExpanded(TreePath path);

    /**
     * Returns a rectangle giving the bounds needed to draw path.
     *
     * @param path     a <code>TreePath</code> specifying a node
     * @param placeIn  a <code>Rectangle</code> object giving the
     *		available space
     * @return a <code>Rectangle</code> object specifying the space to be used
     */
    public abstract Rectangle getBounds(TreePath path, Rectangle placeIn);

    /**
      * Returns the path for passed in row.  If row is not visible
      * <code>null</code> is returned.
      *
      * @param row  the row being queried
      * @return the <code>TreePath</code> for the given row
      */
    public abstract TreePath getPathForRow(int row);

    /**
      * Returns the row that the last item identified in path is visible
      * at.  Will return -1 if any of the elements in path are not
      * currently visible.
      *
      * @param path the <code>TreePath</code> being queried
      * @return the row where the last item in path is visible or -1
      *		if any elements in path aren't currently visible
      */
    public abstract int getRowForPath(TreePath path);

    /**
      * Returns the path to the node that is closest to x,y.  If
      * there is nothing currently visible this will return <code>null</code>,
      * otherwise it'll always return a valid path.
      * If you need to test if the
      * returned object is exactly at x, y you should get the bounds for
      * the returned path and test x, y against that.
      *
      * @param x the horizontal component of the desired location
      * @param y the vertical component of the desired location
      * @return the <code>TreePath</code> closest to the specified point
      */
    public abstract TreePath getPathClosestTo(int x, int y);

    /**
     * Returns an <code>Enumerator</code> that increments over the visible 
     * paths starting at the passed in location. The ordering of the 
     * enumeration is based on how the paths are displayed.
     * The first element of the returned enumeration will be path,
     * unless it isn't visible,
     * in which case <code>null</code> will be returned.
     *
     * @param path the starting location for the enumeration
     * @return the <code>Enumerator</code> starting at the desired location
     */
    public abstract Enumeration<TreePath> getVisiblePathsFrom(TreePath path);

    /**
     * Returns the number of visible children for row.
     * 
     * @param path  the path being queried
     * @return the number of visible children for the specified path
     */
    public abstract int getVisibleChildCount(TreePath path);

    /**
     * Marks the path <code>path</code> expanded state to
     * <code>isExpanded</code>.
     *
     * @param path  the path being expanded or collapsed
     * @param isExpanded true if the path should be expanded, false otherwise 
     */
    public abstract void setExpandedState(TreePath path, boolean isExpanded);

    /**
     * Returns true if the path is expanded, and visible.
     *
     * @param path  the path being queried
     * @return true if the path is expanded and visible, false otherwise
     */
    public abstract boolean getExpandedState(TreePath path);

    /**
     * Number of rows being displayed.
     * 
     * @return the number of rows being displayed
     */
    public abstract int getRowCount();

    /**
     * Informs the <code>TreeState</code> that it needs to recalculate
     * all the sizes it is referencing.
     */
    public abstract void invalidateSizes();

    /**
     * Instructs the <code>LayoutCache</code> that the bounds for
     * <code>path</code> are invalid, and need to be updated.
     *
     * @param path the path being updated
     */
    public abstract void invalidatePathBounds(TreePath path);

    //
    // TreeModelListener methods
    // AbstractTreeState does not directly become a TreeModelListener on
    // the model, it is up to some other object to forward these methods.
    //

    /**
     * <p>
     * Invoked after a node (or a set of siblings) has changed in some
     * way. The node(s) have not changed locations in the tree or
     * altered their children arrays, but other attributes have
     * changed and may affect presentation. Example: the name of a
     * file has changed, but it is in the same location in the file
     * system.</p>
     *
     * <p>e.path() returns the path the parent of the changed node(s).</p>
     *
     * <p>e.childIndices() returns the index(es) of the changed node(s).</p>
     *
     * @param e  the <code>TreeModelEvent</code>
     */
    public abstract void treeNodesChanged(TreeModelEvent e);

    /**
     * <p>Invoked after nodes have been inserted into the tree.</p>
     *
     * <p>e.path() returns the parent of the new nodes</p>
     * <p>e.childIndices() returns the indices of the new nodes in
     * ascending order.</p>
     *
     * @param e the <code>TreeModelEvent</code>
     */
    public abstract void treeNodesInserted(TreeModelEvent e);

    /**
     * <p>Invoked after nodes have been removed from the tree.  Note that
     * if a subtree is removed from the tree, this method may only be
     * invoked once for the root of the removed subtree, not once for
     * each individual set of siblings removed.</p>
     *
     * <p>e.path() returns the former parent of the deleted nodes.</p>
     *
     * <p>e.childIndices() returns the indices the nodes had before they were deleted in ascending order.</p>
     *
     * @param e the <code>TreeModelEvent</code>
     */
    public abstract void treeNodesRemoved(TreeModelEvent e);

    /**
     * <p>Invoked after the tree has drastically changed structure from a
     * given node down.  If the path returned by <code>e.getPath()</code>
     * is of length one and the first element does not identify the
     * current root node the first element should become the new root
     * of the tree.</p>
     *
     * <p>e.path() holds the path to the node.</p>
     * <p>e.childIndices() returns null.</p>
     *
     * @param e the <code>TreeModelEvent</code>
     */
    public abstract void treeStructureChanged(TreeModelEvent e);

    //
    // RowMapper
    //

    /**
     * Returns the rows that the <code>TreePath</code> instances in
     * <code>path</code> are being displayed at.
     * This method should return an array of the same length as that passed
     * in, and if one of the <code>TreePaths</code>
     * in <code>path</code> is not valid its entry in the array should
     * be set to -1.
     *
     * @param paths the array of <code>TreePath</code>s being queried
     * @return an array of the same length that is passed in containing
     *		the rows that each corresponding where each
     *		<code>TreePath</code> is displayed; if <code>paths</code>
     *		is <code>null</code>, <code>null</code> is returned
     */
    public int[] getRowsForPaths(TreePath[] paths) {
	if(paths == null)
	    return null;

	int               numPaths = paths.length;
	int[]             rows = new int[numPaths];

	for(int counter = 0; counter < numPaths; counter++)
	    rows[counter] = getRowForPath(paths[counter]);
	return rows;
    }

    //
    // Local methods that subclassers may wish to use that are primarly
    // convenience methods.
    //

    /**
     * Returns, by reference in <code>placeIn</code>,
     * the size needed to represent <code>value</code>.
     * If <code>inPlace</code> is <code>null</code>, a newly created
     * <code>Rectangle</code> should be returned, otherwise the value
     * should be placed in <code>inPlace</code> and returned. This will
     * return <code>null</code> if there is no renderer.
     *
     * @param value the <code>value</code> to be represented
     * @param row  row being queried
     * @param depth the depth of the row
     * @param expanded true if row is expanded, false otherwise 
     * @param placeIn  a <code>Rectangle</code> containing the size needed
     *		to represent <code>value</code>
     * @return a <code>Rectangle</code> containing the node dimensions,
     *		or <code>null</code> if node has no dimension
     */
    protected Rectangle getNodeDimensions(Object value, int row, int depth,
					  boolean expanded,
					  Rectangle placeIn) {
	NodeDimensions            nd = getNodeDimensions();

	if(nd != null) {
	    return nd.getNodeDimensions(value, row, depth, expanded, placeIn);
	}
	return null;
    }

    /**
      * Returns true if the height of each row is a fixed size.
      */
    protected boolean isFixedRowHeight() {
	return (rowHeight > 0);
    }


    /**
     * Used by <code>AbstractLayoutCache</code> to determine the size
     * and x origin of a particular node.
     */
    static public abstract class NodeDimensions {
	/**
	 * Returns, by reference in bounds, the size and x origin to
	 * place value at. The calling method is responsible for determining
	 * the Y location. If bounds is <code>null</code>, a newly created
	 * <code>Rectangle</code> should be returned,
         * otherwise the value should be placed in bounds and returned.
         *
         * @param value the <code>value</code> to be represented
    	 * @param row row being queried
  	 * @param depth the depth of the row
	 * @param expanded true if row is expanded, false otherwise
         * @param bounds  a <code>Rectangle</code> containing the size needed
         *		to represent <code>value</code>
   	 * @return a <code>Rectangle</code> containing the node dimensions,
	 * 		or <code>null</code> if node has no dimension
	 */
	public abstract Rectangle getNodeDimensions(Object value, int row,
						    int depth,
						    boolean expanded,
						    Rectangle bounds);
    }
}

Generated By: JavaOnTracks Doclet 0.1.4     ©Thibaut Colar