1 7 8 package javax.swing; 9 10 import java.awt.*; 11 import java.awt.event.*; 12 import java.beans.*; 13 import java.io.*; 14 import java.util.*; 15 import javax.swing.event.*; 16 import javax.swing.plaf.TreeUI ; 17 import javax.swing.tree.*; 18 import javax.swing.text.Position ; 19 import javax.accessibility.*; 20 21 22 120 public class JTree extends JComponent implements Scrollable , Accessible 121 { 122 126 private static final String uiClassID = "TreeUI"; 127 128 131 transient protected TreeModel treeModel; 132 133 136 transient protected TreeSelectionModel selectionModel; 137 138 142 protected boolean rootVisible; 143 144 148 transient protected TreeCellRenderer cellRenderer; 149 150 154 protected int rowHeight; 155 private boolean rowHeightSet = false; 156 157 165 transient private Hashtable expandedState; 166 167 168 190 protected boolean showsRootHandles; 191 private boolean showsRootHandlesSet = false; 192 193 197 protected transient TreeSelectionRedirector selectionRedirector; 198 199 203 transient protected TreeCellEditor cellEditor; 204 205 208 protected boolean editable; 209 210 220 protected boolean largeModel; 221 222 227 protected int visibleRowCount; 228 229 236 protected boolean invokesStopCellEditing; 237 238 242 protected boolean scrollsOnExpand; 243 private boolean scrollsOnExpandSet = false; 244 245 248 protected int toggleClickCount; 249 250 253 transient protected TreeModelListener treeModelListener; 254 255 259 transient private Stack expandedStack; 260 261 264 private TreePath leadPath; 265 266 269 private TreePath anchorPath; 270 271 274 private boolean expandsSelectedPaths; 275 276 279 private boolean settingUI; 280 281 282 private boolean dragEnabled; 283 284 292 private transient TreeExpansionListener uiTreeExpansionListener; 293 294 297 private static int TEMP_STACK_SIZE = 11; 298 299 303 public final static String CELL_RENDERER_PROPERTY = "cellRenderer"; 304 305 public final static String TREE_MODEL_PROPERTY = "model"; 306 307 public final static String ROOT_VISIBLE_PROPERTY = "rootVisible"; 308 309 public final static String SHOWS_ROOT_HANDLES_PROPERTY = "showsRootHandles"; 310 311 public final static String ROW_HEIGHT_PROPERTY = "rowHeight"; 312 313 public final static String CELL_EDITOR_PROPERTY = "cellEditor"; 314 315 public final static String EDITABLE_PROPERTY = "editable"; 316 317 public final static String LARGE_MODEL_PROPERTY = "largeModel"; 318 319 public final static String SELECTION_MODEL_PROPERTY = "selectionModel"; 320 321 public final static String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount"; 322 323 public final static String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing"; 324 325 public final static String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand"; 326 327 public final static String TOGGLE_CLICK_COUNT_PROPERTY = "toggleClickCount"; 328 330 public final static String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath"; 331 333 public final static String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath"; 334 336 public final static String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths"; 337 338 339 345 protected static TreeModel getDefaultTreeModel() { 346 DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree"); 347 DefaultMutableTreeNode parent; 348 349 parent = new DefaultMutableTreeNode("colors"); 350 root.add(parent); 351 parent.add(new DefaultMutableTreeNode("blue")); 352 parent.add(new DefaultMutableTreeNode("violet")); 353 parent.add(new DefaultMutableTreeNode("red")); 354 parent.add(new DefaultMutableTreeNode("yellow")); 355 356 parent = new DefaultMutableTreeNode("sports"); 357 root.add(parent); 358 parent.add(new DefaultMutableTreeNode("basketball")); 359 parent.add(new DefaultMutableTreeNode("soccer")); 360 parent.add(new DefaultMutableTreeNode("football")); 361 parent.add(new DefaultMutableTreeNode("hockey")); 362 363 parent = new DefaultMutableTreeNode("food"); 364 root.add(parent); 365 parent.add(new DefaultMutableTreeNode("hot dogs")); 366 parent.add(new DefaultMutableTreeNode("pizza")); 367 parent.add(new DefaultMutableTreeNode("ravioli")); 368 parent.add(new DefaultMutableTreeNode("bananas")); 369 return new DefaultTreeModel(root); 370 } 371 372 386 protected static TreeModel createTreeModel(Object value) { 387 DefaultMutableTreeNode root; 388 389 if((value instanceof Object []) || (value instanceof Hashtable) || 390 (value instanceof Vector)) { 391 root = new DefaultMutableTreeNode("root"); 392 DynamicUtilTreeNode.createChildren(root, value); 393 } 394 else { 395 root = new DynamicUtilTreeNode("root", value); 396 } 397 return new DefaultTreeModel(root, false); 398 } 399 400 407 public JTree() { 408 this(getDefaultTreeModel()); 409 } 410 411 421 public JTree(Object [] value) { 422 this(createTreeModel(value)); 423 this.setRootVisible(false); 424 this.setShowsRootHandles(true); 425 expandRoot(); 426 } 427 428 437 public JTree(Vector<?> value) { 438 this(createTreeModel(value)); 439 this.setRootVisible(false); 440 this.setShowsRootHandles(true); 441 expandRoot(); 442 } 443 444 454 public JTree(Hashtable<?,?> value) { 455 this(createTreeModel(value)); 456 this.setRootVisible(false); 457 this.setShowsRootHandles(true); 458 expandRoot(); 459 } 460 461 470 public JTree(TreeNode root) { 471 this(root, false); 472 } 473 474 486 public JTree(TreeNode root, boolean asksAllowsChildren) { 487 this(new DefaultTreeModel(root, asksAllowsChildren)); 488 } 489 490 496 public JTree(TreeModel newModel) { 497 super(); 498 expandedStack = new Stack(); 499 toggleClickCount = 2; 500 expandedState = new Hashtable(); 501 setLayout(null); 502 rowHeight = 16; 503 visibleRowCount = 20; 504 rootVisible = true; 505 selectionModel = new DefaultTreeSelectionModel(); 506 cellRenderer = null; 507 scrollsOnExpand = true; 508 setOpaque(true); 509 expandsSelectedPaths = true; 510 updateUI(); 511 setModel(newModel); 512 } 513 514 519 public TreeUI getUI() { 520 return (TreeUI )ui; 521 } 522 523 534 public void setUI(TreeUI ui) { 535 if ((TreeUI )this.ui != ui) { 536 settingUI = true; 537 uiTreeExpansionListener = null; 538 try { 539 super.setUI(ui); 540 } 541 finally { 542 settingUI = false; 543 } 544 } 545 } 546 547 554 public void updateUI() { 555 setUI((TreeUI )UIManager.getUI(this)); 556 invalidate(); 557 } 558 559 560 567 public String getUIClassID() { 568 return uiClassID; 569 } 570 571 572 578 public TreeCellRenderer getCellRenderer() { 579 return cellRenderer; 580 } 581 582 592 public void setCellRenderer(TreeCellRenderer x) { 593 TreeCellRenderer oldValue = cellRenderer; 594 595 cellRenderer = x; 596 firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, cellRenderer); 597 invalidate(); 598 } 599 600 610 public void setEditable(boolean flag) { 611 boolean oldValue = this.editable; 612 613 this.editable = flag; 614 firePropertyChange(EDITABLE_PROPERTY, oldValue, flag); 615 if (accessibleContext != null) { 616 accessibleContext.firePropertyChange( 617 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 618 (oldValue ? AccessibleState.EDITABLE : null), 619 (flag ? AccessibleState.EDITABLE : null)); 620 } 621 } 622 623 628 public boolean isEditable() { 629 return editable; 630 } 631 632 644 public void setCellEditor(TreeCellEditor cellEditor) { 645 TreeCellEditor oldEditor = this.cellEditor; 646 647 this.cellEditor = cellEditor; 648 firePropertyChange(CELL_EDITOR_PROPERTY, oldEditor, cellEditor); 649 invalidate(); 650 } 651 652 658 public TreeCellEditor getCellEditor() { 659 return cellEditor; 660 } 661 662 667 public TreeModel getModel() { 668 return treeModel; 669 } 670 671 679 public void setModel(TreeModel newModel) { 680 clearSelection(); 681 682 TreeModel oldModel = treeModel; 683 684 if(treeModel != null && treeModelListener != null) 685 treeModel.removeTreeModelListener(treeModelListener); 686 687 if (accessibleContext != null) { 688 if (treeModel != null) { 689 treeModel.removeTreeModelListener((TreeModelListener)accessibleContext); 690 } 691 if (newModel != null) { 692 newModel.addTreeModelListener((TreeModelListener)accessibleContext); 693 } 694 } 695 696 treeModel = newModel; 697 clearToggledPaths(); 698 if(treeModel != null) { 699 if(treeModelListener == null) 700 treeModelListener = createTreeModelListener(); 701 if(treeModelListener != null) 702 treeModel.addTreeModelListener(treeModelListener); 703 if(treeModel.getRoot() != null && 705 !treeModel.isLeaf(treeModel.getRoot())) { 706 expandedState.put(new TreePath(treeModel.getRoot()), 707 Boolean.TRUE); 708 } 709 } 710 firePropertyChange(TREE_MODEL_PROPERTY, oldModel, treeModel); 711 invalidate(); 712 } 713 714 720 public boolean isRootVisible() { 721 return rootVisible; 722 } 723 724 735 public void setRootVisible(boolean rootVisible) { 736 boolean oldValue = this.rootVisible; 737 738 this.rootVisible = rootVisible; 739 firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, this.rootVisible); 740 if (accessibleContext != null) { 741 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange(); 742 } 743 } 744 745 762 public void setShowsRootHandles(boolean newValue) { 763 boolean oldValue = showsRootHandles; 764 TreeModel model = getModel(); 765 766 showsRootHandles = newValue; 767 showsRootHandlesSet = true; 768 firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, 769 showsRootHandles); 770 if (accessibleContext != null) { 771 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange(); 772 } 773 invalidate(); 774 } 775 776 782 public boolean getShowsRootHandles() 783 { 784 return showsRootHandles; 785 } 786 787 797 public void setRowHeight(int rowHeight) 798 { 799 int oldValue = this.rowHeight; 800 801 this.rowHeight = rowHeight; 802 rowHeightSet = true; 803 firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, this.rowHeight); 804 invalidate(); 805 } 806 807 813 public int getRowHeight() 814 { 815 return rowHeight; 816 } 817 818 823 public boolean isFixedRowHeight() 824 { 825 return (rowHeight > 0); 826 } 827 828 840 public void setLargeModel(boolean newValue) { 841 boolean oldValue = largeModel; 842 843 largeModel = newValue; 844 firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, newValue); 845 } 846 847 853 public boolean isLargeModel() { 854 return largeModel; 855 } 856 857 874 public void setInvokesStopCellEditing(boolean newValue) { 875 boolean oldValue = invokesStopCellEditing; 876 877 invokesStopCellEditing = newValue; 878 firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY, oldValue, 879 newValue); 880 } 881 882 890 public boolean getInvokesStopCellEditing() { 891 return invokesStopCellEditing; 892 } 893 894 913 public void setScrollsOnExpand(boolean newValue) { 914 boolean oldValue = scrollsOnExpand; 915 916 scrollsOnExpand = newValue; 917 scrollsOnExpandSet = true; 918 firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, 919 newValue); 920 } 921 922 927 public boolean getScrollsOnExpand() { 928 return scrollsOnExpand; 929 } 930 931 940 public void setToggleClickCount(int clickCount) { 941 int oldCount = toggleClickCount; 942 943 toggleClickCount = clickCount; 944 firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldCount, 945 clickCount); 946 } 947 948 954 public int getToggleClickCount() { 955 return toggleClickCount; 956 } 957 958 978 public void setExpandsSelectedPaths(boolean newValue) { 979 boolean oldValue = expandsSelectedPaths; 980 981 expandsSelectedPaths = newValue; 982 firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, 983 newValue); 984 } 985 986 993 public boolean getExpandsSelectedPaths() { 994 return expandsSelectedPaths; 995 } 996 997 1041 public void setDragEnabled(boolean b) { 1042 if (b && GraphicsEnvironment.isHeadless()) { 1043 throw new HeadlessException(); 1044 } 1045 dragEnabled = b; 1046 } 1047 1048 1055 public boolean getDragEnabled() { 1056 return dragEnabled; 1057 } 1058 1059 1068 public boolean isPathEditable(TreePath path) { 1069 return isEditable(); 1070 } 1071 1072 1088 public String getToolTipText(MouseEvent event) { 1089 if(event != null) { 1090 Point p = event.getPoint(); 1091 int selRow = getRowForLocation(p.x, p.y); 1092 TreeCellRenderer r = getCellRenderer(); 1093 1094 if(selRow != -1 && r != null) { 1095 TreePath path = getPathForRow(selRow); 1096 Object lastPath = path.getLastPathComponent(); 1097 Component rComponent = r.getTreeCellRendererComponent 1098 (this, lastPath, isRowSelected(selRow), 1099 isExpanded(selRow), getModel().isLeaf(lastPath), selRow, 1100 true); 1101 1102 if(rComponent instanceof JComponent ) { 1103 MouseEvent newEvent; 1104 Rectangle pathBounds = getPathBounds(path); 1105 1106 p.translate(-pathBounds.x, -pathBounds.y); 1107 newEvent = new MouseEvent(rComponent, event.getID(), 1108 event.getWhen(), 1109 event.getModifiers(), 1110 p.x, p.y, event.getClickCount(), 1111 event.isPopupTrigger()); 1112 1113 return ((JComponent )rComponent).getToolTipText(newEvent); 1114 } 1115 } 1116 } 1117 return null; 1118 } 1119 1120 1135 public String convertValueToText(Object value, boolean selected, 1136 boolean expanded, boolean leaf, int row, 1137 boolean hasFocus) { 1138 if(value != null) { 1139 String sValue = value.toString(); 1140 if (sValue != null) { 1141 return sValue; 1142 } 1143 } 1144 return ""; 1145 } 1146 1147 1152 1157 public int getRowCount() { 1158 TreeUI tree = getUI(); 1159 1160 if(tree != null) 1161 return tree.getRowCount(this); 1162 return 0; 1163 } 1164 1165 1173 public void setSelectionPath(TreePath path) { 1174 getSelectionModel().setSelectionPath(path); 1175 } 1176 1177 1186 public void setSelectionPaths(TreePath[] paths) { 1187 getSelectionModel().setSelectionPaths(paths); 1188 } 1189 1190 1201 public void setLeadSelectionPath(TreePath newPath) { 1202 TreePath oldValue = leadPath; 1203 1204 leadPath = newPath; 1205 firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, newPath); 1206 } 1207 1208 1219 public void setAnchorSelectionPath(TreePath newPath) { 1220 TreePath oldValue = anchorPath; 1221 1222 anchorPath = newPath; 1223 firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, newPath); 1224 } 1225 1226 1232 public void setSelectionRow(int row) { 1233 int[] rows = { row }; 1234 1235 setSelectionRows(rows); 1236 } 1237 1238 1250 public void setSelectionRows(int[] rows) { 1251 TreeUI ui = getUI(); 1252 1253 if(ui != null && rows != null) { 1254 int numRows = rows.length; 1255 TreePath[] paths = new TreePath[numRows]; 1256 1257 for(int counter = 0; counter < numRows; counter++) { 1258 paths[counter] = ui.getPathForRow(this, rows[counter]); 1259 } 1260 setSelectionPaths(paths); 1261 } 1262 } 1263 1264 1276 public void addSelectionPath(TreePath path) { 1277 getSelectionModel().addSelectionPath(path); 1278 } 1279 1280 1293 public void addSelectionPaths(TreePath[] paths) { 1294 getSelectionModel().addSelectionPaths(paths); 1295 } 1296 1297 1303 public void addSelectionRow(int row) { 1304 int[] rows = { row }; 1305 1306 addSelectionRows(rows); 1307 } 1308 1309 1315 public void addSelectionRows(int[] rows) { 1316 TreeUI ui = getUI(); 1317 1318 if(ui != null && rows != null) { 1319 int numRows = rows.length; 1320 TreePath[] paths = new TreePath[numRows]; 1321 1322 for(int counter = 0; counter < numRows; counter++) 1323 paths[counter] = ui.getPathForRow(this, rows[counter]); 1324 addSelectionPaths(paths); 1325 } 1326 } 1327 1328 1337 public Object getLastSelectedPathComponent() { 1338 TreePath selPath = getSelectionModel().getSelectionPath(); 1339 1340 if(selPath != null) 1341 return selPath.getLastPathComponent(); 1342 return null; 1343 } 1344 1345 1349 public TreePath getLeadSelectionPath() { 1350 return leadPath; 1351 } 1352 1353 1358 public TreePath getAnchorSelectionPath() { 1359 return anchorPath; 1360 } 1361 1362 1368 public TreePath getSelectionPath() { 1369 return getSelectionModel().getSelectionPath(); 1370 } 1371 1372 1378 public TreePath[] getSelectionPaths() { 1379 return getSelectionModel().getSelectionPaths(); 1380 } 1381 1382 1392 public int[] getSelectionRows() { 1393 return getSelectionModel().getSelectionRows(); 1394 } 1395 1396 1401 public int getSelectionCount() { 1402 return selectionModel.getSelectionCount(); 1403 } 1404 1405 1411 public int getMinSelectionRow() { 1412 return getSelectionModel().getMinSelectionRow(); 1413 } 1414 1415 1421 public int getMaxSelectionRow() { 1422 return getSelectionModel().getMaxSelectionRow(); 1423 } 1424 1425 1432 public int getLeadSelectionRow() { 1433 TreePath leadPath = getLeadSelectionPath(); 1434 1435 if (leadPath != null) { 1436 return getRowForPath(leadPath); 1437 } 1438 return -1; 1439 } 1440 1441 1447 public boolean isPathSelected(TreePath path) { 1448 return getSelectionModel().isPathSelected(path); 1449 } 1450 1451 1458 public boolean isRowSelected(int row) { 1459 return getSelectionModel().isRowSelected(row); 1460 } 1461 1462 1477 public Enumeration<TreePath> getExpandedDescendants(TreePath parent) { 1478 if(!isExpanded(parent)) 1479 return null; 1480 1481 Enumeration toggledPaths = expandedState.keys(); 1482 Vector elements = null; 1483 TreePath path; 1484 Object value; 1485 1486 if(toggledPaths != null) { 1487 while(toggledPaths.hasMoreElements()) { 1488 path = (TreePath)toggledPaths.nextElement(); 1489 value = expandedState.get(path); 1490 if(path != parent && value != null && 1494 ((Boolean )value).booleanValue() && 1495 parent.isDescendant(path) && isVisible(path)) { 1496 if (elements == null) { 1497 elements = new Vector(); 1498 } 1499 elements.addElement(path); 1500 } 1501 } 1502 } 1503 if (elements == null) { 1504 Set<TreePath> empty = Collections.emptySet(); 1505 return Collections.enumeration(empty); 1506 } 1507 return elements.elements(); 1508 } 1509 1510 1515 public boolean hasBeenExpanded(TreePath path) { 1516 return (path != null && expandedState.get(path) != null); 1517 } 1518 1519 1526 public boolean isExpanded(TreePath path) { 1527 if(path == null) 1528 return false; 1529 1530 Object value = expandedState.get(path); 1532 1533 if(value == null || !((Boolean )value).booleanValue()) 1534 return false; 1535 1536 TreePath parentPath = path.getParentPath(); 1538 1539 if(parentPath != null) 1540 return isExpanded(parentPath); 1541 return true; 1542 } 1543 1544 1552 public boolean isExpanded(int row) { 1553 TreeUI tree = getUI(); 1554 1555 if(tree != null) { 1556 TreePath path = tree.getPathForRow(this, row); 1557 1558 if(path != null) { 1559 Boolean value = (Boolean )expandedState.get(path); 1560 1561 return (value != null && value.booleanValue()); 1562 } 1563 } 1564 return false; 1565 } 1566 1567 1576 public boolean isCollapsed(TreePath path) { 1577 return !isExpanded(path); 1578 } 1579 1580 1587 public boolean isCollapsed(int row) { 1588 return !isExpanded(row); 1589 } 1590 1591 1596 public void makeVisible(TreePath path) { 1597 if(path != null) { 1598 TreePath parentPath = path.getParentPath(); 1599 1600 if(parentPath != null) { 1601 expandPath(parentPath); 1602 } 1603 } 1604 } 1605 1606 1613 public boolean isVisible(TreePath path) { 1614 if(path != null) { 1615 TreePath parentPath = path.getParentPath(); 1616 1617 if(parentPath != null) 1618 return isExpanded(parentPath); 1619 return true; 1621 } 1622 return false; 1623 } 1624 1625 1638 public Rectangle getPathBounds(TreePath path) { 1639 TreeUI tree = getUI(); 1640 1641 if(tree != null) 1642 return tree.getPathBounds(this, path); 1643 return null; 1644 } 1645 1646 1654 public Rectangle getRowBounds(int row) { 1655 return getPathBounds(getPathForRow(row)); 1656 } 1657 1658 1667 public void scrollPathToVisible(TreePath path) { 1668 if(path != null) { 1669 makeVisible(path); 1670 1671 Rectangle bounds = getPathBounds(path); 1672 1673 if(bounds != null) { 1674 scrollRectToVisible(bounds); 1675 if (accessibleContext != null) { 1676 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange(); 1677 } 1678 } 1679 } 1680 } 1681 1682 1691 public void scrollRowToVisible(int row) { 1692 scrollPathToVisible(getPathForRow(row)); 1693 } 1694 1695 1704 public TreePath getPathForRow(int row) { 1705 TreeUI tree = getUI(); 1706 1707 if(tree != null) 1708 return tree.getPathForRow(this, row); 1709 return null; 1710 } 1711 1712 1721 public int getRowForPath(TreePath path) { 1722 TreeUI tree = getUI(); 1723 1724 if(tree != null) 1725 return tree.getRowForPath(this, path); 1726 return -1; 1727 } 1728 1729 1736 public void expandPath(TreePath path) { 1737 TreeModel model = getModel(); 1739 1740 if(path != null && model != null && 1741 !model.isLeaf(path.getLastPathComponent())) { 1742 setExpandedState(path, true); 1743 } 1744 } 1745 1746 1756 public void expandRow(int row) { 1757 expandPath(getPathForRow(row)); 1758 } 1759 1760 1766 public void collapsePath(TreePath path) { 1767 setExpandedState(path, false); 1768 } 1769 1770 1779 public void collapseRow(int row) { 1780 collapsePath(getPathForRow(row)); 1781 } 1782 1783 1792 public TreePath getPathForLocation(int x, int y) { 1793 TreePath closestPath = getClosestPathForLocation(x, y); 1794 1795 if(closestPath != null) { 1796 Rectangle pathBounds = getPathBounds(closestPath); 1797 1798 if(pathBounds != null && 1799 x >= pathBounds.x && x < (pathBounds.x + pathBounds.width) && 1800 y >= pathBounds.y && y < (pathBounds.y + pathBounds.height)) 1801 return closestPath; 1802 } 1803 return null; 1804 } 1805 1806 1817 public int getRowForLocation(int x, int y) { 1818 return getRowForPath(getPathForLocation(x, y)); 1819 } 1820 1821 1838 public TreePath getClosestPathForLocation(int x, int y) { 1839 TreeUI tree = getUI(); 1840 1841 if(tree != null) 1842 return tree.getClosestPathForLocation(this, x, y); 1843 return null; 1844 } 1845 1846 1863 public int getClosestRowForLocation(int x, int y) { 1864 return getRowForPath(getClosestPathForLocation(x, y)); 1865 } 1866 1867 1874 public boolean isEditing() { 1875 TreeUI tree = getUI(); 1876 1877 if(tree != null) 1878 return tree.isEditing(this); 1879 return false; 1880 } 1881 1882 1897 public boolean stopEditing() { 1898 TreeUI tree = getUI(); 1899 1900 if(tree != null) 1901 return tree.stopEditing(this); 1902 return false; 1903 } 1904 1905 1909 public void cancelEditing() { 1910 TreeUI tree = getUI(); 1911 1912 if(tree != null) 1913 tree.cancelEditing(this); 1914 } 1915 1916 1924 public void startEditingAtPath(TreePath path) { 1925 TreeUI tree = getUI(); 1926 1927 if(tree != null) 1928 tree.startEditingAtPath(this, path); 1929 } 1930 1931 1936 public TreePath getEditingPath() { 1937 TreeUI tree = getUI(); 1938 1939 if(tree != null) 1940 return tree.getEditingPath(this); 1941 return null; 1942 } 1943 1944 1953 1965 public void setSelectionModel(TreeSelectionModel selectionModel) { 1966 if(selectionModel == null) 1967 selectionModel = EmptySelectionModel.sharedInstance(); 1968 1969 TreeSelectionModel oldValue = this.selectionModel; 1970 1971 if (this.selectionModel != null && selectionRedirector != null) { 1972 this.selectionModel.removeTreeSelectionListener 1973 (selectionRedirector); 1974 } 1975 if (accessibleContext != null) { 1976 this.selectionModel.removeTreeSelectionListener((TreeSelectionListener)accessibleContext); 1977 selectionModel.addTreeSelectionListener((TreeSelectionListener)accessibleContext); 1978 } 1979 1980 this.selectionModel = selectionModel; 1981 if (selectionRedirector != null) { 1982 this.selectionModel.addTreeSelectionListener(selectionRedirector); 1983 } 1984 firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, 1985 this.selectionModel); 1986 1987 if (accessibleContext != null) { 1988 accessibleContext.firePropertyChange( 1989 AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, 1990 Boolean.valueOf(false), Boolean.valueOf(true)); 1991 } 1992 } 1993 1994 2003 public TreeSelectionModel getSelectionModel() { 2004 return selectionModel; 2005 } 2006 2007 2019 protected TreePath[] getPathBetweenRows(int index0, int index1) { 2020 int newMinIndex, newMaxIndex; 2021 TreeUI tree = getUI(); 2022 2023 newMinIndex = Math.min(index0, index1); 2024 newMaxIndex = Math.max(index0, index1); 2025 2026 if(tree != null) { 2027 TreePath[] selection = new TreePath[newMaxIndex - 2028 newMinIndex + 1]; 2029 2030 for(int counter = newMinIndex; counter <= newMaxIndex; counter++) 2031 selection[counter - newMinIndex] = tree.getPathForRow(this, 2032 counter); 2033 return selection; 2034 } 2035 return null; 2036 } 2037 2038 2045 public void setSelectionInterval(int index0, int index1) { 2046 TreePath[] paths = getPathBetweenRows(index0, index1); 2047 2048 this.getSelectionModel().setSelectionPaths(paths); 2049 } 2050 2051 2059 public void addSelectionInterval(int index0, int index1) { 2060 TreePath[] paths = getPathBetweenRows(index0, index1); 2061 2062 this.getSelectionModel().addSelectionPaths(paths); 2063 } 2064 2065 2073 public void removeSelectionInterval(int index0, int index1) { 2074 TreePath[] paths = getPathBetweenRows(index0, index1); 2075 2076 this.getSelectionModel().removeSelectionPaths(paths); 2077 } 2078 2079 2085 public void removeSelectionPath(TreePath path) { 2086 this.getSelectionModel().removeSelectionPath(path); 2087 } 2088 2089 2096 public void removeSelectionPaths(TreePath[] paths) { 2097 this.getSelectionModel().removeSelectionPaths(paths); 2098 } 2099 2100 2106 public void removeSelectionRow(int row) { 2107 int[] rows = { row }; 2108 2109 removeSelectionRows(rows); 2110 } 2111 2112 2119 public void removeSelectionRows(int[] rows) { 2120 TreeUI ui = getUI(); 2121 2122 if(ui != null && rows != null) { 2123 int numRows = rows.length; 2124 TreePath[] paths = new TreePath[numRows]; 2125 2126 for(int counter = 0; counter < numRows; counter++) 2127 paths[counter] = ui.getPathForRow(this, rows[counter]); 2128 removeSelectionPaths(paths); 2129 } 2130 } 2131 2132 2135 public void clearSelection() { 2136 getSelectionModel().clearSelection(); 2137 } 2138 2139 2144 public boolean isSelectionEmpty() { 2145 return getSelectionModel().isSelectionEmpty(); 2146 } 2147 2148 2155 public void addTreeExpansionListener(TreeExpansionListener tel) { 2156 if (settingUI) { 2157 uiTreeExpansionListener = tel; 2158 } 2159 listenerList.add(TreeExpansionListener.class, tel); 2160 } 2161 2162 2167 public void removeTreeExpansionListener(TreeExpansionListener tel) { 2168 listenerList.remove(TreeExpansionListener.class, tel); 2169 if (uiTreeExpansionListener == tel) { 2170 uiTreeExpansionListener = null; 2171 } 2172 } 2173 2174 2182 public TreeExpansionListener[] getTreeExpansionListeners() { 2183 return (TreeExpansionListener[])listenerList.getListeners( 2184 TreeExpansionListener.class); 2185 } 2186 2187 2194 public void addTreeWillExpandListener(TreeWillExpandListener tel) { 2195 listenerList.add(TreeWillExpandListener.class, tel); 2196 } 2197 2198 2203 public void removeTreeWillExpandListener(TreeWillExpandListener tel) { 2204 listenerList.remove(TreeWillExpandListener.class, tel); 2205 } 2206 2207 2215 public TreeWillExpandListener[] getTreeWillExpandListeners() { 2216 return (TreeWillExpandListener[])listenerList.getListeners( 2217 TreeWillExpandListener.class); 2218 } 2219 2220 2229 public void fireTreeExpanded(TreePath path) { 2230 Object [] listeners = listenerList.getListenerList(); 2232 TreeExpansionEvent e = null; 2233 if (uiTreeExpansionListener != null) { 2234 e = new TreeExpansionEvent(this, path); 2235 uiTreeExpansionListener.treeExpanded(e); 2236 } 2237 for (int i = listeners.length-2; i>=0; i-=2) { 2240 if (listeners[i]==TreeExpansionListener.class && 2241 listeners[i + 1] != uiTreeExpansionListener) { 2242 if (e == null) 2244 e = new TreeExpansionEvent(this, path); 2245 ((TreeExpansionListener)listeners[i+1]). 2246 treeExpanded(e); 2247 } 2248 } 2249 } 2250 2251 2260 public void fireTreeCollapsed(TreePath path) { 2261 Object [] listeners = listenerList.getListenerList(); 2263 TreeExpansionEvent e = null; 2264 if (uiTreeExpansionListener != null) { 2265 e = new TreeExpansionEvent(this, path); 2266 uiTreeExpansionListener.treeCollapsed(e); 2267 } 2268 for (int i = listeners.length-2; i>=0; i-=2) { 2271 if (listeners[i]==TreeExpansionListener.class && 2272 listeners[i + 1] != uiTreeExpansionListener) { 2273 if (e == null) 2275 e = new TreeExpansionEvent(this, path); 2276 ((TreeExpansionListener)listeners[i+1]). 2277 treeCollapsed(e); 2278 } 2279 } 2280 } 2281 2282 2291 public void fireTreeWillExpand(TreePath path) throws ExpandVetoException { 2292 Object [] listeners = listenerList.getListenerList(); 2294 TreeExpansionEvent e = null; 2295 for (int i = listeners.length-2; i>=0; i-=2) { 2298 if (listeners[i]==TreeWillExpandListener.class) { 2299 if (e == null) 2301 e = new TreeExpansionEvent(this, path); 2302 ((TreeWillExpandListener)listeners[i+1]). 2303 treeWillExpand(e); 2304 } 2305 } 2306 } 2307 2308 2317 public void fireTreeWillCollapse(TreePath path) throws ExpandVetoException { 2318 Object [] listeners = listenerList.getListenerList(); 2320 TreeExpansionEvent e = null; 2321 for (int i = listeners.length-2; i>=0; i-=2) { 2324 if (listeners[i]==TreeWillExpandListener.class) { 2325 if (e == null) 2327 e = new TreeExpansionEvent(this, path); 2328 ((TreeWillExpandListener)listeners[i+1]). 2329 treeWillCollapse(e); 2330 } 2331 } 2332 } 2333 2334 2341 public void addTreeSelectionListener(TreeSelectionListener tsl) { 2342 listenerList.add(TreeSelectionListener.class,tsl); 2343 if(listenerList.getListenerCount(TreeSelectionListener.class) != 0 2344 && selectionRedirector == null) { 2345 selectionRedirector = new TreeSelectionRedirector(); 2346 selectionModel.addTreeSelectionListener(selectionRedirector); 2347 } 2348 } 2349 2350 2355 public void removeTreeSelectionListener(TreeSelectionListener tsl) { 2356 listenerList.remove(TreeSelectionListener.class,tsl); 2357 if(listenerList.getListenerCount(TreeSelectionListener.class) == 0 2358 && selectionRedirector != null) { 2359 selectionModel.removeTreeSelectionListener 2360 (selectionRedirector); 2361 selectionRedirector = null; 2362 } 2363 } 2364 2365 2373 public TreeSelectionListener[] getTreeSelectionListeners() { 2374 return (TreeSelectionListener[])listenerList.getListeners( 2375 TreeSelectionListener.class); 2376 } 2377 2378 2388 protected void fireValueChanged(TreeSelectionEvent e) { 2389 Object [] listeners = listenerList.getListenerList(); 2391 for (int i = listeners.length-2; i>=0; i-=2) { 2394 if (listeners[i]==TreeSelectionListener.class) { 2396 ((TreeSelectionListener)listeners[i+1]).valueChanged(e); 2400 } 2401 } 2402 } 2403 2404 2411 public void treeDidChange() { 2412 revalidate(); 2413 repaint(); 2414 } 2415 2416 2427 public void setVisibleRowCount(int newCount) { 2428 int oldCount = visibleRowCount; 2429 2430 visibleRowCount = newCount; 2431 firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldCount, 2432 visibleRowCount); 2433 invalidate(); 2434 if (accessibleContext != null) { 2435 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange(); 2436 } 2437 } 2438 2439 2444 public int getVisibleRowCount() { 2445 return visibleRowCount; 2446 } 2447 2448 2451 private void expandRoot() { 2452 TreeModel model = getModel(); 2453 2454 if(model != null && model.getRoot() != null) { 2455 expandPath(new TreePath(model.getRoot())); 2456 } 2457 } 2458 2459 2475 public TreePath getNextMatch(String prefix, int startingRow, 2476 Position.Bias bias) { 2477 2478 int max = getRowCount(); 2479 if (prefix == null) { 2480 throw new IllegalArgumentException (); 2481 } 2482 if (startingRow < 0 || startingRow >= max) { 2483 throw new IllegalArgumentException (); 2484 } 2485 prefix = prefix.toUpperCase(); 2486 2487 int increment = (bias == Position.Bias.Forward) ? 1 : -1; 2490 int row = startingRow; 2491 do { 2492 TreePath path = getPathForRow(row); 2493 String text = convertValueToText( 2494 path.getLastPathComponent(), isRowSelected(row), 2495 isExpanded(row), true, row, false); 2496 2497 if (text.toUpperCase().startsWith(prefix)) { 2498 return path; 2499 } 2500 row = (row + increment + max) % max; 2501 } while (row != startingRow); 2502 return null; 2503 } 2504 2505 private void writeObject(ObjectOutputStream s) throws IOException { 2507 Vector values = new Vector(); 2508 2509 s.defaultWriteObject(); 2510 if(cellRenderer != null && cellRenderer instanceof Serializable) { 2512 values.addElement("cellRenderer"); 2513 values.addElement(cellRenderer); 2514 } 2515 if(cellEditor != null && cellEditor instanceof Serializable) { 2517 values.addElement("cellEditor"); 2518 values.addElement(cellEditor); 2519 } 2520 if(treeModel != null && treeModel instanceof Serializable) { 2522 values.addElement("treeModel"); 2523 values.addElement(treeModel); 2524 } 2525 if(selectionModel != null && selectionModel instanceof Serializable) { 2527 values.addElement("selectionModel"); 2528 values.addElement(selectionModel); 2529 } 2530 2531 Object expandedData = getArchivableExpandedState(); 2532 2533 if(expandedData != null) { 2534 values.addElement("expandedState"); 2535 values.addElement(expandedData); 2536 } 2537 2538 s.writeObject(values); 2539 if (getUIClassID().equals(uiClassID)) { 2540 byte count = JComponent.getWriteObjCounter(this); 2541 JComponent.setWriteObjCounter(this, --count); 2542 if (count == 0 && ui != null) { 2543 ui.installUI(this); 2544 } 2545 } 2546 } 2547 2548 private void readObject(ObjectInputStream s) 2549 throws IOException, ClassNotFoundException { 2550 s.defaultReadObject(); 2551 2552 2554 expandedState = new Hashtable(); 2555 2556 expandedStack = new Stack(); 2557 2558 Vector values = (Vector)s.readObject(); 2559 int indexCounter = 0; 2560 int maxCounter = values.size(); 2561 2562 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2563 equals("cellRenderer")) { 2564 cellRenderer = (TreeCellRenderer)values.elementAt(++indexCounter); 2565 indexCounter++; 2566 } 2567 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2568 equals("cellEditor")) { 2569 cellEditor = (TreeCellEditor)values.elementAt(++indexCounter); 2570 indexCounter++; 2571 } 2572 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2573 equals("treeModel")) { 2574 treeModel = (TreeModel)values.elementAt(++indexCounter); 2575 indexCounter++; 2576 } 2577 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2578 equals("selectionModel")) { 2579 selectionModel = (TreeSelectionModel)values.elementAt(++indexCounter); 2580 indexCounter++; 2581 } 2582 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2583 equals("expandedState")) { 2584 unarchiveExpandedState(values.elementAt(++indexCounter)); 2585 indexCounter++; 2586 } 2587 if(listenerList.getListenerCount(TreeSelectionListener.class) != 0) { 2589 selectionRedirector = new TreeSelectionRedirector(); 2590 selectionModel.addTreeSelectionListener(selectionRedirector); 2591 } 2592 if(treeModel != null) { 2594 treeModelListener = createTreeModelListener(); 2595 if(treeModelListener != null) 2596 treeModel.addTreeModelListener(treeModelListener); 2597 } 2598 } 2599 2600 2605 private Object getArchivableExpandedState() { 2606 TreeModel model = getModel(); 2607 2608 if(model != null) { 2609 Enumeration paths = expandedState.keys(); 2610 2611 if(paths != null) { 2612 Vector state = new Vector(); 2613 2614 while(paths.hasMoreElements()) { 2615 TreePath path = (TreePath)paths.nextElement(); 2616 Object archivePath; 2617 2618 try { 2619 archivePath = getModelIndexsForPath(path); 2620 } catch (Error error) { 2621 archivePath = null; 2622 } 2623 if(archivePath != null) { 2624 state.addElement(archivePath); 2625 state.addElement(expandedState.get(path)); 2626 } 2627 } 2628 return state; 2629 } 2630 } 2631 return null; 2632 } 2633 2634 2638 private void unarchiveExpandedState(Object state) { 2639 if(state instanceof Vector) { 2640 Vector paths = (Vector)state; 2641 2642 for(int counter = paths.size() - 1; counter >= 0; counter--) { 2643 Boolean eState = (Boolean )paths.elementAt(counter--); 2644 TreePath path; 2645 2646 try { 2647 path = getPathForIndexs((int[])paths.elementAt(counter)); 2648 if(path != null) 2649 expandedState.put(path, eState); 2650 } catch (Error error) {} 2651 } 2652 } 2653 } 2654 2655 2661 private int[] getModelIndexsForPath(TreePath path) { 2662 if(path != null) { 2663 TreeModel model = getModel(); 2664 int count = path.getPathCount(); 2665 int[] indexs = new int[count - 1]; 2666 Object parent = model.getRoot(); 2667 2668 for(int counter = 1; counter < count; counter++) { 2669 indexs[counter - 1] = model.getIndexOfChild 2670 (parent, path.getPathComponent(counter)); 2671 parent = path.getPathComponent(counter); 2672 if(indexs[counter - 1] < 0) 2673 return null; 2674 } 2675 return indexs; 2676 } 2677 return null; 2678 } 2679 2680 2686 private TreePath getPathForIndexs(int[] indexs) { 2687 if(indexs == null) 2688 return null; 2689 2690 TreeModel model = getModel(); 2691 2692 if(model == null) 2693 return null; 2694 2695 int count = indexs.length; 2696 Object parent = model.getRoot(); 2697 TreePath parentPath = new TreePath(parent); 2698 2699 for(int counter = 0; counter < count; counter++) { 2700 parent = model.getChild(parent, indexs[counter]); 2701 if(parent == null) 2702 return null; 2703 parentPath = parentPath.pathByAddingChild(parent); 2704 } 2705 return parentPath; 2706 } 2707 2708 2721 protected static class EmptySelectionModel extends 2722 DefaultTreeSelectionModel 2723 { 2724 2725 protected static final EmptySelectionModel sharedInstance = 2726 new EmptySelectionModel(); 2727 2728 2729 static public EmptySelectionModel sharedInstance() { 2730 return sharedInstance; 2731 } 2732 2733 2734 public void setSelectionPaths(TreePath[] pPaths) {} 2735 2736 public void addSelectionPaths(TreePath[] paths) {} 2737 2738 public void removeSelectionPaths(TreePath[] paths) {} 2739 } 2740 2741 2742 2756 protected class TreeSelectionRedirector implements Serializable, 2757 TreeSelectionListener 2758 { 2759 2766 public void valueChanged(TreeSelectionEvent e) { 2767 TreeSelectionEvent newE; 2768 2769 newE = (TreeSelectionEvent)e.cloneWithSource(JTree.this); 2770 fireValueChanged(newE); 2771 } 2772 } 2774 2778 2785 public Dimension getPreferredScrollableViewportSize() { 2786 int width = getPreferredSize().width; 2787 int visRows = getVisibleRowCount(); 2788 int height = -1; 2789 2790 if(isFixedRowHeight()) 2791 height = visRows * getRowHeight(); 2792 else { 2793 TreeUI ui = getUI(); 2794 2795 if (ui != null && visRows > 0) { 2796 int rc = ui.getRowCount(this); 2797 2798 if (rc >= visRows) { 2799 Rectangle bounds = getRowBounds(visRows - 1); 2800 if (bounds != null) { 2801 height = bounds.y + bounds.height; 2802 } 2803 } 2804 else if (rc > 0) { 2805 Rectangle bounds = getRowBounds(0); 2806 if (bounds != null) { 2807 height = bounds.height * visRows; 2808 } 2809 } 2810 } 2811 if (height == -1) { 2812 height = 16 * visRows; 2813 } 2814 } 2815 return new Dimension(width, height); 2816 } 2817 2818 2832 public int getScrollableUnitIncrement(Rectangle visibleRect, 2833 int orientation, int direction) { 2834 if(orientation == SwingConstants.VERTICAL) { 2835 Rectangle rowBounds; 2836 int firstIndex = getClosestRowForLocation 2837 (0, visibleRect.y); 2838 2839 if(firstIndex != -1) { 2840 rowBounds = getRowBounds(firstIndex); 2841 if(rowBounds.y != visibleRect.y) { 2842 if(direction < 0) { 2843 return Math.max(0, (visibleRect.y - rowBounds.y)); 2845 } 2846 return (rowBounds.y + rowBounds.height - visibleRect.y); 2847 } 2848 if(direction < 0) { if(firstIndex != 0) { 2850 rowBounds = getRowBounds(firstIndex - 1); 2851 return rowBounds.height; 2852 } 2853 } 2854 else { 2855 return rowBounds.height; 2856 } 2857 } 2858 return 0; 2859 } 2860 return 4; 2861 } 2862 2863 2864 2876 public int getScrollableBlockIncrement(Rectangle visibleRect, 2877 int orientation, int direction) { 2878 return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : 2879 visibleRect.width; 2880 } 2881 2882 2891 public boolean getScrollableTracksViewportWidth() { 2892 if (getParent() instanceof JViewport ) { 2893 return (((JViewport )getParent()).getWidth() > getPreferredSize().width); 2894 } 2895 return false; 2896 } 2897 2898 2907 public boolean getScrollableTracksViewportHeight() { 2908 if (getParent() instanceof JViewport ) { 2909 return (((JViewport )getParent()).getHeight() > getPreferredSize().height); 2910 } 2911 return false; 2912 } 2913 2914 2923 protected void setExpandedState(TreePath path, boolean state) { 2924 if(path != null) { 2925 Stack stack; 2927 TreePath parentPath = path.getParentPath(); 2928 2929 if (expandedStack.size() == 0) { 2930 stack = new Stack(); 2931 } 2932 else { 2933 stack = (Stack)expandedStack.pop(); 2934 } 2935 2936 try { 2937 while(parentPath != null) { 2938 if(isExpanded(parentPath)) { 2939 parentPath = null; 2940 } 2941 else { 2942 stack.push(parentPath); 2943 parentPath = parentPath.getParentPath(); 2944 } 2945 } 2946 for(int counter = stack.size() - 1; counter >= 0; counter--) { 2947 parentPath = (TreePath)stack.pop(); 2948 if(!isExpanded(parentPath)) { 2949 try { 2950 fireTreeWillExpand(parentPath); 2951 } catch (ExpandVetoException eve) { 2952 return; 2954 } 2955 expandedState.put(parentPath, Boolean.TRUE); 2956 fireTreeExpanded(parentPath); 2957 if (accessibleContext != null) { 2958 ((AccessibleJTree)accessibleContext). 2959 fireVisibleDataPropertyChange(); 2960 } 2961 } 2962 } 2963 } 2964 finally { 2965 if (expandedStack.size() < TEMP_STACK_SIZE) { 2966 stack.removeAllElements(); 2967 expandedStack.push(stack); 2968 } 2969 } 2970 if(!state) { 2971 Object cValue = expandedState.get(path); 2973 2974 if(cValue != null && ((Boolean )cValue).booleanValue()) { 2975 try { 2976 fireTreeWillCollapse(path); 2977 } 2978 catch (ExpandVetoException eve) { 2979 return; 2980 } 2981 expandedState.put(path, Boolean.FALSE); 2982 fireTreeCollapsed(path); 2983 if (removeDescendantSelectedPaths(path, false) && 2984 !isPathSelected(path)) { 2985 addSelectionPath(path); 2987 } 2988 if (accessibleContext != null) { 2989 ((AccessibleJTree)accessibleContext). 2990 fireVisibleDataPropertyChange(); 2991 } 2992 } 2993 } 2994 else { 2995 Object cValue = expandedState.get(path); 2997 2998 if(cValue == null || !((Boolean )cValue).booleanValue()) { 2999 try { 3000 fireTreeWillExpand(path); 3001 } 3002 catch (ExpandVetoException eve) { 3003 return; 3004 } 3005 expandedState.put(path, Boolean.TRUE); 3006 fireTreeExpanded(path); 3007 if (accessibleContext != null) { 3008 ((AccessibleJTree)accessibleContext). 3009 fireVisibleDataPropertyChange(); 3010 } 3011 } 3012 } 3013 } 3014 } 3015 3016 3021 protected Enumeration<TreePath> 3022 getDescendantToggledPaths(TreePath parent) 3023 { 3024 if(parent == null) 3025 return null; 3026 3027 Vector descendants = new Vector(); 3028 Enumeration nodes = expandedState.keys(); 3029 TreePath path; 3030 3031 while(nodes.hasMoreElements()) { 3032 path = (TreePath)nodes.nextElement(); 3033 if(parent.isDescendant(path)) 3034 descendants.addElement(path); 3035 } 3036 return descendants.elements(); 3037 } 3038 3039 3044 protected void 3045 removeDescendantToggledPaths(Enumeration<TreePath> toRemove) 3046 { 3047 if(toRemove != null) { 3048 while(toRemove.hasMoreElements()) { 3049 Enumeration descendants = getDescendantToggledPaths 3050 ((TreePath)toRemove.nextElement()); 3051 3052 if(descendants != null) { 3053 while(descendants.hasMoreElements()) { 3054 expandedState.remove(descendants.nextElement()); 3055 } 3056 } 3057 } 3058 } 3059 } 3060 3061 3065 protected void clearToggledPaths() { 3066 expandedState.clear(); 3067 } 3068 3069 3078 protected TreeModelListener createTreeModelListener() { 3079 return new TreeModelHandler(); 3080 } 3081 3082 3090 protected boolean removeDescendantSelectedPaths(TreePath path, 3091 boolean includePath) { 3092 TreePath[] toRemove = getDescendantSelectedPaths(path, includePath); 3093 3094 if (toRemove != null) { 3095 getSelectionModel().removeSelectionPaths(toRemove); 3096 return true; 3097 } 3098 return false; 3099 } 3100 3101 3105 private TreePath[] getDescendantSelectedPaths(TreePath path, 3106 boolean includePath) { 3107 TreeSelectionModel sm = getSelectionModel(); 3108 TreePath[] selPaths = (sm != null) ? sm.getSelectionPaths() : 3109 null; 3110 3111 if(selPaths != null) { 3112 boolean shouldRemove = false; 3113 3114 for(int counter = selPaths.length - 1; counter >= 0; counter--) { 3115 if(selPaths[counter] != null && 3116 path.isDescendant(selPaths[counter]) && 3117 (!path.equals(selPaths[counter]) || includePath)) 3118 shouldRemove = true; 3119 else 3120 selPaths[counter] = null; 3121 } 3122 if(!shouldRemove) { 3123 selPaths = null; 3124 } 3125 return selPaths; 3126 } 3127 return null; 3128 } 3129 3130 3134 void removeDescendantSelectedPaths(TreeModelEvent e) { 3135 TreePath pPath = e.getTreePath(); 3136 Object [] oldChildren = e.getChildren(); 3137 TreeSelectionModel sm = getSelectionModel(); 3138 3139 if (sm != null && pPath != null && oldChildren != null && 3140 oldChildren.length > 0) { 3141 for (int counter = oldChildren.length - 1; counter >= 0; 3142 counter--) { 3143 removeDescendantSelectedPaths(pPath.pathByAddingChild 3146 (oldChildren[counter]), true); 3147 } 3148 } 3149 } 3150 3151 3152 3156 protected class TreeModelHandler implements TreeModelListener { 3157 public void treeNodesChanged(TreeModelEvent e) { } 3158 3159 public void treeNodesInserted(TreeModelEvent e) { } 3160 3161 public void treeStructureChanged(TreeModelEvent e) { 3162 if(e == null) 3163 return; 3164 3165 TreePath parent = e.getTreePath(); 3170 3171 if(parent == null) 3172 return; 3173 3174 if (parent.getPathCount() == 1) { 3175 clearToggledPaths(); 3177 if(treeModel.getRoot() != null && 3178 !treeModel.isLeaf(treeModel.getRoot())) { 3179 expandedState.put(parent, Boolean.TRUE); 3181 } 3182 } 3183 else if(expandedState.get(parent) != null) { 3184 Vector<TreePath> toRemove = new Vector<TreePath>(1); 3185 boolean isExpanded = isExpanded(parent); 3186 3187 toRemove.addElement(parent); 3188 removeDescendantToggledPaths(toRemove.elements()); 3189 if(isExpanded) { 3190 TreeModel model = getModel(); 3191 3192 if(model == null || model.isLeaf 3193 (parent.getLastPathComponent())) 3194 collapsePath(parent); 3195 else 3196 expandedState.put(parent, Boolean.TRUE); 3197 } 3198 } 3199 removeDescendantSelectedPaths(parent, false); 3200 } 3201 3202 public void treeNodesRemoved(TreeModelEvent e) { 3203 if(e == null) 3204 return; 3205 3206 TreePath parent = e.getTreePath(); 3207 Object [] children = e.getChildren(); 3208 3209 if(children == null) 3210 return; 3211 3212 TreePath rPath; 3213 Vector<TreePath> toRemove 3214 = new Vector<TreePath>(Math.max(1, children.length)); 3215 3216 for(int counter = children.length - 1; counter >= 0; counter--) { 3217 rPath = parent.pathByAddingChild(children[counter]); 3218 if(expandedState.get(rPath) != null) 3219 toRemove.addElement(rPath); 3220 } 3221 if(toRemove.size() > 0) 3222 removeDescendantToggledPaths(toRemove.elements()); 3223 3224 TreeModel model = getModel(); 3225 3226 if(model == null || model.isLeaf(parent.getLastPathComponent())) 3227 expandedState.remove(parent); 3228 3229 removeDescendantSelectedPaths(e); 3230 } 3231 } 3232 3233 3234 3249 public static class DynamicUtilTreeNode extends DefaultMutableTreeNode { 3250 3254 protected boolean hasChildren; 3255 3256 protected Object childValue; 3257 3258 protected boolean loadedChildren; 3259 3260 3267 public static void createChildren(DefaultMutableTreeNode parent, 3268 Object children) { 3269 if(children instanceof Vector) { 3270 Vector childVector = (Vector)children; 3271 3272 for(int counter = 0, maxCounter = childVector.size(); 3273 counter < maxCounter; counter++) 3274 parent.add(new DynamicUtilTreeNode 3275 (childVector.elementAt(counter), 3276 childVector.elementAt(counter))); 3277 } 3278 else if(children instanceof Hashtable) { 3279 Hashtable childHT = (Hashtable)children; 3280 Enumeration keys = childHT.keys(); 3281 Object aKey; 3282 3283 while(keys.hasMoreElements()) { 3284 aKey = keys.nextElement(); 3285 parent.add(new DynamicUtilTreeNode(aKey, 3286 childHT.get(aKey))); 3287 } 3288 } 3289 else if(children instanceof Object []) { 3290 Object [] childArray = (Object [])children; 3291 3292 for(int counter = 0, maxCounter = childArray.length; 3293 counter < maxCounter; counter++) 3294 parent.add(new DynamicUtilTreeNode(childArray[counter], 3295 childArray[counter])); 3296 } 3297 } 3298 3299 3316 public DynamicUtilTreeNode(Object value, Object children) { 3317 super(value); 3318 loadedChildren = false; 3319 childValue = children; 3320 if(children != null) { 3321 if(children instanceof Vector) 3322 setAllowsChildren(true); 3323 else if(children instanceof Hashtable) 3324 setAllowsChildren(true); 3325 else if(children instanceof Object []) 3326 setAllowsChildren(true); 3327 else 3328 setAllowsChildren(false); 3329 } 3330 else 3331 setAllowsChildren(false); 3332 } 3333 3334 3341 public boolean isLeaf() { 3342 return !getAllowsChildren(); 3343 } 3344 3345 3350 public int getChildCount() { 3351 if(!loadedChildren) 3352 loadChildren(); 3353 return super.getChildCount(); 3354 } 3355 3356 3364 protected void loadChildren() { 3365 loadedChildren = true; 3366 createChildren(this, childValue); 3367 } 3368 3369 3372 public TreeNode getChildAt(int index) { 3373 if(!loadedChildren) 3374 loadChildren(); 3375 return super.getChildAt(index); 3376 } 3377 3378 3381 public Enumeration children() { 3382 if(!loadedChildren) 3383 loadChildren(); 3384 return super.children(); 3385 } 3386 } 3387 3388 void setUIProperty(String propertyName, Object value) { 3389 if (propertyName == "rowHeight") { 3390 if (!rowHeightSet) { 3391 setRowHeight(((Number )value).intValue()); 3392 rowHeightSet = false; 3393 } 3394 } else if (propertyName == "scrollsOnExpand") { 3395 if (!scrollsOnExpandSet) { 3396 setScrollsOnExpand(((Boolean )value).booleanValue()); 3397 scrollsOnExpandSet = false; 3398 } 3399 } else if (propertyName == "showsRootHandles") { 3400 if (!showsRootHandlesSet) { 3401 setShowsRootHandles(((Boolean )value).booleanValue()); 3402 showsRootHandlesSet = false; 3403 } 3404 } else { 3405 super.setUIProperty(propertyName, value); 3406 } 3407 } 3408 3409 3410 3420 protected String paramString() { 3421 String rootVisibleString = (rootVisible ? 3422 "true" : "false"); 3423 String showsRootHandlesString = (showsRootHandles ? 3424 "true" : "false"); 3425 String editableString = (editable ? 3426 "true" : "false"); 3427 String largeModelString = (largeModel ? 3428 "true" : "false"); 3429 String invokesStopCellEditingString = (invokesStopCellEditing ? 3430 "true" : "false"); 3431 String scrollsOnExpandString = (scrollsOnExpand ? 3432 "true" : "false"); 3433 3434 return super.paramString() + 3435 ",editable=" + editableString + 3436 ",invokesStopCellEditing=" + invokesStopCellEditingString + 3437 ",largeModel=" + largeModelString + 3438 ",rootVisible=" + rootVisibleString + 3439 ",rowHeight=" + rowHeight + 3440 ",scrollsOnExpand=" + scrollsOnExpandString + 3441 ",showsRootHandles=" + showsRootHandlesString + 3442 ",toggleClickCount=" + toggleClickCount + 3443 ",visibleRowCount=" + visibleRowCount; 3444 } 3445 3446 3450 3459 public AccessibleContext getAccessibleContext() { 3460 if (accessibleContext == null) { 3461 accessibleContext = new AccessibleJTree(); 3462 } 3463 return accessibleContext; 3464 } 3465 3466 3480 protected class AccessibleJTree extends AccessibleJComponent 3481 implements AccessibleSelection, TreeSelectionListener, 3482 TreeModelListener, TreeExpansionListener { 3483 3484 TreePath leadSelectionPath; 3485 Accessible leadSelectionAccessible; 3486 3487 public AccessibleJTree() { 3488 TreeModel model = JTree.this.getModel(); 3490 if (model != null) { 3491 model.addTreeModelListener(this); 3492 } 3493 JTree.this.addTreeExpansionListener(this); 3494 JTree.this.addTreeSelectionListener(this); 3495 leadSelectionPath = JTree.this.getLeadSelectionPath(); 3496 leadSelectionAccessible = (leadSelectionPath != null) 3497 ? new AccessibleJTreeNode(JTree.this, 3498 leadSelectionPath, 3499 JTree.this) 3500 : null; 3501 } 3502 3503 3510 public void valueChanged(TreeSelectionEvent e) { 3511 TreePath oldLeadSelectionPath = e.getOldLeadSelectionPath(); 3514 leadSelectionPath = e.getNewLeadSelectionPath(); 3515 3516 if (oldLeadSelectionPath != leadSelectionPath) { 3517 Accessible oldLSA = leadSelectionAccessible; 3520 leadSelectionAccessible = (leadSelectionPath != null) 3521 ? new AccessibleJTreeNode(JTree.this, 3522 leadSelectionPath, 3523 null) : null; 3525 firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, 3526 oldLSA, leadSelectionAccessible); 3527 } 3528 firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, 3529 Boolean.valueOf(false), Boolean.valueOf(true)); 3530 } 3531 3532 3541 public void fireVisibleDataPropertyChange() { 3542 firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, 3543 Boolean.valueOf(false), Boolean.valueOf(true)); 3544 } 3545 3546 3548 3553 public void treeNodesChanged(TreeModelEvent e) { 3554 fireVisibleDataPropertyChange(); 3555 } 3556 3557 3562 public void treeNodesInserted(TreeModelEvent e) { 3563 fireVisibleDataPropertyChange(); 3564 } 3565 3566 3571 public void treeNodesRemoved(TreeModelEvent e) { 3572 fireVisibleDataPropertyChange(); 3573 } 3574 3575 3580 public void treeStructureChanged(TreeModelEvent e) { 3581 fireVisibleDataPropertyChange(); 3582 } 3583 3584 3589 public void treeCollapsed(TreeExpansionEvent e) { 3590 fireVisibleDataPropertyChange(); 3591 TreePath path = e.getPath(); 3592 if (path != null) { 3593 AccessibleJTreeNode node = new AccessibleJTreeNode(JTree.this, 3596 path, 3597 null); 3598 PropertyChangeEvent pce = new PropertyChangeEvent(node, 3599 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3600 AccessibleState.EXPANDED, 3601 AccessibleState.COLLAPSED); 3602 firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3603 null, pce); 3604 } 3605 } 3606 3607 3612 public void treeExpanded(TreeExpansionEvent e) { 3613 fireVisibleDataPropertyChange(); 3614 TreePath path = e.getPath(); 3615 if (path != null) { 3616 AccessibleJTreeNode node = new AccessibleJTreeNode(JTree.this, 3620 path, 3621 null); 3622 PropertyChangeEvent pce = new PropertyChangeEvent(node, 3623 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3624 AccessibleState.COLLAPSED, 3625 AccessibleState.EXPANDED); 3626 firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3627 null, pce); 3628 } 3629 } 3630 3631 3632 private AccessibleContext getCurrentAccessibleContext() { 3633 Component c = getCurrentComponent(); 3634 if (c instanceof Accessible) { 3635 return (((Accessible) c).getAccessibleContext()); 3636 } else { 3637 return null; 3638 } 3639 } 3640 3641 private Component getCurrentComponent() { 3642 TreeModel model = JTree.this.getModel(); 3646 if (model == null) { 3647 return null; 3648 } 3649 TreePath path = new TreePath(model.getRoot()); 3650 if (JTree.this.isVisible(path)) { 3651 TreeCellRenderer r = JTree.this.getCellRenderer(); 3652 TreeUI ui = JTree.this.getUI(); 3653 if (ui != null) { 3654 int row = ui.getRowForPath(JTree.this, path); 3655 int lsr = JTree.this.getLeadSelectionRow(); 3656 boolean hasFocus = JTree.this.isFocusOwner() 3657 && (lsr == row); 3658 boolean selected = JTree.this.isPathSelected(path); 3659 boolean expanded = JTree.this.isExpanded(path); 3660 3661 return r.getTreeCellRendererComponent(JTree.this, 3662 model.getRoot(), selected, expanded, 3663 model.isLeaf(model.getRoot()), row, hasFocus); 3664 } 3665 } 3666 return null; 3667 } 3668 3669 3671 3678 public AccessibleRole getAccessibleRole() { 3679 return AccessibleRole.TREE; 3680 } 3681 3682 3691 public Accessible getAccessibleAt(Point p) { 3692 TreePath path = getClosestPathForLocation(p.x, p.y); 3693 if (path != null) { 3694 return new AccessibleJTreeNode(JTree.this, path, null); 3696 } else { 3697 return null; 3698 } 3699 } 3700 3701 3707 public int getAccessibleChildrenCount() { 3708 TreeModel model = JTree.this.getModel(); 3709 if (model != null) { 3710 return 1; 3711 } else { 3712 return 0; 3713 } 3714 } 3715 3716 3722 public Accessible getAccessibleChild(int i) { 3723 TreeModel model = JTree.this.getModel(); 3724 if (model != null) { 3725 if (i != 0) { 3726 return null; 3727 } else { 3728 Object [] objPath = {model.getRoot()}; 3729 TreePath path = new TreePath(objPath); 3730 return new AccessibleJTreeNode(JTree.this, path, 3731 JTree.this); 3732 } 3733 } 3734 return null; 3735 } 3736 3737 3744 public int getAccessibleIndexInParent() { 3745 return super.getAccessibleIndexInParent(); 3747 } 3748 3749 3758 public AccessibleSelection getAccessibleSelection() { 3759 return this; 3760 } 3761 3762 3768 public int getAccessibleSelectionCount() { 3769 Object [] rootPath = new Object [1]; 3770 rootPath[0] = treeModel.getRoot(); 3771 TreePath childPath = new TreePath(rootPath); 3772 if (JTree.this.isPathSelected(childPath)) { 3773 return 1; 3774 } else { 3775 return 0; 3776 } 3777 } 3778 3779 3788 public Accessible getAccessibleSelection(int i) { 3789 if (i == 0) { 3791 Object [] rootPath = new Object [1]; 3792 rootPath[0] = treeModel.getRoot(); 3793 TreePath childPath = new TreePath(rootPath); 3794 if (JTree.this.isPathSelected(childPath)) { 3795 return new AccessibleJTreeNode(JTree.this, childPath, JTree.this); 3796 } 3797 } 3798 return null; 3799 } 3800 3801 3807 public boolean isAccessibleChildSelected(int i) { 3808 if (i == 0) { 3810 Object [] rootPath = new Object [1]; 3811 rootPath[0] = treeModel.getRoot(); 3812 TreePath childPath = new TreePath(rootPath); 3813 return JTree.this.isPathSelected(childPath); 3814 } else { 3815 return false; 3816 } 3817 } 3818 3819 3828 public void addAccessibleSelection(int i) { 3829 TreeModel model = JTree.this.getModel(); 3830 if (model != null) { 3831 if (i == 0) { 3832 Object [] objPath = {model.getRoot()}; 3833 TreePath path = new TreePath(objPath); 3834 JTree.this.addSelectionPath(path); 3835 } 3836 } 3837 } 3838 3839 3846 public void removeAccessibleSelection(int i) { 3847 TreeModel model = JTree.this.getModel(); 3848 if (model != null) { 3849 if (i == 0) { 3850 Object [] objPath = {model.getRoot()}; 3851 TreePath path = new TreePath(objPath); 3852 JTree.this.removeSelectionPath(path); 3853 } 3854 } 3855 } 3856 3857 3861 public void clearAccessibleSelection() { 3862 int childCount = getAccessibleChildrenCount(); 3863 for (int i = 0; i < childCount; i++) { 3864 removeAccessibleSelection(i); 3865 } 3866 } 3867 3868 3872 public void selectAllAccessibleSelection() { 3873 TreeModel model = JTree.this.getModel(); 3874 if (model != null) { 3875 Object [] objPath = {model.getRoot()}; 3876 TreePath path = new TreePath(objPath); 3877 JTree.this.addSelectionPath(path); 3878 } 3879 } 3880 3881 3886 protected class AccessibleJTreeNode extends AccessibleContext 3887 implements Accessible, AccessibleComponent, AccessibleSelection, 3888 AccessibleAction { 3889 3890 private JTree tree = null; 3891 private TreeModel treeModel = null; 3892 private Object obj = null; 3893 private TreePath path = null; 3894 private Accessible accessibleParent = null; 3895 private int index = 0; 3896 private boolean isLeaf = false; 3897 3898 3901 public AccessibleJTreeNode(JTree t, TreePath p, Accessible ap) { 3902 tree = t; 3903 path = p; 3904 accessibleParent = ap; 3905 treeModel = t.getModel(); 3906 obj = p.getLastPathComponent(); 3907 if (treeModel != null) { 3908 isLeaf = treeModel.isLeaf(obj); 3909 } 3910 } 3911 3912 private TreePath getChildTreePath(int i) { 3913 if (i < 0 || i >= getAccessibleChildrenCount()) { 3916 return null; 3917 } else { 3918 Object childObj = treeModel.getChild(obj, i); 3919 Object [] objPath = path.getPath(); 3920 Object [] objChildPath = new Object [objPath.length+1]; 3921 java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length); 3922 objChildPath[objChildPath.length-1] = childObj; 3923 return new TreePath(objChildPath); 3924 } 3925 } 3926 3927 3935 public AccessibleContext getAccessibleContext() { 3936 return this; 3937 } 3938 3939 private AccessibleContext getCurrentAccessibleContext() { 3940 Component c = getCurrentComponent(); 3941 if (c instanceof Accessible) { 3942 return (((Accessible) c).getAccessibleContext()); 3943 } else { 3944 return null; 3945 } 3946 } 3947 3948 private Component getCurrentComponent() { 3949 if (tree.isVisible(path)) { 3953 TreeCellRenderer r = tree.getCellRenderer(); 3954 if (r == null) { 3955 return null; 3956 } 3957 TreeUI ui = tree.getUI(); 3958 if (ui != null) { 3959 int row = ui.getRowForPath(JTree.this, path); 3960 boolean selected = tree.isPathSelected(path); 3961 boolean expanded = tree.isExpanded(path); 3962 boolean hasFocus = false; return r.getTreeCellRendererComponent(tree, obj, 3964 selected, expanded, isLeaf, row, hasFocus); 3965 } 3966 } 3967 return null; 3968 } 3969 3970 3972 3978 public String getAccessibleName() { 3979 AccessibleContext ac = getCurrentAccessibleContext(); 3980 if (ac != null) { 3981 String name = ac.getAccessibleName(); 3982 if ((name != null) && (name != "")) { 3983 return ac.getAccessibleName(); 3984 } else { 3985 return null; 3986 } 3987 } 3988 if ((accessibleName != null) && (accessibleName != "")) { 3989 return accessibleName; 3990 } else { 3991 return null; 3992 } 3993 } 3994 3995 4000 public void setAccessibleName(String s) { 4001 AccessibleContext ac = getCurrentAccessibleContext(); 4002 if (ac != null) { 4003 ac.setAccessibleName(s); 4004 } else { 4005 super.setAccessibleName(s); 4006 } 4007 } 4008 4009 4018 public String getAccessibleDescription() { 4019 AccessibleContext ac = getCurrentAccessibleContext(); 4020 if (ac != null) { 4021 return ac.getAccessibleDescription(); 4022 } else { 4023 return super.getAccessibleDescription(); 4024 } 4025 } 4026 4027 4032 public void setAccessibleDescription(String s) { 4033 AccessibleContext ac = getCurrentAccessibleContext(); 4034 if (ac != null) { 4035 ac.setAccessibleDescription(s); 4036 } else { 4037 super.setAccessibleDescription(s); 4038 } 4039 } 4040 4041 4047 public AccessibleRole getAccessibleRole() { 4048 AccessibleContext ac = getCurrentAccessibleContext(); 4049 if (ac != null) { 4050 return ac.getAccessibleRole(); 4051 } else { 4052 return AccessibleRole.UNKNOWN; 4053 } 4054 } 4055 4056 4063 public AccessibleStateSet getAccessibleStateSet() { 4064 AccessibleContext ac = getCurrentAccessibleContext(); 4065 AccessibleStateSet states; 4066 int row = tree.getUI().getRowForPath(tree,path); 4067 int lsr = tree.getLeadSelectionRow(); 4068 if (ac != null) { 4069 states = ac.getAccessibleStateSet(); 4070 } else { 4071 states = new AccessibleStateSet(); 4072 } 4073 if (isShowing()) { 4076 states.add(AccessibleState.SHOWING); 4077 } else if (states.contains(AccessibleState.SHOWING)) { 4078 states.remove(AccessibleState.SHOWING); 4079 } 4080 if (isVisible()) { 4081 states.add(AccessibleState.VISIBLE); 4082 } else if (states.contains(AccessibleState.VISIBLE)) { 4083 states.remove(AccessibleState.VISIBLE); 4084 } 4085 if (tree.isPathSelected(path)){ 4086 states.add(AccessibleState.SELECTED); 4087 } 4088 if (lsr == row) { 4089 states.add(AccessibleState.ACTIVE); 4090 } 4091 if (!isLeaf) { 4092 states.add(AccessibleState.EXPANDABLE); 4093 } 4094 if (tree.isExpanded(path)) { 4095 states.add(AccessibleState.EXPANDED); 4096 } else { 4097 states.add(AccessibleState.COLLAPSED); 4098 } 4099 if (tree.isEditable()) { 4100 states.add(AccessibleState.EDITABLE); 4101 } 4102 return states; 4103 } 4104 4105 4111 public Accessible getAccessibleParent() { 4112 if (accessibleParent == null) { 4115 Object [] objPath = path.getPath(); 4116 if (objPath.length > 1) { 4117 Object objParent = objPath[objPath.length-2]; 4118 if (treeModel != null) { 4119 index = treeModel.getIndexOfChild(objParent, obj); 4120 } 4121 Object [] objParentPath = new Object [objPath.length-1]; 4122 java.lang.System.arraycopy(objPath, 0, objParentPath, 4123 0, objPath.length-1); 4124 TreePath parentPath = new TreePath(objParentPath); 4125 accessibleParent = new AccessibleJTreeNode(tree, 4126 parentPath, 4127 null); 4128 this.setAccessibleParent(accessibleParent); 4129 } else if (treeModel != null) { 4130 accessibleParent = tree; index = 0; this.setAccessibleParent(accessibleParent); 4133 } 4134 } 4135 return accessibleParent; 4136 } 4137 4138 4145 public int getAccessibleIndexInParent() { 4146 if (accessibleParent == null) { 4148 getAccessibleParent(); 4149 } 4150 Object [] objPath = path.getPath(); 4151 if (objPath.length > 1) { 4152 Object objParent = objPath[objPath.length-2]; 4153 if (treeModel != null) { 4154 index = treeModel.getIndexOfChild(objParent, obj); 4155 } 4156 } 4157 return index; 4158 } 4159 4160 4165 public int getAccessibleChildrenCount() { 4166 return treeModel.getChildCount(obj); 4169 } 4170 4171 4177 public Accessible getAccessibleChild(int i) { 4178 if (i < 0 || i >= getAccessibleChildrenCount()) { 4181 return null; 4182 } else { 4183 Object childObj = treeModel.getChild(obj, i); 4184 Object [] objPath = path.getPath(); 4185 Object [] objChildPath = new Object [objPath.length+1]; 4186 java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length); 4187 objChildPath[objChildPath.length-1] = childObj; 4188 TreePath childPath = new TreePath(objChildPath); 4189 return new AccessibleJTreeNode(JTree.this, childPath, this); 4190 } 4191 } 4192 4193 4205 public Locale getLocale() { 4206 AccessibleContext ac = getCurrentAccessibleContext(); 4207 if (ac != null) { 4208 return ac.getLocale(); 4209 } else { 4210 return tree.getLocale(); 4211 } 4212 } 4213 4214 4220 public void addPropertyChangeListener(PropertyChangeListener l) { 4221 AccessibleContext ac = getCurrentAccessibleContext(); 4222 if (ac != null) { 4223 ac.addPropertyChangeListener(l); 4224 } else { 4225 super.addPropertyChangeListener(l); 4226 } 4227 } 4228 4229 4236 public void removePropertyChangeListener(PropertyChangeListener l) { 4237 AccessibleContext ac = getCurrentAccessibleContext(); 4238 if (ac != null) { 4239 ac.removePropertyChangeListener(l); 4240 } else { 4241 super.removePropertyChangeListener(l); 4242 } 4243 } 4244 4245 4253 public AccessibleAction getAccessibleAction() { 4254 return this; 4255 } 4256 4257 4265 public AccessibleComponent getAccessibleComponent() { 4266 return this; } 4268 4269 4275 public AccessibleSelection getAccessibleSelection() { 4276 AccessibleContext ac = getCurrentAccessibleContext(); 4277 if (ac != null && isLeaf) { 4278 return getCurrentAccessibleContext().getAccessibleSelection(); 4279 } else { 4280 return this; 4281 } 4282 } 4283 4284 4290 public AccessibleText getAccessibleText() { 4291 AccessibleContext ac = getCurrentAccessibleContext(); 4292 if (ac != null) { 4293 return getCurrentAccessibleContext().getAccessibleText(); 4294 } else { 4295 return null; 4296 } 4297 } 4298 4299 4305 public AccessibleValue getAccessibleValue() { 4306 AccessibleContext ac = getCurrentAccessibleContext(); 4307 if (ac != null) { 4308 return getCurrentAccessibleContext().getAccessibleValue(); 4309 } else { 4310 return null; 4311 } 4312 } 4313 4314 4315 4317 4323 public Color getBackground() { 4324 AccessibleContext ac = getCurrentAccessibleContext(); 4325 if (ac instanceof AccessibleComponent) { 4326 return ((AccessibleComponent) ac).getBackground(); 4327 } else { 4328 Component c = getCurrentComponent(); 4329 if (c != null) { 4330 return c.getBackground(); 4331 } else { 4332 return null; 4333 } 4334 } 4335 } 4336 4337 4342 public void setBackground(Color c) { 4343 AccessibleContext ac = getCurrentAccessibleContext(); 4344 if (ac instanceof AccessibleComponent) { 4345 ((AccessibleComponent) ac).setBackground(c); 4346 } else { 4347 Component cp = getCurrentComponent(); 4348 if (cp != null) { 4349 cp.setBackground(c); 4350 } 4351 } 4352 } 4353 4354 4355 4361 public Color getForeground() { 4362 AccessibleContext ac = getCurrentAccessibleContext(); 4363 if (ac instanceof AccessibleComponent) { 4364 return ((AccessibleComponent) ac).getForeground(); 4365 } else { 4366 Component c = getCurrentComponent(); 4367 if (c != null) { 4368 return c.getForeground(); 4369 } else { 4370 return null; 4371 } 4372 } 4373 } 4374 4375 public void setForeground(Color c) { 4376 AccessibleContext ac = getCurrentAccessibleContext(); 4377 if (ac instanceof AccessibleComponent) { 4378 ((AccessibleComponent) ac).setForeground(c); 4379 } else { 4380 Component cp = getCurrentComponent(); 4381 if (cp != null) { 4382 cp.setForeground(c); 4383 } 4384 } 4385 } 4386 4387 public Cursor getCursor() { 4388 AccessibleContext ac = getCurrentAccessibleContext(); 4389 if (ac instanceof AccessibleComponent) { 4390 return ((AccessibleComponent) ac).getCursor(); 4391 } else { 4392 Component c = getCurrentComponent(); 4393 if (c != null) { 4394 return c.getCursor(); 4395 } else { 4396 Accessible ap = getAccessibleParent(); 4397 if (ap instanceof AccessibleComponent) { 4398 return ((AccessibleComponent) ap).getCursor(); 4399 } else { 4400 return null; 4401 } 4402 } 4403 } 4404 } 4405 4406 public void setCursor(Cursor c) { 4407 AccessibleContext ac = getCurrentAccessibleContext(); 4408 if (ac instanceof AccessibleComponent) { 4409 ((AccessibleComponent) ac).setCursor(c); 4410 } else { 4411 Component cp = getCurrentComponent(); 4412 if (cp != null) { 4413 cp.setCursor(c); 4414 } 4415 } 4416 } 4417 4418 public Font getFont() { 4419 AccessibleContext ac = getCurrentAccessibleContext(); 4420 if (ac instanceof AccessibleComponent) { 4421 return ((AccessibleComponent) ac).getFont(); 4422 } else { 4423 Component c = getCurrentComponent(); 4424 if (c != null) { 4425 return c.getFont(); 4426 } else { 4427 return null; 4428 } 4429 } 4430 } 4431 4432 public void setFont(Font f) { 4433 AccessibleContext ac = getCurrentAccessibleContext(); 4434 if (ac instanceof AccessibleComponent) { 4435 ((AccessibleComponent) ac).setFont(f); 4436 } else { 4437 Component c = getCurrentComponent(); 4438 if (c != null) { 4439 c.setFont(f); 4440 } 4441 } 4442 } 4443 4444 public FontMetrics getFontMetrics(Font f) { 4445 AccessibleContext ac = getCurrentAccessibleContext(); 4446 if (ac instanceof AccessibleComponent) { 4447 return ((AccessibleComponent) ac).getFontMetrics(f); 4448 } else { 4449 Component c = getCurrentComponent(); 4450 if (c != null) { 4451 return c.getFontMetrics(f); 4452 } else { 4453 return null; 4454 } 4455 } 4456 } 4457 4458 public boolean isEnabled() { 4459 AccessibleContext ac = getCurrentAccessibleContext(); 4460 if (ac instanceof AccessibleComponent) { 4461 return ((AccessibleComponent) ac).isEnabled(); 4462 } else { 4463 Component c = getCurrentComponent(); 4464 if (c != null) { 4465 return c.isEnabled(); 4466 } else { 4467 return false; 4468 } 4469 } 4470 } 4471 4472 public void setEnabled(boolean b) { 4473 AccessibleContext ac = getCurrentAccessibleContext(); 4474 if (ac instanceof AccessibleComponent) { 4475 ((AccessibleComponent) ac).setEnabled(b); 4476 } else { 4477 Component c = getCurrentComponent(); 4478 if (c != null) { 4479 c.setEnabled(b); 4480 } 4481 } 4482 } 4483 4484 public boolean isVisible() { 4485 Rectangle pathBounds = tree.getPathBounds(path); 4486 Rectangle parentBounds = tree.getVisibleRect(); 4487 if (pathBounds != null && parentBounds != null && 4488 parentBounds.intersects(pathBounds)) { 4489 return true; 4490 } else { 4491 return false; 4492 } 4493 } 4494 4495 public void setVisible(boolean b) { 4496 } 4497 4498 public boolean isShowing() { 4499 return (tree.isShowing() && isVisible()); 4500 } 4501 4502 public boolean contains(Point p) { 4503 AccessibleContext ac = getCurrentAccessibleContext(); 4504 if (ac instanceof AccessibleComponent) { 4505 Rectangle r = ((AccessibleComponent) ac).getBounds(); 4506 return r.contains(p); 4507 } else { 4508 Component c = getCurrentComponent(); 4509 if (c != null) { 4510 Rectangle r = c.getBounds(); 4511 return r.contains(p); 4512 } else { 4513 return getBounds().contains(p); 4514 } 4515 } 4516 } 4517 4518 public Point getLocationOnScreen() { 4519 if (tree != null) { 4520 Point treeLocation = tree.getLocationOnScreen(); 4521 Rectangle pathBounds = tree.getPathBounds(path); 4522 if (treeLocation != null && pathBounds != null) { 4523 Point nodeLocation = new Point(pathBounds.x, 4524 pathBounds.y); 4525 nodeLocation.translate(treeLocation.x, treeLocation.y); 4526 return nodeLocation; 4527 } else { 4528 return null; 4529 } 4530 } else { 4531 return null; 4532 } 4533 } 4534 4535 protected Point getLocationInJTree() { 4536 Rectangle r = tree.getPathBounds(path); 4537 if (r != null) { 4538 return r.getLocation(); 4539 } else { 4540 return null; 4541 } 4542 } 4543 4544 public Point getLocation() { 4545 Rectangle r = getBounds(); 4546 if (r != null) { 4547 return r.getLocation(); 4548 } else { 4549 return null; 4550 } 4551 } 4552 4553 public void setLocation(Point p) { 4554 } 4555 4556 public Rectangle getBounds() { 4557 Rectangle r = tree.getPathBounds(path); 4558 Accessible parent = getAccessibleParent(); 4559 if (parent != null) { 4560 if (parent instanceof AccessibleJTreeNode) { 4561 Point parentLoc = ((AccessibleJTreeNode) parent).getLocationInJTree(); 4562 if (parentLoc != null && r != null) { 4563 r.translate(-parentLoc.x, -parentLoc.y); 4564 } else { 4565 return null; } 4567 } 4568 } 4569 return r; 4570 } 4571 4572 public void setBounds(Rectangle r) { 4573 AccessibleContext ac = getCurrentAccessibleContext(); 4574 if (ac instanceof AccessibleComponent) { 4575 ((AccessibleComponent) ac).setBounds(r); 4576 } else { 4577 Component c = getCurrentComponent(); 4578 if (c != null) { 4579 c.setBounds(r); 4580 } 4581 } 4582 } 4583 4584 public Dimension getSize() { 4585 return getBounds().getSize(); 4586 } 4587 4588 public void setSize (Dimension d) { 4589 AccessibleContext ac = getCurrentAccessibleContext(); 4590 if (ac instanceof AccessibleComponent) { 4591 ((AccessibleComponent) ac).setSize(d); 4592 } else { 4593 Component c = getCurrentComponent(); 4594 if (c != null) { 4595 c.setSize(d); 4596 } 4597 } 4598 } 4599 4600 4610 public Accessible getAccessibleAt(Point p) { 4611 AccessibleContext ac = getCurrentAccessibleContext(); 4612 if (ac instanceof AccessibleComponent) { 4613 return ((AccessibleComponent) ac).getAccessibleAt(p); 4614 } else { 4615 return null; 4616 } 4617 } 4618 4619 public boolean isFocusTraversable() { 4620 AccessibleContext ac = getCurrentAccessibleContext(); 4621 if (ac instanceof AccessibleComponent) { 4622 return ((AccessibleComponent) ac).isFocusTraversable(); 4623 } else { 4624 Component c = getCurrentComponent(); 4625 if (c != null) { 4626 return c.isFocusTraversable(); 4627 } else { 4628 return false; 4629 } 4630 } 4631 } 4632 4633 public void requestFocus() { 4634 AccessibleContext ac = getCurrentAccessibleContext(); 4635 if (ac instanceof AccessibleComponent) { 4636 ((AccessibleComponent) ac).requestFocus(); 4637 } else { 4638 Component c = getCurrentComponent(); 4639 if (c != null) { 4640 c.requestFocus(); 4641 } 4642 } 4643 } 4644 4645 public void addFocusListener(FocusListener l) { 4646 AccessibleContext ac = getCurrentAccessibleContext(); 4647 if (ac instanceof AccessibleComponent) { 4648 ((AccessibleComponent) ac).addFocusListener(l); 4649 } else { 4650 Component c = getCurrentComponent(); 4651 if (c != null) { 4652 c.addFocusListener(l); 4653 } 4654 } 4655 } 4656 4657 public void removeFocusListener(FocusListener l) { 4658 AccessibleContext ac = getCurrentAccessibleContext(); 4659 if (ac instanceof AccessibleComponent) { 4660 ((AccessibleComponent) ac).removeFocusListener(l); 4661 } else { 4662 Component c = getCurrentComponent(); 4663 if (c != null) { 4664 c.removeFocusListener(l); 4665 } 4666 } 4667 } 4668 4669 4671 4677 public int getAccessibleSelectionCount() { 4678 int count = 0; 4679 int childCount = getAccessibleChildrenCount(); 4680 for (int i = 0; i < childCount; i++) { 4681 TreePath childPath = getChildTreePath(i); 4682 if (tree.isPathSelected(childPath)) { 4683 count++; 4684 } 4685 } 4686 return count; 4687 } 4688 4689 4698 public Accessible getAccessibleSelection(int i) { 4699 int childCount = getAccessibleChildrenCount(); 4700 if (i < 0 || i >= childCount) { 4701 return null; } 4703 int count = 0; 4704 for (int j = 0; j < childCount && i >= count; j++) { 4705 TreePath childPath = getChildTreePath(j); 4706 if (tree.isPathSelected(childPath)) { 4707 if (count == i) { 4708 return new AccessibleJTreeNode(tree, childPath, this); 4709 } else { 4710 count++; 4711 } 4712 } 4713 } 4714 return null; 4715 } 4716 4717 4724 public boolean isAccessibleChildSelected(int i) { 4725 int childCount = getAccessibleChildrenCount(); 4726 if (i < 0 || i >= childCount) { 4727 return false; } else { 4729 TreePath childPath = getChildTreePath(i); 4730 return tree.isPathSelected(childPath); 4731 } 4732 } 4733 4734 4743 public void addAccessibleSelection(int i) { 4744 TreeModel model = JTree.this.getModel(); 4745 if (model != null) { 4746 if (i >= 0 && i < getAccessibleChildrenCount()) { 4747 TreePath path = getChildTreePath(i); 4748 JTree.this.addSelectionPath(path); 4749 } 4750 } 4751 } 4752 4753 4761 public void removeAccessibleSelection(int i) { 4762 TreeModel model = JTree.this.getModel(); 4763 if (model != null) { 4764 if (i >= 0 && i < getAccessibleChildrenCount()) { 4765 TreePath path = getChildTreePath(i); 4766 JTree.this.removeSelectionPath(path); 4767 } 4768 } 4769 } 4770 4771 4775 public void clearAccessibleSelection() { 4776 int childCount = getAccessibleChildrenCount(); 4777 for (int i = 0; i < childCount; i++) { 4778 removeAccessibleSelection(i); 4779 } 4780 } 4781 4782 4786 public void selectAllAccessibleSelection() { 4787 TreeModel model = JTree.this.getModel(); 4788 if (model != null) { 4789 int childCount = getAccessibleChildrenCount(); 4790 TreePath path; 4791 for (int i = 0; i < childCount; i++) { 4792 path = getChildTreePath(i); 4793 JTree.this.addSelectionPath(path); 4794 } 4795 } 4796 } 4797 4798 4800 4808 public int getAccessibleActionCount() { 4809 AccessibleContext ac = getCurrentAccessibleContext(); 4810 if (ac != null) { 4811 AccessibleAction aa = ac.getAccessibleAction(); 4812 if (aa != null) { 4813 return (aa.getAccessibleActionCount() + (isLeaf ? 0 : 1)); 4814 } 4815 } 4816 return isLeaf ? 0 : 1; 4817 } 4818 4819 4828 public String getAccessibleActionDescription(int i) { 4829 if (i < 0 || i >= getAccessibleActionCount()) { 4830 return null; 4831 } 4832 AccessibleContext ac = getCurrentAccessibleContext(); 4833 if (i == 0) { 4834 return AccessibleAction.TOGGLE_EXPAND; 4836 } else if (ac != null) { 4837 AccessibleAction aa = ac.getAccessibleAction(); 4838 if (aa != null) { 4839 return aa.getAccessibleActionDescription(i - 1); 4840 } 4841 } 4842 return null; 4843 } 4844 4845 4854 public boolean doAccessibleAction(int i) { 4855 if (i < 0 || i >= getAccessibleActionCount()) { 4856 return false; 4857 } 4858 AccessibleContext ac = getCurrentAccessibleContext(); 4859 if (i == 0) { 4860 if (JTree.this.isExpanded(path)) { 4861 JTree.this.collapsePath(path); 4862 } else { 4863 JTree.this.expandPath(path); 4864 } 4865 return true; 4866 } else if (ac != null) { 4867 AccessibleAction aa = ac.getAccessibleAction(); 4868 if (aa != null) { 4869 return aa.doAccessibleAction(i - 1); 4870 } 4871 } 4872 return false; 4873 } 4874 4875 } 4877 } 4879} 4881 | Popular Tags |