1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70:
71: public class JTree
72: extends JComponent
73: implements Scrollable, Accessible
74: {
75:
79: protected class TreeModelHandler
80: implements
81: TreeModelListener
82: {
83:
84:
87: protected TreeModelHandler()
88: {
89: }
90:
91:
101: public void treeNodesChanged(TreeModelEvent ev)
102: {
103:
104: }
105:
106:
113: public void treeNodesInserted(TreeModelEvent ev)
114: {
115:
116: }
117:
118:
125: public void treeNodesRemoved(TreeModelEvent ev)
126: {
127:
128:
129: }
130:
131:
138: public void treeStructureChanged(TreeModelEvent ev)
139: {
140:
141: TreePath path = ev.getTreePath();
142: setExpandedState(path, isExpanded(path));
143: }
144: }
145:
146:
152: protected class TreeSelectionRedirector
153: implements
154: TreeSelectionListener,
155: Serializable
156: {
157:
158: private static final long serialVersionUID = -3505069663646241664L;
159:
160:
163: protected TreeSelectionRedirector()
164: {
165: }
166:
167:
172: public void valueChanged(TreeSelectionEvent ev)
173: {
174: TreeSelectionEvent rewritten = (TreeSelectionEvent) ev
175: .cloneWithSource(JTree.this);
176: fireValueChanged(rewritten);
177: JTree.this.repaint();
178: }
179: }
180:
181:
184: protected static class EmptySelectionModel
185: extends
186: DefaultTreeSelectionModel
187: {
188:
189: private static final long serialVersionUID = -5815023306225701477L;
190:
191:
194: protected static final EmptySelectionModel sharedInstance = new EmptySelectionModel();
195:
196:
199: protected EmptySelectionModel()
200: {
201: }
202:
203:
208: public static EmptySelectionModel sharedInstance()
209: {
210: return sharedInstance;
211: }
212:
213:
218: public void setSelectionPaths(TreePath[] paths)
219: {
220:
221: }
222:
223:
228: public void addSelectionPaths(TreePath[] paths)
229: {
230:
231: }
232:
233:
238: public void removeSelectionPaths(TreePath[] paths)
239: {
240:
241: }
242: }
243:
244: private static final long serialVersionUID = 7559816092864483649L;
245: public static final String CELL_EDITOR_PROPERTY = "cellEditor";
246: public static final String CELL_RENDERER_PROPERTY = "cellRenderer";
247: public static final String EDITABLE_PROPERTY = "editable";
248: public static final String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing";
249: public static final String LARGE_MODEL_PROPERTY = "largeModel";
250: public static final String ROOT_VISIBLE_PROPERTY = "rootVisible";
251: public static final String ROW_HEIGHT_PROPERTY = "rowHeight";
252: public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand";
253: public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
254: public static final String SHOWS_ROOT_HANDLES_PROPERTY = "showsRootHandles";
255: public static final String TOGGLE_CLICK_COUNT_PROPERTY = "toggleClickCount";
256: public static final String TREE_MODEL_PROPERTY = "model";
257: public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount";
258:
259:
260: public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath";
261:
262:
263: public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath";
264:
265:
266: public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths";
267: private static final Object EXPANDED = new Object();
268: private static final Object COLLAPSED = new Object();
269: private boolean dragEnabled;
270: private boolean expandsSelectedPaths;
271: private TreePath anchorSelectionPath;
272: private TreePath leadSelectionPath;
273:
274:
279: private Hashtable nodeStates = new Hashtable();
280: protected transient TreeCellEditor cellEditor;
281: protected transient TreeCellRenderer cellRenderer;
282: protected boolean editable;
283: protected boolean invokesStopCellEditing;
284: protected boolean largeModel;
285: protected boolean rootVisible;
286: protected int rowHeight;
287: protected boolean scrollsOnExpand;
288: protected transient TreeSelectionModel selectionModel;
289: protected boolean showsRootHandles;
290: protected int toggleClickCount;
291: protected transient TreeModel treeModel;
292: protected int visibleRowCount;
293:
294:
297: protected transient TreeModelListener treeModelListener;
298:
299:
302: protected TreeSelectionRedirector selectionRedirector =
303: new TreeSelectionRedirector();
304:
305:
308: public JTree()
309: {
310: this(createTreeModel(null));
311: }
312:
313:
318: public JTree(Hashtable value)
319: {
320: this(createTreeModel(value));
321: }
322:
323:
328: public JTree(Object[] value)
329: {
330: this(createTreeModel(value));
331: }
332:
333:
338: public JTree(TreeModel model)
339: {
340: setModel(model);
341: setSelectionModel(EmptySelectionModel.sharedInstance());
342: setCellRenderer(new DefaultTreeCellRenderer());
343: updateUI();
344: }
345:
346:
351: public JTree(TreeNode root)
352: {
353: this(root, false);
354: }
355:
356:
364: public JTree(TreeNode root, boolean asksAllowChildren)
365: {
366: this(new DefaultTreeModel(root, asksAllowChildren));
367: }
368:
369:
374: public JTree(Vector value)
375: {
376: this(createTreeModel(value));
377: }
378:
379: public static class DynamicUtilTreeNode
380: extends
381: DefaultMutableTreeNode
382: {
383: protected Object childValue;
384: protected boolean loadedChildren;
385:
386:
390: protected boolean hasChildren;
391:
392: public DynamicUtilTreeNode(Object value, Object children)
393: {
394: super(value);
395: childValue = children;
396: loadedChildren = false;
397: }
398:
399: public int getChildCount()
400: {
401: loadChildren();
402: return super.getChildCount();
403: }
404:
405: protected void loadChildren()
406: {
407: if (!loadedChildren)
408: {
409: createChildren(this, childValue);
410: loadedChildren = true;
411: }
412: }
413:
414: public Enumeration children()
415: {
416: loadChildren();
417: return super.children();
418: }
419:
420:
428: public TreeNode getChildAt(int pos)
429: {
430: loadChildren();
431: return super.getChildAt(pos);
432: }
433:
434: public boolean isLeaf()
435: {
436: return (childValue == null || !(childValue instanceof Hashtable
437: || childValue instanceof Vector || childValue.getClass()
438: .isArray()));
439: }
440:
441: public static void createChildren(DefaultMutableTreeNode parent,
442: Object children)
443: {
444: if (children instanceof Hashtable)
445: {
446: Hashtable tab = (Hashtable) children;
447: Enumeration e = tab.keys();
448: while (e.hasMoreElements())
449: {
450: Object key = e.nextElement();
451: Object val = tab.get(key);
452: parent.add(new DynamicUtilTreeNode(key, val));
453: }
454: } else if (children instanceof Vector)
455: {
456: Iterator i = ((Vector) children).iterator();
457: while (i.hasNext())
458: {
459: Object n = i.next();
460: parent.add(new DynamicUtilTreeNode(n, n));
461: }
462: } else if (children != null && children.getClass().isArray())
463: {
464: Object[] arr = (Object[]) children;
465: for (int i = 0; i < arr.length; ++i)
466: parent.add(new DynamicUtilTreeNode(arr[i], arr[i]));
467: }
468: }
469: }
470:
471: public int getRowForPath(TreePath path)
472: {
473: TreeUI ui = getUI();
474:
475: if (ui != null)
476: return ui.getRowForPath(this, path);
477:
478: return -1;
479: }
480:
481: public TreePath getPathForRow(int row)
482: {
483: TreeUI ui = getUI();
484: return ui != null ? ui.getPathForRow(this, row) : null;
485: }
486:
487: protected TreePath[] getPathBetweenRows(int index0, int index1)
488: {
489: TreeUI ui = getUI();
490:
491: if (ui == null)
492: return null;
493:
494: int minIndex = Math.min(index0, index1);
495: int maxIndex = Math.max(index0, index1);
496: TreePath[] paths = new TreePath[maxIndex - minIndex + 1];
497:
498: for (int i = minIndex; i <= maxIndex; ++i)
499: paths[i - minIndex] = ui.getPathForRow(this, i);
500:
501: return paths;
502: }
503:
504:
509: protected static TreeModel createTreeModel(Object value)
510: {
511: return new DefaultTreeModel(new DynamicUtilTreeNode(value, value));
512: }
513:
514:
519: public TreeUI getUI()
520: {
521: return (TreeUI) ui;
522: }
523:
524:
529: public void setUI(TreeUI ui)
530: {
531: super.setUI(ui);
532: }
533:
534:
537: public void updateUI()
538: {
539: setUI((TreeUI) UIManager.getUI(this));
540: revalidate();
541: repaint();
542: }
543:
544:
549: public String getUIClassID()
550: {
551: return "TreeUI";
552: }
553:
554:
560: public AccessibleContext getAccessibleContext()
561: {
562: return null;
563: }
564:
565:
570: public Dimension getPreferredScrollableViewportSize()
571: {
572: return new Dimension (getPreferredSize().width, getVisibleRowCount()*getRowHeight());
573: }
574:
575: public int getScrollableUnitIncrement(Rectangle visibleRect,
576: int orientation, int direction)
577: {
578: return 1;
579: }
580:
581: public int getScrollableBlockIncrement(Rectangle visibleRect,
582: int orientation, int direction)
583: {
584: return 1;
585: }
586:
587: public boolean getScrollableTracksViewportWidth()
588: {
589: if (getParent() instanceof JViewport)
590: return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
591: return false;
592: }
593:
594: public boolean getScrollableTracksViewportHeight()
595: {
596: if (getParent() instanceof JViewport)
597: return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
598: return false;
599: }
600:
601:
606: public void addTreeExpansionListener(TreeExpansionListener listener)
607: {
608: listenerList.add(TreeExpansionListener.class, listener);
609: }
610:
611:
616: public void removeTreeExpansionListener(TreeExpansionListener listener)
617: {
618: listenerList.remove(TreeExpansionListener.class, listener);
619: }
620:
621:
626: public TreeExpansionListener[] getTreeExpansionListeners()
627: {
628: return (TreeExpansionListener[]) getListeners(TreeExpansionListener.class);
629: }
630:
631:
636: public void fireTreeCollapsed(TreePath path)
637: {
638: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
639: TreeExpansionListener[] listeners = getTreeExpansionListeners();
640:
641: for (int index = 0; index < listeners.length; ++index)
642: listeners[index].treeCollapsed(event);
643: }
644:
645:
650: public void fireTreeExpanded(TreePath path)
651: {
652: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
653: TreeExpansionListener[] listeners = getTreeExpansionListeners();
654:
655: for (int index = 0; index < listeners.length; ++index)
656: listeners[index].treeExpanded(event);
657: }
658:
659:
664: public void addTreeSelectionListener(TreeSelectionListener listener)
665: {
666: listenerList.add(TreeSelectionListener.class, listener);
667: }
668:
669:
674: public void removeTreeSelectionListener(TreeSelectionListener listener)
675: {
676: listenerList.remove(TreeSelectionListener.class, listener);
677: }
678:
679:
684: public TreeSelectionListener[] getTreeSelectionListeners()
685: {
686: return (TreeSelectionListener[])
687: getListeners(TreeSelectionListener.class);
688: }
689:
690:
695: protected void fireValueChanged(TreeSelectionEvent event)
696: {
697: TreeSelectionListener[] listeners = getTreeSelectionListeners();
698:
699: for (int index = 0; index < listeners.length; ++index)
700: listeners[index].valueChanged(event);
701: }
702:
703:
708: public void addTreeWillExpandListener(TreeWillExpandListener listener)
709: {
710: listenerList.add(TreeWillExpandListener.class, listener);
711: }
712:
713:
718: public void removeTreeWillExpandListener(TreeWillExpandListener listener)
719: {
720: listenerList.remove(TreeWillExpandListener.class, listener);
721: }
722:
723:
728: public TreeWillExpandListener[] getTreeWillExpandListeners()
729: {
730: return (TreeWillExpandListener[])
731: getListeners(TreeWillExpandListener.class);
732: }
733:
734:
739: public void fireTreeWillCollapse(TreePath path) throws ExpandVetoException
740: {
741: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
742: TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
743:
744: for (int index = 0; index < listeners.length; ++index)
745: listeners[index].treeWillCollapse(event);
746: }
747:
748:
753: public void fireTreeWillExpand(TreePath path) throws ExpandVetoException
754: {
755: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
756: TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
757:
758: for (int index = 0; index < listeners.length; ++index)
759: listeners[index].treeWillExpand(event);
760: }
761:
762:
767: public TreeModel getModel()
768: {
769: return treeModel;
770: }
771:
772:
777: public void setModel(TreeModel model)
778: {
779: if (treeModel == model)
780: return;
781:
782:
783: if (treeModelListener == null)
784: treeModelListener = createTreeModelListener();
785: if (model != null)
786: model.addTreeModelListener(treeModelListener);
787:
788: TreeModel oldValue = treeModel;
789: treeModel = model;
790:
791: firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
792: }
793:
794:
800: public boolean isEditable()
801: {
802: return editable;
803: }
804:
805:
811: public void setEditable(boolean flag)
812: {
813: if (editable == flag)
814: return;
815:
816: boolean oldValue = editable;
817: editable = flag;
818: firePropertyChange(EDITABLE_PROPERTY, oldValue, editable);
819: }
820:
821:
827: public boolean isRootVisible()
828: {
829: return rootVisible;
830: }
831:
832: public void setRootVisible(boolean flag)
833: {
834: if (rootVisible == flag)
835: return;
836:
837: boolean oldValue = rootVisible;
838: rootVisible = flag;
839: firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
840: }
841:
842: public boolean getShowsRootHandles()
843: {
844: return showsRootHandles;
845: }
846:
847: public void setShowsRootHandles(boolean flag)
848: {
849: if (showsRootHandles == flag)
850: return;
851:
852: boolean oldValue = showsRootHandles;
853: showsRootHandles = flag;
854: firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, flag);
855: }
856:
857: public TreeCellEditor getCellEditor()
858: {
859:
860: return cellEditor;
861: }
862:
863: public void setCellEditor(TreeCellEditor editor)
864: {
865: if (cellEditor == editor)
866: return;
867:
868: TreeCellEditor oldValue = cellEditor;
869: cellEditor = editor;
870: firePropertyChange(CELL_EDITOR_PROPERTY, oldValue, editor);
871: }
872:
873: public TreeCellRenderer getCellRenderer()
874: {
875: return cellRenderer;
876: }
877:
878: public void setCellRenderer(TreeCellRenderer newRenderer)
879: {
880: if (cellRenderer == newRenderer)
881: return;
882:
883: TreeCellRenderer oldValue = cellRenderer;
884: cellRenderer = newRenderer;
885: firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, newRenderer);
886: }
887:
888: public TreeSelectionModel getSelectionModel()
889: {
890: return selectionModel;
891: }
892:
893: public void setSelectionModel(TreeSelectionModel model)
894: {
895: if (selectionModel == model)
896: return;
897:
898: if (selectionModel != null)
899: selectionModel.removeTreeSelectionListener(selectionRedirector);
900:
901: TreeSelectionModel oldValue = selectionModel;
902: selectionModel = model;
903:
904: if (selectionModel != null)
905: selectionModel.addTreeSelectionListener(selectionRedirector);
906:
907: firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, model);
908: revalidate();
909: repaint();
910: }
911:
912: public int getVisibleRowCount()
913: {
914: return visibleRowCount;
915: }
916:
917: public void setVisibleRowCount(int rows)
918: {
919: if (visibleRowCount == rows)
920: return;
921:
922: int oldValue = visibleRowCount;
923: visibleRowCount = rows;
924: firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldValue, rows);
925: }
926:
927: public boolean isLargeModel()
928: {
929: return largeModel;
930: }
931:
932: public void setLargeModel(boolean large)
933: {
934: if (largeModel == large)
935: return;
936:
937: boolean oldValue = largeModel;
938: largeModel = large;
939: firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, large);
940: }
941:
942: public int getRowHeight()
943: {
944:
945: return rowHeight;
946: }
947:
948: public void setRowHeight(int height)
949: {
950: if (rowHeight == height)
951: return;
952:
953: int oldValue = rowHeight;
954: rowHeight = height;
955: firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, height);
956: }
957:
958: public boolean isFixedRowHeight()
959: {
960: return rowHeight > 0;
961: }
962:
963: public boolean getInvokesStopCellEditing()
964: {
965: return invokesStopCellEditing;
966: }
967:
968: public void setInvokesStopCellEditing(boolean invoke)
969: {
970: if (invokesStopCellEditing == invoke)
971: return;
972:
973: boolean oldValue = invokesStopCellEditing;
974: invokesStopCellEditing = invoke;
975: firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY,
976: oldValue, invoke);
977: }
978:
979:
982: public int getToggleClickCount()
983: {
984: return toggleClickCount;
985: }
986:
987:
990: public void setToggleClickCount(int count)
991: {
992: if (toggleClickCount == count)
993: return;
994:
995: int oldValue = toggleClickCount;
996: toggleClickCount = count;
997: firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count);
998: }
999:
1000: public void scrollPathToVisible(TreePath path)
1001: {
1002: if (path == null)
1003: return;
1004:
1005: Rectangle rect = getPathBounds(path);
1006:
1007: if (rect == null)
1008: return;
1009:
1010: scrollRectToVisible(rect);
1011: }
1012:
1013: public void scrollRowToVisible(int row)
1014: {
1015: scrollPathToVisible(getPathForRow(row));
1016: }
1017:
1018: public boolean getScrollsOnExpand()
1019: {
1020: return scrollsOnExpand;
1021: }
1022:
1023: public void setScrollsOnExpand(boolean scroll)
1024: {
1025: if (scrollsOnExpand == scroll)
1026: return;
1027:
1028: boolean oldValue = scrollsOnExpand;
1029: scrollsOnExpand = scroll;
1030: firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, scroll);
1031: }
1032:
1033: public void setSelectionPath(TreePath path)
1034: {
1035: selectionModel.setSelectionPath(path);
1036: }
1037:
1038: public void setSelectionPaths(TreePath[] paths)
1039: {
1040: selectionModel.setSelectionPaths(paths);
1041: }
1042:
1043: public void setSelectionRow(int row)
1044: {
1045: TreePath path = getPathForRow(row);
1046:
1047: if (path != null)
1048: selectionModel.setSelectionPath(path);
1049: }
1050:
1051: public void setSelectionRows(int[] rows)
1052: {
1053:
1054: if (rows == null || getUI() == null)
1055: return;
1056:
1057: TreePath[] paths = new TreePath[rows.length];
1058:
1059: for (int i = rows.length - 1; i >= 0; --i)
1060: paths[i] = getPathForRow(rows[i]);
1061:
1062: setSelectionPaths(paths);
1063: }
1064:
1065: public void setSelectionInterval(int index0, int index1)
1066: {
1067: TreePath[] paths = getPathBetweenRows(index0, index1);
1068:
1069: if (paths != null)
1070: setSelectionPaths(paths);
1071: }
1072:
1073: public void addSelectionPath(TreePath path)
1074: {
1075: selectionModel.addSelectionPath(path);
1076: }
1077:
1078: public void addSelectionPaths(TreePath[] paths)
1079: {
1080: selectionModel.addSelectionPaths(paths);
1081: }
1082:
1083: public void addSelectionRow(int row)
1084: {
1085: TreePath path = getPathForRow(row);
1086:
1087: if (path != null)
1088: selectionModel.addSelectionPath(path);
1089: }
1090:
1091: public void addSelectionRows(int[] rows)
1092: {
1093:
1094: if (rows == null || getUI() == null)
1095: return;
1096:
1097: TreePath[] paths = new TreePath[rows.length];
1098:
1099: for (int i = rows.length - 1; i >= 0; --i)
1100: paths[i] = getPathForRow(rows[i]);
1101:
1102: addSelectionPaths(paths);
1103: }
1104:
1105: public void addSelectionInterval(int index0, int index1)
1106: {
1107: TreePath[] paths = getPathBetweenRows(index0, index1);
1108:
1109: if (paths != null)
1110: addSelectionPaths(paths);
1111: }
1112:
1113: public void removeSelectionPath(TreePath path)
1114: {
1115: selectionModel.removeSelectionPath(path);
1116: }
1117:
1118: public void removeSelectionPaths(TreePath[] paths)
1119: {
1120: selectionModel.removeSelectionPaths(paths);
1121: }
1122:
1123: public void removeSelectionRow(int row)
1124: {
1125: TreePath path = getPathForRow(row);
1126:
1127: if (path != null)
1128: selectionModel.removeSelectionPath(path);
1129: }
1130:
1131: public void removeSelectionRows(int[] rows)
1132: {
1133: if (rows == null || getUI() == null)
1134: return;
1135:
1136: TreePath[] paths = new TreePath[rows.length];
1137:
1138: for (int i = rows.length - 1; i >= 0; --i)
1139: paths[i] = getPathForRow(rows[i]);
1140:
1141: removeSelectionPaths(paths);
1142: }
1143:
1144: public void removeSelectionInterval(int index0, int index1)
1145: {
1146: TreePath[] paths = getPathBetweenRows(index0, index1);
1147:
1148: if (paths != null)
1149: removeSelectionPaths(paths);
1150: }
1151:
1152: public void clearSelection()
1153: {
1154: selectionModel.clearSelection();
1155: setLeadSelectionPath(null);
1156: }
1157:
1158: public TreePath getLeadSelectionPath()
1159: {
1160: return leadSelectionPath;
1161: }
1162:
1163:
1166: public void setLeadSelectionPath(TreePath path)
1167: {
1168: if (leadSelectionPath == path)
1169: return;
1170:
1171: TreePath oldValue = leadSelectionPath;
1172: leadSelectionPath = path;
1173: firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
1174: }
1175:
1176:
1179: public TreePath getAnchorSelectionPath()
1180: {
1181: return anchorSelectionPath;
1182: }
1183:
1184:
1187: public void setAnchorSelectionPath(TreePath path)
1188: {
1189: if (anchorSelectionPath == path)
1190: return;
1191:
1192: TreePath oldValue = anchorSelectionPath;
1193: anchorSelectionPath = path;
1194: firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, path);
1195: }
1196:
1197: public int getLeadSelectionRow()
1198: {
1199: return selectionModel.getLeadSelectionRow();
1200: }
1201:
1202: public int getMaxSelectionRow()
1203: {
1204: return selectionModel.getMaxSelectionRow();
1205: }
1206:
1207: public int getMinSelectionRow()
1208: {
1209: return selectionModel.getMinSelectionRow();
1210: }
1211:
1212: public int getSelectionCount()
1213: {
1214: return selectionModel.getSelectionCount();
1215: }
1216:
1217: public TreePath getSelectionPath()
1218: {
1219: return selectionModel.getSelectionPath();
1220: }
1221:
1222: public TreePath[] getSelectionPaths()
1223: {
1224: return selectionModel.getSelectionPaths();
1225: }
1226:
1227: public int[] getSelectionRows()
1228: {
1229: return selectionModel.getSelectionRows();
1230: }
1231:
1232: public boolean isPathSelected(TreePath path)
1233: {
1234: return selectionModel.isPathSelected(path);
1235: }
1236:
1237: public boolean isRowSelected(int row)
1238: {
1239: return selectionModel.isPathSelected(getPathForRow(row));
1240: }
1241:
1242: public boolean isSelectionEmpty()
1243: {
1244: return selectionModel.isSelectionEmpty();
1245: }
1246:
1247:
1254: public boolean getDragEnabled()
1255: {
1256: return dragEnabled;
1257: }
1258:
1259:
1266: public void setDragEnabled(boolean enabled)
1267: {
1268:
1269: dragEnabled = enabled;
1270: }
1271:
1272: public int getRowCount()
1273: {
1274: TreeUI ui = getUI();
1275:
1276: if (ui != null)
1277: return ui.getRowCount(this);
1278:
1279: return 0;
1280: }
1281:
1282: public void collapsePath(TreePath path)
1283: {
1284: try
1285: {
1286: fireTreeWillCollapse(path);
1287: }
1288: catch (ExpandVetoException ev)
1289: {
1290: }
1291: setExpandedState(path, false);
1292: fireTreeCollapsed(path);
1293: }
1294:
1295: public void collapseRow(int row)
1296: {
1297: if (row < 0 || row >= getRowCount())
1298: return;
1299:
1300: TreePath path = getPathForRow(row);
1301:
1302: if (path != null)
1303: collapsePath(path);
1304: }
1305:
1306: public void expandPath(TreePath path)
1307: {
1308:
1309: if ((path == null) || (treeModel.isLeaf(path.getLastPathComponent())))
1310: return;
1311:
1312: try
1313: {
1314: fireTreeWillExpand(path);
1315: }
1316: catch (ExpandVetoException ev)
1317: {
1318: }
1319:
1320: setExpandedState(path, true);
1321: fireTreeExpanded(path);
1322: }
1323:
1324: public void expandRow(int row)
1325: {
1326: if (row < 0 || row >= getRowCount())
1327: return;
1328:
1329: TreePath path = getPathForRow(row);
1330:
1331: if (path != null)
1332: expandPath(path);
1333: }
1334:
1335: public boolean isCollapsed(TreePath path)
1336: {
1337: return !isExpanded(path);
1338: }
1339:
1340: public boolean isCollapsed(int row)
1341: {
1342: if (row < 0 || row >= getRowCount())
1343: return false;
1344:
1345: TreePath path = getPathForRow(row);
1346:
1347: if (path != null)
1348: return isCollapsed(path);
1349:
1350: return false;
1351: }
1352:
1353: public boolean isExpanded(TreePath path)
1354: {
1355: if (path == null)
1356: return false;
1357:
1358: Object state = nodeStates.get(path);
1359:
1360: if ((state == null) || (state != EXPANDED))
1361: return false;
1362:
1363: TreePath parent = path.getParentPath();
1364:
1365: if (parent != null)
1366: return isExpanded(parent);
1367:
1368: return true;
1369: }
1370:
1371: public boolean isExpanded(int row)
1372: {
1373: if (row < 0 || row >= getRowCount())
1374: return false;
1375:
1376: TreePath path = getPathForRow(row);
1377:
1378: if (path != null)
1379: return isExpanded(path);
1380:
1381: return false;
1382: }
1383:
1384:
1387: public boolean getExpandsSelectedPaths()
1388: {
1389: return expandsSelectedPaths;
1390: }
1391:
1392:
1395: public void setExpandsSelectedPaths(boolean flag)
1396: {
1397: if (expandsSelectedPaths == flag)
1398: return;
1399:
1400: boolean oldValue = expandsSelectedPaths;
1401: expandsSelectedPaths = flag;
1402: firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, flag);
1403: }
1404:
1405: public Rectangle getPathBounds(TreePath path)
1406: {
1407: TreeUI ui = getUI();
1408:
1409: if (ui == null)
1410: return null;
1411:
1412: return ui.getPathBounds(this, path);
1413: }
1414:
1415: public Rectangle getRowBounds(int row)
1416: {
1417: TreePath path = getPathForRow(row);
1418:
1419: if (path != null)
1420: return getPathBounds(path);
1421:
1422: return null;
1423: }
1424:
1425: public boolean isEditing()
1426: {
1427: TreeUI ui = getUI();
1428:
1429: if (ui != null)
1430: return ui.isEditing(this);
1431:
1432: return false;
1433: }
1434:
1435: public boolean stopEditing()
1436: {
1437: TreeUI ui = getUI();
1438:
1439: if (ui != null)
1440: return ui.stopEditing(this);
1441:
1442: return false;
1443: }
1444:
1445: public void cancelEditing()
1446: {
1447: TreeUI ui = getUI();
1448:
1449: if (ui != null)
1450: ui.cancelEditing(this);
1451: }
1452:
1453: public void startEditingAtPath(TreePath path)
1454: {
1455: TreeUI ui = getUI();
1456:
1457: if (ui != null)
1458: ui.startEditingAtPath(this, path);
1459: }
1460:
1461: public TreePath getEditingPath()
1462: {
1463: TreeUI ui = getUI();
1464:
1465: if (ui != null)
1466: return ui.getEditingPath(this);
1467:
1468: return null;
1469: }
1470:
1471: public TreePath getPathForLocation(int x, int y)
1472: {
1473: TreePath path = getClosestPathForLocation(x, y);
1474:
1475: if (path != null)
1476: {
1477: Rectangle rect = getPathBounds(path);
1478:
1479: if ((rect != null) && rect.contains(x, y))
1480: return path;
1481: }
1482:
1483: return null;
1484: }
1485:
1486: public int getRowForLocation(int x, int y)
1487: {
1488: TreePath path = getPathForLocation(x, y);
1489:
1490: if (path != null)
1491: return getRowForPath(path);
1492:
1493: return -1;
1494: }
1495:
1496: public TreePath getClosestPathForLocation(int x, int y)
1497: {
1498: TreeUI ui = getUI();
1499:
1500: if (ui != null)
1501: return ui.getClosestPathForLocation(this, x, y);
1502:
1503: return null;
1504: }
1505:
1506: public int getClosestRowForLocation(int x, int y)
1507: {
1508: TreePath path = getClosestPathForLocation(x, y);
1509:
1510: if (path != null)
1511: return getRowForPath(path);
1512:
1513: return -1;
1514: }
1515:
1516: public Object getLastSelectedPathComponent()
1517: {
1518: TreePath path = getSelectionPath();
1519:
1520: if (path != null)
1521: return path.getLastPathComponent();
1522:
1523: return null;
1524: }
1525:
1526: private void doExpandParents(TreePath path, boolean state)
1527: {
1528: TreePath parent = path.getParentPath();
1529:
1530: if (!isExpanded(parent) && parent != null)
1531: doExpandParents(parent, false);
1532:
1533: nodeStates.put(path, state ? EXPANDED : COLLAPSED);
1534: }
1535:
1536: protected void setExpandedState(TreePath path, boolean state)
1537: {
1538: if (path == null)
1539: return;
1540: TreePath parent = path.getParentPath();
1541:
1542: doExpandParents(path, state);
1543: }
1544:
1545: protected void clearToggledPaths()
1546: {
1547: nodeStates.clear();
1548: }
1549:
1550: protected Enumeration getDescendantToggledPaths(TreePath parent)
1551: {
1552: if (parent == null)
1553: return null;
1554:
1555: Enumeration nodes = nodeStates.keys();
1556: Vector result = new Vector();
1557:
1558: while (nodes.hasMoreElements())
1559: {
1560: TreePath path = (TreePath) nodes.nextElement();
1561:
1562: if (path.isDescendant(parent))
1563: result.addElement(path);
1564: }
1565:
1566: return result.elements();
1567: }
1568:
1569: public boolean hasBeenExpanded(TreePath path)
1570: {
1571: if (path == null)
1572: return false;
1573:
1574: return nodeStates.get(path) != null;
1575: }
1576:
1577: public boolean isVisible(TreePath path)
1578: {
1579: if (path == null)
1580: return false;
1581:
1582: TreePath parent = path.getParentPath();
1583:
1584: if (parent == null)
1585: return true;
1586:
1587: return isExpanded(parent);
1588: }
1589:
1590: public void makeVisible(TreePath path)
1591: {
1592: if (path == null)
1593: return;
1594:
1595: expandPath(path.getParentPath());
1596: }
1597:
1598: public boolean isPathEditable(TreePath path)
1599: {
1600: return isEditable();
1601: }
1602:
1603:
1608: protected TreeModelListener createTreeModelListener()
1609: {
1610: return new TreeModelHandler();
1611: }
1612:
1613:
1619: protected static TreeModel getDefaultTreeModel()
1620: {
1621: DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root node");
1622: DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(
1623: "Child node 1");
1624: DefaultMutableTreeNode child11 = new DefaultMutableTreeNode(
1625: "Child node 1.1");
1626: DefaultMutableTreeNode child12 = new DefaultMutableTreeNode(
1627: "Child node 1.2");
1628: DefaultMutableTreeNode child13 = new DefaultMutableTreeNode(
1629: "Child node 1.3");
1630: DefaultMutableTreeNode child2 = new DefaultMutableTreeNode(
1631: "Child node 2");
1632: DefaultMutableTreeNode child21 = new DefaultMutableTreeNode(
1633: "Child node 2.1");
1634: DefaultMutableTreeNode child22 = new DefaultMutableTreeNode(
1635: "Child node 2.2");
1636: DefaultMutableTreeNode child23 = new DefaultMutableTreeNode(
1637: "Child node 2.3");
1638: DefaultMutableTreeNode child24 = new DefaultMutableTreeNode(
1639: "Child node 2.4");
1640:
1641: DefaultMutableTreeNode child3 = new DefaultMutableTreeNode(
1642: "Child node 3");
1643: root.add(child1);
1644: root.add(child2);
1645: root.add(child3);
1646: child1.add(child11);
1647: child1.add(child12);
1648: child1.add(child13);
1649: child2.add(child21);
1650: child2.add(child22);
1651: child2.add(child23);
1652: child2.add(child24);
1653: return new DefaultTreeModel(root);
1654: }
1655:
1656:
1671: public String convertValueToText(Object value, boolean selected,
1672: boolean expanded, boolean leaf, int row, boolean hasFocus)
1673: {
1674: return value.toString();
1675: }
1676:
1677:
1684: public String paramString()
1685: {
1686:
1687:
1688:
1689: return "";
1690: }
1691:
1692:
1701: public Enumeration getExpandedDescendants(TreePath path)
1702: {
1703: Enumeration paths = nodeStates.keys();
1704: Vector relevantPaths = new Vector();
1705: while (paths.hasMoreElements())
1706: {
1707: TreePath nextPath = (TreePath) paths.nextElement();
1708: if (nodeStates.get(nextPath) == EXPANDED
1709: && path.isDescendant(nextPath))
1710: {
1711: relevantPaths.add(nextPath);
1712: }
1713: }
1714: return relevantPaths.elements();
1715: }
1716:
1717:
1735: public TreePath getNextMatch(String prefix, int startingRow,
1736: Position.Bias bias)
1737: {
1738: if (prefix == null)
1739: throw new IllegalArgumentException(
1740: "The argument 'prefix' must not be" + " null.");
1741: if (startingRow < 0)
1742: throw new IllegalArgumentException(
1743: "The argument 'startingRow' must not"
1744: + " be less than zero.");
1745:
1746: int size = getRowCount();
1747: if (startingRow > size)
1748: throw new IllegalArgumentException(
1749: "The argument 'startingRow' must not"
1750: + " be greater than the number of"
1751: + " elements in the TreeModel.");
1752:
1753: TreePath foundPath = null;
1754: if (bias == Position.Bias.Forward)
1755: {
1756: for (int i = startingRow; i < size; i++)
1757: {
1758: TreePath path = getPathForRow(i);
1759: Object o = path.getLastPathComponent();
1760:
1761:
1762: String item = convertValueToText(o, isRowSelected(i),
1763: isExpanded(i), treeModel.isLeaf(o), i, false);
1764: if (item.startsWith(prefix))
1765: {
1766: foundPath = path;
1767: break;
1768: }
1769: }
1770: } else
1771: {
1772: for (int i = startingRow; i >= 0; i--)
1773: {
1774: TreePath path = getPathForRow(i);
1775: Object o = path.getLastPathComponent();
1776:
1777:
1778: String item = convertValueToText(o, isRowSelected(i),
1779: isExpanded(i), treeModel.isLeaf(o), i, false);
1780: if (item.startsWith(prefix))
1781: {
1782: foundPath = path;
1783: break;
1784: }
1785: }
1786: }
1787: return foundPath;
1788: }
1789:
1790:
1805: protected boolean removeDescendantSelectedPaths(TreePath path,
1806: boolean includeSelected)
1807: {
1808: boolean removedSomething = false;
1809: TreePath[] selected = getSelectionPaths();
1810: for (int index = 0; index < selected.length; index++)
1811: {
1812: if ((selected[index] == path && includeSelected)
1813: || (selected[index].isDescendant(path)))
1814: {
1815: removeSelectionPath(selected[index]);
1816: removedSomething = true;
1817: }
1818: }
1819: return removedSomething;
1820: }
1821: }