277 map.put(TransferHandler.getCutAction()); |
289 map.put(TransferHandler.getCutAction()); |
278 map.put(TransferHandler.getCopyAction()); |
290 map.put(TransferHandler.getCopyAction()); |
279 map.put(TransferHandler.getPasteAction()); |
291 map.put(TransferHandler.getPasteAction()); |
280 } |
292 } |
281 |
293 |
282 |
294 /** |
|
295 * Constructs a new instance of {@code BasicTreeUI}. |
|
296 */ |
283 public BasicTreeUI() { |
297 public BasicTreeUI() { |
284 super(); |
298 super(); |
285 } |
299 } |
286 |
300 |
|
301 /** |
|
302 * Returns the hash color. |
|
303 * |
|
304 * @return the hash color |
|
305 */ |
287 protected Color getHashColor() { |
306 protected Color getHashColor() { |
288 return hashColor; |
307 return hashColor; |
289 } |
308 } |
290 |
309 |
|
310 /** |
|
311 * Sets the hash color. |
|
312 * |
|
313 * @param color the hash color |
|
314 */ |
291 protected void setHashColor(Color color) { |
315 protected void setHashColor(Color color) { |
292 hashColor = color; |
316 hashColor = color; |
293 } |
317 } |
294 |
318 |
|
319 /** |
|
320 * Sets the left child indent. |
|
321 * |
|
322 * @param newAmount the left child indent |
|
323 */ |
295 public void setLeftChildIndent(int newAmount) { |
324 public void setLeftChildIndent(int newAmount) { |
296 leftChildIndent = newAmount; |
325 leftChildIndent = newAmount; |
297 totalChildIndent = leftChildIndent + rightChildIndent; |
326 totalChildIndent = leftChildIndent + rightChildIndent; |
298 if(treeState != null) |
327 if(treeState != null) |
299 treeState.invalidateSizes(); |
328 treeState.invalidateSizes(); |
300 updateSize(); |
329 updateSize(); |
301 } |
330 } |
302 |
331 |
|
332 /** |
|
333 * Returns the left child indent. |
|
334 * |
|
335 * @return the left child indent |
|
336 */ |
303 public int getLeftChildIndent() { |
337 public int getLeftChildIndent() { |
304 return leftChildIndent; |
338 return leftChildIndent; |
305 } |
339 } |
306 |
340 |
|
341 /** |
|
342 * Sets the right child indent. |
|
343 * |
|
344 * @param newAmount the right child indent |
|
345 */ |
307 public void setRightChildIndent(int newAmount) { |
346 public void setRightChildIndent(int newAmount) { |
308 rightChildIndent = newAmount; |
347 rightChildIndent = newAmount; |
309 totalChildIndent = leftChildIndent + rightChildIndent; |
348 totalChildIndent = leftChildIndent + rightChildIndent; |
310 if(treeState != null) |
349 if(treeState != null) |
311 treeState.invalidateSizes(); |
350 treeState.invalidateSizes(); |
312 updateSize(); |
351 updateSize(); |
313 } |
352 } |
314 |
353 |
|
354 /** |
|
355 * Returns the right child indent. |
|
356 * |
|
357 * @return the right child indent |
|
358 */ |
315 public int getRightChildIndent() { |
359 public int getRightChildIndent() { |
316 return rightChildIndent; |
360 return rightChildIndent; |
317 } |
361 } |
318 |
362 |
|
363 /** |
|
364 * Sets the expanded icon. |
|
365 * |
|
366 * @param newG the expanded icon |
|
367 */ |
319 public void setExpandedIcon(Icon newG) { |
368 public void setExpandedIcon(Icon newG) { |
320 expandedIcon = newG; |
369 expandedIcon = newG; |
321 } |
370 } |
322 |
371 |
|
372 /** |
|
373 * Returns the expanded icon. |
|
374 * |
|
375 * @return the expanded icon |
|
376 */ |
323 public Icon getExpandedIcon() { |
377 public Icon getExpandedIcon() { |
324 return expandedIcon; |
378 return expandedIcon; |
325 } |
379 } |
326 |
380 |
|
381 /** |
|
382 * Sets the collapsed icon. |
|
383 * |
|
384 * @param newG the collapsed icon |
|
385 */ |
327 public void setCollapsedIcon(Icon newG) { |
386 public void setCollapsedIcon(Icon newG) { |
328 collapsedIcon = newG; |
387 collapsedIcon = newG; |
329 } |
388 } |
330 |
389 |
|
390 /** |
|
391 * Returns the collapsed icon. |
|
392 * |
|
393 * @return the collapsed icon |
|
394 */ |
331 public Icon getCollapsedIcon() { |
395 public Icon getCollapsedIcon() { |
332 return collapsedIcon; |
396 return collapsedIcon; |
333 } |
397 } |
334 |
398 |
335 // |
399 // |
352 updateLayoutCacheExpandedNodesIfNecessary(); |
418 updateLayoutCacheExpandedNodesIfNecessary(); |
353 updateSize(); |
419 updateSize(); |
354 } |
420 } |
355 } |
421 } |
356 |
422 |
|
423 /** |
|
424 * Returns {@code true} if large model is set. |
|
425 * |
|
426 * @return {@code true} if large model is set |
|
427 */ |
357 protected boolean isLargeModel() { |
428 protected boolean isLargeModel() { |
358 return largeModel; |
429 return largeModel; |
359 } |
430 } |
360 |
431 |
361 /** |
432 /** |
362 * Sets the row height, this is forwarded to the treeState. |
433 * Sets the row height, this is forwarded to the treeState. |
|
434 * |
|
435 * @param rowHeight the row height |
363 */ |
436 */ |
364 protected void setRowHeight(int rowHeight) { |
437 protected void setRowHeight(int rowHeight) { |
365 completeEditing(); |
438 completeEditing(); |
366 if(treeState != null) { |
439 if(treeState != null) { |
367 setLargeModel(tree.isLargeModel()); |
440 setLargeModel(tree.isLargeModel()); |
368 treeState.setRowHeight(rowHeight); |
441 treeState.setRowHeight(rowHeight); |
369 updateSize(); |
442 updateSize(); |
370 } |
443 } |
371 } |
444 } |
372 |
445 |
|
446 /** |
|
447 * Returns the row height. |
|
448 * |
|
449 * @return the row height |
|
450 */ |
373 protected int getRowHeight() { |
451 protected int getRowHeight() { |
374 return (tree == null) ? -1 : tree.getRowHeight(); |
452 return (tree == null) ? -1 : tree.getRowHeight(); |
375 } |
453 } |
376 |
454 |
377 /** |
455 /** |
378 * Sets the TreeCellRenderer to <code>tcr</code>. This invokes |
456 * Sets the {@code TreeCellRenderer} to {@code tcr}. This invokes |
379 * <code>updateRenderer</code>. |
457 * {@code updateRenderer}. |
|
458 * |
|
459 * @param tcr the new value |
380 */ |
460 */ |
381 protected void setCellRenderer(TreeCellRenderer tcr) { |
461 protected void setCellRenderer(TreeCellRenderer tcr) { |
382 completeEditing(); |
462 completeEditing(); |
383 updateRenderer(); |
463 updateRenderer(); |
384 if(treeState != null) { |
464 if(treeState != null) { |
386 updateSize(); |
466 updateSize(); |
387 } |
467 } |
388 } |
468 } |
389 |
469 |
390 /** |
470 /** |
391 * Return currentCellRenderer, which will either be the trees |
471 * Return {@code currentCellRenderer}, which will either be the trees |
392 * renderer, or defaultCellRenderer, which ever wasn't null. |
472 * renderer, or {@code defaultCellRenderer}, which ever wasn't null. |
|
473 * |
|
474 * @return an instance of {@code TreeCellRenderer} |
393 */ |
475 */ |
394 protected TreeCellRenderer getCellRenderer() { |
476 protected TreeCellRenderer getCellRenderer() { |
395 return currentCellRenderer; |
477 return currentCellRenderer; |
396 } |
478 } |
397 |
479 |
398 /** |
480 /** |
399 * Sets the TreeModel. |
481 * Sets the {@code TreeModel}. |
|
482 * |
|
483 * @param model the new value |
400 */ |
484 */ |
401 protected void setModel(TreeModel model) { |
485 protected void setModel(TreeModel model) { |
402 completeEditing(); |
486 completeEditing(); |
403 if(treeModel != null && treeModelListener != null) |
487 if(treeModel != null && treeModelListener != null) |
404 treeModel.removeTreeModelListener(treeModelListener); |
488 treeModel.removeTreeModelListener(treeModelListener); |
429 treeState.invalidateSizes(); |
520 treeState.invalidateSizes(); |
430 updateSize(); |
521 updateSize(); |
431 } |
522 } |
432 } |
523 } |
433 |
524 |
|
525 /** |
|
526 * Returns {@code true} if the tree root is visible. |
|
527 * |
|
528 * @return {@code true} if the tree root is visible |
|
529 */ |
434 protected boolean isRootVisible() { |
530 protected boolean isRootVisible() { |
435 return (tree != null) ? tree.isRootVisible() : false; |
531 return (tree != null) ? tree.isRootVisible() : false; |
436 } |
532 } |
437 |
533 |
438 /** |
534 /** |
439 * Determines whether the node handles are to be displayed. |
535 * Determines whether the node handles are to be displayed. |
|
536 * |
|
537 * @param newValue the new value |
440 */ |
538 */ |
441 protected void setShowsRootHandles(boolean newValue) { |
539 protected void setShowsRootHandles(boolean newValue) { |
442 completeEditing(); |
540 completeEditing(); |
443 updateDepthOffset(); |
541 updateDepthOffset(); |
444 if(treeState != null) { |
542 if(treeState != null) { |
445 treeState.invalidateSizes(); |
543 treeState.invalidateSizes(); |
446 updateSize(); |
544 updateSize(); |
447 } |
545 } |
448 } |
546 } |
449 |
547 |
|
548 /** |
|
549 * Returns {@code true} if the root handles are to be displayed. |
|
550 * |
|
551 * @return {@code true} if the root handles are to be displayed |
|
552 */ |
450 protected boolean getShowsRootHandles() { |
553 protected boolean getShowsRootHandles() { |
451 return (tree != null) ? tree.getShowsRootHandles() : false; |
554 return (tree != null) ? tree.getShowsRootHandles() : false; |
452 } |
555 } |
453 |
556 |
454 /** |
557 /** |
455 * Sets the cell editor. |
558 * Sets the cell editor. |
|
559 * |
|
560 * @param editor the new cell editor |
456 */ |
561 */ |
457 protected void setCellEditor(TreeCellEditor editor) { |
562 protected void setCellEditor(TreeCellEditor editor) { |
458 updateCellEditor(); |
563 updateCellEditor(); |
459 } |
564 } |
460 |
565 |
|
566 /** |
|
567 * Returns an instance of {@code TreeCellEditor}. |
|
568 * |
|
569 * @return an instance of {@code TreeCellEditor} |
|
570 */ |
461 protected TreeCellEditor getCellEditor() { |
571 protected TreeCellEditor getCellEditor() { |
462 return (tree != null) ? tree.getCellEditor() : null; |
572 return (tree != null) ? tree.getCellEditor() : null; |
463 } |
573 } |
464 |
574 |
465 /** |
575 /** |
466 * Configures the receiver to allow, or not allow, editing. |
576 * Configures the receiver to allow, or not allow, editing. |
|
577 * |
|
578 * @param newValue the new value |
467 */ |
579 */ |
468 protected void setEditable(boolean newValue) { |
580 protected void setEditable(boolean newValue) { |
469 updateCellEditor(); |
581 updateCellEditor(); |
470 } |
582 } |
471 |
583 |
|
584 /** |
|
585 * Returns {@code true} if the tree is editable. |
|
586 * |
|
587 * @return {@code true} if the tree is editable |
|
588 */ |
472 protected boolean isEditable() { |
589 protected boolean isEditable() { |
473 return (tree != null) ? tree.isEditable() : false; |
590 return (tree != null) ? tree.isEditable() : false; |
474 } |
591 } |
475 |
592 |
476 /** |
593 /** |
477 * Resets the selection model. The appropriate listener are installed |
594 * Resets the selection model. The appropriate listener are installed |
478 * on the model. |
595 * on the model. |
|
596 * |
|
597 * @param newLSM new selection model |
479 */ |
598 */ |
480 protected void setSelectionModel(TreeSelectionModel newLSM) { |
599 protected void setSelectionModel(TreeSelectionModel newLSM) { |
481 completeEditing(); |
600 completeEditing(); |
482 if(selectionModelPropertyChangeListener != null && |
601 if(selectionModelPropertyChangeListener != null && |
483 treeSelectionModel != null) |
602 treeSelectionModel != null) |
860 } |
997 } |
861 |
998 |
862 /** |
999 /** |
863 * Creates the listener responsible for updating the selection based on |
1000 * Creates the listener responsible for updating the selection based on |
864 * mouse events. |
1001 * mouse events. |
|
1002 * |
|
1003 * @return an instance of the {@code MouseListener} |
865 */ |
1004 */ |
866 protected MouseListener createMouseListener() { |
1005 protected MouseListener createMouseListener() { |
867 return getHandler(); |
1006 return getHandler(); |
868 } |
1007 } |
869 |
1008 |
870 /** |
1009 /** |
871 * Creates a listener that is responsible for updating the display |
1010 * Creates a listener that is responsible for updating the display |
872 * when focus is lost/gained. |
1011 * when focus is lost/gained. |
|
1012 * |
|
1013 * @return an instance of the {@code FocusListener} |
873 */ |
1014 */ |
874 protected FocusListener createFocusListener() { |
1015 protected FocusListener createFocusListener() { |
875 return getHandler(); |
1016 return getHandler(); |
876 } |
1017 } |
877 |
1018 |
878 /** |
1019 /** |
879 * Creates the listener reponsible for getting key events from |
1020 * Creates the listener responsible for getting key events from |
880 * the tree. |
1021 * the tree. |
|
1022 * |
|
1023 * @return an instance of the {@code KeyListener} |
881 */ |
1024 */ |
882 protected KeyListener createKeyListener() { |
1025 protected KeyListener createKeyListener() { |
883 return getHandler(); |
1026 return getHandler(); |
884 } |
1027 } |
885 |
1028 |
886 /** |
1029 /** |
887 * Creates the listener responsible for getting property change |
1030 * Creates the listener responsible for getting property change |
888 * events from the selection model. |
1031 * events from the selection model. |
|
1032 * |
|
1033 * @return an instance of the {@code PropertyChangeListener} |
889 */ |
1034 */ |
890 protected PropertyChangeListener createSelectionModelPropertyChangeListener() { |
1035 protected PropertyChangeListener createSelectionModelPropertyChangeListener() { |
891 return getHandler(); |
1036 return getHandler(); |
892 } |
1037 } |
893 |
1038 |
894 /** |
1039 /** |
895 * Creates the listener that updates the display based on selection change |
1040 * Creates the listener that updates the display based on selection change |
896 * methods. |
1041 * methods. |
|
1042 * |
|
1043 * @return an instance of the {@code TreeSelectionListener} |
897 */ |
1044 */ |
898 protected TreeSelectionListener createTreeSelectionListener() { |
1045 protected TreeSelectionListener createTreeSelectionListener() { |
899 return getHandler(); |
1046 return getHandler(); |
900 } |
1047 } |
901 |
1048 |
902 /** |
1049 /** |
903 * Creates a listener to handle events from the current editor. |
1050 * Creates a listener to handle events from the current editor. |
|
1051 * |
|
1052 * @return an instance of the {@code CellEditorListener} |
904 */ |
1053 */ |
905 protected CellEditorListener createCellEditorListener() { |
1054 protected CellEditorListener createCellEditorListener() { |
906 return getHandler(); |
1055 return getHandler(); |
907 } |
1056 } |
908 |
1057 |
909 /** |
1058 /** |
910 * Creates and returns a new ComponentHandler. This is used for |
1059 * Creates and returns a new ComponentHandler. This is used for |
911 * the large model to mark the validCachedPreferredSize as invalid |
1060 * the large model to mark the validCachedPreferredSize as invalid |
912 * when the component moves. |
1061 * when the component moves. |
|
1062 * |
|
1063 * @return an instance of the {@code ComponentListener} |
913 */ |
1064 */ |
914 protected ComponentListener createComponentListener() { |
1065 protected ComponentListener createComponentListener() { |
915 return new ComponentHandler(); |
1066 return new ComponentHandler(); |
916 } |
1067 } |
917 |
1068 |
918 /** |
1069 /** |
919 * Creates and returns the object responsible for updating the treestate |
1070 * Creates and returns the object responsible for updating the treestate |
920 * when nodes expanded state changes. |
1071 * when nodes expanded state changes. |
|
1072 * |
|
1073 * @return an instance of the {@code TreeExpansionListener} |
921 */ |
1074 */ |
922 protected TreeExpansionListener createTreeExpansionListener() { |
1075 protected TreeExpansionListener createTreeExpansionListener() { |
923 return getHandler(); |
1076 return getHandler(); |
924 } |
1077 } |
925 |
1078 |
926 /** |
1079 /** |
927 * Creates the object responsible for managing what is expanded, as |
1080 * Creates the object responsible for managing what is expanded, as |
928 * well as the size of nodes. |
1081 * well as the size of nodes. |
|
1082 * |
|
1083 * @return the object responsible for managing what is expanded |
929 */ |
1084 */ |
930 protected AbstractLayoutCache createLayoutCache() { |
1085 protected AbstractLayoutCache createLayoutCache() { |
931 if(isLargeModel() && getRowHeight() > 0) { |
1086 if(isLargeModel() && getRowHeight() > 0) { |
932 return new FixedHeightLayoutCache(); |
1087 return new FixedHeightLayoutCache(); |
933 } |
1088 } |
934 return new VariableHeightLayoutCache(); |
1089 return new VariableHeightLayoutCache(); |
935 } |
1090 } |
936 |
1091 |
937 /** |
1092 /** |
938 * Returns the renderer pane that renderer components are placed in. |
1093 * Returns the renderer pane that renderer components are placed in. |
|
1094 * |
|
1095 * @return an instance of the {@code CellRendererPane} |
939 */ |
1096 */ |
940 protected CellRendererPane createCellRendererPane() { |
1097 protected CellRendererPane createCellRendererPane() { |
941 return new CellRendererPane(); |
1098 return new CellRendererPane(); |
942 } |
1099 } |
943 |
1100 |
944 /** |
1101 /** |
945 * Creates a default cell editor. |
1102 * Creates a default cell editor. |
946 */ |
1103 * |
|
1104 * @return a default cell editor |
|
1105 */ |
947 protected TreeCellEditor createDefaultCellEditor() { |
1106 protected TreeCellEditor createDefaultCellEditor() { |
948 if(currentCellRenderer != null && |
1107 if(currentCellRenderer != null && |
949 (currentCellRenderer instanceof DefaultTreeCellRenderer)) { |
1108 (currentCellRenderer instanceof DefaultTreeCellRenderer)) { |
950 DefaultTreeCellEditor editor = new DefaultTreeCellEditor |
1109 DefaultTreeCellEditor editor = new DefaultTreeCellEditor |
951 (tree, (DefaultTreeCellRenderer)currentCellRenderer); |
1110 (tree, (DefaultTreeCellRenderer)currentCellRenderer); |
1014 treeSelectionModel = null; |
1183 treeSelectionModel = null; |
1015 treeSelectionListener = null; |
1184 treeSelectionListener = null; |
1016 treeExpansionListener = null; |
1185 treeExpansionListener = null; |
1017 } |
1186 } |
1018 |
1187 |
|
1188 /** |
|
1189 * Uninstalls default properties. |
|
1190 */ |
1019 protected void uninstallDefaults() { |
1191 protected void uninstallDefaults() { |
1020 if (tree.getTransferHandler() instanceof UIResource) { |
1192 if (tree.getTransferHandler() instanceof UIResource) { |
1021 tree.setTransferHandler(null); |
1193 tree.setTransferHandler(null); |
1022 } |
1194 } |
1023 } |
1195 } |
1024 |
1196 |
|
1197 /** |
|
1198 * Unregisters listeners. |
|
1199 */ |
1025 protected void uninstallListeners() { |
1200 protected void uninstallListeners() { |
1026 if(componentListener != null) { |
1201 if(componentListener != null) { |
1027 tree.removeComponentListener(componentListener); |
1202 tree.removeComponentListener(componentListener); |
1028 } |
1203 } |
1029 if (propertyChangeListener != null) { |
1204 if (propertyChangeListener != null) { |
1338 return rect; |
1516 return rect; |
1339 } |
1517 } |
1340 |
1518 |
1341 /** |
1519 /** |
1342 * Paints the horizontal part of the leg. The receiver should |
1520 * Paints the horizontal part of the leg. The receiver should |
1343 * NOT modify <code>clipBounds</code>, or <code>insets</code>.<p> |
1521 * NOT modify {@code clipBounds}, or {@code insets}.<p> |
1344 * NOTE: <code>parentRow</code> can be -1 if the root is not visible. |
1522 * NOTE: {@code parentRow} can be -1 if the root is not visible. |
|
1523 * |
|
1524 * @param g a graphics context |
|
1525 * @param clipBounds a clipped rectangle |
|
1526 * @param insets insets |
|
1527 * @param bounds a bounding rectangle |
|
1528 * @param path a tree path |
|
1529 * @param row a row |
|
1530 * @param isExpanded {@code true} if the path is expanded |
|
1531 * @param hasBeenExpanded {@code true} if the path has been expanded |
|
1532 * @param isLeaf {@code true} if the path is leaf |
1345 */ |
1533 */ |
1346 protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, |
1534 protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, |
1347 Insets insets, Rectangle bounds, |
1535 Insets insets, Rectangle bounds, |
1348 TreePath path, int row, |
1536 TreePath path, int row, |
1349 boolean isExpanded, |
1537 boolean isExpanded, |
1470 } |
1663 } |
1471 } |
1664 } |
1472 |
1665 |
1473 /** |
1666 /** |
1474 * Paints the expand (toggle) part of a row. The receiver should |
1667 * Paints the expand (toggle) part of a row. The receiver should |
1475 * NOT modify <code>clipBounds</code>, or <code>insets</code>. |
1668 * NOT modify {@code clipBounds}, or {@code insets}. |
|
1669 * |
|
1670 * @param g a graphics context |
|
1671 * @param clipBounds a clipped rectangle |
|
1672 * @param insets insets |
|
1673 * @param bounds a bounding rectangle |
|
1674 * @param path a tree path |
|
1675 * @param row a row |
|
1676 * @param isExpanded {@code true} if the path is expanded |
|
1677 * @param hasBeenExpanded {@code true} if the path has been expanded |
|
1678 * @param isLeaf {@code true} if the row is leaf |
1476 */ |
1679 */ |
1477 protected void paintExpandControl(Graphics g, |
1680 protected void paintExpandControl(Graphics g, |
1478 Rectangle clipBounds, Insets insets, |
1681 Rectangle clipBounds, Insets insets, |
1479 Rectangle bounds, TreePath path, |
1682 Rectangle bounds, TreePath path, |
1480 int row, boolean isExpanded, |
1683 int row, boolean isExpanded, |
1509 } |
1712 } |
1510 } |
1713 } |
1511 |
1714 |
1512 /** |
1715 /** |
1513 * Paints the renderer part of a row. The receiver should |
1716 * Paints the renderer part of a row. The receiver should |
1514 * NOT modify <code>clipBounds</code>, or <code>insets</code>. |
1717 * NOT modify {@code clipBounds}, or {@code insets}. |
|
1718 * |
|
1719 * @param g a graphics context |
|
1720 * @param clipBounds a clipped rectangle |
|
1721 * @param insets insets |
|
1722 * @param bounds a bounding rectangle |
|
1723 * @param path a tree path |
|
1724 * @param row a row |
|
1725 * @param isExpanded {@code true} if the path is expanded |
|
1726 * @param hasBeenExpanded {@code true} if the path has been expanded |
|
1727 * @param isLeaf {@code true} if the path is leaf |
1515 */ |
1728 */ |
1516 protected void paintRow(Graphics g, Rectangle clipBounds, |
1729 protected void paintRow(Graphics g, Rectangle clipBounds, |
1517 Insets insets, Rectangle bounds, TreePath path, |
1730 Insets insets, Rectangle bounds, TreePath path, |
1518 int row, boolean isExpanded, |
1731 int row, boolean isExpanded, |
1519 boolean hasBeenExpanded, boolean isLeaf) { |
1732 boolean hasBeenExpanded, boolean isLeaf) { |
1539 rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y, |
1752 rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y, |
1540 bounds.width, bounds.height, true); |
1753 bounds.width, bounds.height, true); |
1541 } |
1754 } |
1542 |
1755 |
1543 /** |
1756 /** |
1544 * Returns true if the expand (toggle) control should be drawn for |
1757 * Returns {@code true} if the expand (toggle) control should be drawn for |
1545 * the specified row. |
1758 * the specified row. |
|
1759 * |
|
1760 * @param path a tree path |
|
1761 * @param row a row |
|
1762 * @param isExpanded {@code true} if the path is expanded |
|
1763 * @param hasBeenExpanded {@code true} if the path has been expanded |
|
1764 * @param isLeaf {@code true} if the row is leaf |
|
1765 * @return {@code true} if the expand (toggle) control should be drawn |
|
1766 * for the specified row |
1546 */ |
1767 */ |
1547 protected boolean shouldPaintExpandControl(TreePath path, int row, |
1768 protected boolean shouldPaintExpandControl(TreePath path, int row, |
1548 boolean isExpanded, |
1769 boolean isExpanded, |
1549 boolean hasBeenExpanded, |
1770 boolean hasBeenExpanded, |
1550 boolean isLeaf) { |
1771 boolean isLeaf) { |
1571 } |
1798 } |
1572 } |
1799 } |
1573 |
1800 |
1574 /** |
1801 /** |
1575 * Paints a horizontal line. |
1802 * Paints a horizontal line. |
|
1803 * |
|
1804 * @param g a graphics context |
|
1805 * @param c a component |
|
1806 * @param y an Y coordinate |
|
1807 * @param left an X1 coordinate |
|
1808 * @param right an X2 coordinate |
1576 */ |
1809 */ |
1577 protected void paintHorizontalLine(Graphics g, JComponent c, int y, |
1810 protected void paintHorizontalLine(Graphics g, JComponent c, int y, |
1578 int left, int right) { |
1811 int left, int right) { |
1579 if (lineTypeDashed) { |
1812 if (lineTypeDashed) { |
1580 drawDashedHorizontalLine(g, y, left, right); |
1813 drawDashedHorizontalLine(g, y, left, right); |
1608 |
1845 |
1609 // |
1846 // |
1610 // Generic painting methods |
1847 // Generic painting methods |
1611 // |
1848 // |
1612 |
1849 |
1613 // Draws the icon centered at (x,y) |
1850 /** |
|
1851 * Draws the {@code icon} centered at (x,y). |
|
1852 * |
|
1853 * @param c a component |
|
1854 * @param graphics a graphics context |
|
1855 * @param icon an icon |
|
1856 * @param x an X coordinate |
|
1857 * @param y an Y coordinate |
|
1858 */ |
1614 protected void drawCentered(Component c, Graphics graphics, Icon icon, |
1859 protected void drawCentered(Component c, Graphics graphics, Icon icon, |
1615 int x, int y) { |
1860 int x, int y) { |
1616 icon.paintIcon(c, graphics, |
1861 icon.paintIcon(c, graphics, |
1617 findCenteredX(x, icon.getIconWidth()), |
1862 findCenteredX(x, icon.getIconWidth()), |
1618 y - icon.getIconHeight() / 2); |
1863 y - icon.getIconHeight() / 2); |
1904 } |
2154 } |
1905 validCachedPreferredSize = true; |
2155 validCachedPreferredSize = true; |
1906 } |
2156 } |
1907 |
2157 |
1908 /** |
2158 /** |
1909 * Messaged from the VisibleTreeNode after it has been expanded. |
2159 * Messaged from the {@code VisibleTreeNode} after it has been expanded. |
1910 */ |
2160 * |
|
2161 * @param path a tree path |
|
2162 */ |
1911 protected void pathWasExpanded(TreePath path) { |
2163 protected void pathWasExpanded(TreePath path) { |
1912 if(tree != null) { |
2164 if(tree != null) { |
1913 tree.fireTreeExpanded(path); |
2165 tree.fireTreeExpanded(path); |
1914 } |
2166 } |
1915 } |
2167 } |
1916 |
2168 |
1917 /** |
2169 /** |
1918 * Messaged from the VisibleTreeNode after it has collapsed. |
2170 * Messaged from the {@code VisibleTreeNode} after it has collapsed. |
1919 */ |
2171 * |
|
2172 * @param path a tree path |
|
2173 */ |
1920 protected void pathWasCollapsed(TreePath path) { |
2174 protected void pathWasCollapsed(TreePath path) { |
1921 if(tree != null) { |
2175 if(tree != null) { |
1922 tree.fireTreeCollapsed(path); |
2176 tree.fireTreeCollapsed(path); |
1923 } |
2177 } |
1924 } |
2178 } |
1925 |
2179 |
1926 /** |
2180 /** |
1927 * Ensures that the rows identified by beginRow through endRow are |
2181 * Ensures that the rows identified by {@code beginRow} through |
1928 * visible. |
2182 * {@code endRow} are visible. |
1929 */ |
2183 * |
|
2184 * @param beginRow the begin row |
|
2185 * @param endRow the end row |
|
2186 */ |
1930 protected void ensureRowsAreVisible(int beginRow, int endRow) { |
2187 protected void ensureRowsAreVisible(int beginRow, int endRow) { |
1931 if(tree != null && beginRow >= 0 && endRow < getRowCount(tree)) { |
2188 if(tree != null && beginRow >= 0 && endRow < getRowCount(tree)) { |
1932 boolean scrollVert = DefaultLookup.getBoolean(tree, this, |
2189 boolean scrollVert = DefaultLookup.getBoolean(tree, this, |
1933 "Tree.scrollsHorizontallyAndVertically", false); |
2190 "Tree.scrollsHorizontallyAndVertically", false); |
1934 if(beginRow == endRow) { |
2191 if(beginRow == endRow) { |
1967 } |
2224 } |
1968 } |
2225 } |
1969 } |
2226 } |
1970 } |
2227 } |
1971 |
2228 |
1972 /** Sets the preferred minimum size. |
2229 /** |
1973 */ |
2230 * Sets the preferred minimum size. |
|
2231 * |
|
2232 * @param newSize the new preferred size |
|
2233 */ |
1974 public void setPreferredMinSize(Dimension newSize) { |
2234 public void setPreferredMinSize(Dimension newSize) { |
1975 preferredMinSize = newSize; |
2235 preferredMinSize = newSize; |
1976 } |
2236 } |
1977 |
2237 |
1978 /** Returns the minimum preferred size. |
2238 /** |
1979 */ |
2239 * Returns the minimum preferred size. |
|
2240 * |
|
2241 * @return the minimum preferred size |
|
2242 */ |
1980 public Dimension getPreferredMinSize() { |
2243 public Dimension getPreferredMinSize() { |
1981 if(preferredMinSize == null) |
2244 if(preferredMinSize == null) |
1982 return null; |
2245 return null; |
1983 return new Dimension(preferredMinSize); |
2246 return new Dimension(preferredMinSize); |
1984 } |
2247 } |
1985 |
2248 |
1986 /** Returns the preferred size to properly display the tree, |
2249 /** |
1987 * this is a cover method for getPreferredSize(c, true). |
2250 * Returns the preferred size to properly display the tree, |
1988 */ |
2251 * this is a cover method for {@code getPreferredSize(c, true)}. |
|
2252 * |
|
2253 * @param c a component |
|
2254 * @return the preferred size to represent the tree in the component |
|
2255 */ |
1989 public Dimension getPreferredSize(JComponent c) { |
2256 public Dimension getPreferredSize(JComponent c) { |
1990 return getPreferredSize(c, true); |
2257 return getPreferredSize(c, true); |
1991 } |
2258 } |
1992 |
2259 |
1993 /** Returns the preferred size to represent the tree in |
2260 /** |
1994 * <I>c</I>. If <I>checkConsistency</I> is true |
2261 * Returns the preferred size to represent the tree in |
1995 * <b>checkConsistency</b> is messaged first. |
2262 * <I>c</I>. If <I>checkConsistency</I> is {@code true} |
1996 */ |
2263 * <b>checkConsistency</b> is messaged first. |
|
2264 * |
|
2265 * @param c a component |
|
2266 * @param checkConsistency if {@code true} consistency is checked |
|
2267 * @return the preferred size to represent the tree in the component |
|
2268 */ |
1997 public Dimension getPreferredSize(JComponent c, |
2269 public Dimension getPreferredSize(JComponent c, |
1998 boolean checkConsistency) { |
2270 boolean checkConsistency) { |
1999 Dimension pSize = this.getPreferredMinSize(); |
2271 Dimension pSize = this.getPreferredMinSize(); |
2000 |
2272 |
2001 if(!validCachedPreferredSize) |
2273 if(!validCachedPreferredSize) |
2054 was successful. */ |
2326 was successful. */ |
2055 completeEditing(false, true, false); |
2327 completeEditing(false, true, false); |
2056 } |
2328 } |
2057 |
2329 |
2058 /** |
2330 /** |
2059 * Stops the editing session. If messageStop is true the editor |
2331 * Stops the editing session. If {@code messageStop} is {@code true} the editor |
2060 * is messaged with stopEditing, if messageCancel is true the |
2332 * is messaged with {@code stopEditing}, if {@code messageCancel} |
2061 * editor is messaged with cancelEditing. If messageTree is true |
2333 * is {@code true} the editor is messaged with {@code cancelEditing}. |
2062 * the treeModel is messaged with valueForPathChanged. |
2334 * If {@code messageTree} is {@code true} the {@code treeModel} is messaged |
2063 */ |
2335 * with {@code valueForPathChanged}. |
|
2336 * |
|
2337 * @param messageStop message to stop editing |
|
2338 * @param messageCancel message to cancel editing |
|
2339 * @param messageTree message to tree |
|
2340 */ |
2064 protected void completeEditing(boolean messageStop, |
2341 protected void completeEditing(boolean messageStop, |
2065 boolean messageCancel, |
2342 boolean messageCancel, |
2066 boolean messageTree) { |
2343 boolean messageTree) { |
2067 if(stopEditingInCompleteEditing && editingComponent != null) { |
2344 if(stopEditingInCompleteEditing && editingComponent != null) { |
2068 Component oldComponent = editingComponent; |
2345 Component oldComponent = editingComponent; |
2218 // |
2499 // |
2219 // Following are primarily for handling mouse events. |
2500 // Following are primarily for handling mouse events. |
2220 // |
2501 // |
2221 |
2502 |
2222 /** |
2503 /** |
2223 * If the <code>mouseX</code> and <code>mouseY</code> are in the |
2504 * If the {@code mouseX} and {@code mouseY} are in the |
2224 * expand/collapse region of the <code>row</code>, this will toggle |
2505 * expand/collapse region of the {@code row}, this will toggle |
2225 * the row. |
2506 * the row. |
|
2507 * |
|
2508 * @param path a tree path |
|
2509 * @param mouseX an X coordinate |
|
2510 * @param mouseY an Y coordinate |
2226 */ |
2511 */ |
2227 protected void checkForClickInExpandControl(TreePath path, |
2512 protected void checkForClickInExpandControl(TreePath path, |
2228 int mouseX, int mouseY) { |
2513 int mouseX, int mouseY) { |
2229 if (isLocationInExpandControl(path, mouseX, mouseY)) { |
2514 if (isLocationInExpandControl(path, mouseX, mouseY)) { |
2230 handleExpandControlClick(path, mouseX, mouseY); |
2515 handleExpandControlClick(path, mouseX, mouseY); |
2231 } |
2516 } |
2232 } |
2517 } |
2233 |
2518 |
2234 /** |
2519 /** |
2235 * Returns true if <code>mouseX</code> and <code>mouseY</code> fall |
2520 * Returns {@code true} if {@code mouseX} and {@code mouseY} fall |
2236 * in the area of row that is used to expand/collapse the node and |
2521 * in the area of row that is used to expand/collapse the node and |
2237 * the node at <code>row</code> does not represent a leaf. |
2522 * the node at {@code row} does not represent a leaf. |
|
2523 * |
|
2524 * @param path a tree path |
|
2525 * @param mouseX an X coordinate |
|
2526 * @param mouseY an Y coordinate |
|
2527 * @return {@code true} if the mouse cursor fall in the area of row that |
|
2528 * is used to expand/collapse the node and the node is not a leaf. |
2238 */ |
2529 */ |
2239 protected boolean isLocationInExpandControl(TreePath path, |
2530 protected boolean isLocationInExpandControl(TreePath path, |
2240 int mouseX, int mouseY) { |
2531 int mouseX, int mouseY) { |
2241 if(path != null && !treeModel.isLeaf(path.getLastPathComponent())){ |
2532 if(path != null && !treeModel.isLeaf(path.getLastPathComponent())){ |
2242 int boxWidth; |
2533 int boxWidth; |
2263 return false; |
2554 return false; |
2264 } |
2555 } |
2265 |
2556 |
2266 /** |
2557 /** |
2267 * Messaged when the user clicks the particular row, this invokes |
2558 * Messaged when the user clicks the particular row, this invokes |
2268 * toggleExpandState. |
2559 * {@code toggleExpandState}. |
|
2560 * |
|
2561 * @param path a tree path |
|
2562 * @param mouseX an X coordinate |
|
2563 * @param mouseY an Y coordinate |
2269 */ |
2564 */ |
2270 protected void handleExpandControlClick(TreePath path, int mouseX, |
2565 protected void handleExpandControlClick(TreePath path, int mouseX, |
2271 int mouseY) { |
2566 int mouseY) { |
2272 toggleExpandState(path); |
2567 toggleExpandState(path); |
2273 } |
2568 } |
2274 |
2569 |
2275 /** |
2570 /** |
2276 * Expands path if it is not expanded, or collapses row if it is expanded. |
2571 * Expands path if it is not expanded, or collapses row if it is expanded. |
2277 * If expanding a path and JTree scrolls on expand, ensureRowsAreVisible |
2572 * If expanding a path and {@code JTree} scrolls on expand, |
2278 * is invoked to scroll as many of the children to visible as possible |
2573 * {@code ensureRowsAreVisible} is invoked to scroll as many of the children |
2279 * (tries to scroll to last visible descendant of path). |
2574 * to visible as possible (tries to scroll to last visible descendant of path). |
|
2575 * |
|
2576 * @param path a tree path |
2280 */ |
2577 */ |
2281 protected void toggleExpandState(TreePath path) { |
2578 protected void toggleExpandState(TreePath path) { |
2282 if(!tree.isExpanded(path)) { |
2579 if(!tree.isExpanded(path)) { |
2283 int row = getRowForPath(tree, path); |
2580 int row = getRowForPath(tree, path); |
2284 |
2581 |
2297 updateSize(); |
2594 updateSize(); |
2298 } |
2595 } |
2299 } |
2596 } |
2300 |
2597 |
2301 /** |
2598 /** |
2302 * Returning true signifies a mouse event on the node should toggle |
2599 * Returning {@code true} signifies a mouse event on the node should toggle |
2303 * the selection of only the row under mouse. |
2600 * the selection of only the row under mouse. |
|
2601 * |
|
2602 * @param event a mouse event |
|
2603 * @return {@code true} if a mouse event on the node should toggle the selection |
2304 */ |
2604 */ |
2305 protected boolean isToggleSelectionEvent(MouseEvent event) { |
2605 protected boolean isToggleSelectionEvent(MouseEvent event) { |
2306 return (SwingUtilities.isLeftMouseButton(event) && |
2606 return (SwingUtilities.isLeftMouseButton(event) && |
2307 BasicGraphicsUtils.isMenuShortcutKeyDown(event)); |
2607 BasicGraphicsUtils.isMenuShortcutKeyDown(event)); |
2308 } |
2608 } |
2309 |
2609 |
2310 /** |
2610 /** |
2311 * Returning true signifies a mouse event on the node should select |
2611 * Returning {@code true} signifies a mouse event on the node should select |
2312 * from the anchor point. |
2612 * from the anchor point. |
|
2613 * |
|
2614 * @param event a mouse event |
|
2615 * @return {@code true} if a mouse event on the node should select |
|
2616 * from the anchor point |
2313 */ |
2617 */ |
2314 protected boolean isMultiSelectEvent(MouseEvent event) { |
2618 protected boolean isMultiSelectEvent(MouseEvent event) { |
2315 return (SwingUtilities.isLeftMouseButton(event) && |
2619 return (SwingUtilities.isLeftMouseButton(event) && |
2316 event.isShiftDown()); |
2620 event.isShiftDown()); |
2317 } |
2621 } |
2318 |
2622 |
2319 /** |
2623 /** |
2320 * Returning true indicates the row under the mouse should be toggled |
2624 * Returning {@code true} indicates the row under the mouse should be toggled |
2321 * based on the event. This is invoked after checkForClickInExpandControl, |
2625 * based on the event. This is invoked after {@code checkForClickInExpandControl}, |
2322 * implying the location is not in the expand (toggle) control |
2626 * implying the location is not in the expand (toggle) control. |
|
2627 * |
|
2628 * @param event a mouse event |
|
2629 * @return {@code true} if the row under the mouse should be toggled |
2323 */ |
2630 */ |
2324 protected boolean isToggleEvent(MouseEvent event) { |
2631 protected boolean isToggleEvent(MouseEvent event) { |
2325 if(!SwingUtilities.isLeftMouseButton(event)) { |
2632 if(!SwingUtilities.isLeftMouseButton(event)) { |
2326 return false; |
2633 return false; |
2327 } |
2634 } |
2332 } |
2639 } |
2333 return ((event.getClickCount() % clickCount) == 0); |
2640 return ((event.getClickCount() % clickCount) == 0); |
2334 } |
2641 } |
2335 |
2642 |
2336 /** |
2643 /** |
2337 * Messaged to update the selection based on a MouseEvent over a |
2644 * Messaged to update the selection based on a {@code MouseEvent} over a |
2338 * particular row. If the event is a toggle selection event, the |
2645 * particular row. If the event is a toggle selection event, the |
2339 * row is either selected, or deselected. If the event identifies |
2646 * row is either selected, or deselected. If the event identifies |
2340 * a multi selection event, the selection is updated from the |
2647 * a multi selection event, the selection is updated from the |
2341 * anchor point. Otherwise the row is selected, and if the event |
2648 * anchor point. Otherwise the row is selected, and if the event |
2342 * specified a toggle event the row is expanded/collapsed. |
2649 * specified a toggle event the row is expanded/collapsed. |
|
2650 * |
|
2651 * @param path the selected path |
|
2652 * @param event the mouse event |
2343 */ |
2653 */ |
2344 protected void selectPathForEvent(TreePath path, MouseEvent event) { |
2654 protected void selectPathForEvent(TreePath path, MouseEvent event) { |
2345 /* Adjust from the anchor point. */ |
2655 /* Adjust from the anchor point. */ |
2346 if(isMultiSelectEvent(event)) { |
2656 if(isMultiSelectEvent(event)) { |
2347 TreePath anchor = getAnchorSelectionPath(); |
2657 TreePath anchor = getAnchorSelectionPath(); |
2922 protected int direction; |
3241 protected int direction; |
2923 /** True if the selection is reset, false means only the lead path |
3242 /** True if the selection is reset, false means only the lead path |
2924 * changes. */ |
3243 * changes. */ |
2925 private boolean changeSelection; |
3244 private boolean changeSelection; |
2926 |
3245 |
|
3246 /** |
|
3247 * Constructs a new instance of {@code TreeTraverseAction}. |
|
3248 * |
|
3249 * @param direction the direction |
|
3250 * @param name the name of action |
|
3251 */ |
2927 public TreeTraverseAction(int direction, String name) { |
3252 public TreeTraverseAction(int direction, String name) { |
2928 this(direction, name, true); |
3253 this(direction, name, true); |
2929 } |
3254 } |
2930 |
3255 |
2931 private TreeTraverseAction(int direction, String name, |
3256 private TreeTraverseAction(int direction, String name, |
2954 protected int direction; |
3279 protected int direction; |
2955 /** True indicates should set selection from anchor path. */ |
3280 /** True indicates should set selection from anchor path. */ |
2956 private boolean addToSelection; |
3281 private boolean addToSelection; |
2957 private boolean changeSelection; |
3282 private boolean changeSelection; |
2958 |
3283 |
|
3284 /** |
|
3285 * Constructs a new instance of {@code TreePageAction}. |
|
3286 * |
|
3287 * @param direction the direction |
|
3288 * @param name the name of action |
|
3289 */ |
2959 public TreePageAction(int direction, String name) { |
3290 public TreePageAction(int direction, String name) { |
2960 this(direction, name, false, true); |
3291 this(direction, name, false, true); |
2961 } |
3292 } |
2962 |
3293 |
2963 private TreePageAction(int direction, String name, |
3294 private TreePageAction(int direction, String name, |
2991 /** If true the new item is added to the selection, if false the |
3322 /** If true the new item is added to the selection, if false the |
2992 * selection is reset. */ |
3323 * selection is reset. */ |
2993 private boolean addToSelection; |
3324 private boolean addToSelection; |
2994 private boolean changeSelection; |
3325 private boolean changeSelection; |
2995 |
3326 |
|
3327 /** |
|
3328 * Constructs a new instance of {@code TreeIncrementAction}. |
|
3329 * |
|
3330 * @param direction the direction |
|
3331 * @param name the name of action |
|
3332 */ |
2996 public TreeIncrementAction(int direction, String name) { |
3333 public TreeIncrementAction(int direction, String name) { |
2997 this(direction, name, false, true); |
3334 this(direction, name, false, true); |
2998 } |
3335 } |
2999 |
3336 |
3000 private TreeIncrementAction(int direction, String name, |
3337 private TreeIncrementAction(int direction, String name, |
3022 * Scrolls either the first or last cell to be visible based on |
3359 * Scrolls either the first or last cell to be visible based on |
3023 * direction. |
3360 * direction. |
3024 */ |
3361 */ |
3025 @SuppressWarnings("serial") // Superclass is not serializable across versions |
3362 @SuppressWarnings("serial") // Superclass is not serializable across versions |
3026 public class TreeHomeAction extends AbstractAction { |
3363 public class TreeHomeAction extends AbstractAction { |
|
3364 /** |
|
3365 * The direction. |
|
3366 */ |
3027 protected int direction; |
3367 protected int direction; |
3028 /** Set to true if append to selection. */ |
3368 /** Set to true if append to selection. */ |
3029 private boolean addToSelection; |
3369 private boolean addToSelection; |
3030 private boolean changeSelection; |
3370 private boolean changeSelection; |
3031 |
3371 |
|
3372 /** |
|
3373 * Constructs a new instance of {@code TreeHomeAction}. |
|
3374 * |
|
3375 * @param direction the direction |
|
3376 * @param name the name of action |
|
3377 */ |
3032 public TreeHomeAction(int direction, String name) { |
3378 public TreeHomeAction(int direction, String name) { |
3033 this(direction, name, false, true); |
3379 this(direction, name, false, true); |
3034 } |
3380 } |
3035 |
3381 |
3036 private TreeHomeAction(int direction, String name, |
3382 private TreeHomeAction(int direction, String name, |
3108 /** Destination that receives all events. */ |
3464 /** Destination that receives all events. */ |
3109 protected Component destination; |
3465 protected Component destination; |
3110 private Component focusComponent; |
3466 private Component focusComponent; |
3111 private boolean dispatchedEvent; |
3467 private boolean dispatchedEvent; |
3112 |
3468 |
|
3469 /** |
|
3470 * Constructs a new instance of {@code MouseInputHandler}. |
|
3471 * |
|
3472 * @param source a source component |
|
3473 * @param destination a destination component |
|
3474 * @param event a mouse event |
|
3475 */ |
3113 public MouseInputHandler(Component source, Component destination, |
3476 public MouseInputHandler(Component source, Component destination, |
3114 MouseEvent event){ |
3477 MouseEvent event){ |
3115 this(source, destination, event, null); |
3478 this(source, destination, event, null); |
3116 } |
3479 } |
3117 |
3480 |