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