diff options
Diffstat (limited to 'libjava/classpath/javax/swing/JTree.java')
-rw-r--r-- | libjava/classpath/javax/swing/JTree.java | 232 |
1 files changed, 188 insertions, 44 deletions
diff --git a/libjava/classpath/javax/swing/JTree.java b/libjava/classpath/javax/swing/JTree.java index 7876eeb6aaa..e3b8b7e7ca5 100644 --- a/libjava/classpath/javax/swing/JTree.java +++ b/libjava/classpath/javax/swing/JTree.java @@ -1276,10 +1276,16 @@ public class JTree extends JComponent implements Scrollable, Accessible */ public void valueChanged(TreeSelectionEvent ev) { - TreeSelectionEvent rewritten = + TreeSelectionEvent rewritten = (TreeSelectionEvent) ev.cloneWithSource(JTree.this); fireValueChanged(rewritten); - JTree.this.repaint(); + + // Only repaint the changed nodes. + TreePath[] changed = ev.getPaths(); + for (int i = 0; i < changed.length; i++) + { + repaint(getPathBounds(changed[i])); + } } } @@ -1396,8 +1402,6 @@ public class JTree extends JComponent implements Scrollable, Accessible 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 @@ -1443,6 +1447,33 @@ public class JTree extends JComponent implements Scrollable, Accessible new TreeSelectionRedirector(); /** + * Indicates if the rowHeight property has been set by a client + * program or by the UI. + * + * @see #setUIProperty(String, Object) + * @see LookAndFeel#installProperty(JComponent, String, Object) + */ + private boolean clientRowHeightSet = false; + + /** + * Indicates if the scrollsOnExpand property has been set by a client + * program or by the UI. + * + * @see #setUIProperty(String, Object) + * @see LookAndFeel#installProperty(JComponent, String, Object) + */ + private boolean clientScrollsOnExpandSet = false; + + /** + * Indicates if the showsRootHandles property has been set by a client + * program or by the UI. + * + * @see #setUIProperty(String, Object) + * @see LookAndFeel#installProperty(JComponent, String, Object) + */ + private boolean clientShowsRootHandlesSet = false; + + /** * Creates a new <code>JTree</code> object. */ public JTree() @@ -1477,8 +1508,8 @@ public class JTree extends JComponent implements Scrollable, Accessible */ public JTree(TreeModel model) { - updateUI(); setRootVisible(true); + // The setModel also calls the updateUI setModel(model); setSelectionModel(new EmptySelectionModel()); selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); @@ -1535,7 +1566,15 @@ public class JTree extends JComponent implements Scrollable, Accessible TreeUI ui = getUI(); return ui != null ? ui.getPathForRow(this, row) : null; } - + + /** + * Get the pathes that are displayes between the two given rows. + * + * @param index0 the starting row, inclusive + * @param index1 the ending row, inclusive + * + * @return the array of the tree pathes + */ protected TreePath[] getPathBetweenRows(int index0, int index1) { TreeUI ui = getUI(); @@ -1619,19 +1658,48 @@ public class JTree extends JComponent implements Scrollable, Accessible */ public Dimension getPreferredScrollableViewportSize() { - return new Dimension (getPreferredSize().width, getVisibleRowCount()*getRowHeight()); + return getPreferredSize(); } - - public int getScrollableUnitIncrement(Rectangle visibleRect, - int orientation, int direction) + + /** + * Return the preferred scrolling amount (in pixels) for the given scrolling + * direction and orientation. This method handles a partially exposed row by + * returning the distance required to completely expose the item. + * + * @param visibleRect the currently visible part of the component. + * @param orientation the scrolling orientation + * @param direction the scrolling direction (negative - up, positive -down). + * The values greater than one means that more mouse wheel or similar + * events were generated, and hence it is better to scroll the longer + * distance. + * @author Audrius Meskauskas (audriusa@bioinformatics.org) + */ + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, + int direction) { - return 1; + int delta; + + // Round so that the top would start from the row boundary + if (orientation == SwingConstants.VERTICAL) + { + // One pixel down, otherwise picks another row too high. + int row = getClosestRowForLocation(visibleRect.x, visibleRect.y + 1); + row = row + direction; + if (row < 0) + row = 0; + + Rectangle newTop = getRowBounds(row); + delta = newTop.y - visibleRect.y; + } + else + delta = direction * rowHeight == 0 ? 20 : rowHeight; + return delta; } public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - return 1; + return getScrollableUnitIncrement(visibleRect, orientation, direction); } public boolean getScrollableTracksViewportHeight() @@ -1885,9 +1953,19 @@ public class JTree extends JComponent implements Scrollable, Accessible if (rootVisible == flag) return; + // If the root is currently selected, unselect it + if (rootVisible && !flag) + { + TreeSelectionModel model = getSelectionModel(); + // The root is always shown in the first row + TreePath rootPath = getPathForRow(0); + model.removeSelectionPath(rootPath); + } + boolean oldValue = rootVisible; rootVisible = flag; firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag); + } public boolean getShowsRootHandles() @@ -1897,6 +1975,8 @@ public class JTree extends JComponent implements Scrollable, Accessible public void setShowsRootHandles(boolean flag) { + clientShowsRootHandlesSet = true; + if (showsRootHandles == flag) return; @@ -1996,6 +2076,8 @@ public class JTree extends JComponent implements Scrollable, Accessible public void setRowHeight(int height) { + clientRowHeightSet = true; + if (rowHeight == height) return; @@ -2050,27 +2132,8 @@ public class JTree extends JComponent implements Scrollable, Accessible { if (path == null) return; - - Object[] oPath = path.getPath(); - TreePath temp = new TreePath(oPath[0]); - boolean stop = false; - int i = 1; - while (!stop) - { - while (isVisible(temp)) - if (i < oPath.length) - temp = temp.pathByAddingChild(oPath[i++]); - else - { - stop = true; - break; - } - makeVisible(temp); - } Rectangle rect = getPathBounds(path); scrollRectToVisible(rect); - revalidate(); - repaint(); } public void scrollRowToVisible(int row) @@ -2085,6 +2148,7 @@ public class JTree extends JComponent implements Scrollable, Accessible public void setScrollsOnExpand(boolean scroll) { + clientScrollsOnExpandSet = true; if (scrollsOnExpand == scroll) return; @@ -2164,7 +2228,15 @@ public class JTree extends JComponent implements Scrollable, Accessible addSelectionPaths(paths); } - + + /** + * Select all rows between the two given indexes, inclusive. The method + * will not select the inner leaves and braches of the currently collapsed + * nodes in this interval. + * + * @param index0 the starting row, inclusive + * @param index1 the ending row, inclusive + */ public void addSelectionInterval(int index0, int index1) { TreePath[] paths = getPathBetweenRows(index0, index1); @@ -2220,7 +2292,10 @@ public class JTree extends JComponent implements Scrollable, Accessible public TreePath getLeadSelectionPath() { - return leadSelectionPath; + if (selectionModel == null) + return null; + else + return selectionModel.getLeadSelectionPath(); } /** @@ -2228,12 +2303,24 @@ public class JTree extends JComponent implements Scrollable, Accessible */ public void setLeadSelectionPath(TreePath path) { - if (leadSelectionPath == path) - return; - - TreePath oldValue = leadSelectionPath; - leadSelectionPath = path; - firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path); + if (selectionModel != null) + { + TreePath oldValue = selectionModel.getLeadSelectionPath(); + if (path.equals(oldValue)) + return; + + // Repaint the previous and current rows with the lead selection path. + if (path != null) + { + repaint(getPathBounds(path)); + selectionModel.addSelectionPath(path); + } + + if (oldValue!=null) + repaint(getPathBounds(oldValue)); + + firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path); + } } /** @@ -2369,7 +2456,8 @@ public class JTree extends JComponent implements Scrollable, Accessible public void expandPath(TreePath path) { // Don't expand if path is null - if (path == null) + // or is already expanded. + if (path == null || isExpanded(path)) return; try @@ -2906,13 +2994,69 @@ public class JTree extends JComponent implements Scrollable, Accessible } /** - * Sent when the tree has changed enough that we need to resize the bounds, - * but not enough that we need to remove the expanded node set (e.g nodes - * were expanded or collapsed, or nodes were inserted into the tree). You - * should never have to invoke this, the UI will invoke this as it needs to. + * <p> + * Sent when the tree has changed enough that we need to resize the bounds, + * but not enough that we need to remove the expanded node set (e.g nodes were + * expanded or collapsed, or nodes were inserted into the tree). You should + * never have to invoke this, the UI will invoke this as it needs to. + * </p> + * <p> + * If the tree uses {@link DefaultTreeModel}, you must call + * {@link DefaultTreeModel#reload(TreeNode)} or + * {@link DefaultTreeModel#reload()} after adding or removing nodes. Following + * the official Java 1.5 API standard, just calling treeDidChange, repaint() + * or revalidate() does <i>not</i> update the tree appearance properly. + * + * @see DefaultTreeModel#reload() */ public void treeDidChange() { repaint(); } + + /** + * Helper method for + * {@link LookAndFeel#installProperty(JComponent, String, Object)}. + * + * @param propertyName the name of the property + * @param value the value of the property + * + * @throws IllegalArgumentException if the specified property cannot be set + * by this method + * @throws ClassCastException if the property value does not match the + * property type + * @throws NullPointerException if <code>c</code> or + * <code>propertyValue</code> is <code>null</code> + */ + void setUIProperty(String propertyName, Object value) + { + if (propertyName.equals("rowHeight")) + { + if (! clientRowHeightSet) + { + setRowHeight(((Integer) value).intValue()); + clientRowHeightSet = false; + } + } + else if (propertyName.equals("scrollsOnExpand")) + { + if (! clientScrollsOnExpandSet) + { + setScrollsOnExpand(((Boolean) value).booleanValue()); + clientScrollsOnExpandSet = false; + } + } + else if (propertyName.equals("showsRootHandles")) + { + if (! clientShowsRootHandlesSet) + { + setShowsRootHandles(((Boolean) value).booleanValue()); + clientShowsRootHandlesSet = false; + } + } + else + { + super.setUIProperty(propertyName, value); + } + } } |