53 |
import javax.swing.event.TreeSelectionListener; |
import javax.swing.event.TreeSelectionListener; |
54 |
import javax.swing.event.TreeWillExpandListener; |
import javax.swing.event.TreeWillExpandListener; |
55 |
import javax.swing.plaf.TreeUI; |
import javax.swing.plaf.TreeUI; |
|
import javax.swing.tree.ExpandVetoException; |
|
56 |
import javax.swing.tree.DefaultMutableTreeNode; |
import javax.swing.tree.DefaultMutableTreeNode; |
57 |
import javax.swing.tree.DefaultTreeCellRenderer; |
import javax.swing.tree.DefaultTreeCellRenderer; |
58 |
import javax.swing.tree.DefaultTreeModel; |
import javax.swing.tree.DefaultTreeModel; |
59 |
|
import javax.swing.tree.ExpandVetoException; |
60 |
import javax.swing.tree.TreeCellEditor; |
import javax.swing.tree.TreeCellEditor; |
61 |
import javax.swing.tree.TreeCellRenderer; |
import javax.swing.tree.TreeCellRenderer; |
62 |
import javax.swing.tree.TreeModel; |
import javax.swing.tree.TreeModel; |
70 |
{ |
{ |
71 |
private static final long serialVersionUID = 7559816092864483649L; |
private static final long serialVersionUID = 7559816092864483649L; |
72 |
|
|
|
public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath"; |
|
73 |
public static final String CELL_EDITOR_PROPERTY = "cellEditor"; |
public static final String CELL_EDITOR_PROPERTY = "cellEditor"; |
74 |
public static final String CELL_RENDERER_PROPERTY = "cellRenderer"; |
public static final String CELL_RENDERER_PROPERTY = "cellRenderer"; |
75 |
public static final String EDITABLE_PROPERTY = "editable"; |
public static final String EDITABLE_PROPERTY = "editable"; |
|
public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths"; |
|
76 |
public static final String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing"; |
public static final String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing"; |
77 |
public static final String LARGE_MODEL_PROPERTY = "largeModel"; |
public static final String LARGE_MODEL_PROPERTY = "largeModel"; |
|
public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath"; |
|
78 |
public static final String ROOT_VISIBLE_PROPERTY = "rootVisible"; |
public static final String ROOT_VISIBLE_PROPERTY = "rootVisible"; |
79 |
public static final String ROW_HEIGHT_PROPERTY = "rowHeight"; |
public static final String ROW_HEIGHT_PROPERTY = "rowHeight"; |
80 |
public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand"; |
public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand"; |
84 |
public static final String TREE_MODEL_PROPERTY = "model"; |
public static final String TREE_MODEL_PROPERTY = "model"; |
85 |
public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount"; |
public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount"; |
86 |
|
|
87 |
|
/** @since 1.3 */ |
88 |
|
public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath"; |
89 |
|
/** @since 1.3 */ |
90 |
|
public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath"; |
91 |
|
/** @since 1.3 */ |
92 |
|
public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths"; |
93 |
|
|
94 |
|
private static final Object EXPANDED = new Object(); |
95 |
|
private static final Object COLLAPSED = new Object(); |
96 |
|
|
97 |
private boolean dragEnabled; |
private boolean dragEnabled; |
98 |
private boolean expandsSelectedPaths; |
private boolean expandsSelectedPaths; |
99 |
private TreePath anchorSelectionPath; |
private TreePath anchorSelectionPath; |
100 |
private TreePath leadSelectionPath; |
private TreePath leadSelectionPath; |
101 |
|
|
102 |
protected TreeCellEditor cellEditor; |
/* |
103 |
protected TreeCellRenderer cellRenderer; |
* This contains the state of all nodes in the tree. Al/ entries map the |
104 |
|
* TreePath of a note to to its state. Valid states are EXPANDED and |
105 |
|
* COLLAPSED. Nodes not in this Hashtable are assumed state COLLAPSED. |
106 |
|
*/ |
107 |
|
private Hashtable nodeStates; |
108 |
|
|
109 |
|
protected transient TreeCellEditor cellEditor; |
110 |
|
protected transient TreeCellRenderer cellRenderer; |
111 |
protected boolean editable; |
protected boolean editable; |
112 |
protected boolean invokesStopCellEditing; |
protected boolean invokesStopCellEditing; |
113 |
protected boolean largeModel; |
protected boolean largeModel; |
114 |
protected boolean rootVisible; |
protected boolean rootVisible; |
115 |
protected int rowHeight; |
protected int rowHeight; |
116 |
protected boolean scrollsOnExpand; |
protected boolean scrollsOnExpand; |
117 |
protected TreeSelectionModel selectionModel; |
protected transient TreeSelectionModel selectionModel; |
118 |
protected boolean showsRootHandles; |
protected boolean showsRootHandles; |
119 |
protected int toggleClickCount; |
protected int toggleClickCount; |
120 |
protected TreeModel treeModel; |
protected transient TreeModel treeModel; |
121 |
protected int visibleRowCount; |
protected int visibleRowCount; |
122 |
|
|
123 |
/** |
/** |
197 |
{ |
{ |
198 |
protected Object childValue; |
protected Object childValue; |
199 |
protected boolean loadedChildren; |
protected boolean loadedChildren; |
200 |
|
|
201 |
|
/** |
202 |
|
* Currently not set or used by this class. |
203 |
|
* It might be set and used in later versions of this class. |
204 |
|
*/ |
205 |
|
protected boolean hasChildren; |
206 |
|
|
207 |
public DynamicUtilTreeNode(Object value, |
public DynamicUtilTreeNode(Object value, |
208 |
Object children) |
Object children) |
209 |
{ |
{ |
778 |
firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count); |
firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count); |
779 |
} |
} |
780 |
|
|
781 |
|
public void scrollPathToVisible(TreePath path) |
782 |
|
{ |
783 |
|
if (path == null) |
784 |
|
return; |
785 |
|
|
786 |
|
Rectangle rect = getPathBounds(path); |
787 |
|
|
788 |
|
if (rect == null) |
789 |
|
return; |
790 |
|
|
791 |
|
scrollRectToVisible(rect); |
792 |
|
} |
793 |
|
|
794 |
|
public void scrollRowToVisible(int row) |
795 |
|
{ |
796 |
|
scrollPathToVisible(getPathForRow(row)); |
797 |
|
} |
798 |
|
|
799 |
public boolean getScrollsOnExpand() |
public boolean getScrollsOnExpand() |
800 |
{ |
{ |
801 |
return scrollsOnExpand; |
return scrollsOnExpand; |
1058 |
|
|
1059 |
return 0; |
return 0; |
1060 |
} |
} |
1061 |
|
|
1062 |
|
public void collapsePath(TreePath path) |
1063 |
|
{ |
1064 |
|
setExpandedState(path, false); |
1065 |
|
} |
1066 |
|
|
1067 |
|
public void collapseRow(int row) |
1068 |
|
{ |
1069 |
|
if (row < 0 || row >= getRowCount()) |
1070 |
|
return; |
1071 |
|
|
1072 |
|
TreePath path = getPathForRow(row); |
1073 |
|
|
1074 |
|
if (path != null) |
1075 |
|
collapsePath(path); |
1076 |
|
} |
1077 |
|
|
1078 |
|
public void expandPath(TreePath path) |
1079 |
|
{ |
1080 |
|
// Don't expand if last path component is a leaf node. |
1081 |
|
if ((path == null) |
1082 |
|
|| (treeModel.isLeaf(path.getLastPathComponent()))) |
1083 |
|
return; |
1084 |
|
|
1085 |
|
setExpandedState(path, true); |
1086 |
|
} |
1087 |
|
|
1088 |
|
public void expandRow(int row) |
1089 |
|
{ |
1090 |
|
if (row < 0 || row >= getRowCount()) |
1091 |
|
return; |
1092 |
|
|
1093 |
|
TreePath path = getPathForRow(row); |
1094 |
|
|
1095 |
|
if (path != null) |
1096 |
|
expandPath(path); |
1097 |
|
} |
1098 |
|
|
1099 |
|
public boolean isCollapsed(TreePath path) |
1100 |
|
{ |
1101 |
|
return ! isExpanded(path); |
1102 |
|
} |
1103 |
|
|
1104 |
|
public boolean isCollapsed(int row) |
1105 |
|
{ |
1106 |
|
if (row < 0 || row >= getRowCount()) |
1107 |
|
return false; |
1108 |
|
|
1109 |
|
TreePath path = getPathForRow(row); |
1110 |
|
|
1111 |
|
if (path != null) |
1112 |
|
return isCollapsed(path); |
1113 |
|
|
1114 |
|
return false; |
1115 |
|
} |
1116 |
|
|
1117 |
|
public boolean isExpanded(TreePath path) |
1118 |
|
{ |
1119 |
|
if (path == null) |
1120 |
|
return false; |
1121 |
|
|
1122 |
|
Object state = nodeStates.get(path); |
1123 |
|
|
1124 |
|
if ((state == null) || (state != EXPANDED)) |
1125 |
|
return false; |
1126 |
|
|
1127 |
|
TreePath parent = path.getParentPath(); |
1128 |
|
|
1129 |
|
if (parent != null) |
1130 |
|
return isExpanded(parent); |
1131 |
|
|
1132 |
|
return true; |
1133 |
|
} |
1134 |
|
|
1135 |
|
public boolean isExpanded(int row) |
1136 |
|
{ |
1137 |
|
if (row < 0 || row >= getRowCount()) |
1138 |
|
return false; |
1139 |
|
|
1140 |
|
TreePath path = getPathForRow(row); |
1141 |
|
|
1142 |
|
if (path != null) |
1143 |
|
return isExpanded(path); |
1144 |
|
|
1145 |
|
return false; |
1146 |
|
} |
1147 |
|
|
1148 |
/** |
/** |
1149 |
* @since 1.3 |
* @since 1.3 |
1286 |
|
|
1287 |
return null; |
return null; |
1288 |
} |
} |
1289 |
|
|
1290 |
|
private void checkExpandParents(TreePath path) |
1291 |
|
throws ExpandVetoException |
1292 |
|
{ |
1293 |
|
TreePath parent = path.getParentPath(); |
1294 |
|
|
1295 |
|
if (parent != null) |
1296 |
|
checkExpandParents(parent); |
1297 |
|
|
1298 |
|
fireTreeWillExpand(path); |
1299 |
|
} |
1300 |
|
|
1301 |
|
private void doExpandParents(TreePath path, boolean state) |
1302 |
|
{ |
1303 |
|
TreePath parent = path.getParentPath(); |
1304 |
|
|
1305 |
|
if (isExpanded(parent)) |
1306 |
|
return; |
1307 |
|
|
1308 |
|
if (parent != null) |
1309 |
|
doExpandParents(parent, false); |
1310 |
|
|
1311 |
|
nodeStates.put(path, state ? EXPANDED : COLLAPSED); |
1312 |
|
} |
1313 |
|
|
1314 |
|
protected void setExpandedState(TreePath path, boolean state) |
1315 |
|
{ |
1316 |
|
if (path == null) |
1317 |
|
return; |
1318 |
|
|
1319 |
|
TreePath parent = path.getParentPath(); |
1320 |
|
|
1321 |
|
try |
1322 |
|
{ |
1323 |
|
while (parent != null) |
1324 |
|
checkExpandParents(parent); |
1325 |
|
} |
1326 |
|
catch (ExpandVetoException e) |
1327 |
|
{ |
1328 |
|
// Expansion vetoed. |
1329 |
|
return; |
1330 |
|
} |
1331 |
|
|
1332 |
|
doExpandParents(path, state); |
1333 |
|
} |
1334 |
|
|
1335 |
|
protected void clearToggledPaths() |
1336 |
|
{ |
1337 |
|
nodeStates.clear(); |
1338 |
|
} |
1339 |
|
|
1340 |
|
protected Enumeration getDescendantToggledPaths(TreePath parent) |
1341 |
|
{ |
1342 |
|
if (parent == null) |
1343 |
|
return null; |
1344 |
|
|
1345 |
|
Enumeration nodes = nodeStates.keys(); |
1346 |
|
Vector result = new Vector(); |
1347 |
|
|
1348 |
|
while (nodes.hasMoreElements()) |
1349 |
|
{ |
1350 |
|
TreePath path = (TreePath) nodes.nextElement(); |
1351 |
|
|
1352 |
|
if (path.isDescendant(parent)) |
1353 |
|
result.addElement(path); |
1354 |
|
} |
1355 |
|
|
1356 |
|
return result.elements(); |
1357 |
|
} |
1358 |
|
|
1359 |
|
public boolean hasBeenExpanded(TreePath path) |
1360 |
|
{ |
1361 |
|
if (path == null) |
1362 |
|
return false; |
1363 |
|
|
1364 |
|
return nodeStates.get(path) != null; |
1365 |
|
} |
1366 |
|
|
1367 |
|
public boolean isVisible(TreePath path) |
1368 |
|
{ |
1369 |
|
if (path == null) |
1370 |
|
return false; |
1371 |
|
|
1372 |
|
TreePath parent = path.getParentPath(); |
1373 |
|
|
1374 |
|
if (parent == null) |
1375 |
|
return true; // Is root node. |
1376 |
|
|
1377 |
|
return isExpanded(parent); |
1378 |
|
} |
1379 |
|
|
1380 |
|
public void makeVisible(TreePath path) |
1381 |
|
{ |
1382 |
|
if (path == null) |
1383 |
|
return; |
1384 |
|
|
1385 |
|
expandPath(path.getParentPath()); |
1386 |
|
} |
1387 |
|
|
1388 |
|
public boolean isPathEditable(TreePath path) |
1389 |
|
{ |
1390 |
|
return isEditable(); |
1391 |
|
} |
1392 |
} |
} |