1 |
/* BasicTreeUI.java -- |
/* BasicTreeUI.java -- |
2 |
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. |
Copyright (C) 2002, 2004 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
35 |
obligated to do so. If you do not wish to do so, delete this |
obligated to do so. If you do not wish to do so, delete this |
36 |
exception statement from your version. */ |
exception statement from your version. */ |
37 |
|
|
|
|
|
38 |
package javax.swing.plaf.basic; |
package javax.swing.plaf.basic; |
39 |
|
|
40 |
import java.awt.Color; |
import java.awt.Color; |
41 |
import java.awt.Component; |
import java.awt.Component; |
42 |
import java.awt.Dimension; |
import java.awt.Dimension; |
43 |
import java.awt.Graphics; |
import java.awt.Graphics; |
44 |
|
import java.awt.Point; |
45 |
import java.awt.Rectangle; |
import java.awt.Rectangle; |
46 |
|
import java.awt.event.ActionEvent; |
47 |
|
import java.awt.event.ActionListener; |
48 |
|
import java.awt.event.ComponentAdapter; |
49 |
|
import java.awt.event.ComponentEvent; |
50 |
|
import java.awt.event.ComponentListener; |
51 |
|
import java.awt.event.FocusEvent; |
52 |
|
import java.awt.event.FocusListener; |
53 |
|
import java.awt.event.KeyAdapter; |
54 |
|
import java.awt.event.KeyEvent; |
55 |
|
import java.awt.event.KeyListener; |
56 |
|
import java.awt.event.MouseAdapter; |
57 |
|
import java.awt.event.MouseEvent; |
58 |
|
import java.awt.event.MouseListener; |
59 |
|
import java.awt.event.MouseMotionListener; |
60 |
|
|
61 |
|
import java.beans.PropertyChangeEvent; |
62 |
|
import java.beans.PropertyChangeListener; |
63 |
|
|
64 |
|
import javax.swing.AbstractAction; |
65 |
|
import javax.swing.Action; |
66 |
|
import javax.swing.CellRendererPane; |
67 |
|
import javax.swing.Icon; |
68 |
import javax.swing.JComponent; |
import javax.swing.JComponent; |
69 |
|
import javax.swing.JScrollBar; |
70 |
|
import javax.swing.JScrollPane; |
71 |
import javax.swing.JTree; |
import javax.swing.JTree; |
72 |
|
import javax.swing.Timer; |
73 |
import javax.swing.UIDefaults; |
import javax.swing.UIDefaults; |
74 |
import javax.swing.UIManager; |
import javax.swing.UIManager; |
75 |
|
import javax.swing.event.CellEditorListener; |
76 |
|
import javax.swing.event.ChangeEvent; |
77 |
|
import javax.swing.event.MouseInputListener; |
78 |
|
import javax.swing.event.TreeExpansionEvent; |
79 |
|
import javax.swing.event.TreeExpansionListener; |
80 |
|
import javax.swing.event.TreeModelEvent; |
81 |
|
import javax.swing.event.TreeModelListener; |
82 |
|
import javax.swing.event.TreeSelectionEvent; |
83 |
|
import javax.swing.event.TreeSelectionListener; |
84 |
import javax.swing.plaf.ComponentUI; |
import javax.swing.plaf.ComponentUI; |
85 |
import javax.swing.plaf.TreeUI; |
import javax.swing.plaf.TreeUI; |
86 |
|
import javax.swing.tree.AbstractLayoutCache; |
87 |
|
import javax.swing.tree.FixedHeightLayoutCache; |
88 |
|
import javax.swing.tree.DefaultMutableTreeNode; |
89 |
|
import javax.swing.tree.DefaultTreeCellEditor; |
90 |
|
import javax.swing.tree.DefaultTreeCellRenderer; |
91 |
|
import javax.swing.tree.TreeCellEditor; |
92 |
|
import javax.swing.tree.TreeCellRenderer; |
93 |
|
import javax.swing.tree.TreeSelectionModel; |
94 |
import javax.swing.tree.TreeModel; |
import javax.swing.tree.TreeModel; |
95 |
|
import javax.swing.tree.TreeNode; |
96 |
import javax.swing.tree.TreePath; |
import javax.swing.tree.TreePath; |
97 |
|
|
98 |
|
import java.util.Enumeration; |
99 |
|
import java.util.Hashtable; |
100 |
|
|
101 |
/** |
/** |
102 |
* A delegate providing the user interface for <code>JTree</code> |
* A delegate providing the user interface for <code>JTree</code> according to |
103 |
* according to the Basic look and feel. The current implementation |
* the Basic look and feel. |
104 |
* of GNU Classpath does really work; it is just a stub that allows |
* |
|
* compiling the code. |
|
|
* |
|
105 |
* @see javax.swing.JTree |
* @see javax.swing.JTree |
|
* |
|
106 |
* @author Sascha Brawer (brawer@dandelis.ch) |
* @author Sascha Brawer (brawer@dandelis.ch) |
107 |
|
* @author Lillian Angel (langel@redhat.com) |
108 |
*/ |
*/ |
109 |
public class BasicTreeUI |
public class BasicTreeUI |
110 |
extends TreeUI |
extends TreeUI |
111 |
{ |
{ |
112 |
|
|
113 |
/** |
/** Collapse Icon for the tree. */ |
114 |
* Determines the geometric extent of the label that is |
protected transient Icon collapsedIcon; |
115 |
* drawn for a path. |
|
116 |
* |
/** Expanded Icon for the tree. */ |
117 |
* @param tree the <code>JTree</code> for which this delegate |
protected transient Icon expandedIcon; |
118 |
* object provides the user interface. |
|
119 |
* |
/** Distance between left margin and where vertical dashes will be drawn. */ |
120 |
* @param path the path whose label extent is requested. |
protected int leftChildIndent; |
121 |
* |
|
122 |
* @return a rectangle enclosing the label, or <code>null</code> |
/** |
123 |
* if <code>path</code> contains invalid nodes. |
* Distance between leftChildIndent and where cell contents will be drawn. |
124 |
*/ |
*/ |
125 |
public Rectangle getPathBounds(JTree tree, TreePath path) |
protected int rightChildIndent; |
126 |
{ |
|
127 |
return null; // FIXME: not implemented |
/** |
128 |
} |
* Total fistance that will be indented. The sum of leftChildIndent and |
129 |
|
* rightChildIndent . |
130 |
|
*/ |
131 |
/** |
protected int totalChildIndent; |
132 |
* Creates a <code>TreePath</code> for the specified row. |
|
133 |
* |
/** Minimum preferred size. */ |
134 |
* @param tree the <code>JTree</code> for which this delegate |
protected Dimension preferredMinsize; |
135 |
* object provides the user interface. |
|
136 |
* |
/** Index of the row that was last selected. */ |
137 |
* @param row the index of the row, which should be a number |
protected int lastSelectedRow; |
138 |
* in the range <code>[0, getRowCount(tree) - 1]</code>. |
|
139 |
* |
/** Component that we're going to be drawing onto. */ |
140 |
* @return a <code>TreePath</code> for the specified row, or |
protected JTree tree; |
141 |
* <code>null</code> if <code>row</code> is outside |
|
142 |
* the valid range. |
/** Renderer that is being used to do the actual cell drawing. */ |
143 |
*/ |
protected transient TreeCellRenderer currentCellRenderer; |
144 |
public TreePath getPathForRow(JTree tree, int row) |
|
145 |
{ |
/** |
146 |
return null; // FIXME: not implemented |
* Set to true if the renderer that is currently in the tree was created by |
147 |
} |
* this instance. |
148 |
|
*/ |
149 |
|
protected boolean createdRenderer; |
150 |
/** |
|
151 |
* Determines in which row a <code>TreePath</code> is currently |
/** Editor for the tree. */ |
152 |
* being displayed. |
protected transient TreeCellEditor cellEditor; |
153 |
* |
|
154 |
* @param tree the <code>JTree</code> for which this delegate |
/** |
155 |
* object provides the user interface. |
* Set to true if editor that is currently in the tree was created by this |
156 |
* |
* instance. |
157 |
* @param path the path for which the caller wants to know |
*/ |
158 |
* in which row it is being displayed. |
protected boolean createdCellEditor; |
159 |
* |
|
160 |
* @return a number in the range <code>[0, getRowCount(tree) |
/** |
161 |
* - 1]</code> if the path is currently on display; |
* Set to false when editing and shouldSelectCall() returns true meaning the |
162 |
* <code>-1</code> if the path is not shown to the |
* node should be selected before editing, used in completeEditing. |
163 |
* user. |
*/ |
164 |
*/ |
protected boolean stopEditingInCompleteEditing; |
165 |
public int getRowForPath(JTree tree, TreePath path) |
|
166 |
{ |
/** Used to paint the TreeCellRenderer. */ |
167 |
return -1; // FIXME: not implemented |
protected CellRendererPane rendererPane; |
168 |
} |
|
169 |
|
/** Size needed to completely display all the nodes. */ |
170 |
|
protected Dimension preferredSize; |
171 |
/** |
|
172 |
* Counts how many rows are currently displayed. |
/** Is the preferredSize valid? */ |
173 |
* |
protected boolean validCachedPreferredSize; |
174 |
* @param tree the <code>JTree</code> for which this delegate |
|
175 |
* object provides the user interface. |
/** Object responsible for handling sizing and expanded issues. */ |
176 |
* |
protected AbstractLayoutCache treeState; |
177 |
* @return the number of visible rows. |
|
178 |
*/ |
/** Used for minimizing the drawing of vertical lines. */ |
179 |
public int getRowCount(JTree tree) |
protected Hashtable drawingCache; |
180 |
{ |
|
181 |
return 0; // FIXME: not implemented |
/** |
182 |
} |
* True if doing optimizations for a largeModel. Subclasses that don't |
183 |
|
* support this may wish to override createLayoutCache to not return a |
184 |
|
* FixedHeightLayoutCache instance. |
185 |
/** |
*/ |
186 |
* Finds the path that is closest to the specified position. |
protected boolean largeModel; |
187 |
* |
|
188 |
* <p><img src="../doc-files/TreeUI-1.png" width="300" height="250" |
/** Responsible for telling the TreeState the size needed for a node. */ |
189 |
* alt="[A screen shot of a JTree]" /> |
protected AbstractLayoutCache.NodeDimensions nodeDimensions; |
190 |
* |
|
191 |
* <p>As shown by the above illustration, the bounds of the |
/** Used to determine what to display. */ |
192 |
* closest path do not necessarily need to contain the passed |
protected TreeModel treeModel; |
193 |
* location. |
|
194 |
* |
/** Model maintaining the selection. */ |
195 |
* @param tree the <code>JTree</code> for which this delegate |
protected TreeSelectionModel treeSelectionModel; |
196 |
* object provides the user interface. |
|
197 |
* |
/** |
198 |
* @param x the horizontal location, relative to the origin |
* How much the depth should be offset to properly calculate x locations. |
199 |
* of <code>tree</code>. |
* This is based on whether or not the root is visible, and if the root |
200 |
* |
* handles are visible. |
201 |
* @param y the vertical location, relative to the origin |
*/ |
202 |
* of <code>tree</code>. |
protected int depthOffset; |
203 |
* |
|
204 |
* @return the closest path, or <code>null</code> if the |
/** |
205 |
* tree is currenlty not displaying any paths at all. |
* When editing, this will be the Component that is doing the actual |
206 |
*/ |
* editing. |
207 |
public TreePath getClosestPathForLocation(JTree tree, |
*/ |
208 |
int x, int y) |
protected Component editingComponent; |
209 |
{ |
|
210 |
return null; // FIXME: not implemented |
/** Path that is being edited. */ |
211 |
} |
protected TreePath editingPath; |
212 |
|
|
213 |
|
/** |
214 |
/** |
* Row that is being edited. Should only be referenced if editingComponent |
215 |
* Determines whether the user is currently editing a tree cell. |
* is null. |
216 |
* |
*/ |
217 |
* @param tree the <code>JTree</code> for which this delegate |
protected int editingRow; |
218 |
* object provides the user interface. |
|
219 |
* |
/** Set to true if the editor has a different size than the renderer. */ |
220 |
* @see #getEditingPath |
protected boolean editorHasDifferentSize; |
221 |
*/ |
|
222 |
public boolean isEditing(JTree tree) |
/** Listeners */ |
223 |
{ |
private PropertyChangeListener propertyChangeListener; |
224 |
return false; // FIXME: not implemented |
|
225 |
} |
private FocusListener focusListener; |
226 |
|
|
227 |
|
private TreeSelectionListener treeSelectionListener; |
228 |
/** |
|
229 |
* Stops editing a tree cell, committing the entered value into the |
private MouseInputListener mouseInputListener; |
230 |
* tree’s model. If no editing session is active, or if the |
|
231 |
* active editor does not agree to stopping, nothing happens. In |
private KeyListener keyListener; |
232 |
* some look and feels, this action happens when the user has |
|
233 |
* pressed the enter key. |
private PropertyChangeListener selectionModelPropertyChangeListener; |
234 |
* |
|
235 |
* @param tree the <code>JTree</code> for which this delegate |
private ComponentListener componentListener; |
236 |
* object provides the user interface. |
|
237 |
* |
private CellEditorListener cellEditorListener; |
238 |
* @return <code>false</code> if the editing still goes on because |
|
239 |
* the cell editor has objected to stopping the session; |
private TreeExpansionListener treeExpansionListener; |
240 |
* <code>true</code> if editing has been stopped. |
|
241 |
*/ |
private TreeModelListener treeModelListener; |
242 |
public boolean stopEditing(JTree tree) |
|
243 |
{ |
/** |
244 |
return true; // FIXME: not implemented |
* Creates a new BasicTreeUI object. |
245 |
} |
*/ |
246 |
|
public BasicTreeUI() |
247 |
/** |
{ |
248 |
* Cancels editing a tree cell, discarding any entered value. |
drawingCache = new Hashtable(); |
249 |
* If no editing session is active, nothing happens. The cell |
cellEditor = createDefaultCellEditor(); |
250 |
* editor is not given an opportunity to veto the canceling. |
currentCellRenderer = createDefaultCellRenderer(); |
251 |
* In some look and feels, this action happens when the user has |
nodeDimensions = createNodeDimensions(); |
252 |
* pressed the escape key. |
rendererPane = createCellRendererPane(); |
253 |
* |
configureLayoutCache(); |
254 |
* @param tree the <code>JTree</code> for which this delegate |
|
255 |
* object provides the user interface. |
propertyChangeListener = createPropertyChangeListener(); |
256 |
*/ |
focusListener = createFocusListener(); |
257 |
public void cancelEditing(JTree tree) |
treeSelectionListener = createTreeSelectionListener(); |
258 |
{ |
mouseInputListener = new MouseInputHandler(null, null, null); |
259 |
// FIXME: not implemented |
keyListener = createKeyListener(); |
260 |
} |
selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener(); |
261 |
|
componentListener = createComponentListener(); |
262 |
|
cellEditorListener = createCellEditorListener(); |
263 |
/** |
treeExpansionListener = createTreeExpansionListener(); |
264 |
* Starts a session to edit a tree cell. If the cell editor |
treeModelListener = createTreeModelListener(); |
265 |
* rejects editing the cell, it will just be selected. |
|
266 |
* |
createdRenderer = true; |
267 |
* @param tree the <code>JTree</code> for which this delegate |
createdCellEditor = true; |
268 |
* object provides the user interface. |
editingRow = -1; |
269 |
* |
lastSelectedRow = -1; |
270 |
* @param path the cell to edit. |
} |
271 |
*/ |
|
272 |
public void startEditingAtPath(JTree tree, TreePath path) |
/** |
273 |
{ |
* Returns an instance of the UI delegate for the specified component. |
274 |
// FIXME: not implemented |
* |
275 |
} |
* @param c the <code>JComponent</code> for which we need a UI delegate |
276 |
|
* for. |
277 |
|
* @return the <code>ComponentUI</code> for c. |
278 |
/** |
*/ |
279 |
* Retrieves the tree cell that is currently being edited. |
public static ComponentUI createUI(JComponent c) |
280 |
* |
{ |
281 |
* @return the currently edited path, or <code>null</code> |
return new BasicTreeUI(); |
282 |
* if no editing session is currently active. |
} |
283 |
*/ |
|
284 |
public TreePath getEditingPath(JTree tree) |
/** |
285 |
{ |
* Returns the Hash color. |
286 |
return null; // FIXME: not implemented |
* |
287 |
} |
* @return the <code>Color</code> of the Hash. |
288 |
|
*/ |
289 |
public static ComponentUI createUI(JComponent c) |
protected Color getHashColor() |
290 |
{ |
{ |
291 |
return new BasicTreeUI(); |
return UIManager.getLookAndFeelDefaults().getColor("Tree.hash"); |
292 |
} |
} |
293 |
|
|
294 |
int rightChildIndent; |
/** |
295 |
int leftChildIndent; |
* Sets the Hash color. |
296 |
int rowHeight; |
* |
297 |
Color hashColor; |
* @param the <code>Color</code> to set the Hash to. |
298 |
|
*/ |
299 |
protected void installDefaults(JTree tree) |
protected void setHashColor(Color color) |
300 |
{ |
{ |
301 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
// FIXME: not implemented |
302 |
|
|
303 |
tree.setFont(defaults.getFont("Tree.font")); |
} |
304 |
tree.setForeground(defaults.getColor("Tree.foreground")); |
|
305 |
tree.setBackground(defaults.getColor("Tree.background")); |
/** |
306 |
tree.setOpaque(true); |
* Sets the left child's indent value. |
307 |
|
* |
308 |
hashColor = defaults.getColor("Tree.hash"); |
* @param newAmount is the new indent value for the left child. |
309 |
rightChildIndent = defaults.getInt("Tree.rightChildIndent"); |
*/ |
310 |
leftChildIndent = defaults.getInt("Tree.leftChildIndent"); |
public void setLeftChildIndent(int newAmount) |
311 |
rowHeight = defaults.getInt("Tree.rowHeight"); |
{ |
312 |
} |
leftChildIndent = newAmount; |
313 |
|
} |
314 |
protected void installKeyboardActions() |
|
315 |
{ |
/** |
316 |
} |
* Returns the indent value for the left child. |
317 |
|
* |
318 |
protected void installListeners() |
* @return the indent value for the left child. |
319 |
{ |
*/ |
320 |
} |
public int getLeftChildIndent(int newAmount) |
321 |
|
{ |
322 |
public void installUI(JComponent c) |
return leftChildIndent; |
323 |
{ |
} |
324 |
installDefaults((JTree) c); |
|
325 |
} |
/** |
326 |
|
* Sets the right child's indent value. |
327 |
|
* |
328 |
protected void uninstallDefaults(JTree tree) |
* @param newAmount is the new indent value for the right child. |
329 |
{ |
*/ |
330 |
tree.setFont(null); |
public void setRightChildIndent(int newAmount) |
331 |
tree.setForeground(null); |
{ |
332 |
tree.setBackground(null); |
rightChildIndent = newAmount; |
333 |
|
} |
334 |
tree.setCellRenderer(null); |
|
335 |
} |
/** |
336 |
|
* Returns the indent value for the right child. |
337 |
public void uninstallUI(JComponent c) |
* |
338 |
{ |
* @return the indent value for the right child. |
339 |
uninstallDefaults((JTree) c); |
*/ |
340 |
} |
public int getRightChildIndent(int newAmount) |
341 |
|
{ |
342 |
public Dimension getPreferredSize(JComponent c) |
return rightChildIndent; |
343 |
{ |
} |
344 |
return new Dimension(200,200); |
|
345 |
} |
/** |
346 |
|
* Sets the expanded icon. |
347 |
protected void paintLeaf(Graphics g, int x, int y, JTree tree, Object leaf) |
* |
348 |
{ |
* @param newG is the new expanded icon. |
349 |
Component c = tree.getCellRenderer().getTreeCellRendererComponent(tree, |
*/ |
350 |
leaf, |
public void setExpandedIcon(Icon newG) |
351 |
false, // selected |
{ |
352 |
false, // expanded |
expandedIcon = newG; |
353 |
true, // leaf |
} |
354 |
0, // row |
|
355 |
false // hasFocus |
/** |
356 |
); |
* Returns the current expanded icon. |
357 |
g.translate(x, y); |
* |
358 |
c.paint(g); |
* @return the current expanded icon. |
359 |
g.translate(-x, -y); |
*/ |
360 |
} |
public Icon getExpandedIcon() |
361 |
|
{ |
362 |
protected void paintNonLeaf(Graphics g, int x, int y, JTree tree, Object nonLeaf) |
return expandedIcon; |
363 |
{ |
} |
364 |
Component c = tree.getCellRenderer().getTreeCellRendererComponent(tree, |
|
365 |
nonLeaf, |
/** |
366 |
false, // selected |
* Sets the collapsed icon. |
367 |
false, // expanded |
* |
368 |
false, // leaf |
* @param newG is the new collapsed icon. |
369 |
0, // row |
*/ |
370 |
false // hasFocus |
public void setCollapsedIcon(Icon newG) |
371 |
); |
{ |
372 |
g.translate(x, y); |
collapsedIcon = newG; |
373 |
c.paint(g); |
} |
374 |
g.translate(-x, -y); |
|
375 |
} |
/** |
376 |
|
* Returns the current collapsed icon. |
377 |
protected int paintRecursive(Graphics g, |
* |
378 |
int indentation, |
* @return the current collapsed icon. |
379 |
int descent, |
*/ |
380 |
int childNumber, |
public Icon getCollapsedIcon() |
381 |
int depth, |
{ |
382 |
JTree tree, |
return collapsedIcon; |
383 |
TreeModel mod, |
} |
384 |
Object curr) |
|
385 |
{ |
/** |
386 |
Rectangle clip = g.getClipBounds(); |
* Updates the componentListener, if necessary. |
387 |
if (indentation > clip.x + clip.width + rightChildIndent || |
* |
388 |
descent > clip.y + clip.height + rowHeight) |
* @param largeModel sets this.largeModel to it. |
389 |
return descent; |
*/ |
390 |
|
protected void setLargeModel(boolean largeModel) |
391 |
|
{ |
392 |
int halfHeight = rowHeight / 2; |
if (largeModel != this.largeModel) |
393 |
int halfWidth = rightChildIndent / 2; |
{ |
394 |
int y0 = descent + halfHeight; |
tree.removeComponentListener(componentListener); |
395 |
|
this.largeModel = largeModel; |
396 |
if (mod.isLeaf(curr)) |
tree.addComponentListener(componentListener); |
397 |
{ |
} |
398 |
paintLeaf(g, indentation, descent, tree, curr); |
} |
399 |
descent += rowHeight; |
|
400 |
} |
/** |
401 |
else |
* Returns true if largeModel is set |
402 |
{ |
* |
403 |
if (depth > 0 || tree.isRootVisible()) |
* @return true if largeModel is set, otherwise false. |
404 |
{ |
*/ |
405 |
paintNonLeaf(g, indentation, descent, tree, curr); |
protected boolean isLargeModel() |
406 |
descent += rowHeight; |
{ |
407 |
y0 += halfHeight; |
return largeModel; |
408 |
} |
} |
409 |
int max = mod.getChildCount(curr); |
|
410 |
for (int i = 0; i < max; ++i) |
/** |
411 |
{ |
* Sets the row height. |
412 |
g.setColor(hashColor); |
* |
413 |
g.drawLine(indentation + halfWidth, descent + halfHeight, |
* @param rowHeight is the height to set this.rowHeight to. |
414 |
indentation + rightChildIndent, descent + halfHeight); |
*/ |
415 |
descent = paintRecursive(g, |
protected void setRowHeight(int rowHeight) |
416 |
indentation + rightChildIndent, descent, |
{ |
417 |
i, depth+1, |
treeState.setRowHeight(rowHeight); |
418 |
tree, mod, mod.getChild(curr, i)); |
} |
419 |
} |
|
420 |
} |
/** |
421 |
|
* Returns the current row height. |
422 |
int y1 = descent - halfHeight; |
* |
423 |
if (y0 != y1) |
* @return current row height. |
424 |
{ |
*/ |
425 |
g.setColor(hashColor); |
protected int getRowHeight() |
426 |
g.drawLine(indentation + halfWidth, y0, |
{ |
427 |
indentation + halfWidth, y1); |
return treeState.getRowHeight(); |
428 |
} |
} |
429 |
|
|
430 |
return descent; |
/** |
431 |
} |
* Sets the TreeCellRenderer to <code>tcr</code>. This invokes |
432 |
|
* <code>updateRenderer</code>. |
433 |
public void paint(Graphics g, JComponent c) |
* |
434 |
{ |
* @param tcr is the new TreeCellRenderer. |
435 |
JTree tree = (JTree) c; |
*/ |
436 |
TreeModel mod = tree.getModel(); |
protected void setCellRenderer(TreeCellRenderer tcr) |
437 |
g.translate(10, 10); |
{ |
438 |
paintRecursive(g, 0, 0, 0, 0, tree, mod, mod.getRoot()); |
currentCellRenderer = tcr; |
439 |
g.translate(-10, -10); |
updateRenderer(); |
440 |
} |
} |
441 |
} |
|
442 |
|
/** |
443 |
|
* Return currentCellRenderer, which will either be the trees renderer, or |
444 |
|
* defaultCellRenderer, which ever was not null. |
445 |
|
* |
446 |
|
* @return the current Cell Renderer |
447 |
|
*/ |
448 |
|
protected TreeCellRenderer getCellRenderer() |
449 |
|
{ |
450 |
|
if (currentCellRenderer != null) |
451 |
|
return currentCellRenderer; |
452 |
|
|
453 |
|
return createDefaultCellRenderer(); |
454 |
|
} |
455 |
|
|
456 |
|
/** |
457 |
|
* Sets the tree's model. |
458 |
|
* |
459 |
|
* @param model to set the treeModel to. |
460 |
|
*/ |
461 |
|
protected void setModel(TreeModel model) |
462 |
|
{ |
463 |
|
treeState.setModel(model); |
464 |
|
treeModel = model; |
465 |
|
} |
466 |
|
|
467 |
|
/** |
468 |
|
* Returns the tree's model |
469 |
|
* |
470 |
|
* @return treeModel |
471 |
|
*/ |
472 |
|
protected TreeModel getModel() |
473 |
|
{ |
474 |
|
return treeModel; |
475 |
|
} |
476 |
|
|
477 |
|
/** |
478 |
|
* Sets the root to being visible. |
479 |
|
* |
480 |
|
* @param newValue sets the visibility of the root |
481 |
|
*/ |
482 |
|
protected void setRootVisible(boolean newValue) |
483 |
|
{ |
484 |
|
treeState.setRootVisible(newValue); |
485 |
|
} |
486 |
|
|
487 |
|
/** |
488 |
|
* Returns true if the root is visible. |
489 |
|
* |
490 |
|
* @return true if the root is visible. |
491 |
|
*/ |
492 |
|
protected boolean isRootVisible() |
493 |
|
{ |
494 |
|
return treeState.isRootVisible(); |
495 |
|
} |
496 |
|
|
497 |
|
/** |
498 |
|
* Determines whether the node handles are to be displayed. |
499 |
|
* |
500 |
|
* @param newValue sets whether or not node handles should be displayed. |
501 |
|
*/ |
502 |
|
protected void setShowsRootHandles(boolean newValue) |
503 |
|
{ |
504 |
|
tree.setShowsRootHandles(newValue); |
505 |
|
} |
506 |
|
|
507 |
|
/** |
508 |
|
* Returns true if the node handles are to be displayed. |
509 |
|
* |
510 |
|
* @return true if the node handles are to be displayed. |
511 |
|
*/ |
512 |
|
protected boolean getShowsRootHandles() |
513 |
|
{ |
514 |
|
return tree.getShowsRootHandles(); |
515 |
|
} |
516 |
|
|
517 |
|
/** |
518 |
|
* Sets the cell editor. |
519 |
|
* |
520 |
|
* @param editor to set the cellEditor to. |
521 |
|
*/ |
522 |
|
protected void setCellEditor(TreeCellEditor editor) |
523 |
|
{ |
524 |
|
cellEditor = editor; |
525 |
|
} |
526 |
|
|
527 |
|
/** |
528 |
|
* Returns the <code>TreeCellEditor</code> for this tree. |
529 |
|
* |
530 |
|
* @return the cellEditor for this tree. |
531 |
|
*/ |
532 |
|
protected TreeCellEditor getCellEditor() |
533 |
|
{ |
534 |
|
return cellEditor; |
535 |
|
} |
536 |
|
|
537 |
|
/** |
538 |
|
* Configures the receiver to allow, or not allow, editing. |
539 |
|
* |
540 |
|
* @param newValue sets the receiver to allow editing if true. |
541 |
|
*/ |
542 |
|
protected void setEditable(boolean newValue) |
543 |
|
{ |
544 |
|
tree.setEditable(newValue); |
545 |
|
} |
546 |
|
|
547 |
|
/** |
548 |
|
* Returns true if the receiver allows editing. |
549 |
|
* |
550 |
|
* @return true if the receiver allows editing. |
551 |
|
*/ |
552 |
|
protected boolean isEditable() |
553 |
|
{ |
554 |
|
return tree.isEditable(); |
555 |
|
} |
556 |
|
|
557 |
|
/** |
558 |
|
* Resets the selection model. The appropriate listeners are installed on |
559 |
|
* the model. |
560 |
|
* |
561 |
|
* @param newLSM resets the selection model. |
562 |
|
*/ |
563 |
|
protected void setSelectionModel(TreeSelectionModel newLSM) |
564 |
|
{ |
565 |
|
if (newLSM != null) |
566 |
|
{ |
567 |
|
tree |
568 |
|
.removePropertyChangeListener(selectionModelPropertyChangeListener); |
569 |
|
treeSelectionModel = newLSM; |
570 |
|
treeState.setSelectionModel(newLSM); |
571 |
|
tree |
572 |
|
.addPropertyChangeListener(selectionModelPropertyChangeListener); |
573 |
|
tree.setSelectionModel(treeSelectionModel); |
574 |
|
} |
575 |
|
} |
576 |
|
|
577 |
|
/** |
578 |
|
* Returns the current selection model. |
579 |
|
* |
580 |
|
* @return the current selection model. |
581 |
|
*/ |
582 |
|
protected TreeSelectionModel getSelectionModel() |
583 |
|
{ |
584 |
|
return treeSelectionModel; |
585 |
|
} |
586 |
|
|
587 |
|
/** |
588 |
|
* Returns the Rectangle enclosing the label portion that the last item in |
589 |
|
* path will be drawn to. Will return null if any component in path is |
590 |
|
* currently valid. |
591 |
|
* |
592 |
|
* @param tree is the current tree the path will be drawn to. |
593 |
|
* @param path is the current path the tree to draw to. |
594 |
|
* @return the Rectangle enclosing the label portion that the last item in |
595 |
|
* the path will be drawn to. |
596 |
|
*/ |
597 |
|
public Rectangle getPathBounds(JTree tree, TreePath path) |
598 |
|
{ |
599 |
|
// FIXME: not implemented |
600 |
|
return null; |
601 |
|
} |
602 |
|
|
603 |
|
/** |
604 |
|
* Returns the path for passed in row. If row is not visible null is |
605 |
|
* returned. |
606 |
|
* |
607 |
|
* @param tree is the current tree to return path for. |
608 |
|
* @param row is the row number of the row to return. |
609 |
|
* @return the path for passed in row. If row is not visible null is |
610 |
|
* returned. |
611 |
|
*/ |
612 |
|
public TreePath getPathForRow(JTree tree, int row) |
613 |
|
{ |
614 |
|
// FIXME: check visibility when expand/collapse is implemented |
615 |
|
DefaultMutableTreeNode pathForRow = ((DefaultMutableTreeNode) (tree |
616 |
|
.getModel()).getRoot()); |
617 |
|
for (int i = 0; i < row; i++) |
618 |
|
{ |
619 |
|
if (pathForRow != null) |
620 |
|
pathForRow = pathForRow.getNextNode(); |
621 |
|
} |
622 |
|
return new TreePath(pathForRow.getPath()); |
623 |
|
} |
624 |
|
|
625 |
|
/** |
626 |
|
* Returns the row that the last item identified in path is visible at. Will |
627 |
|
* return -1 if any of the elments in the path are not currently visible. |
628 |
|
* |
629 |
|
* @param tree is the current tree to return the row for. |
630 |
|
* @param path is the path used to find the row. |
631 |
|
* @return the row that the last item identified in path is visible at. Will |
632 |
|
* return -1 if any of the elments in the path are not currently |
633 |
|
* visible. |
634 |
|
*/ |
635 |
|
public int getRowForPath(JTree tree, TreePath path) |
636 |
|
{ |
637 |
|
// FIXME: check visibility |
638 |
|
// right now, just returns last element because |
639 |
|
// expand/collapse is not implemented |
640 |
|
return path.length - 1; |
641 |
|
} |
642 |
|
|
643 |
|
/** |
644 |
|
* Returns the number of rows that are being displayed. |
645 |
|
* |
646 |
|
* @param tree is the current tree to return the number of rows for. |
647 |
|
* @return the number of rows being displayed. |
648 |
|
*/ |
649 |
|
public int getRowCount(JTree tree) |
650 |
|
{ |
651 |
|
return treeState.getRowCount(); |
652 |
|
} |
653 |
|
|
654 |
|
/** |
655 |
|
* Returns the path to the node that is closest to x,y. If there is nothing |
656 |
|
* currently visible this will return null, otherwise it'll always return a |
657 |
|
* valid path. If you need to test if the returned object is exactly at x,y |
658 |
|
* you should get the bounds for the returned path and test x,y against |
659 |
|
* that. |
660 |
|
* |
661 |
|
* @param tree the tree to search for the closest path |
662 |
|
* @param x is the x coordinate of the location to search |
663 |
|
* @param y is the y coordinate of the location to search |
664 |
|
* @return the tree path closes to x,y. |
665 |
|
*/ |
666 |
|
public TreePath getClosestPathForLocation(JTree tree, int x, int y) |
667 |
|
{ |
668 |
|
return treeState.getPathClosestTo(x, y); |
669 |
|
} |
670 |
|
|
671 |
|
/** |
672 |
|
* Returns true if the tree is being edited. The item that is being edited |
673 |
|
* can be returned by getEditingPath(). |
674 |
|
* |
675 |
|
* @param tree is the tree to check for editing. |
676 |
|
* @return true if the tree is being edited. |
677 |
|
*/ |
678 |
|
public boolean isEditing(JTree tree) |
679 |
|
{ |
680 |
|
// FIXME: not implemented |
681 |
|
return false; |
682 |
|
} |
683 |
|
|
684 |
|
/** |
685 |
|
* Stops the current editing session. This has no effect if the tree is not |
686 |
|
* being edited. Returns true if the editor allows the editing session to |
687 |
|
* stop. |
688 |
|
* |
689 |
|
* @param tree is the tree to stop the editing on |
690 |
|
* @return true if the editor allows the editing session to stop. |
691 |
|
*/ |
692 |
|
public boolean stopEditing(JTree tree) |
693 |
|
{ |
694 |
|
// FIXME: not implemented |
695 |
|
return false; |
696 |
|
} |
697 |
|
|
698 |
|
/** |
699 |
|
* Cancels the current editing session. |
700 |
|
* |
701 |
|
* @param tree is the tree to cancel the editing session on. |
702 |
|
*/ |
703 |
|
public void cancelEditing(JTree tree) |
704 |
|
{ |
705 |
|
// FIXME: not implemented |
706 |
|
} |
707 |
|
|
708 |
|
/** |
709 |
|
* Selects the last item in path and tries to edit it. Editing will fail if |
710 |
|
* the CellEditor won't allow it for the selected item. |
711 |
|
* |
712 |
|
* @param tree is the tree to edit on. |
713 |
|
* @param path is the path in tree to edit on. |
714 |
|
*/ |
715 |
|
public void startEditingAtPath(JTree tree, TreePath path) |
716 |
|
{ |
717 |
|
// FIXME: not implemented |
718 |
|
} |
719 |
|
|
720 |
|
/** |
721 |
|
* Returns the path to the element that is being editted. |
722 |
|
* |
723 |
|
* @param tree is the tree to get the editing path from. |
724 |
|
* @return the path that is being edited. |
725 |
|
*/ |
726 |
|
public TreePath getEditingPath(JTree tree) |
727 |
|
{ |
728 |
|
// FIXME: not implemented |
729 |
|
return null; |
730 |
|
} |
731 |
|
|
732 |
|
/** |
733 |
|
* Invoked after the tree instance variable has been set, but before any |
734 |
|
* default/listeners have been installed. |
735 |
|
*/ |
736 |
|
protected void prepareForUIInstall() |
737 |
|
{ |
738 |
|
// FIXME: not implemented |
739 |
|
} |
740 |
|
|
741 |
|
/** |
742 |
|
* Invoked from installUI after all the defaults/listeners have been |
743 |
|
* installed. |
744 |
|
*/ |
745 |
|
protected void completeUIInstall() |
746 |
|
{ |
747 |
|
// FIXME: not implemented |
748 |
|
} |
749 |
|
|
750 |
|
/** |
751 |
|
* Invoked from uninstallUI after all the defaults/listeners have been |
752 |
|
* uninstalled. |
753 |
|
*/ |
754 |
|
protected void completeUIUninstall() |
755 |
|
{ |
756 |
|
// FIXME: not implemented |
757 |
|
} |
758 |
|
|
759 |
|
/** |
760 |
|
* Installs the subcomponents of the tree, which is the renderer pane. |
761 |
|
*/ |
762 |
|
protected void installComponents() |
763 |
|
{ |
764 |
|
// FIXME: not implemented |
765 |
|
} |
766 |
|
|
767 |
|
/** |
768 |
|
* Creates an instance of NodeDimensions that is able to determine the size |
769 |
|
* of a given node in the tree. |
770 |
|
* |
771 |
|
* @return the NodeDimensions of a given node in the tree |
772 |
|
*/ |
773 |
|
protected AbstractLayoutCache.NodeDimensions createNodeDimensions() |
774 |
|
{ |
775 |
|
// FIXME: not implemented |
776 |
|
return null; |
777 |
|
} |
778 |
|
|
779 |
|
/** |
780 |
|
* Creates a listener that is reponsible for the updates the UI based on how |
781 |
|
* the tree changes. |
782 |
|
* |
783 |
|
* @return the PropertyChangeListener that is reposnsible for the updates |
784 |
|
*/ |
785 |
|
protected PropertyChangeListener createPropertyChangeListener() |
786 |
|
{ |
787 |
|
return new PropertyChangeHandler(); |
788 |
|
} |
789 |
|
|
790 |
|
/** |
791 |
|
* Creates the listener responsible for updating the selection based on |
792 |
|
* mouse events. |
793 |
|
* |
794 |
|
* @return the MouseListener responsible for updating. |
795 |
|
*/ |
796 |
|
protected MouseListener createMouseListener() |
797 |
|
{ |
798 |
|
return new MouseHandler(); |
799 |
|
} |
800 |
|
|
801 |
|
/** |
802 |
|
* Creates the listener that is responsible for updating the display when |
803 |
|
* focus is lost/grained. |
804 |
|
* |
805 |
|
* @return the FocusListener responsible for updating. |
806 |
|
*/ |
807 |
|
protected FocusListener createFocusListener() |
808 |
|
{ |
809 |
|
return new FocusHandler(); |
810 |
|
} |
811 |
|
|
812 |
|
/** |
813 |
|
* Creates the listener reponsible for getting key events from the tree. |
814 |
|
* |
815 |
|
* @return the KeyListener responsible for getting key events. |
816 |
|
*/ |
817 |
|
protected KeyListener createKeyListener() |
818 |
|
{ |
819 |
|
return new KeyHandler(); |
820 |
|
} |
821 |
|
|
822 |
|
/** |
823 |
|
* Creates the listener responsible for getting property change events from |
824 |
|
* the selection model. |
825 |
|
* |
826 |
|
* @returns the PropertyChangeListener reponsible for getting property |
827 |
|
* change events from the selection model. |
828 |
|
*/ |
829 |
|
protected PropertyChangeListener createSelectionModelPropertyChangeListener() |
830 |
|
{ |
831 |
|
return new SelectionModelPropertyChangeHandler(); |
832 |
|
} |
833 |
|
|
834 |
|
/** |
835 |
|
* Creates the listener that updates the display based on selection change |
836 |
|
* methods. |
837 |
|
* |
838 |
|
* @return the TreeSelectionListener responsible for updating. |
839 |
|
*/ |
840 |
|
protected TreeSelectionListener createTreeSelectionListener() |
841 |
|
{ |
842 |
|
return new TreeSelectionHandler(); |
843 |
|
} |
844 |
|
|
845 |
|
/** |
846 |
|
* Creates a listener to handle events from the current editor |
847 |
|
* |
848 |
|
* @return the CellEditorListener that handles events from the current |
849 |
|
* editor |
850 |
|
*/ |
851 |
|
protected CellEditorListener createCellEditorListener() |
852 |
|
{ |
853 |
|
return new CellEditorHandler(); |
854 |
|
} |
855 |
|
|
856 |
|
/** |
857 |
|
* Creates and returns a new ComponentHandler. This is used for the large |
858 |
|
* model to mark the validCachedPreferredSize as invalid when the component |
859 |
|
* moves. |
860 |
|
* |
861 |
|
* @return a new ComponentHandler. |
862 |
|
*/ |
863 |
|
protected ComponentListener createComponentListener() |
864 |
|
{ |
865 |
|
return new ComponentHandler(); |
866 |
|
} |
867 |
|
|
868 |
|
/** |
869 |
|
* Creates and returns the object responsible for updating the treestate |
870 |
|
* when a nodes expanded state changes. |
871 |
|
* |
872 |
|
* @return the TreeExpansionListener responsible for updating the treestate |
873 |
|
*/ |
874 |
|
protected TreeExpansionListener createTreeExpansionListener() |
875 |
|
{ |
876 |
|
return new TreeExpansionHandler(); |
877 |
|
} |
878 |
|
|
879 |
|
/** |
880 |
|
* Creates the object responsible for managing what is expanded, as well as |
881 |
|
* the size of nodes. |
882 |
|
* |
883 |
|
* @return the object responsible for managing what is expanded. |
884 |
|
*/ |
885 |
|
protected AbstractLayoutCache createLayoutCache() |
886 |
|
{ |
887 |
|
return new FixedHeightLayoutCache(); |
888 |
|
} |
889 |
|
|
890 |
|
/** |
891 |
|
* Returns the renderer pane that renderer components are placed in. |
892 |
|
* |
893 |
|
* @return the rendererpane that render components are placed in. |
894 |
|
*/ |
895 |
|
protected CellRendererPane createCellRendererPane() |
896 |
|
{ |
897 |
|
return new CellRendererPane(); |
898 |
|
} |
899 |
|
|
900 |
|
/** |
901 |
|
* Creates a default cell editor. |
902 |
|
* |
903 |
|
* @return the default cell editor. |
904 |
|
*/ |
905 |
|
protected TreeCellEditor createDefaultCellEditor() |
906 |
|
{ |
907 |
|
return new DefaultTreeCellEditor(tree, |
908 |
|
(DefaultTreeCellRenderer) createDefaultCellRenderer(), |
909 |
|
cellEditor); |
910 |
|
} |
911 |
|
|
912 |
|
/** |
913 |
|
* Returns the default cell renderer that is used to do the stamping of each |
914 |
|
* node. |
915 |
|
* |
916 |
|
* @return the default cell renderer that is used to do the stamping of each |
917 |
|
* node. |
918 |
|
*/ |
919 |
|
protected TreeCellRenderer createDefaultCellRenderer() |
920 |
|
{ |
921 |
|
return new DefaultTreeCellRenderer(); |
922 |
|
} |
923 |
|
|
924 |
|
/** |
925 |
|
* Returns a listener that can update the tree when the model changes. |
926 |
|
* |
927 |
|
* @return a listener that can update the tree when the model changes. |
928 |
|
*/ |
929 |
|
protected TreeModelListener createTreeModelListener() |
930 |
|
{ |
931 |
|
return new TreeModelHandler(); |
932 |
|
} |
933 |
|
|
934 |
|
/** |
935 |
|
* Uninstall all registered listeners |
936 |
|
*/ |
937 |
|
protected void uninstallListeners() |
938 |
|
{ |
939 |
|
tree.removePropertyChangeListener(propertyChangeListener); |
940 |
|
tree.removeFocusListener(focusListener); |
941 |
|
tree.removeTreeSelectionListener(treeSelectionListener); |
942 |
|
tree.removeMouseListener(mouseInputListener); |
943 |
|
tree.removeKeyListener(keyListener); |
944 |
|
tree.removePropertyChangeListener(selectionModelPropertyChangeListener); |
945 |
|
tree.removeComponentListener(componentListener); |
946 |
|
tree.getCellEditor().removeCellEditorListener(cellEditorListener); |
947 |
|
tree.removeTreeExpansionListener(treeExpansionListener); |
948 |
|
tree.getModel().removeTreeModelListener(treeModelListener); |
949 |
|
} |
950 |
|
|
951 |
|
/** |
952 |
|
* Uninstall all keyboard actions. |
953 |
|
*/ |
954 |
|
protected void uninstallKeyboardActions() |
955 |
|
{ |
956 |
|
} |
957 |
|
|
958 |
|
/** |
959 |
|
* Uninstall the rendererPane. |
960 |
|
*/ |
961 |
|
protected void uninstallComponents() |
962 |
|
{ |
963 |
|
// FIXME: not implemented |
964 |
|
} |
965 |
|
|
966 |
|
/** |
967 |
|
* The vertical element of legs between nodes starts at the bottom of the |
968 |
|
* parent node by default. This method makes the leg start below that. |
969 |
|
* |
970 |
|
* @return the vertical leg buffer |
971 |
|
*/ |
972 |
|
protected int getVerticalLegBuffer() |
973 |
|
{ |
974 |
|
// FIXME: not implemented |
975 |
|
return 0; |
976 |
|
} |
977 |
|
|
978 |
|
/** |
979 |
|
* The horizontal element of legs between nodes starts at the right of the |
980 |
|
* left-hand side of the child node by default. This method makes the leg |
981 |
|
* end before that. |
982 |
|
* |
983 |
|
* @return the horizontal leg buffer |
984 |
|
*/ |
985 |
|
protected int getHorizontalLegBuffer() |
986 |
|
{ |
987 |
|
// FIXME: not implemented |
988 |
|
return 0; |
989 |
|
} |
990 |
|
|
991 |
|
/** |
992 |
|
* Make all the nodes that are expanded in JTree expanded in LayoutCache. |
993 |
|
* This invokes update ExpandedDescendants with the root path. |
994 |
|
*/ |
995 |
|
protected void updateLayoutCacheExpandedNodes() |
996 |
|
{ |
997 |
|
// FIXME: not implemented |
998 |
|
} |
999 |
|
|
1000 |
|
/** |
1001 |
|
* Updates the expanded state of all the descendants of the |
1002 |
|
* <code>path</code> by getting the expanded descendants from the tree and |
1003 |
|
* forwarding to the tree state. |
1004 |
|
* |
1005 |
|
* @param path the path used to update the expanded states |
1006 |
|
*/ |
1007 |
|
protected void updateExpandedDescendants(TreePath path) |
1008 |
|
{ |
1009 |
|
// FIXME: not implemented |
1010 |
|
} |
1011 |
|
|
1012 |
|
/** |
1013 |
|
* Returns a path to the last child of <code>parent</code> |
1014 |
|
* |
1015 |
|
* @param parent is the topmost path to specified |
1016 |
|
* @return a path to the last child of parent |
1017 |
|
*/ |
1018 |
|
protected TreePath getLastChildPath(TreePath parent) |
1019 |
|
{ |
1020 |
|
return ((TreePath) parent.getLastPathComponent()); |
1021 |
|
} |
1022 |
|
|
1023 |
|
/** |
1024 |
|
* Updates how much each depth should be offset by. |
1025 |
|
*/ |
1026 |
|
protected void updateDepthOffset() |
1027 |
|
{ |
1028 |
|
// FIXME: not implemented |
1029 |
|
} |
1030 |
|
|
1031 |
|
/** |
1032 |
|
* Updates the cellEditor based on editability of the JTree that we're |
1033 |
|
* contained in. Ig the tree is editable but doesn't have a cellEditor, a |
1034 |
|
* basic one will be used. |
1035 |
|
*/ |
1036 |
|
protected void updateCellEditor() |
1037 |
|
{ |
1038 |
|
// FIXME: not implemented |
1039 |
|
} |
1040 |
|
|
1041 |
|
/** |
1042 |
|
* Messaged from the tree we're in when the renderer has changed. |
1043 |
|
*/ |
1044 |
|
protected void updateRenderer() |
1045 |
|
{ |
1046 |
|
// FIXME: not implemented |
1047 |
|
} |
1048 |
|
|
1049 |
|
/** |
1050 |
|
* Resets the treeState instance based on the tree we're providing the look |
1051 |
|
* and feel for. |
1052 |
|
*/ |
1053 |
|
protected void configureLayoutCache() |
1054 |
|
{ |
1055 |
|
treeState = createLayoutCache(); |
1056 |
|
} |
1057 |
|
|
1058 |
|
/** |
1059 |
|
* Marks the cached size as being invalid, and messages the tree with |
1060 |
|
* <code>treeDidChange</code>. |
1061 |
|
*/ |
1062 |
|
protected void updateSize() |
1063 |
|
{ |
1064 |
|
// FIXME: not implemented |
1065 |
|
} |
1066 |
|
|
1067 |
|
/** |
1068 |
|
* Updates the <code>preferredSize</code> instance variable, which is |
1069 |
|
* returned from <code>getPreferredSize()</code>. For left to right |
1070 |
|
* orientations, the size is determined from the current |
1071 |
|
* AbstractLayoutCache. For RTL orientations, the preferred size becomes the |
1072 |
|
* width minus the minimum x position. |
1073 |
|
*/ |
1074 |
|
protected void updateCachedPreferredSize() |
1075 |
|
{ |
1076 |
|
// FIXME: not implemented |
1077 |
|
} |
1078 |
|
|
1079 |
|
/** |
1080 |
|
* Messaged from the VisibleTreeNode after it has been expanded. |
1081 |
|
* |
1082 |
|
* @param path is the path that has been expanded. |
1083 |
|
*/ |
1084 |
|
protected void pathWasExpanded(TreePath path) |
1085 |
|
{ |
1086 |
|
// FIXME: not implemented |
1087 |
|
} |
1088 |
|
|
1089 |
|
/** |
1090 |
|
* Messaged from the VisibleTreeNode after it has collapsed |
1091 |
|
*/ |
1092 |
|
protected void pathWasCollapsed(TreePath path) |
1093 |
|
{ |
1094 |
|
// FIXME: not implemented |
1095 |
|
} |
1096 |
|
|
1097 |
|
protected void installDefaults(JTree tree) |
1098 |
|
{ |
1099 |
|
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
1100 |
|
|
1101 |
|
tree.setFont(defaults.getFont("Tree.font")); |
1102 |
|
tree.setForeground(defaults.getColor("Tree.foreground")); |
1103 |
|
tree.setBackground(defaults.getColor("Tree.background")); |
1104 |
|
tree.setOpaque(true); |
1105 |
|
|
1106 |
|
rightChildIndent = defaults.getInt("Tree.rightChildIndent"); |
1107 |
|
leftChildIndent = defaults.getInt("Tree.leftChildIndent"); |
1108 |
|
setRowHeight(defaults.getInt("Tree.rowHeight")); |
1109 |
|
} |
1110 |
|
|
1111 |
|
protected void installKeyboardActions() |
1112 |
|
{ |
1113 |
|
} |
1114 |
|
|
1115 |
|
protected void installListeners() |
1116 |
|
{ |
1117 |
|
tree.addPropertyChangeListener(propertyChangeListener); |
1118 |
|
tree.addFocusListener(focusListener); |
1119 |
|
tree.addTreeSelectionListener(treeSelectionListener); |
1120 |
|
tree.addMouseListener(mouseInputListener); |
1121 |
|
tree.addKeyListener(keyListener); |
1122 |
|
tree.addPropertyChangeListener(selectionModelPropertyChangeListener); |
1123 |
|
tree.addComponentListener(componentListener); |
1124 |
|
cellEditor.addCellEditorListener(cellEditorListener); |
1125 |
|
tree.addTreeExpansionListener(treeExpansionListener); |
1126 |
|
treeModel.addTreeModelListener(treeModelListener); |
1127 |
|
} |
1128 |
|
|
1129 |
|
public void installUI(JComponent c) |
1130 |
|
{ |
1131 |
|
super.installUI(c); |
1132 |
|
installDefaults((JTree) c); |
1133 |
|
tree = (JTree) c; |
1134 |
|
setModel(tree.getModel()); |
1135 |
|
treeSelectionModel = tree.getSelectionModel(); |
1136 |
|
installListeners(); |
1137 |
|
installKeyboardActions(); |
1138 |
|
completeUIInstall(); |
1139 |
|
} |
1140 |
|
|
1141 |
|
protected void uninstallDefaults(JTree tree) |
1142 |
|
{ |
1143 |
|
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
1144 |
|
tree.setFont(null); |
1145 |
|
tree.setForeground(null); |
1146 |
|
tree.setBackground(null); |
1147 |
|
tree.setCellRenderer(null); |
1148 |
|
} |
1149 |
|
|
1150 |
|
public void uninstallUI(JComponent c) |
1151 |
|
{ |
1152 |
|
uninstallDefaults((JTree) c); |
1153 |
|
uninstallKeyboardActions(); |
1154 |
|
uninstallListeners(); |
1155 |
|
tree = null; |
1156 |
|
completeUIUninstall(); |
1157 |
|
} |
1158 |
|
|
1159 |
|
public void paint(Graphics g, JComponent c) |
1160 |
|
{ |
1161 |
|
JTree tree = (JTree) c; |
1162 |
|
TreeModel mod = tree.getModel(); |
1163 |
|
g.translate(10, 10); |
1164 |
|
paintRecursive(g, 0, 0, 0, 0, tree, mod, mod.getRoot()); |
1165 |
|
g.translate(-10, -10); |
1166 |
|
} |
1167 |
|
|
1168 |
|
/** |
1169 |
|
* Ensures that the rows identified by beginRow through endRow are visible. |
1170 |
|
* |
1171 |
|
* @param beginRow is the first row |
1172 |
|
* @param endRow is the last row |
1173 |
|
*/ |
1174 |
|
protected void ensureRowsAreVisible(int beginRow, int endRow) |
1175 |
|
{ |
1176 |
|
// FIXME: not implemented |
1177 |
|
} |
1178 |
|
|
1179 |
|
/** |
1180 |
|
* Sets the preferred minimum size. |
1181 |
|
* |
1182 |
|
* @param newSize is the new preferred minimum size. |
1183 |
|
*/ |
1184 |
|
public void setPreferredMinSize(Dimension newSize) |
1185 |
|
{ |
1186 |
|
// FIXME: not implemented |
1187 |
|
} |
1188 |
|
|
1189 |
|
/** |
1190 |
|
* Gets the preferred minimum size. |
1191 |
|
* |
1192 |
|
* @returns the preferred minimum size. |
1193 |
|
*/ |
1194 |
|
public Dimension getPreferredMinSize() |
1195 |
|
{ |
1196 |
|
// FIXME: not implemented |
1197 |
|
return null; |
1198 |
|
} |
1199 |
|
|
1200 |
|
/** |
1201 |
|
* Returns the preferred size to properly display the tree, this is a cover |
1202 |
|
* method for getPreferredSize(c, false). |
1203 |
|
* |
1204 |
|
* @param c the component whose preferred size is being queried; this |
1205 |
|
* argument is often ignored but might be used if the UI object is |
1206 |
|
* stateless and shared by multiple components |
1207 |
|
* @return the preferred size |
1208 |
|
*/ |
1209 |
|
public Dimension getPreferredSize(JComponent c) |
1210 |
|
{ |
1211 |
|
return getPreferredSize(c, false); |
1212 |
|
} |
1213 |
|
|
1214 |
|
/** |
1215 |
|
* Returns the preferred size to represent the tree in c. If |
1216 |
|
* checkConsistancy is true, checkConsistancy is messaged first. |
1217 |
|
* |
1218 |
|
* @param c the component whose preferred size is being queried. |
1219 |
|
* @param checkConsistancy if true must check consistancy |
1220 |
|
* @return the preferred size |
1221 |
|
*/ |
1222 |
|
public Dimension getPreferredSize(JComponent c, boolean checkConsistancy) |
1223 |
|
{ |
1224 |
|
// FIXME: not implemented |
1225 |
|
return new Dimension(200, 900); |
1226 |
|
} |
1227 |
|
|
1228 |
|
/** |
1229 |
|
* Returns the minimum size for this component. Which will be the min |
1230 |
|
* preferred size or (0,0). |
1231 |
|
* |
1232 |
|
* @param c the component whose min size is being queried. |
1233 |
|
* @returns the preferred size or null |
1234 |
|
*/ |
1235 |
|
public Dimension getMinimumSize(JComponent c) |
1236 |
|
{ |
1237 |
|
// FIXME: not implemented |
1238 |
|
return new Dimension(200, 900); |
1239 |
|
} |
1240 |
|
|
1241 |
|
/** |
1242 |
|
* Returns the maximum size for the component, which will be the preferred |
1243 |
|
* size if the instance is currently in JTree or (0,0). |
1244 |
|
* |
1245 |
|
* @param c the component whose preferred size is being queried |
1246 |
|
* @return the max size or null |
1247 |
|
*/ |
1248 |
|
public Dimension getMaximumSize(JComponent c) |
1249 |
|
{ |
1250 |
|
// FIXME: not implemented |
1251 |
|
return new Dimension(200, 900); |
1252 |
|
} |
1253 |
|
|
1254 |
|
/** |
1255 |
|
* Messages to stop the editing session. If the UI the receiver is providing |
1256 |
|
* the look and feel for returns true from |
1257 |
|
* <code>getInvokesStopCellEditing</code>, stopCellEditing will be |
1258 |
|
* invoked on the current editor. Then completeEditing will be messaged with |
1259 |
|
* false, true, false to cancel any lingering editing. |
1260 |
|
*/ |
1261 |
|
protected void completeEditing() |
1262 |
|
{ |
1263 |
|
// FIXME: not implemented |
1264 |
|
} |
1265 |
|
|
1266 |
|
/** |
1267 |
|
* Stops the editing session. If messageStop is true, the editor is messaged |
1268 |
|
* with stopEditing, if messageCancel is true the editor is messaged with |
1269 |
|
* cancelEditing. If messageTree is true, the treeModel is messaged with |
1270 |
|
* valueForPathChanged. |
1271 |
|
* |
1272 |
|
* @param messageStop message to stop editing |
1273 |
|
* @param messageCancel message to cancel editing |
1274 |
|
* @param messageTree message to treeModel |
1275 |
|
*/ |
1276 |
|
protected void completeEditing(boolean messageStop, boolean messageCancel, |
1277 |
|
boolean messageTree) |
1278 |
|
{ |
1279 |
|
// FIXME: not implemented |
1280 |
|
} |
1281 |
|
|
1282 |
|
/** |
1283 |
|
* Will start editing for node if there is a cellEditor and shouldSelectCall |
1284 |
|
* returns true. This assumes that path is valid and visible. |
1285 |
|
* |
1286 |
|
* @param path is the path to start editing |
1287 |
|
* @param event is the MouseEvent performed on the path |
1288 |
|
* @return true if successful |
1289 |
|
*/ |
1290 |
|
protected boolean startEditing(TreePath path, MouseEvent event) |
1291 |
|
{ |
1292 |
|
// FIXME: not implemented |
1293 |
|
return false; |
1294 |
|
} |
1295 |
|
|
1296 |
|
/** |
1297 |
|
* If the <code>mouseX</code> and <code>mouseY</code> are in the expand |
1298 |
|
* or collapse region of the row, this will toggle the row. |
1299 |
|
* |
1300 |
|
* @param path the path we are concerned with |
1301 |
|
* @param mouseX is the cursor's x position |
1302 |
|
* @param mouseY is the cursor's y position |
1303 |
|
*/ |
1304 |
|
protected void checkForClickInExpandControl(TreePath path, int mouseX, |
1305 |
|
int mouseY) |
1306 |
|
{ |
1307 |
|
// FIXME: not implemented |
1308 |
|
} |
1309 |
|
|
1310 |
|
/** |
1311 |
|
* Returns true if the <code>mouseX</code> and <code>mouseY</code> fall |
1312 |
|
* in the area of row that is used to expand/collpse the node and the node |
1313 |
|
* at row does not represent a leaf. |
1314 |
|
* |
1315 |
|
* @param path the path we are concerned with |
1316 |
|
* @param mouseX is the cursor's x position |
1317 |
|
* @param mouseY is the cursor's y position |
1318 |
|
* @return true if the <code>mouseX</code> and <code>mouseY</code> fall |
1319 |
|
* in the area of row that is used to expand/collpse the node and |
1320 |
|
* the node at row does not represent a leaf. |
1321 |
|
*/ |
1322 |
|
protected boolean isLocationInExpandControl(TreePath path, int mouseX, |
1323 |
|
int mouseY) |
1324 |
|
{ |
1325 |
|
// FIXME: not implemented |
1326 |
|
return false; |
1327 |
|
} |
1328 |
|
|
1329 |
|
/** |
1330 |
|
* Messaged when the user clicks the particular row, this invokes |
1331 |
|
* toggleExpandState. |
1332 |
|
* |
1333 |
|
* @param path the path we are concerned with |
1334 |
|
* @param mouseX is the cursor's x position |
1335 |
|
* @param mouseY is the cursor's y position |
1336 |
|
*/ |
1337 |
|
protected void handleExpandControlClick(TreePath path, int mouseX, |
1338 |
|
int mouseY) |
1339 |
|
{ |
1340 |
|
// FIXME: not implemented |
1341 |
|
} |
1342 |
|
|
1343 |
|
/** |
1344 |
|
* Expands path if it is not expanded, or collapses row if it is expanded. |
1345 |
|
* If expanding a path and JTree scroll on expand, ensureRowsAreVisible is |
1346 |
|
* invoked to scroll as many of the children to visible as possible (tries |
1347 |
|
* to scroll to last visible descendant of path). |
1348 |
|
* |
1349 |
|
* @param path the path we are concerned with |
1350 |
|
*/ |
1351 |
|
protected void toggleExpandState(TreePath path) |
1352 |
|
{ |
1353 |
|
// FIXME: not implemented |
1354 |
|
} |
1355 |
|
|
1356 |
|
/** |
1357 |
|
* Returning true signifies a mouse event on the node should toggle the |
1358 |
|
* selection of only the row under the mouse. |
1359 |
|
* |
1360 |
|
* @param event is the MouseEvent performed on the row. |
1361 |
|
* @return true signifies a mouse event on the node should toggle the |
1362 |
|
* selection of only the row under the mouse. |
1363 |
|
*/ |
1364 |
|
protected boolean isToggleSelectionEvent(MouseEvent event) |
1365 |
|
{ |
1366 |
|
// FIXME: not implemented |
1367 |
|
return false; |
1368 |
|
} |
1369 |
|
|
1370 |
|
/** |
1371 |
|
* Returning true signifies a mouse event on the node should select from the |
1372 |
|
* anchor point. |
1373 |
|
* |
1374 |
|
* @param event is the MouseEvent performed on the node. |
1375 |
|
* @return true signifies a mouse event on the node should select from the |
1376 |
|
* anchor point. |
1377 |
|
*/ |
1378 |
|
protected boolean isMultiSelectEvent(MouseEvent event) |
1379 |
|
{ |
1380 |
|
// FIXME: not implemented |
1381 |
|
return false; |
1382 |
|
} |
1383 |
|
|
1384 |
|
/** |
1385 |
|
* Returning true indicates the row under the mouse should be toggled based |
1386 |
|
* on the event. This is invoked after checkForClickInExpandControl, |
1387 |
|
* implying the location is not in the expand (toggle) control. |
1388 |
|
* |
1389 |
|
* @param event is the MouseEvent performed on the row. |
1390 |
|
* @return true indicates the row under the mouse should be toggled based on |
1391 |
|
* the event. |
1392 |
|
*/ |
1393 |
|
protected boolean isToggleEvent(MouseEvent event) |
1394 |
|
{ |
1395 |
|
// FIXME: not implemented |
1396 |
|
return false; |
1397 |
|
} |
1398 |
|
|
1399 |
|
/** |
1400 |
|
* Messaged to update the selection based on a MouseEvent over a particular |
1401 |
|
* row. If the even is a toggle selection event, the row is either selected, |
1402 |
|
* or deselected. If the event identifies a multi selection event, the |
1403 |
|
* selection is updated from the anchor point. Otherwise, the row is |
1404 |
|
* selected, and if the even specified a toggle event the row is |
1405 |
|
* expanded/collapsed. |
1406 |
|
* |
1407 |
|
* @param path is the path selected for an event |
1408 |
|
* @param event is the MouseEvent performed on the path. |
1409 |
|
*/ |
1410 |
|
protected void selectPathForEvent(TreePath path, MouseEvent event) |
1411 |
|
{ |
1412 |
|
// FIXME: not implemented |
1413 |
|
} |
1414 |
|
|
1415 |
|
/** |
1416 |
|
* Returns true if the node at <code>row</code> is a leaf. |
1417 |
|
* |
1418 |
|
* @param row is the row we are concerned with. |
1419 |
|
* @return true if the node at <code>row</code> is a leaf. |
1420 |
|
*/ |
1421 |
|
protected boolean isLeaf(int row) |
1422 |
|
{ |
1423 |
|
return false; |
1424 |
|
// FIXME: not implemented |
1425 |
|
} |
1426 |
|
|
1427 |
|
/* * INTERNAL CLASSES * */ |
1428 |
|
|
1429 |
|
/** |
1430 |
|
* Updates the preferred size when scrolling, if necessary. |
1431 |
|
*/ |
1432 |
|
public class ComponentHandler |
1433 |
|
extends ComponentAdapter |
1434 |
|
implements ActionListener |
1435 |
|
{ |
1436 |
|
/** |
1437 |
|
* Timer used when inside a scrollpane and the scrollbar is adjusting |
1438 |
|
*/ |
1439 |
|
protected Timer timer; |
1440 |
|
|
1441 |
|
/** ScrollBar that is being adjusted */ |
1442 |
|
protected JScrollBar scrollBar; |
1443 |
|
|
1444 |
|
/** |
1445 |
|
* Constructor |
1446 |
|
*/ |
1447 |
|
public ComponentHandler() |
1448 |
|
{ |
1449 |
|
} |
1450 |
|
|
1451 |
|
/** |
1452 |
|
* Invoked when the component's position changes. |
1453 |
|
* |
1454 |
|
* @param e the event that occurs when moving the component |
1455 |
|
*/ |
1456 |
|
public void componentMoved(ComponentEvent e) |
1457 |
|
{ |
1458 |
|
} |
1459 |
|
|
1460 |
|
/** |
1461 |
|
* Creats, if necessary, and starts a Timer to check if needed to resize |
1462 |
|
* the bounds |
1463 |
|
*/ |
1464 |
|
protected void startTimer() |
1465 |
|
{ |
1466 |
|
} |
1467 |
|
|
1468 |
|
/** |
1469 |
|
* Returns the JScrollPane housing the JTree, or null if one isn't |
1470 |
|
* found. |
1471 |
|
* |
1472 |
|
* @return JScrollPane housing the JTree, or null if one isn't found. |
1473 |
|
*/ |
1474 |
|
protected JScrollPane getScrollPane() |
1475 |
|
{ |
1476 |
|
return null; |
1477 |
|
} |
1478 |
|
|
1479 |
|
/** |
1480 |
|
* Public as a result of Timer. If the scrollBar is null, or not |
1481 |
|
* adjusting, this stops the timer and updates the sizing. |
1482 |
|
* |
1483 |
|
* @param ae is the action performed |
1484 |
|
*/ |
1485 |
|
public void actionPerformed(ActionEvent ae) |
1486 |
|
{ |
1487 |
|
} |
1488 |
|
}// ComponentHandler |
1489 |
|
|
1490 |
|
/** |
1491 |
|
* Listener responsible for getting cell editing events and updating the |
1492 |
|
* tree accordingly. |
1493 |
|
*/ |
1494 |
|
public class CellEditorHandler |
1495 |
|
implements CellEditorListener |
1496 |
|
{ |
1497 |
|
/** |
1498 |
|
* Constructor |
1499 |
|
*/ |
1500 |
|
public CellEditorHandler() |
1501 |
|
{ |
1502 |
|
} |
1503 |
|
|
1504 |
|
/** |
1505 |
|
* Messaged when editing has stopped in the tree. Tells the listeners |
1506 |
|
* editing has stopped. |
1507 |
|
* |
1508 |
|
* @param e is the notification event |
1509 |
|
*/ |
1510 |
|
public void editingStopped(ChangeEvent e) |
1511 |
|
{ |
1512 |
|
} |
1513 |
|
|
1514 |
|
/** |
1515 |
|
* Messaged when editing has been canceled in the tree. This tells the |
1516 |
|
* listeners the editor has canceled editing. |
1517 |
|
* |
1518 |
|
* @param e is the notification event |
1519 |
|
*/ |
1520 |
|
public void editingCanceled(ChangeEvent e) |
1521 |
|
{ |
1522 |
|
} |
1523 |
|
}// CellEditorHandler |
1524 |
|
|
1525 |
|
/** |
1526 |
|
* Repaints the lead selection row when focus is lost/grained. |
1527 |
|
*/ |
1528 |
|
public class FocusHandler |
1529 |
|
implements FocusListener |
1530 |
|
{ |
1531 |
|
/** |
1532 |
|
* Constructor |
1533 |
|
*/ |
1534 |
|
public FocusHandler() |
1535 |
|
{ |
1536 |
|
} |
1537 |
|
|
1538 |
|
/** |
1539 |
|
* Invoked when focus is activated on the tree we're in, redraws the |
1540 |
|
* lead row. Invoked when a component gains the keyboard focus. |
1541 |
|
* |
1542 |
|
* @param e is the focus event that is activated |
1543 |
|
*/ |
1544 |
|
public void focusGained(FocusEvent e) |
1545 |
|
{ |
1546 |
|
} |
1547 |
|
|
1548 |
|
/** |
1549 |
|
* Invoked when focus is deactivated on the tree we're in, redraws the |
1550 |
|
* lead row. Invoked when a component loses the keyboard focus. |
1551 |
|
* |
1552 |
|
* @param e is the focus event that is deactivated |
1553 |
|
*/ |
1554 |
|
public void focusLost(FocusEvent e) |
1555 |
|
{ |
1556 |
|
} |
1557 |
|
}// FocusHandler |
1558 |
|
|
1559 |
|
/** |
1560 |
|
* This is used to get multiple key down events to appropriately genereate |
1561 |
|
* events. |
1562 |
|
*/ |
1563 |
|
public class KeyHandler |
1564 |
|
extends KeyAdapter |
1565 |
|
{ |
1566 |
|
/** Key code that is being generated for. */ |
1567 |
|
protected Action repeatKeyAction; |
1568 |
|
|
1569 |
|
/** Set to true while keyPressed is active */ |
1570 |
|
protected boolean isKeyDown; |
1571 |
|
|
1572 |
|
/** |
1573 |
|
* Constructor |
1574 |
|
*/ |
1575 |
|
public KeyHandler() |
1576 |
|
{ |
1577 |
|
} |
1578 |
|
|
1579 |
|
/** |
1580 |
|
* Invoked when a key has been typed. Moves the keyboard focus to the |
1581 |
|
* first element whose first letter matches the alphanumeric key pressed |
1582 |
|
* by the user. Subsequent same key presses move the keyboard focus to |
1583 |
|
* the next object that starts with the same letter. |
1584 |
|
* |
1585 |
|
* @param e the key typed |
1586 |
|
*/ |
1587 |
|
public void keyTyped(KeyEvent e) |
1588 |
|
{ |
1589 |
|
} |
1590 |
|
|
1591 |
|
/** |
1592 |
|
* Invoked when a key has been pressed. |
1593 |
|
* |
1594 |
|
* @param e the key pressed |
1595 |
|
*/ |
1596 |
|
public void keyPressed(KeyEvent e) |
1597 |
|
{ |
1598 |
|
} |
1599 |
|
|
1600 |
|
/** |
1601 |
|
* Invoked when a key has been released |
1602 |
|
* |
1603 |
|
* @param e the key released |
1604 |
|
*/ |
1605 |
|
public void keyReleased(KeyEvent e) |
1606 |
|
{ |
1607 |
|
} |
1608 |
|
}// KeyHandler |
1609 |
|
|
1610 |
|
/** |
1611 |
|
* MouseListener is responsible for updating the selevtion based on mouse |
1612 |
|
* events. |
1613 |
|
*/ |
1614 |
|
public class MouseHandler |
1615 |
|
extends MouseAdapter |
1616 |
|
implements MouseMotionListener |
1617 |
|
{ |
1618 |
|
/** |
1619 |
|
* Constructor |
1620 |
|
*/ |
1621 |
|
public MouseHandler() |
1622 |
|
{ |
1623 |
|
} |
1624 |
|
|
1625 |
|
/** |
1626 |
|
* Invoked when a mouse button has been pressed on a component. |
1627 |
|
* |
1628 |
|
* @param e is the mouse event that occured |
1629 |
|
*/ |
1630 |
|
public void mousePressed(MouseEvent e) |
1631 |
|
{ |
1632 |
|
} |
1633 |
|
|
1634 |
|
/** |
1635 |
|
* Invoked when a mouse button is pressed on a component and then |
1636 |
|
* dragged. MOUSE_DRAGGED events will continue to be delivered to the |
1637 |
|
* component where the drag originated until the mouse button is |
1638 |
|
* released (regardless of whether the mouse position is within the |
1639 |
|
* bounds of the component). |
1640 |
|
* |
1641 |
|
* @param e is the mouse event that occured |
1642 |
|
*/ |
1643 |
|
public void mouseDragged(MouseEvent e) |
1644 |
|
{ |
1645 |
|
} |
1646 |
|
|
1647 |
|
/** |
1648 |
|
* Invoked when the mouse button has been moved on a component (with no |
1649 |
|
* buttons no down). |
1650 |
|
* |
1651 |
|
* @param e the mouse event that occured |
1652 |
|
*/ |
1653 |
|
public void mouseMoved(MouseEvent e) |
1654 |
|
{ |
1655 |
|
} |
1656 |
|
|
1657 |
|
/** |
1658 |
|
* Invoked when a mouse button has been released on a component. |
1659 |
|
* |
1660 |
|
* @param e is the mouse event that occured |
1661 |
|
*/ |
1662 |
|
public void mouseReleased(MouseEvent e) |
1663 |
|
{ |
1664 |
|
} |
1665 |
|
}// MouseHandler |
1666 |
|
|
1667 |
|
/** |
1668 |
|
* MouseInputHandler handles passing all mouse events, including mouse |
1669 |
|
* motion events, until the mouse is released to the destination it is |
1670 |
|
* constructed with. |
1671 |
|
*/ |
1672 |
|
public class MouseInputHandler |
1673 |
|
implements MouseInputListener |
1674 |
|
{ |
1675 |
|
/** Source that events are coming from */ |
1676 |
|
protected Component source; |
1677 |
|
|
1678 |
|
/** Destination that receives all events. */ |
1679 |
|
protected Component destination; |
1680 |
|
|
1681 |
|
/** |
1682 |
|
* Constructor |
1683 |
|
* |
1684 |
|
* @param source that events are coming from |
1685 |
|
* @param destination that receives all events |
1686 |
|
* @param event is the event received |
1687 |
|
*/ |
1688 |
|
public MouseInputHandler(Component source, Component destination, |
1689 |
|
MouseEvent e) |
1690 |
|
{ |
1691 |
|
} |
1692 |
|
|
1693 |
|
/** |
1694 |
|
* Invoked when the mouse button has been clicked (pressed and released) |
1695 |
|
* on a component. |
1696 |
|
* |
1697 |
|
* @param e mouse event that occured |
1698 |
|
*/ |
1699 |
|
public void mouseClicked(MouseEvent e) |
1700 |
|
{ |
1701 |
|
Point click = e.getPoint(); |
1702 |
|
int row = ((int) click.getY() / getRowHeight()) - 1; |
1703 |
|
|
1704 |
|
if (BasicTreeUI.this.tree.getSelectionModel().getSelectionMode() == treeSelectionModel.SINGLE_TREE_SELECTION) |
1705 |
|
BasicTreeUI.this.tree.addSelectionRow(row); |
1706 |
|
else if (BasicTreeUI.this.tree.isRowSelected(row)) |
1707 |
|
BasicTreeUI.this.tree.removeSelectionRow(row); |
1708 |
|
// FIXME: add in selection for more than 1 row, or an entire |
1709 |
|
// path |
1710 |
|
} |
1711 |
|
|
1712 |
|
/** |
1713 |
|
* Invoked when a mouse button has been pressed on a component. |
1714 |
|
* |
1715 |
|
* @param e mouse event that occured |
1716 |
|
*/ |
1717 |
|
public void mousePressed(MouseEvent e) |
1718 |
|
{ |
1719 |
|
} |
1720 |
|
|
1721 |
|
/** |
1722 |
|
* Invoked when a mouse button has been released on a component. |
1723 |
|
* |
1724 |
|
* @param e mouse event that occured |
1725 |
|
*/ |
1726 |
|
public void mouseReleased(MouseEvent e) |
1727 |
|
{ |
1728 |
|
} |
1729 |
|
|
1730 |
|
/** |
1731 |
|
* Invoked when the mouse enters a component. |
1732 |
|
* |
1733 |
|
* @param e mouse event that occured |
1734 |
|
*/ |
1735 |
|
public void mouseEntered(MouseEvent e) |
1736 |
|
{ |
1737 |
|
} |
1738 |
|
|
1739 |
|
/** |
1740 |
|
* Invoked when the mouse exits a component. |
1741 |
|
* |
1742 |
|
* @param e mouse event that occured |
1743 |
|
*/ |
1744 |
|
public void mouseExited(MouseEvent e) |
1745 |
|
{ |
1746 |
|
} |
1747 |
|
|
1748 |
|
/** |
1749 |
|
* Invoked when a mouse button is pressed on a component and then |
1750 |
|
* dragged. MOUSE_DRAGGED events will continue to be delivered to the |
1751 |
|
* component where the drag originated until the mouse button is |
1752 |
|
* released (regardless of whether the mouse position is within the |
1753 |
|
* bounds of the component). |
1754 |
|
* |
1755 |
|
* @param e mouse event that occured |
1756 |
|
*/ |
1757 |
|
public void mouseDragged(MouseEvent e) |
1758 |
|
{ |
1759 |
|
} |
1760 |
|
|
1761 |
|
/** |
1762 |
|
* Invoked when the mouse cursor has been moved onto a component but no |
1763 |
|
* buttons have been pushed. |
1764 |
|
* |
1765 |
|
* @param e mouse event that occured |
1766 |
|
*/ |
1767 |
|
public void mouseMoved(MouseEvent e) |
1768 |
|
{ |
1769 |
|
} |
1770 |
|
|
1771 |
|
/** |
1772 |
|
* Removes event from the source |
1773 |
|
*/ |
1774 |
|
protected void removeFromSource() |
1775 |
|
{ |
1776 |
|
} |
1777 |
|
}// MouseInputHandler |
1778 |
|
|
1779 |
|
/** |
1780 |
|
* Class responsible for getting size of node, method is forwarded to |
1781 |
|
* BasicTreeUI method. X location does not include insets, that is handled |
1782 |
|
* in getPathBounds. |
1783 |
|
*/ |
1784 |
|
public class NodeDimensionsHandler |
1785 |
|
extends AbstractLayoutCache.NodeDimensions |
1786 |
|
{ |
1787 |
|
/** |
1788 |
|
* Constructor |
1789 |
|
*/ |
1790 |
|
public NodeDimensionsHandler() |
1791 |
|
{ |
1792 |
|
} |
1793 |
|
|
1794 |
|
/** |
1795 |
|
* Responsible for getting the size of a particular node. |
1796 |
|
* |
1797 |
|
* @param value the value to be represented |
1798 |
|
* @param row row being queried |
1799 |
|
* @param depth the depth of the row |
1800 |
|
* @param expanded true if row is expanded |
1801 |
|
* @param size a Rectangle containing the size needed to represent value |
1802 |
|
* @return containing the node dimensions, or null if node has no |
1803 |
|
* dimension |
1804 |
|
*/ |
1805 |
|
public Rectangle getNodeDimensions(Object value, int row, int depth, |
1806 |
|
boolean expanded, Rectangle size) |
1807 |
|
{ |
1808 |
|
return null; |
1809 |
|
} |
1810 |
|
|
1811 |
|
/** |
1812 |
|
* Returns the amount to indent the given row |
1813 |
|
* |
1814 |
|
* @return amount to indent the given row. |
1815 |
|
*/ |
1816 |
|
protected int getRowX(int row, int depth) |
1817 |
|
{ |
1818 |
|
return 0; |
1819 |
|
} |
1820 |
|
}// NodeDimensionsHandler |
1821 |
|
|
1822 |
|
/** |
1823 |
|
* PropertyChangeListener for the tree. Updates the appropriate varaible, or |
1824 |
|
* TreeState, based on what changes. |
1825 |
|
*/ |
1826 |
|
public class PropertyChangeHandler |
1827 |
|
implements PropertyChangeListener |
1828 |
|
{ |
1829 |
|
|
1830 |
|
/** |
1831 |
|
* Constructor |
1832 |
|
*/ |
1833 |
|
public PropertyChangeHandler() |
1834 |
|
{ |
1835 |
|
} |
1836 |
|
|
1837 |
|
/** |
1838 |
|
* This method gets called when a bound property is changed. |
1839 |
|
* |
1840 |
|
* @param event A PropertyChangeEvent object describing the event source |
1841 |
|
* and the property that has changed. |
1842 |
|
*/ |
1843 |
|
public void propertyChange(PropertyChangeEvent event) |
1844 |
|
{ |
1845 |
|
} |
1846 |
|
}// PropertyChangeHandler |
1847 |
|
|
1848 |
|
/** |
1849 |
|
* Listener on the TreeSelectionModel, resets the row selection if any of |
1850 |
|
* the properties of the model change. |
1851 |
|
*/ |
1852 |
|
public class SelectionModelPropertyChangeHandler |
1853 |
|
implements PropertyChangeListener |
1854 |
|
{ |
1855 |
|
|
1856 |
|
/** |
1857 |
|
* Constructor |
1858 |
|
*/ |
1859 |
|
public SelectionModelPropertyChangeHandler() |
1860 |
|
{ |
1861 |
|
} |
1862 |
|
|
1863 |
|
/** |
1864 |
|
* This method gets called when a bound property is changed. |
1865 |
|
* |
1866 |
|
* @param event A PropertyChangeEvent object describing the event source |
1867 |
|
* and the property that has changed. |
1868 |
|
*/ |
1869 |
|
public void propertyChange(PropertyChangeEvent event) |
1870 |
|
{ |
1871 |
|
} |
1872 |
|
}// SelectionModelPropertyChangeHandler |
1873 |
|
|
1874 |
|
/** |
1875 |
|
* ActionListener that invokes cancelEditing when action performed. |
1876 |
|
*/ |
1877 |
|
public class TreeCancelEditingAction |
1878 |
|
extends AbstractAction |
1879 |
|
{ |
1880 |
|
|
1881 |
|
/** |
1882 |
|
* Constructor |
1883 |
|
*/ |
1884 |
|
public TreeCancelEditingAction() |
1885 |
|
{ |
1886 |
|
} |
1887 |
|
|
1888 |
|
/** |
1889 |
|
* Invoked when an action occurs. |
1890 |
|
* |
1891 |
|
* @param e event that occured |
1892 |
|
*/ |
1893 |
|
public void actionPerformed(ActionEvent e) |
1894 |
|
{ |
1895 |
|
} |
1896 |
|
|
1897 |
|
/** |
1898 |
|
* Returns true if the action is enabled. |
1899 |
|
* |
1900 |
|
* @return true if the action is enabled, false otherwise |
1901 |
|
*/ |
1902 |
|
public boolean isEnabled() |
1903 |
|
{ |
1904 |
|
return false; |
1905 |
|
} |
1906 |
|
}// TreeCancelEditingAction |
1907 |
|
|
1908 |
|
/** |
1909 |
|
* Updates the TreeState in response to nodes expanding/collapsing. |
1910 |
|
*/ |
1911 |
|
public class TreeExpansionHandler |
1912 |
|
implements TreeExpansionListener |
1913 |
|
{ |
1914 |
|
|
1915 |
|
/** |
1916 |
|
* Constructor |
1917 |
|
*/ |
1918 |
|
public TreeExpansionHandler() |
1919 |
|
{ |
1920 |
|
} |
1921 |
|
|
1922 |
|
/** |
1923 |
|
* Called whenever an item in the tree has been expanded. |
1924 |
|
* |
1925 |
|
* @param event is the event that occured |
1926 |
|
*/ |
1927 |
|
public void treeExpanded(TreeExpansionEvent event) |
1928 |
|
{ |
1929 |
|
} |
1930 |
|
|
1931 |
|
/** |
1932 |
|
* Called whenever an item in the tree has been collapsed. |
1933 |
|
* |
1934 |
|
* @param event is the event that occured |
1935 |
|
*/ |
1936 |
|
public void treeCollapsed(TreeExpansionEvent event) |
1937 |
|
{ |
1938 |
|
} |
1939 |
|
}// TreeExpansionHandler |
1940 |
|
|
1941 |
|
/** |
1942 |
|
* TreeHomeAction is used to handle end/home actions. Scrolls either the |
1943 |
|
* first or last cell to be visible based on direction. |
1944 |
|
*/ |
1945 |
|
public class TreeHomeAction |
1946 |
|
extends AbstractAction |
1947 |
|
{ |
1948 |
|
|
1949 |
|
/** direction is either home or end */ |
1950 |
|
protected int direction; |
1951 |
|
|
1952 |
|
/** |
1953 |
|
* Constructor |
1954 |
|
* |
1955 |
|
* @param direction - it is home or end |
1956 |
|
* @param name is the name of the direction |
1957 |
|
*/ |
1958 |
|
public TreeHomeAction(int direction, String name) |
1959 |
|
{ |
1960 |
|
} |
1961 |
|
|
1962 |
|
/** |
1963 |
|
* Invoked when an action occurs. |
1964 |
|
* |
1965 |
|
* @param e is the event that occured |
1966 |
|
*/ |
1967 |
|
public void actionPerformed(ActionEvent e) |
1968 |
|
{ |
1969 |
|
} |
1970 |
|
|
1971 |
|
/** |
1972 |
|
* Returns true if the action is enabled. |
1973 |
|
* |
1974 |
|
* @return true if the action is enabled. |
1975 |
|
*/ |
1976 |
|
public boolean isEnabled() |
1977 |
|
{ |
1978 |
|
return false; |
1979 |
|
} |
1980 |
|
}// TreeHomeAction |
1981 |
|
|
1982 |
|
/** |
1983 |
|
* TreeIncrementAction is used to handle up/down actions. Selection is moved |
1984 |
|
* up or down based on direction. |
1985 |
|
*/ |
1986 |
|
public class TreeIncrementAction |
1987 |
|
extends AbstractAction |
1988 |
|
{ |
1989 |
|
|
1990 |
|
/** Specifies the direction to adjust the selection by. */ |
1991 |
|
protected int direction; |
1992 |
|
|
1993 |
|
/** |
1994 |
|
* Constructor |
1995 |
|
* |
1996 |
|
* @param direction up or down |
1997 |
|
* @param name is the name of the direction |
1998 |
|
*/ |
1999 |
|
public TreeIncrementAction(int direction, String name) |
2000 |
|
{ |
2001 |
|
} |
2002 |
|
|
2003 |
|
/** |
2004 |
|
* Invoked when an action occurs. |
2005 |
|
* |
2006 |
|
* @param e is the event that occured |
2007 |
|
*/ |
2008 |
|
public void actionPerformed(ActionEvent e) |
2009 |
|
{ |
2010 |
|
} |
2011 |
|
|
2012 |
|
/** |
2013 |
|
* Returns true if the action is enabled. |
2014 |
|
* |
2015 |
|
* @return true if the action is enabled. |
2016 |
|
*/ |
2017 |
|
public boolean isEnabled() |
2018 |
|
{ |
2019 |
|
return false; |
2020 |
|
} |
2021 |
|
}// TreeIncrementAction |
2022 |
|
|
2023 |
|
/** |
2024 |
|
* Forwards all TreeModel events to the TreeState. |
2025 |
|
*/ |
2026 |
|
public class TreeModelHandler |
2027 |
|
implements TreeModelListener |
2028 |
|
{ |
2029 |
|
/** |
2030 |
|
* Constructor |
2031 |
|
*/ |
2032 |
|
public TreeModelHandler() |
2033 |
|
{ |
2034 |
|
} |
2035 |
|
|
2036 |
|
/** |
2037 |
|
* Invoked after a node (or a set of siblings) has changed in some way. |
2038 |
|
* The node(s) have not changed locations in the tree or altered their |
2039 |
|
* children arrays, but other attributes have changed and may affect |
2040 |
|
* presentation. Example: the name of a file has changed, but it is in |
2041 |
|
* the same location in the file system. To indicate the root has |
2042 |
|
* changed, childIndices and children will be null. Use e.getPath() to |
2043 |
|
* get the parent of the changed node(s). e.getChildIndices() returns |
2044 |
|
* the index(es) of the changed node(s). |
2045 |
|
* |
2046 |
|
* @param e is the event that occured |
2047 |
|
*/ |
2048 |
|
public void treeNodesChanged(TreeModelEvent e) |
2049 |
|
{ |
2050 |
|
} |
2051 |
|
|
2052 |
|
/** |
2053 |
|
* Invoked after nodes have been inserted into the tree. Use e.getPath() |
2054 |
|
* to get the parent of the new node(s). e.getChildIndices() returns the |
2055 |
|
* index(es) of the new node(s) in ascending order. |
2056 |
|
* |
2057 |
|
* @param e is the event that occured |
2058 |
|
*/ |
2059 |
|
public void treeNodesInserted(TreeModelEvent e) |
2060 |
|
{ |
2061 |
|
} |
2062 |
|
|
2063 |
|
/** |
2064 |
|
* Invoked after nodes have been removed from the tree. Note that if a |
2065 |
|
* subtree is removed from the tree, this method may only be invoked |
2066 |
|
* once for the root of the removed subtree, not once for each |
2067 |
|
* individual set of siblings removed. Use e.getPath() to get the former |
2068 |
|
* parent of the deleted node(s). e.getChildIndices() returns, in |
2069 |
|
* ascending order, the index(es) the node(s) had before being deleted. |
2070 |
|
* |
2071 |
|
* @param e is the event that occured |
2072 |
|
*/ |
2073 |
|
public void treeNodesRemoved(TreeModelEvent e) |
2074 |
|
{ |
2075 |
|
} |
2076 |
|
|
2077 |
|
/** |
2078 |
|
* Invoked after the tree has drastically changed structure from a given |
2079 |
|
* node down. If the path returned by e.getPath() is of length one and |
2080 |
|
* the first element does not identify the current root node the first |
2081 |
|
* element should become the new root of the tree. Use e.getPath() to |
2082 |
|
* get the path to the node. e.getChildIndices() returns null. |
2083 |
|
* |
2084 |
|
* @param e is the event that occured |
2085 |
|
*/ |
2086 |
|
public void treeStructureChanged(TreeModelEvent e) |
2087 |
|
{ |
2088 |
|
} |
2089 |
|
}// TreeModelHandler |
2090 |
|
|
2091 |
|
/** |
2092 |
|
* TreePageAction handles page up and page down events. |
2093 |
|
*/ |
2094 |
|
public class TreePageAction |
2095 |
|
extends AbstractAction |
2096 |
|
{ |
2097 |
|
/** Specifies the direction to adjust the selection by. */ |
2098 |
|
protected int direction; |
2099 |
|
|
2100 |
|
/** |
2101 |
|
* Constructor |
2102 |
|
* |
2103 |
|
* @param direction up or down |
2104 |
|
* @param name is the name of the direction |
2105 |
|
*/ |
2106 |
|
public TreePageAction(int direction, String name) |
2107 |
|
{ |
2108 |
|
} |
2109 |
|
|
2110 |
|
/** |
2111 |
|
* Invoked when an action occurs. |
2112 |
|
* |
2113 |
|
* @param e is the event that occured |
2114 |
|
*/ |
2115 |
|
public void actionPerformed(ActionEvent e) |
2116 |
|
{ |
2117 |
|
} |
2118 |
|
|
2119 |
|
/** |
2120 |
|
* Returns true if the action is enabled. |
2121 |
|
* |
2122 |
|
* @return true if the action is enabled. |
2123 |
|
*/ |
2124 |
|
public boolean isEnabled() |
2125 |
|
{ |
2126 |
|
return false; |
2127 |
|
} |
2128 |
|
}// TreePageAction |
2129 |
|
|
2130 |
|
/** |
2131 |
|
* Listens for changes in the selection model and updates the display |
2132 |
|
* accordingly. |
2133 |
|
*/ |
2134 |
|
public class TreeSelectionHandler |
2135 |
|
implements TreeSelectionListener |
2136 |
|
{ |
2137 |
|
/** |
2138 |
|
* Constructor |
2139 |
|
*/ |
2140 |
|
public TreeSelectionHandler() |
2141 |
|
{ |
2142 |
|
} |
2143 |
|
|
2144 |
|
/** |
2145 |
|
* Messaged when the selection changes in the tree we're displaying for. |
2146 |
|
* Stops editing, messages super and displays the changed paths. |
2147 |
|
* |
2148 |
|
* @param event the event that characterizes the change. |
2149 |
|
*/ |
2150 |
|
public void valueChanged(TreeSelectionEvent event) |
2151 |
|
{ |
2152 |
|
} |
2153 |
|
}// TreeSelectionHandler |
2154 |
|
|
2155 |
|
/** |
2156 |
|
* For the first selected row expandedness will be toggled. |
2157 |
|
*/ |
2158 |
|
public class TreeToggleAction |
2159 |
|
extends AbstractAction |
2160 |
|
{ |
2161 |
|
/** |
2162 |
|
* Constructor |
2163 |
|
* |
2164 |
|
* @param name is the name of <code>Action</code> field |
2165 |
|
*/ |
2166 |
|
public TreeToggleAction(String name) |
2167 |
|
{ |
2168 |
|
} |
2169 |
|
|
2170 |
|
/** |
2171 |
|
* Invoked when an action occurs. |
2172 |
|
* |
2173 |
|
* @param e the event that occured |
2174 |
|
*/ |
2175 |
|
public void actionPerformed(ActionEvent e) |
2176 |
|
{ |
2177 |
|
} |
2178 |
|
|
2179 |
|
/** |
2180 |
|
* Returns true if the action is enabled. |
2181 |
|
* |
2182 |
|
* @return true if the action is enabled, false otherwise |
2183 |
|
*/ |
2184 |
|
public boolean isEnabled() |
2185 |
|
{ |
2186 |
|
return false; |
2187 |
|
} |
2188 |
|
} // TreeToggleAction |
2189 |
|
|
2190 |
|
/** |
2191 |
|
* TreeTraverseAction is the action used for left/right keys. Will toggle |
2192 |
|
* the expandedness of a node, as well as potentially incrementing the |
2193 |
|
* selection. |
2194 |
|
*/ |
2195 |
|
public class TreeTraverseAction |
2196 |
|
extends AbstractAction |
2197 |
|
{ |
2198 |
|
/** |
2199 |
|
* Determines direction to traverse, 1 means expand, -1 means collapse. |
2200 |
|
*/ |
2201 |
|
protected int direction; |
2202 |
|
|
2203 |
|
/** |
2204 |
|
* Constructor |
2205 |
|
* |
2206 |
|
* @param direction to traverse |
2207 |
|
* @param name is the name of the direction |
2208 |
|
*/ |
2209 |
|
public TreeTraverseAction(int direction, String name) |
2210 |
|
{ |
2211 |
|
} |
2212 |
|
|
2213 |
|
/** |
2214 |
|
* Invoked when an action occurs. |
2215 |
|
* |
2216 |
|
* @param e the event that occured |
2217 |
|
*/ |
2218 |
|
public void actionPerformed(ActionEvent e) |
2219 |
|
{ |
2220 |
|
} |
2221 |
|
|
2222 |
|
/** |
2223 |
|
* Returns true if the action is enabled. |
2224 |
|
* |
2225 |
|
* @return true if the action is enabled, false otherwise |
2226 |
|
*/ |
2227 |
|
public boolean isEnabled() |
2228 |
|
{ |
2229 |
|
return false; |
2230 |
|
} |
2231 |
|
} // TreeTraverseAction |
2232 |
|
|
2233 |
|
/* * HELPER METHODS FOR PAINTING * */ |
2234 |
|
|
2235 |
|
private void paintLeaf(Graphics g, int x, int y, JTree tree, Object leaf) |
2236 |
|
{ |
2237 |
|
Component c = tree.getCellRenderer().getTreeCellRendererComponent(tree, |
2238 |
|
leaf, false, false, true, 0, false); |
2239 |
|
g.translate(x, y); |
2240 |
|
c.paint(g); |
2241 |
|
g.translate(-x, -y); |
2242 |
|
} |
2243 |
|
|
2244 |
|
private void paintNonLeaf(Graphics g, int x, int y, JTree tree, |
2245 |
|
Object nonLeaf) |
2246 |
|
{ |
2247 |
|
Component c = tree.getCellRenderer().getTreeCellRendererComponent(tree, |
2248 |
|
nonLeaf, false, false, false, 0, false); |
2249 |
|
g.translate(x, y); |
2250 |
|
c.paint(g); |
2251 |
|
g.translate(-x, -y); |
2252 |
|
} |
2253 |
|
|
2254 |
|
private int paintRecursive(Graphics g, int indentation, int descent, |
2255 |
|
int childNumber, int depth, JTree tree, TreeModel mod, Object curr) |
2256 |
|
{ |
2257 |
|
Rectangle clip = g.getClipBounds(); |
2258 |
|
if (indentation > clip.x + clip.width + rightChildIndent |
2259 |
|
|| descent > clip.y + clip.height + getRowHeight()) |
2260 |
|
return descent; |
2261 |
|
|
2262 |
|
int halfHeight = getRowHeight() / 2; |
2263 |
|
int halfWidth = rightChildIndent / 2; |
2264 |
|
int y0 = descent + halfHeight; |
2265 |
|
|
2266 |
|
if (mod.isLeaf(curr)) |
2267 |
|
{ |
2268 |
|
paintLeaf(g, indentation, descent, tree, curr); |
2269 |
|
descent += getRowHeight(); |
2270 |
|
} else |
2271 |
|
{ |
2272 |
|
if (depth > 0 || tree.isRootVisible()) |
2273 |
|
{ |
2274 |
|
paintNonLeaf(g, indentation, descent, tree, curr); |
2275 |
|
descent += getRowHeight(); |
2276 |
|
y0 += halfHeight; |
2277 |
|
} |
2278 |
|
int max = mod.getChildCount(curr); |
2279 |
|
for (int i = 0; i < max; ++i) |
2280 |
|
{ |
2281 |
|
g.setColor(getHashColor()); |
2282 |
|
g.drawLine(indentation + halfWidth, descent + halfHeight, |
2283 |
|
indentation + rightChildIndent, descent + halfHeight); |
2284 |
|
descent = paintRecursive(g, indentation + rightChildIndent, |
2285 |
|
descent, i, depth + 1, tree, mod, mod.getChild(curr, i)); |
2286 |
|
} |
2287 |
|
} |
2288 |
|
|
2289 |
|
int y1 = descent - halfHeight; |
2290 |
|
if (y0 != y1) |
2291 |
|
{ |
2292 |
|
g.setColor(getHashColor()); |
2293 |
|
g |
2294 |
|
.drawLine(indentation + halfWidth, y0, indentation |
2295 |
|
+ halfWidth, y1); |
2296 |
|
} |
2297 |
|
|
2298 |
|
return descent; |
2299 |
|
} |
2300 |
|
|
2301 |
|
} // BasicTreeUI |