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: selectionModel.addTreeSelectionListener(selectionRedirector);
343: setCellRenderer(new DefaultTreeCellRenderer());
344: updateUI();
345: }
346:
347:
352: public JTree(TreeNode root)
353: {
354: this(root, false);
355: }
356:
357:
365: public JTree(TreeNode root, boolean asksAllowChildren)
366: {
367: this(new DefaultTreeModel(root, asksAllowChildren));
368: }
369:
370:
375: public JTree(Vector value)
376: {
377: this(createTreeModel(value));
378: }
379:
380: public static class DynamicUtilTreeNode
381: extends
382: DefaultMutableTreeNode
383: {
384: protected Object childValue;
385: protected boolean loadedChildren;
386:
387:
391: protected boolean hasChildren;
392:
393: public DynamicUtilTreeNode(Object value, Object children)
394: {
395: super(value);
396: childValue = children;
397: loadedChildren = false;
398: }
399:
400: public int getChildCount()
401: {
402: loadChildren();
403: return super.getChildCount();
404: }
405:
406: protected void loadChildren()
407: {
408: if (!loadedChildren)
409: {
410: createChildren(this, childValue);
411: loadedChildren = true;
412: }
413: }
414:
415: public Enumeration children()
416: {
417: loadChildren();
418: return super.children();
419: }
420:
421:
429: public TreeNode getChildAt(int pos)
430: {
431: loadChildren();
432: return super.getChildAt(pos);
433: }
434:
435: public boolean isLeaf()
436: {
437: return (childValue == null || !(childValue instanceof Hashtable
438: || childValue instanceof Vector || childValue.getClass()
439: .isArray()));
440: }
441:
442: public static void createChildren(DefaultMutableTreeNode parent,
443: Object children)
444: {
445: if (children instanceof Hashtable)
446: {
447: Hashtable tab = (Hashtable) children;
448: Enumeration e = tab.keys();
449: while (e.hasMoreElements())
450: {
451: Object key = e.nextElement();
452: Object val = tab.get(key);
453: parent.add(new DynamicUtilTreeNode(key, val));
454: }
455: } else if (children instanceof Vector)
456: {
457: Iterator i = ((Vector) children).iterator();
458: while (i.hasNext())
459: {
460: Object n = i.next();
461: parent.add(new DynamicUtilTreeNode(n, n));
462: }
463: } else if (children != null && children.getClass().isArray())
464: {
465: Object[] arr = (Object[]) children;
466: for (int i = 0; i < arr.length; ++i)
467: parent.add(new DynamicUtilTreeNode(arr[i], arr[i]));
468: }
469: }
470: }
471:
472: public int getRowForPath(TreePath path)
473: {
474: TreeUI ui = getUI();
475:
476: if (ui != null)
477: return ui.getRowForPath(this, path);
478:
479: return -1;
480: }
481:
482: public TreePath getPathForRow(int row)
483: {
484: TreeUI ui = getUI();
485: return ui != null ? ui.getPathForRow(this, row) : null;
486: }
487:
488: protected TreePath[] getPathBetweenRows(int index0, int index1)
489: {
490: TreeUI ui = getUI();
491:
492: if (ui == null)
493: return null;
494:
495: int minIndex = Math.min(index0, index1);
496: int maxIndex = Math.max(index0, index1);
497: TreePath[] paths = new TreePath[maxIndex - minIndex + 1];
498:
499: for (int i = minIndex; i <= maxIndex; ++i)
500: paths[i - minIndex] = ui.getPathForRow(this, i);
501:
502: return paths;
503: }
504:
505:
510: protected static TreeModel createTreeModel(Object value)
511: {
512: return new DefaultTreeModel(new DynamicUtilTreeNode(value, value));
513: }
514:
515:
520: public TreeUI getUI()
521: {
522: return (TreeUI) ui;
523: }
524:
525:
530: public void setUI(TreeUI ui)
531: {
532: super.setUI(ui);
533: }
534:
535:
538: public void updateUI()
539: {
540: setUI((TreeUI) UIManager.getUI(this));
541: revalidate();
542: repaint();
543: }
544:
545:
550: public String getUIClassID()
551: {
552: return "TreeUI";
553: }
554:
555:
561: public AccessibleContext getAccessibleContext()
562: {
563: return null;
564: }
565:
566:
571: public Dimension getPreferredScrollableViewportSize()
572: {
573: return null;
574: }
575:
576: public int getScrollableUnitIncrement(Rectangle visibleRect,
577: int orientation, int direction)
578: {
579: return 1;
580: }
581:
582: public int getScrollableBlockIncrement(Rectangle visibleRect,
583: int orientation, int direction)
584: {
585: return 1;
586: }
587:
588: public boolean getScrollableTracksViewportWidth()
589: {
590: return false;
591: }
592:
593: public boolean getScrollableTracksViewportHeight()
594: {
595: return false;
596: }
597:
598:
603: public void addTreeExpansionListener(TreeExpansionListener listener)
604: {
605: listenerList.add(TreeExpansionListener.class, listener);
606: }
607:
608:
613: public void removeTreeExpansionListener(TreeExpansionListener listener)
614: {
615: listenerList.remove(TreeExpansionListener.class, listener);
616: }
617:
618:
623: public TreeExpansionListener[] getTreeExpansionListeners()
624: {
625: return (TreeExpansionListener[]) getListeners(TreeExpansionListener.class);
626: }
627:
628:
633: public void fireTreeCollapsed(TreePath path)
634: {
635: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
636: TreeExpansionListener[] listeners = getTreeExpansionListeners();
637:
638: for (int index = 0; index < listeners.length; ++index)
639: listeners[index].treeCollapsed(event);
640: }
641:
642:
647: public void fireTreeExpanded(TreePath path)
648: {
649: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
650: TreeExpansionListener[] listeners = getTreeExpansionListeners();
651:
652: for (int index = 0; index < listeners.length; ++index)
653: listeners[index].treeExpanded(event);
654: }
655:
656:
661: public void addTreeSelectionListener(TreeSelectionListener listener)
662: {
663: listenerList.add(TreeSelectionListener.class, listener);
664: }
665:
666:
671: public void removeTreeSelectionListener(TreeSelectionListener listener)
672: {
673: listenerList.remove(TreeSelectionListener.class, listener);
674: }
675:
676:
681: public TreeSelectionListener[] getTreeSelectionListeners()
682: {
683: return (TreeSelectionListener[])
684: getListeners(TreeSelectionListener.class);
685: }
686:
687:
692: protected void fireValueChanged(TreeSelectionEvent event)
693: {
694: TreeSelectionListener[] listeners = getTreeSelectionListeners();
695:
696: for (int index = 0; index < listeners.length; ++index)
697: listeners[index].valueChanged(event);
698: }
699:
700:
705: public void addTreeWillExpandListener(TreeWillExpandListener listener)
706: {
707: listenerList.add(TreeWillExpandListener.class, listener);
708: }
709:
710:
715: public void removeTreeWillExpandListener(TreeWillExpandListener listener)
716: {
717: listenerList.remove(TreeWillExpandListener.class, listener);
718: }
719:
720:
725: public TreeWillExpandListener[] getTreeWillExpandListeners()
726: {
727: return (TreeWillExpandListener[])
728: getListeners(TreeWillExpandListener.class);
729: }
730:
731:
736: public void fireTreeWillCollapse(TreePath path) throws ExpandVetoException
737: {
738: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
739: TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
740:
741: for (int index = 0; index < listeners.length; ++index)
742: listeners[index].treeWillCollapse(event);
743: }
744:
745:
750: public void fireTreeWillExpand(TreePath path) throws ExpandVetoException
751: {
752: TreeExpansionEvent event = new TreeExpansionEvent(this, path);
753: TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
754:
755: for (int index = 0; index < listeners.length; ++index)
756: listeners[index].treeWillExpand(event);
757: }
758:
759:
764: public TreeModel getModel()
765: {
766: return treeModel;
767: }
768:
769:
774: public void setModel(TreeModel model)
775: {
776: if (treeModel == model)
777: return;
778:
779: TreeModel oldValue = treeModel;
780: treeModel = model;
781:
782: firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
783:
784:
785: if (treeModelListener == null)
786: treeModelListener = createTreeModelListener();
787: model.addTreeModelListener(treeModelListener);
788: }
789:
790:
796: public boolean isEditable()
797: {
798: return editable;
799: }
800:
801:
807: public void setEditable(boolean flag)
808: {
809: if (editable == flag)
810: return;
811:
812: boolean oldValue = editable;
813: editable = flag;
814: firePropertyChange(EDITABLE_PROPERTY, oldValue, editable);
815: }
816:
817:
823: public boolean isRootVisible()
824: {
825: return rootVisible;
826: }
827:
828: public void setRootVisible(boolean flag)
829: {
830: if (rootVisible == flag)
831: return;
832:
833: boolean oldValue = rootVisible;
834: rootVisible = flag;
835: firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
836: }
837:
838: public boolean getShowsRootHandles()
839: {
840: return showsRootHandles;
841: }
842:
843: public void setShowsRootHandles(boolean flag)
844: {
845: if (showsRootHandles == flag)
846: return;
847:
848: boolean oldValue = showsRootHandles;
849: showsRootHandles = flag;
850: firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, flag);
851: }
852:
853: public TreeCellEditor getCellEditor()
854: {
855:
856: return cellEditor;
857: }
858:
859: public void setCellEditor(TreeCellEditor editor)
860: {
861: if (cellEditor == editor)
862: return;
863:
864: TreeCellEditor oldValue = cellEditor;
865: cellEditor = editor;
866: firePropertyChange(CELL_EDITOR_PROPERTY, oldValue, editor);
867: }
868:
869: public TreeCellRenderer getCellRenderer()
870: {
871: return cellRenderer;
872: }
873:
874: public void setCellRenderer(TreeCellRenderer newRenderer)
875: {
876: if (cellRenderer == newRenderer)
877: return;
878:
879: TreeCellRenderer oldValue = cellRenderer;
880: cellRenderer = newRenderer;
881: firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, newRenderer);
882: }
883:
884: public TreeSelectionModel getSelectionModel()
885: {
886: return selectionModel;
887: }
888:
889: public void setSelectionModel(TreeSelectionModel model)
890: {
891: if (selectionModel == model)
892: return;
893:
894: if (selectionModel != null)
895: selectionModel.removeTreeSelectionListener(selectionRedirector);
896:
897: TreeSelectionModel oldValue = selectionModel;
898: selectionModel = model;
899:
900: if (selectionModel != null)
901: selectionModel.addTreeSelectionListener(selectionRedirector);
902:
903: firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, model);
904: revalidate();
905: repaint();
906: }
907:
908: public int getVisibleRowCount()
909: {
910: return visibleRowCount;
911: }
912:
913: public void setVisibleRowCount(int rows)
914: {
915: if (visibleRowCount == rows)
916: return;
917:
918: int oldValue = visibleRowCount;
919: visibleRowCount = rows;
920: firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldValue, rows);
921: }
922:
923: public boolean isLargeModel()
924: {
925: return largeModel;
926: }
927:
928: public void setLargeModel(boolean large)
929: {
930: if (largeModel == large)
931: return;
932:
933: boolean oldValue = largeModel;
934: largeModel = large;
935: firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, large);
936: }
937:
938: public int getRowHeight()
939: {
940:
941: return rowHeight;
942: }
943:
944: public void setRowHeight(int height)
945: {
946: if (rowHeight == height)
947: return;
948:
949: int oldValue = rowHeight;
950: rowHeight = height;
951: firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, height);
952: }
953:
954: public boolean isFixedRowHeight()
955: {
956: return rowHeight > 0;
957: }
958:
959: public boolean getInvokesStopCellEditing()
960: {
961: return invokesStopCellEditing;
962: }
963:
964: public void setInvokesStopCellEditing(boolean invoke)
965: {
966: if (invokesStopCellEditing == invoke)
967: return;
968:
969: boolean oldValue = invokesStopCellEditing;
970: invokesStopCellEditing = invoke;
971: firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY,
972: oldValue, invoke);
973: }
974:
975:
978: public int getToggleClickCount()
979: {
980: return toggleClickCount;
981: }
982:
983:
986: public void setToggleClickCount(int count)
987: {
988: if (toggleClickCount == count)
989: return;
990:
991: int oldValue = toggleClickCount;
992: toggleClickCount = count;
993: firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count);
994: }
995:
996: public void scrollPathToVisible(TreePath path)
997: {
998: if (path == null)
999: return;
1000:
1001: Rectangle rect = getPathBounds(path);
1002:
1003: if (rect == null)
1004: return;
1005:
1006: scrollRectToVisible(rect);
1007: }
1008:
1009: public void scrollRowToVisible(int row)
1010: {
1011: scrollPathToVisible(getPathForRow(row));
1012: }
1013:
1014: public boolean getScrollsOnExpand()
1015: {
1016: return scrollsOnExpand;
1017: }
1018:
1019: public void setScrollsOnExpand(boolean scroll)
1020: {
1021: if (scrollsOnExpand == scroll)
1022: return;
1023:
1024: boolean oldValue = scrollsOnExpand;
1025: scrollsOnExpand = scroll;
1026: firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, scroll);
1027: }
1028:
1029: public void setSelectionPath(TreePath path)
1030: {
1031: selectionModel.setSelectionPath(path);
1032: }
1033:
1034: public void setSelectionPaths(TreePath[] paths)
1035: {
1036: selectionModel.setSelectionPaths(paths);
1037: }
1038:
1039: public void setSelectionRow(int row)
1040: {
1041: TreePath path = getPathForRow(row);
1042:
1043: if (path != null)
1044: selectionModel.setSelectionPath(path);
1045: }
1046:
1047: public void setSelectionRows(int[] rows)
1048: {
1049:
1050: if (rows == null || getUI() == null)
1051: return;
1052:
1053: TreePath[] paths = new TreePath[rows.length];
1054:
1055: for (int i = rows.length - 1; i >= 0; --i)
1056: paths[i] = getPathForRow(rows[i]);
1057:
1058: setSelectionPaths(paths);
1059: }
1060:
1061: public void setSelectionInterval(int index0, int index1)
1062: {
1063: TreePath[] paths = getPathBetweenRows(index0, index1);
1064:
1065: if (paths != null)
1066: setSelectionPaths(paths);
1067: }
1068:
1069: public void addSelectionPath(TreePath path)
1070: {
1071: selectionModel.addSelectionPath(path);
1072: }
1073:
1074: public void addSelectionPaths(TreePath[] paths)
1075: {
1076: selectionModel.addSelectionPaths(paths);
1077: }
1078:
1079: public void addSelectionRow(int row)
1080: {
1081: TreePath path = getPathForRow(row);
1082:
1083: if (path != null)
1084: selectionModel.addSelectionPath(path);
1085: }
1086:
1087: public void addSelectionRows(int[] rows)
1088: {
1089:
1090: if (rows == null || getUI() == null)
1091: return;
1092:
1093: TreePath[] paths = new TreePath[rows.length];
1094:
1095: for (int i = rows.length - 1; i >= 0; --i)
1096: paths[i] = getPathForRow(rows[i]);
1097:
1098: addSelectionPaths(paths);
1099: }
1100:
1101: public void addSelectionInterval(int index0, int index1)
1102: {
1103: TreePath[] paths = getPathBetweenRows(index0, index1);
1104:
1105: if (paths != null)
1106: addSelectionPaths(paths);
1107: }
1108:
1109: public void removeSelectionPath(TreePath path)
1110: {
1111: selectionModel.removeSelectionPath(path);
1112: }
1113:
1114: public void removeSelectionPaths(TreePath[] paths)
1115: {
1116: selectionModel.removeSelectionPaths(paths);
1117: }
1118:
1119: public void removeSelectionRow(int row)
1120: {
1121: TreePath path = getPathForRow(row);
1122:
1123: if (path != null)
1124: selectionModel.removeSelectionPath(path);
1125: }
1126:
1127: public void removeSelectionRows(int[] rows)
1128: {
1129: if (rows == null || getUI() == null)
1130: return;
1131:
1132: TreePath[] paths = new TreePath[rows.length];
1133:
1134: for (int i = rows.length - 1; i >= 0; --i)
1135: paths[i] = getPathForRow(rows[i]);
1136:
1137: removeSelectionPaths(paths);
1138: }
1139:
1140: public void removeSelectionInterval(int index0, int index1)
1141: {
1142: TreePath[] paths = getPathBetweenRows(index0, index1);
1143:
1144: if (paths != null)
1145: removeSelectionPaths(paths);
1146: }
1147:
1148: public void clearSelection()
1149: {
1150: selectionModel.clearSelection();
1151: setLeadSelectionPath(null);
1152: }
1153:
1154: public TreePath getLeadSelectionPath()
1155: {
1156: return leadSelectionPath;
1157: }
1158:
1159:
1162: public void setLeadSelectionPath(TreePath path)
1163: {
1164: if (leadSelectionPath == path)
1165: return;
1166:
1167: TreePath oldValue = leadSelectionPath;
1168: leadSelectionPath = path;
1169: firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
1170: }
1171:
1172:
1175: public TreePath getAnchorSelectionPath()
1176: {
1177: return anchorSelectionPath;
1178: }
1179:
1180:
1183: public void setAnchorSelectionPath(TreePath path)
1184: {
1185: if (anchorSelectionPath == path)
1186: return;
1187:
1188: TreePath oldValue = anchorSelectionPath;
1189: anchorSelectionPath = path;
1190: firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, path);
1191: }
1192:
1193: public int getLeadSelectionRow()
1194: {
1195: return selectionModel.getLeadSelectionRow();
1196: }
1197:
1198: public int getMaxSelectionRow()
1199: {
1200: return selectionModel.getMaxSelectionRow();
1201: }
1202:
1203: public int getMinSelectionRow()
1204: {
1205: return selectionModel.getMinSelectionRow();
1206: }
1207:
1208: public int getSelectionCount()
1209: {
1210: return selectionModel.getSelectionCount();
1211: }
1212:
1213: public TreePath getSelectionPath()
1214: {
1215: return selectionModel.getSelectionPath();
1216: }
1217:
1218: public TreePath[] getSelectionPaths()
1219: {
1220: return selectionModel.getSelectionPaths();
1221: }
1222:
1223: public int[] getSelectionRows()
1224: {
1225: return selectionModel.getSelectionRows();
1226: }
1227:
1228: public boolean isPathSelected(TreePath path)
1229: {
1230: return selectionModel.isPathSelected(path);
1231: }
1232:
1233: public boolean isRowSelected(int row)
1234: {
1235: return selectionModel.isPathSelected(getPathForRow(row));
1236: }
1237:
1238: public boolean isSelectionEmpty()
1239: {
1240: return selectionModel.isSelectionEmpty();
1241: }
1242:
1243:
1250: public boolean getDragEnabled()
1251: {
1252: return dragEnabled;
1253: }
1254:
1255:
1262: public void setDragEnabled(boolean enabled)
1263: {
1264:
1265: dragEnabled = enabled;
1266: }
1267:
1268: public int getRowCount()
1269: {
1270: TreeUI ui = getUI();
1271:
1272: if (ui != null)
1273: return ui.getRowCount(this);
1274:
1275: return 0;
1276: }
1277:
1278: public void collapsePath(TreePath path)
1279: {
1280: setExpandedState(path, false);
1281: }
1282:
1283: public void collapseRow(int row)
1284: {
1285: if (row < 0 || row >= getRowCount())
1286: return;
1287:
1288: TreePath path = getPathForRow(row);
1289:
1290: if (path != null)
1291: collapsePath(path);
1292: }
1293:
1294: public void expandPath(TreePath path)
1295: {
1296:
1297: if ((path == null) || (treeModel.isLeaf(path.getLastPathComponent())))
1298: return;
1299:
1300: setExpandedState(path, true);
1301: }
1302:
1303: public void expandRow(int row)
1304: {
1305: if (row < 0 || row >= getRowCount())
1306: return;
1307:
1308: TreePath path = getPathForRow(row);
1309:
1310: if (path != null)
1311: expandPath(path);
1312: }
1313:
1314: public boolean isCollapsed(TreePath path)
1315: {
1316: return !isExpanded(path);
1317: }
1318:
1319: public boolean isCollapsed(int row)
1320: {
1321: if (row < 0 || row >= getRowCount())
1322: return false;
1323:
1324: TreePath path = getPathForRow(row);
1325:
1326: if (path != null)
1327: return isCollapsed(path);
1328:
1329: return false;
1330: }
1331:
1332: public boolean isExpanded(TreePath path)
1333: {
1334: if (path == null)
1335: return false;
1336:
1337: Object state = nodeStates.get(path);
1338:
1339: if ((state == null) || (state != EXPANDED))
1340: return false;
1341:
1342: TreePath parent = path.getParentPath();
1343:
1344: if (parent != null)
1345: return isExpanded(parent);
1346:
1347: return true;
1348: }
1349:
1350: public boolean isExpanded(int row)
1351: {
1352: if (row < 0 || row >= getRowCount())
1353: return false;
1354:
1355: TreePath path = getPathForRow(row);
1356:
1357: if (path != null)
1358: return isExpanded(path);
1359:
1360: return false;
1361: }
1362:
1363:
1366: public boolean getExpandsSelectedPaths()
1367: {
1368: return expandsSelectedPaths;
1369: }
1370:
1371:
1374: public void setExpandsSelectedPaths(boolean flag)
1375: {
1376: if (expandsSelectedPaths == flag)
1377: return;
1378:
1379: boolean oldValue = expandsSelectedPaths;
1380: expandsSelectedPaths = flag;
1381: firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, flag);
1382: }
1383:
1384: public Rectangle getPathBounds(TreePath path)
1385: {
1386: TreeUI ui = getUI();
1387:
1388: if (ui == null)
1389: return null;
1390:
1391: return ui.getPathBounds(this, path);
1392: }
1393:
1394: public Rectangle getRowBounds(int row)
1395: {
1396: TreePath path = getPathForRow(row);
1397:
1398: if (path != null)
1399: return getPathBounds(path);
1400:
1401: return null;
1402: }
1403:
1404: public boolean isEditing()
1405: {
1406: TreeUI ui = getUI();
1407:
1408: if (ui != null)
1409: return ui.isEditing(this);
1410:
1411: return false;
1412: }
1413:
1414: public boolean stopEditing()
1415: {
1416: TreeUI ui = getUI();
1417:
1418: if (ui != null)
1419: return ui.stopEditing(this);
1420:
1421: return false;
1422: }
1423:
1424: public void cancelEditing()
1425: {
1426: TreeUI ui = getUI();
1427:
1428: if (ui != null)
1429: ui.cancelEditing(this);
1430: }
1431:
1432: public void startEditingAtPath(TreePath path)
1433: {
1434: TreeUI ui = getUI();
1435:
1436: if (ui != null)
1437: ui.startEditingAtPath(this, path);
1438: }
1439:
1440: public TreePath getEditingPath()
1441: {
1442: TreeUI ui = getUI();
1443:
1444: if (ui != null)
1445: return ui.getEditingPath(this);
1446:
1447: return null;
1448: }
1449:
1450: public TreePath getPathForLocation(int x, int y)
1451: {
1452: TreePath path = getClosestPathForLocation(x, y);
1453:
1454: if (path != null)
1455: {
1456: Rectangle rect = getPathBounds(path);
1457:
1458: if ((rect != null) && rect.contains(x, y))
1459: return path;
1460: }
1461:
1462: return null;
1463: }
1464:
1465: public int getRowForLocation(int x, int y)
1466: {
1467: TreePath path = getPathForLocation(x, y);
1468:
1469: if (path != null)
1470: return getRowForPath(path);
1471:
1472: return -1;
1473: }
1474:
1475: public TreePath getClosestPathForLocation(int x, int y)
1476: {
1477: TreeUI ui = getUI();
1478:
1479: if (ui != null)
1480: return ui.getClosestPathForLocation(this, x, y);
1481:
1482: return null;
1483: }
1484:
1485: public int getClosestRowForLocation(int x, int y)
1486: {
1487: TreePath path = getClosestPathForLocation(x, y);
1488:
1489: if (path != null)
1490: return getRowForPath(path);
1491:
1492: return -1;
1493: }
1494:
1495: public Object getLastSelectedPathComponent()
1496: {
1497: TreePath path = getSelectionPath();
1498:
1499: if (path != null)
1500: return path.getLastPathComponent();
1501:
1502: return null;
1503: }
1504:
1505: private void checkExpandParents(TreePath path) throws ExpandVetoException
1506: {
1507:
1508: TreePath parent = path.getParentPath();
1509:
1510: if (parent != null)
1511: checkExpandParents(parent);
1512:
1513: fireTreeWillExpand(path);
1514: }
1515:
1516: private void doExpandParents(TreePath path, boolean state)
1517: {
1518: TreePath parent = path.getParentPath();
1519:
1520: if (isExpanded(parent))
1521: {
1522: nodeStates.put(path, state ? EXPANDED : COLLAPSED);
1523: return;
1524: }
1525:
1526: if (parent != null)
1527: doExpandParents(parent, false);
1528:
1529: nodeStates.put(path, state ? EXPANDED : COLLAPSED);
1530: }
1531:
1532: protected void setExpandedState(TreePath path, boolean state)
1533: {
1534: if (path == null)
1535: return;
1536:
1537: TreePath parent = path.getParentPath();
1538:
1539: try
1540: {
1541: if (parent != null)
1542: checkExpandParents(parent);
1543: }
1544: catch (ExpandVetoException e)
1545: {
1546:
1547: return;
1548: }
1549:
1550: doExpandParents(path, state);
1551: }
1552:
1553: protected void clearToggledPaths()
1554: {
1555: nodeStates.clear();
1556: }
1557:
1558: protected Enumeration getDescendantToggledPaths(TreePath parent)
1559: {
1560: if (parent == null)
1561: return null;
1562:
1563: Enumeration nodes = nodeStates.keys();
1564: Vector result = new Vector();
1565:
1566: while (nodes.hasMoreElements())
1567: {
1568: TreePath path = (TreePath) nodes.nextElement();
1569:
1570: if (path.isDescendant(parent))
1571: result.addElement(path);
1572: }
1573:
1574: return result.elements();
1575: }
1576:
1577: public boolean hasBeenExpanded(TreePath path)
1578: {
1579: if (path == null)
1580: return false;
1581:
1582: return nodeStates.get(path) != null;
1583: }
1584:
1585: public boolean isVisible(TreePath path)
1586: {
1587: if (path == null)
1588: return false;
1589:
1590: TreePath parent = path.getParentPath();
1591:
1592: if (parent == null)
1593: return true;
1594:
1595: return isExpanded(parent);
1596: }
1597:
1598: public void makeVisible(TreePath path)
1599: {
1600: if (path == null)
1601: return;
1602:
1603: expandPath(path.getParentPath());
1604: }
1605:
1606: public boolean isPathEditable(TreePath path)
1607: {
1608: return isEditable();
1609: }
1610:
1611:
1616: protected TreeModelListener createTreeModelListener()
1617: {
1618: return new TreeModelHandler();
1619: }
1620:
1621:
1627: protected static TreeModel getDefaultTreeModel()
1628: {
1629: DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root node");
1630: DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(
1631: "Child node 1");
1632: DefaultMutableTreeNode child11 = new DefaultMutableTreeNode(
1633: "Child node 1.1");
1634: DefaultMutableTreeNode child12 = new DefaultMutableTreeNode(
1635: "Child node 1.2");
1636: DefaultMutableTreeNode child13 = new DefaultMutableTreeNode(
1637: "Child node 1.3");
1638: DefaultMutableTreeNode child2 = new DefaultMutableTreeNode(
1639: "Child node 2");
1640: DefaultMutableTreeNode child21 = new DefaultMutableTreeNode(
1641: "Child node 2.1");
1642: DefaultMutableTreeNode child22 = new DefaultMutableTreeNode(
1643: "Child node 2.2");
1644: DefaultMutableTreeNode child23 = new DefaultMutableTreeNode(
1645: "Child node 2.3");
1646: DefaultMutableTreeNode child24 = new DefaultMutableTreeNode(
1647: "Child node 2.4");
1648:
1649: DefaultMutableTreeNode child3 = new DefaultMutableTreeNode(
1650: "Child node 3");
1651: root.add(child1);
1652: root.add(child2);
1653: root.add(child3);
1654: child1.add(child11);
1655: child1.add(child12);
1656: child1.add(child13);
1657: child2.add(child21);
1658: child2.add(child22);
1659: child2.add(child23);
1660: child2.add(child24);
1661: return new DefaultTreeModel(root);
1662: }
1663:
1664:
1679: public String convertValueToText(Object value, boolean selected,
1680: boolean expanded, boolean leaf, int row, boolean hasFocus)
1681: {
1682: return value.toString();
1683: }
1684:
1685:
1692: public String paramString()
1693: {
1694:
1695:
1696:
1697: return "";
1698: }
1699:
1700:
1709: public Enumeration getExpandedDescendants(TreePath path)
1710: {
1711: Enumeration paths = nodeStates.keys();
1712: Vector relevantPaths = new Vector();
1713: while (paths.hasMoreElements())
1714: {
1715: TreePath nextPath = (TreePath) paths.nextElement();
1716: if (nodeStates.get(nextPath) == EXPANDED
1717: && path.isDescendant(nextPath))
1718: {
1719: relevantPaths.add(nextPath);
1720: }
1721: }
1722: return relevantPaths.elements();
1723: }
1724:
1725:
1743: public TreePath getNextMatch(String prefix, int startingRow,
1744: Position.Bias bias)
1745: {
1746: if (prefix == null)
1747: throw new IllegalArgumentException(
1748: "The argument 'prefix' must not be" + " null.");
1749: if (startingRow < 0)
1750: throw new IllegalArgumentException(
1751: "The argument 'startingRow' must not"
1752: + " be less than zero.");
1753:
1754: int size = getRowCount();
1755: if (startingRow > size)
1756: throw new IllegalArgumentException(
1757: "The argument 'startingRow' must not"
1758: + " be greater than the number of"
1759: + " elements in the TreeModel.");
1760:
1761: TreePath foundPath = null;
1762: if (bias == Position.Bias.Forward)
1763: {
1764: for (int i = startingRow; i < size; i++)
1765: {
1766: TreePath path = getPathForRow(i);
1767: Object o = path.getLastPathComponent();
1768:
1769:
1770: String item = convertValueToText(o, isRowSelected(i),
1771: isExpanded(i), treeModel.isLeaf(o), i, false);
1772: if (item.startsWith(prefix))
1773: {
1774: foundPath = path;
1775: break;
1776: }
1777: }
1778: } else
1779: {
1780: for (int i = startingRow; i >= 0; i--)
1781: {
1782: TreePath path = getPathForRow(i);
1783: Object o = path.getLastPathComponent();
1784:
1785:
1786: String item = convertValueToText(o, isRowSelected(i),
1787: isExpanded(i), treeModel.isLeaf(o), i, false);
1788: if (item.startsWith(prefix))
1789: {
1790: foundPath = path;
1791: break;
1792: }
1793: }
1794: }
1795: return foundPath;
1796: }
1797:
1798:
1813: protected boolean removeDescendantSelectedPaths(TreePath path,
1814: boolean includeSelected)
1815: {
1816: boolean removedSomething = false;
1817: TreePath[] selected = getSelectionPaths();
1818: for (int index = 0; index < selected.length; index++)
1819: {
1820: if ((selected[index] == path && includeSelected)
1821: || (selected[index].isDescendant(path)))
1822: {
1823: removeSelectionPath(selected[index]);
1824: removedSomething = true;
1825: }
1826: }
1827: return removedSomething;
1828: }
1829: }