diff options
Diffstat (limited to 'libjava/javax/swing/JTree.java')
-rw-r--r-- | libjava/javax/swing/JTree.java | 739 |
1 files changed, 730 insertions, 9 deletions
diff --git a/libjava/javax/swing/JTree.java b/libjava/javax/swing/JTree.java index 8d52257..353547c 100644 --- a/libjava/javax/swing/JTree.java +++ b/libjava/javax/swing/JTree.java @@ -53,10 +53,10 @@ import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeWillExpandListener; import javax.swing.plaf.TreeUI; -import javax.swing.tree.ExpandVetoException; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreeCellEditor; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeModel; @@ -70,14 +70,11 @@ public class JTree extends JComponent { private static final long serialVersionUID = 7559816092864483649L; - public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath"; public static final String CELL_EDITOR_PROPERTY = "cellEditor"; public static final String CELL_RENDERER_PROPERTY = "cellRenderer"; public static final String EDITABLE_PROPERTY = "editable"; - public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths"; public static final String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing"; public static final String LARGE_MODEL_PROPERTY = "largeModel"; - public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath"; public static final String ROOT_VISIBLE_PROPERTY = "rootVisible"; public static final String ROW_HEIGHT_PROPERTY = "rowHeight"; public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand"; @@ -87,18 +84,40 @@ public class JTree extends JComponent public static final String TREE_MODEL_PROPERTY = "model"; public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount"; - protected TreeCellEditor cellEditor; - protected TreeCellRenderer cellRenderer; + /** @since 1.3 */ + public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath"; + /** @since 1.3 */ + public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath"; + /** @since 1.3 */ + public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths"; + + private static final Object EXPANDED = new Object(); + private static final Object COLLAPSED = new Object(); + + private boolean dragEnabled; + private boolean expandsSelectedPaths; + private TreePath anchorSelectionPath; + private TreePath leadSelectionPath; + + /* + * This contains the state of all nodes in the tree. Al/ entries map the + * TreePath of a note to to its state. Valid states are EXPANDED and + * COLLAPSED. Nodes not in this Hashtable are assumed state COLLAPSED. + */ + private Hashtable nodeStates; + + protected transient TreeCellEditor cellEditor; + protected transient TreeCellRenderer cellRenderer; protected boolean editable; protected boolean invokesStopCellEditing; protected boolean largeModel; protected boolean rootVisible; protected int rowHeight; protected boolean scrollsOnExpand; - protected TreeSelectionModel selectionModel; + protected transient TreeSelectionModel selectionModel; protected boolean showsRootHandles; protected int toggleClickCount; - protected TreeModel treeModel; + protected transient TreeModel treeModel; protected int visibleRowCount; /** @@ -178,6 +197,13 @@ public class JTree extends JComponent { protected Object childValue; protected boolean loadedChildren; + + /** + * Currently not set or used by this class. + * It might be set and used in later versions of this class. + */ + protected boolean hasChildren; + public DynamicUtilTreeNode(Object value, Object children) { @@ -247,6 +273,39 @@ public class JTree extends JComponent } } + public int getRowForPath(TreePath path) + { + TreeUI ui = getUI(); + + if (ui != null) + return ui.getRowForPath(this, path); + + return -1; + } + + public TreePath getPathForRow(int row) + { + TreeUI ui = getUI(); + return ui != null ? ui.getPathForRow(this, row) : null; + } + + protected TreePath[] getPathBetweenRows(int index0, int index1) + { + TreeUI ui = getUI(); + + if (ui == null) + return null; + + int minIndex = Math.min(index0, index1); + int maxIndex = Math.max(index0, index1); + TreePath[] paths = new TreePath[maxIndex - minIndex + 1]; + + for (int i = minIndex; i <= maxIndex; ++i) + paths[i - minIndex] = ui.getPathForRow(this, i); + + return paths; + } + /** * Creates a new <code>TreeModel</code> object. * @@ -517,7 +576,12 @@ public class JTree extends JComponent */ public void setModel(TreeModel model) { + if (treeModel == model) + return; + + TreeModel oldValue = treeModel; treeModel = model; + firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model); } /** @@ -544,7 +608,7 @@ public class JTree extends JComponent boolean oldValue = editable; editable = flag; - firePropertyChange("editable", oldValue, editable); + firePropertyChange(EDITABLE_PROPERTY, oldValue, editable); } /** @@ -560,7 +624,12 @@ public class JTree extends JComponent public void setRootVisible(boolean flag) { + if (rootVisible == flag) + return; + + boolean oldValue = rootVisible; rootVisible = flag; + firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag); } public boolean getShowsRootHandles() @@ -570,7 +639,12 @@ public class JTree extends JComponent public void setShowsRootHandles(boolean flag) { + if (showsRootHandles == flag) + return; + + boolean oldValue = showsRootHandles; showsRootHandles = flag; + firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, flag); } public TreeCellEditor getCellEditor() @@ -580,7 +654,12 @@ public class JTree extends JComponent public void setCellEditor(TreeCellEditor editor) { + if (cellEditor == editor) + return; + + TreeCellEditor oldValue = cellEditor; cellEditor = editor; + firePropertyChange(CELL_EDITOR_PROPERTY, oldValue, editor); } public TreeCellRenderer getCellRenderer() @@ -590,7 +669,12 @@ public class JTree extends JComponent public void setCellRenderer(TreeCellRenderer newRenderer) { + if (cellRenderer == newRenderer) + return; + + TreeCellRenderer oldValue = cellRenderer; cellRenderer = newRenderer; + firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, newRenderer); } public TreeSelectionModel getSelectionModel() @@ -600,7 +684,12 @@ public class JTree extends JComponent public void setSelectionModel(TreeSelectionModel model) { + if (selectionModel == model) + return; + + TreeSelectionModel oldValue = selectionModel; selectionModel = model; + firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, model); } public int getVisibleRowCount() @@ -610,7 +699,12 @@ public class JTree extends JComponent public void setVisibleRowCount(int rows) { + if (visibleRowCount == rows) + return; + + int oldValue = visibleRowCount; visibleRowCount = rows; + firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldValue, rows); } public boolean isLargeModel() @@ -620,7 +714,12 @@ public class JTree extends JComponent public void setLargeModel(boolean large) { + if (largeModel == large) + return; + + boolean oldValue = largeModel; largeModel = large; + firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, large); } public int getRowHeight() @@ -630,7 +729,17 @@ public class JTree extends JComponent public void setRowHeight(int height) { + if (rowHeight == height) + return; + + int oldValue = rowHeight; rowHeight = height; + firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, height); + } + + public boolean isFixedRowHeight() + { + return rowHeight > 0; } public boolean getInvokesStopCellEditing() @@ -640,7 +749,12 @@ public class JTree extends JComponent public void setInvokesStopCellEditing(boolean invoke) { + if (invokesStopCellEditing == invoke) + return; + + boolean oldValue = invokesStopCellEditing; invokesStopCellEditing = invoke; + firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY, oldValue, invoke); } /** @@ -656,9 +770,32 @@ public class JTree extends JComponent */ public void setToggleClickCount(int count) { + if (toggleClickCount == count) + return; + + int oldValue = toggleClickCount; toggleClickCount = count; + firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count); + } + + public void scrollPathToVisible(TreePath path) + { + if (path == null) + return; + + Rectangle rect = getPathBounds(path); + + if (rect == null) + return; + + scrollRectToVisible(rect); } + public void scrollRowToVisible(int row) + { + scrollPathToVisible(getPathForRow(row)); + } + public boolean getScrollsOnExpand() { return scrollsOnExpand; @@ -666,6 +803,590 @@ public class JTree extends JComponent public void setScrollsOnExpand(boolean scroll) { + if (scrollsOnExpand == scroll) + return; + + boolean oldValue = scrollsOnExpand; scrollsOnExpand = scroll; + firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, scroll); + } + + public void setSelectionPath(TreePath path) + { + selectionModel.setSelectionPath(path); + } + + public void setSelectionPaths(TreePath[] paths) + { + selectionModel.setSelectionPaths(paths); + } + + public void setSelectionRow(int row) + { + TreePath path = getPathForRow(row); + + if (path != null) + selectionModel.setSelectionPath(path); + } + + public void setSelectionRows(int[] rows) + { + // Make sure we have an UI so getPathForRow() does not return null. + if (rows == null || getUI() == null) + return; + + TreePath[] paths = new TreePath[rows.length]; + + for (int i = rows.length - 1; i >= 0; --i) + paths[i] = getPathForRow(rows[i]); + + setSelectionPaths(paths); + } + + public void setSelectionInterval(int index0, int index1) + { + TreePath[] paths = getPathBetweenRows(index0, index1); + + if (paths != null) + setSelectionPaths(paths); + } + + public void addSelectionPath(TreePath path) + { + selectionModel.addSelectionPath(path); + } + + public void addSelectionPaths(TreePath[] paths) + { + selectionModel.addSelectionPaths(paths); + } + + public void addSelectionRow(int row) + { + TreePath path = getPathForRow(row); + + if (path != null) + selectionModel.addSelectionPath(path); + } + + public void addSelectionRows(int[] rows) + { + // Make sure we have an UI so getPathForRow() does not return null. + if (rows == null || getUI() == null) + return; + + TreePath[] paths = new TreePath[rows.length]; + + for (int i = rows.length - 1; i >= 0; --i) + paths[i] = getPathForRow(rows[i]); + + addSelectionPaths(paths); + } + + public void addSelectionInterval(int index0, int index1) + { + TreePath[] paths = getPathBetweenRows(index0, index1); + + if (paths != null) + addSelectionPaths(paths); + } + + public void removeSelectionPath(TreePath path) + { + selectionModel.removeSelectionPath(path); + } + + public void removeSelectionPaths(TreePath[] paths) + { + selectionModel.removeSelectionPaths(paths); + } + + public void removeSelectionRow(int row) + { + TreePath path = getPathForRow(row); + + if (path != null) + selectionModel.removeSelectionPath(path); + } + + public void removeSelectionRows(int[] rows) + { + // Make sure we have an UI so getPathForRow() does not return null. + if (rows == null || getUI() == null) + return; + + TreePath[] paths = new TreePath[rows.length]; + + for (int i = rows.length - 1; i >= 0; --i) + paths[i] = getPathForRow(rows[i]); + + removeSelectionPaths(paths); + } + + public void removeSelectionInterval(int index0, int index1) + { + TreePath[] paths = getPathBetweenRows(index0, index1); + + if (paths != null) + removeSelectionPaths(paths); + } + + public void clearSelection() + { + selectionModel.clearSelection(); + } + + public TreePath getLeadSelectionPath() + { + return leadSelectionPath; + } + + /** + * @since 1.3 + */ + public void setLeadSelectionPath(TreePath path) + { + if (leadSelectionPath == path) + return; + + TreePath oldValue = leadSelectionPath; + leadSelectionPath = path; + firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path); + } + + /** + * @since 1.3 + */ + public TreePath getAnchorSelectionPath() + { + return anchorSelectionPath; + } + + /** + * @since 1.3 + */ + public void setAnchorSelectionPath(TreePath path) + { + if (anchorSelectionPath == path) + return; + + TreePath oldValue = anchorSelectionPath; + anchorSelectionPath = path; + firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, path); + } + + public int getLeadSelectionRow() + { + return selectionModel.getLeadSelectionRow(); + } + + public int getMaxSelectionRow() + { + return selectionModel.getMaxSelectionRow(); + } + + public int getMinSelectionRow() + { + return selectionModel.getMinSelectionRow(); + } + + public int getSelectionCount() + { + return selectionModel.getSelectionCount(); + } + + public TreePath getSelectionPath() + { + return selectionModel.getSelectionPath(); + } + + public TreePath[] getSelectionPaths() + { + return selectionModel.getSelectionPaths(); + } + + public int[] getSelectionRows() + { + return selectionModel.getSelectionRows(); + } + + public boolean isPathSelected(TreePath path) + { + return selectionModel.isPathSelected(path); + } + + public boolean isRowSelected(int row) + { + return selectionModel.isRowSelected(row); + } + + public boolean isSelectionEmpty() + { + return selectionModel.isSelectionEmpty(); + } + + /** + * Return the value of the <code>dragEnabled</code> property. + * + * @return the value + * + * @since 1.4 + */ + public boolean getDragEnabled() + { + return dragEnabled; + } + + /** + * Set the <code>dragEnabled</code> property. + * + * @param enabled new value + * + * @since 1.4 + */ + public void setDragEnabled(boolean enabled) + { + dragEnabled = enabled; + } + + public int getRowCount() + { + TreeUI ui = getUI(); + + if (ui != null) + return ui.getRowCount(this); + + return 0; + } + + public void collapsePath(TreePath path) + { + setExpandedState(path, false); + } + + public void collapseRow(int row) + { + if (row < 0 || row >= getRowCount()) + return; + + TreePath path = getPathForRow(row); + + if (path != null) + collapsePath(path); + } + + public void expandPath(TreePath path) + { + // Don't expand if last path component is a leaf node. + if ((path == null) + || (treeModel.isLeaf(path.getLastPathComponent()))) + return; + + setExpandedState(path, true); + } + + public void expandRow(int row) + { + if (row < 0 || row >= getRowCount()) + return; + + TreePath path = getPathForRow(row); + + if (path != null) + expandPath(path); + } + + public boolean isCollapsed(TreePath path) + { + return ! isExpanded(path); + } + + public boolean isCollapsed(int row) + { + if (row < 0 || row >= getRowCount()) + return false; + + TreePath path = getPathForRow(row); + + if (path != null) + return isCollapsed(path); + + return false; + } + + public boolean isExpanded(TreePath path) + { + if (path == null) + return false; + + Object state = nodeStates.get(path); + + if ((state == null) || (state != EXPANDED)) + return false; + + TreePath parent = path.getParentPath(); + + if (parent != null) + return isExpanded(parent); + + return true; + } + + public boolean isExpanded(int row) + { + if (row < 0 || row >= getRowCount()) + return false; + + TreePath path = getPathForRow(row); + + if (path != null) + return isExpanded(path); + + return false; + } + + /** + * @since 1.3 + */ + public boolean getExpandsSelectedPaths() + { + return expandsSelectedPaths; + } + + /** + * @since 1.3 + */ + public void setExpandsSelectedPaths(boolean flag) + { + if (expandsSelectedPaths == flag) + return; + + boolean oldValue = expandsSelectedPaths; + expandsSelectedPaths = flag; + firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, flag); + } + + public Rectangle getPathBounds(TreePath path) + { + TreeUI ui = getUI(); + + if (ui == null) + return null; + + return ui.getPathBounds(this, path); + } + + public Rectangle getRowBounds(int row) + { + TreePath path = getPathForRow(row); + + if (path != null) + return getPathBounds(path); + + return null; + } + + public boolean isEditing() + { + TreeUI ui = getUI(); + + if (ui != null) + return ui.isEditing(this); + + return false; + } + + public boolean stopEditing() + { + TreeUI ui = getUI(); + + if (ui != null) + return ui.stopEditing(this); + + return false; + } + + public void cancelEditing() + { + TreeUI ui = getUI(); + + if (ui != null) + ui.cancelEditing(this); + } + + public void startEditingAtPath(TreePath path) + { + TreeUI ui = getUI(); + + if (ui != null) + ui.startEditingAtPath(this, path); + } + + public TreePath getEditingPath() + { + TreeUI ui = getUI(); + + if (ui != null) + return ui.getEditingPath(this); + + return null; + } + + public TreePath getPathForLocation(int x, int y) + { + TreePath path = getClosestPathForLocation(x, y); + + if (path != null) + { + Rectangle rect = getPathBounds(path); + + if ((rect != null) && rect.contains(x, y)) + return path; + } + + return null; + } + + public int getRowForLocation(int x, int y) + { + TreePath path = getPathForLocation(x, y); + + if (path != null) + return getRowForPath(path); + + return -1; + } + + public TreePath getClosestPathForLocation(int x, int y) + { + TreeUI ui = getUI(); + + if (ui != null) + return ui.getClosestPathForLocation(this, x, y); + + return null; + } + + public int getClosestRowForLocation(int x, int y) + { + TreePath path = getClosestPathForLocation(x, y); + + if (path != null) + return getRowForPath(path); + + return -1; + } + + public Object getLastSelectedPathComponent() + { + TreePath path = getSelectionPath(); + + if (path != null) + return path.getLastPathComponent(); + + return null; + } + + private void checkExpandParents(TreePath path) + throws ExpandVetoException + { + TreePath parent = path.getParentPath(); + + if (parent != null) + checkExpandParents(parent); + + fireTreeWillExpand(path); + } + + private void doExpandParents(TreePath path, boolean state) + { + TreePath parent = path.getParentPath(); + + if (isExpanded(parent)) + return; + + if (parent != null) + doExpandParents(parent, false); + + nodeStates.put(path, state ? EXPANDED : COLLAPSED); + } + + protected void setExpandedState(TreePath path, boolean state) + { + if (path == null) + return; + + TreePath parent = path.getParentPath(); + + try + { + while (parent != null) + checkExpandParents(parent); + } + catch (ExpandVetoException e) + { + // Expansion vetoed. + return; + } + + doExpandParents(path, state); + } + + protected void clearToggledPaths() + { + nodeStates.clear(); + } + + protected Enumeration getDescendantToggledPaths(TreePath parent) + { + if (parent == null) + return null; + + Enumeration nodes = nodeStates.keys(); + Vector result = new Vector(); + + while (nodes.hasMoreElements()) + { + TreePath path = (TreePath) nodes.nextElement(); + + if (path.isDescendant(parent)) + result.addElement(path); + } + + return result.elements(); + } + + public boolean hasBeenExpanded(TreePath path) + { + if (path == null) + return false; + + return nodeStates.get(path) != null; + } + + public boolean isVisible(TreePath path) + { + if (path == null) + return false; + + TreePath parent = path.getParentPath(); + + if (parent == null) + return true; // Is root node. + + return isExpanded(parent); + } + + public void makeVisible(TreePath path) + { + if (path == null) + return; + + expandPath(path.getParentPath()); + } + + public boolean isPathEditable(TreePath path) + { + return isEditable(); } } |