summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--gnu/javax/swing/tree/GnuPath.java65
-rw-r--r--javax/swing/JTree.java2
-rw-r--r--javax/swing/ViewportLayout.java43
-rw-r--r--javax/swing/plaf/basic/BasicTreeUI.java1396
-rw-r--r--javax/swing/tree/FixedHeightLayoutCache.java4
-rw-r--r--javax/swing/tree/VariableHeightLayoutCache.java97
7 files changed, 647 insertions, 973 deletions
diff --git a/ChangeLog b/ChangeLog
index aa8a52ea4..f4a5961d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2006-04-13 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JTree.java (getPreferredSize): Return the
+ cloned instance.
+ * javax/swing/ViewportLayout.java (layoutContainer):
+ Do not manage the view size and location if the view is
+ in the scroll pane. Also manage size and location for
+ Scrollable, if it is not in the scroll pane.
+ * javax/swing/plaf/basic/BasicTreeUI.java,
+ * javax/swing/tree/FixedHeightLayoutCache.java,
+ * javax/swing/tree/VariableHeightLayoutCache.java: Rewritten.
+ * gnu/javax/swing/tree/GnuPath.java: New file.
+
2006-04-13 David Gilbert <david.gilbert@object-refinery.com>
* javax/swing/JToolBar.java
diff --git a/gnu/javax/swing/tree/GnuPath.java b/gnu/javax/swing/tree/GnuPath.java
new file mode 100644
index 000000000..dd576e8d3
--- /dev/null
+++ b/gnu/javax/swing/tree/GnuPath.java
@@ -0,0 +1,65 @@
+/* GnuPath.java -- The extended version of TreePath
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.swing.tree;
+
+import javax.swing.tree.TreePath;
+
+/**
+ * The tree path with additional data. Needed for the optimized tree drawing.
+ * Returned by layout caches.
+ *
+ * @author Audrius Meskauskas
+ */
+public class GnuPath extends TreePath
+{
+ /**
+ * The flag, marking the last visible child.
+ */
+ public boolean isLastChild;
+
+ /**
+ * Create a new path, specifying flag if this path is the path to the
+ * last visible child (needed for optimized tree drawing).
+ */
+ public GnuPath(Object[] path, boolean lastChild)
+ {
+ super(path);
+ isLastChild = lastChild;
+ }
+}
diff --git a/javax/swing/JTree.java b/javax/swing/JTree.java
index 4007c0cfd..58f1e9a9d 100644
--- a/javax/swing/JTree.java
+++ b/javax/swing/JTree.java
@@ -1646,7 +1646,7 @@ public class JTree extends JComponent implements Scrollable, Accessible
*/
public Dimension getPreferredScrollableViewportSize()
{
- return new Dimension (getPreferredSize().width, getVisibleRowCount()*getRowHeight());
+ return getPreferredSize();
}
/**
diff --git a/javax/swing/ViewportLayout.java b/javax/swing/ViewportLayout.java
index 4fbe37f31..67b69eb28 100644
--- a/javax/swing/ViewportLayout.java
+++ b/javax/swing/ViewportLayout.java
@@ -120,23 +120,19 @@ public class ViewportLayout implements LayoutManager, Serializable
}
/**
- * Layout the view and viewport to respect the following rules. These are
- * not precisely the rules described in sun's javadocs, but they are the
- * rules which sun's swing implementation follows, if you watch its
- * behavior:
- *
- * <ol>
- *
- * <li>If the port is smaller than the view, leave the view at its
- * current size.</li>
+ * Layout the view and viewport to respect the following rules. These are not
+ * precisely the rules described in sun's javadocs, but they are the rules
+ * which sun's swing implementation follows, if you watch its behavior:
+ * <ol>
+ * <li>If the port is smaller than the view, leave the view at its current
+ * size.</li>
* <li>If the view is smaller than the port, the view is top aligned.</li>
- * <li>If the view tracks the port size, the view position is always zero
- * and the size equal to the viewport size</li>
+ * <li>If the view tracks the port size, the view position is always zero and
+ * the size equal to the viewport size</li>
* <li>In {@link JViewport#setViewSize(Dimension)}, the view size is never
* set smaller that its minimum size.</li>
- *
* </ol>
- *
+ *
* @see JViewport#getViewSize
* @see JViewport#setViewSize
* @see JViewport#getViewPosition
@@ -147,7 +143,7 @@ public class ViewportLayout implements LayoutManager, Serializable
// The way to interpret this function is basically to ignore the names
// of methods it calls, and focus on the variable names here. getViewRect
// doesn't, for example, return the view; it returns the port bounds in
- // view space. Likwise setViewPosition doesn't reposition the view; it
+ // view space. Likwise setViewPosition doesn't reposition the view; it
// positions the port, in view coordinates.
JViewport port = (JViewport) parent;
@@ -156,7 +152,7 @@ public class ViewportLayout implements LayoutManager, Serializable
if (view == null)
return;
- // These dimensions and positions are in *view space*. Do not mix
+ // These dimensions and positions are in *view space*. Do not mix
// variables in here from port space (eg. parent.getBounds()). This
// function should be entirely in view space, because the methods on
// the viewport require inputs in view space.
@@ -185,20 +181,23 @@ public class ViewportLayout implements LayoutManager, Serializable
portBounds.y = 0;
}
}
- else
+
+ // The scroll pane manages the view size itself.
+ if (! (port.getParent() instanceof JScrollPane) )
{
if (viewPref.width < portBounds.width)
viewPref.width = portBounds.width;
if (viewPref.height < portBounds.height)
viewPref.height = portBounds.height;
+ }
- // If the view is larger than the port, the port is top and right aligned.
- if (portLowerRight.x > viewPref.width)
- portBounds.x = 0;
+ // If the view is larger than the port, the port is top and right
+ // aligned.
+ if (portLowerRight.x > viewPref.width)
+ portBounds.x = 0;
- if (portLowerRight.y > viewPref.height)
- portBounds.y = 0;
- }
+ if (portLowerRight.y > viewPref.height)
+ portBounds.y = 0;
port.setViewSize(viewPref);
port.setViewPosition(portBounds.getLocation());
diff --git a/javax/swing/plaf/basic/BasicTreeUI.java b/javax/swing/plaf/basic/BasicTreeUI.java
index 1c6e6c5e5..a20b56315 100644
--- a/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/javax/swing/plaf/basic/BasicTreeUI.java
@@ -38,6 +38,8 @@
package javax.swing.plaf.basic;
+import gnu.javax.swing.tree.GnuPath;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
@@ -76,7 +78,6 @@ import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
-import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
@@ -96,17 +97,16 @@ import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TreeUI;
-import javax.swing.text.Caret;
import javax.swing.tree.AbstractLayoutCache;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
-import javax.swing.tree.FixedHeightLayoutCache;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
+import javax.swing.tree.VariableHeightLayoutCache;
/**
* A delegate providing the user interface for <code>JTree</code> according to
@@ -117,16 +117,17 @@ import javax.swing.tree.TreeSelectionModel;
* @author Sascha Brawer (brawer@dandelis.ch)
* @author Audrius Meskauskas (audriusa@bioinformatics.org)
*/
-public class BasicTreeUI extends TreeUI
+public class BasicTreeUI
+ extends TreeUI
{
/**
* The tree cell editing may be started by the single mouse click on the
* selected cell. To separate it from the double mouse click, the editing
- * session starts after this time (in ms) after that single click, and only
- * no other clicks were performed during that time.
+ * session starts after this time (in ms) after that single click, and only no
+ * other clicks were performed during that time.
*/
- static int WAIT_TILL_EDITING = 900;
-
+ static int WAIT_TILL_EDITING = 900;
+
/** Collapse Icon for the tree. */
protected transient Icon collapsedIcon;
@@ -270,20 +271,21 @@ public class BasicTreeUI extends TreeUI
private TreeExpansionListener treeExpansionListener;
private TreeModelListener treeModelListener;
-
+
/**
* This timer fires the editing action after about 1200 ms if not reset during
- * that time. It handles the editing start with the single mouse click
- * (and not the double mouse click) on the selected tree node.
+ * that time. It handles the editing start with the single mouse click (and
+ * not the double mouse click) on the selected tree node.
*/
Timer startEditTimer;
-
+
/**
* The special value of the mouse event is sent indicating that this is not
* just the mouse click, but the mouse click on the selected node. Sending
* such event forces to start the cell editing session.
*/
- static final MouseEvent EDIT = new MouseEvent(new Label(), 7,7,7,7,7,7, false);
+ static final MouseEvent EDIT = new MouseEvent(new Label(), 7, 7, 7, 7, 7, 7,
+ false);
/**
* Creates a new BasicTreeUI object.
@@ -306,22 +308,21 @@ public class BasicTreeUI extends TreeUI
treeExpansionListener = createTreeExpansionListener();
treeModelListener = createTreeModelListener();
- editingRow = -1;
- lastSelectedRow = -1;
+ editingRow = - 1;
+ lastSelectedRow = - 1;
}
/**
* Returns an instance of the UI delegate for the specified component.
*
- * @param c
- * the <code>JComponent</code> for which we need a UI delegate for.
+ * @param c the <code>JComponent</code> for which we need a UI delegate for.
* @return the <code>ComponentUI</code> for c.
*/
public static ComponentUI createUI(JComponent c)
{
return new BasicTreeUI();
}
-
+
/**
* Returns the Hash color.
*
@@ -335,8 +336,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the Hash color.
*
- * @param color
- * the <code>Color</code> to set the Hash to.
+ * @param color the <code>Color</code> to set the Hash to.
*/
protected void setHashColor(Color color)
{
@@ -347,8 +347,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the left child's indent value.
*
- * @param newAmount
- * is the new indent value for the left child.
+ * @param newAmount is the new indent value for the left child.
*/
public void setLeftChildIndent(int newAmount)
{
@@ -368,8 +367,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the right child's indent value.
*
- * @param newAmount
- * is the new indent value for the right child.
+ * @param newAmount is the new indent value for the right child.
*/
public void setRightChildIndent(int newAmount)
{
@@ -389,8 +387,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the expanded icon.
*
- * @param newG
- * is the new expanded icon.
+ * @param newG is the new expanded icon.
*/
public void setExpandedIcon(Icon newG)
{
@@ -410,8 +407,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the collapsed icon.
*
- * @param newG
- * is the new collapsed icon.
+ * @param newG is the new collapsed icon.
*/
public void setCollapsedIcon(Icon newG)
{
@@ -431,8 +427,7 @@ public class BasicTreeUI extends TreeUI
/**
* Updates the componentListener, if necessary.
*
- * @param largeModel
- * sets this.largeModel to it.
+ * @param largeModel sets this.largeModel to it.
*/
protected void setLargeModel(boolean largeModel)
{
@@ -457,13 +452,12 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the row height.
*
- * @param rowHeight
- * is the height to set this.rowHeight to.
+ * @param rowHeight is the height to set this.rowHeight to.
*/
protected void setRowHeight(int rowHeight)
{
if (rowHeight == 0)
- rowHeight = Math.max(getMaxHeight(tree), 20);
+ rowHeight = getMaxHeight(tree);
treeState.setRowHeight(rowHeight);
}
@@ -474,15 +468,14 @@ public class BasicTreeUI extends TreeUI
*/
protected int getRowHeight()
{
- return treeState.getRowHeight();
+ return tree.getRowHeight();
}
/**
* Sets the TreeCellRenderer to <code>tcr</code>. This invokes
* <code>updateRenderer</code>.
*
- * @param tcr
- * is the new TreeCellRenderer.
+ * @param tcr is the new TreeCellRenderer.
*/
protected void setCellRenderer(TreeCellRenderer tcr)
{
@@ -507,13 +500,13 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the tree's model.
*
- * @param model
- * to set the treeModel to.
+ * @param model to set the treeModel to.
*/
protected void setModel(TreeModel model)
{
tree.setModel(model);
treeModel = tree.getModel();
+ treeState.setModel(treeModel);
}
/**
@@ -529,8 +522,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the root to being visible.
*
- * @param newValue
- * sets the visibility of the root
+ * @param newValue sets the visibility of the root
*/
protected void setRootVisible(boolean newValue)
{
@@ -550,8 +542,7 @@ public class BasicTreeUI extends TreeUI
/**
* Determines whether the node handles are to be displayed.
*
- * @param newValue
- * sets whether or not node handles should be displayed.
+ * @param newValue sets whether or not node handles should be displayed.
*/
protected void setShowsRootHandles(boolean newValue)
{
@@ -571,8 +562,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the cell editor.
*
- * @param editor
- * to set the cellEditor to.
+ * @param editor to set the cellEditor to.
*/
protected void setCellEditor(TreeCellEditor editor)
{
@@ -593,8 +583,7 @@ public class BasicTreeUI extends TreeUI
/**
* Configures the receiver to allow, or not allow, editing.
*
- * @param newValue
- * sets the receiver to allow editing if true.
+ * @param newValue sets the receiver to allow editing if true.
*/
protected void setEditable(boolean newValue)
{
@@ -615,8 +604,7 @@ public class BasicTreeUI extends TreeUI
* Resets the selection model. The appropriate listeners are installed on the
* model.
*
- * @param newLSM
- * resets the selection model.
+ * @param newLSM resets the selection model.
*/
protected void setSelectionModel(TreeSelectionModel newLSM)
{
@@ -642,35 +630,23 @@ public class BasicTreeUI extends TreeUI
* path will be drawn to. Will return null if any component in path is
* currently valid.
*
- * @param tree
- * is the current tree the path will be drawn to.
- * @param path
- * is the current path the tree to draw to.
+ * @param tree is the current tree the path will be drawn to.
+ * @param path is the current path the tree to draw to.
* @return the Rectangle enclosing the label portion that the last item in the
* path will be drawn to.
*/
public Rectangle getPathBounds(JTree tree, TreePath path)
{
- int row = -1;
- Object cell = null;
- if (path != null)
- {
- row = getRowForPath(tree, path);
- cell = path.getLastPathComponent();
- }
- return nodeDimensions.getNodeDimensions(cell, row, getLevel(cell),
- tree.isExpanded(path),
- new Rectangle());
+ return treeState.getBounds(path, new Rectangle());
}
/**
* Returns the max height of all the nodes in the tree.
*
- * @param tree -
- * the current tree
+ * @param tree - the current tree
* @return the max height.
*/
- private int getMaxHeight(JTree tree)
+ int getMaxHeight(JTree tree)
{
if (maxHeight != 0)
return maxHeight;
@@ -699,65 +675,39 @@ public class BasicTreeUI extends TreeUI
/**
* Returns the path for passed in row. If row is not visible null is returned.
*
- * @param tree
- * is the current tree to return path for.
- * @param row
- * is the row number of the row to return.
+ * @param tree is the current tree to return path for.
+ * @param row is the row number of the row to return.
* @return the path for passed in row. If row is not visible null is returned.
*/
public TreePath getPathForRow(JTree tree, int row)
{
- if (treeModel != null && currentVisiblePath != null)
- {
- Object[] nodes = currentVisiblePath.getPath();
- if (row < nodes.length)
- return new TreePath(getPathToRoot(nodes[row], 0));
- }
- return null;
+ return treeState.getPathForRow(row);
}
/**
* Returns the row that the last item identified in path is visible at. Will
* return -1 if any of the elments in the path are not currently visible.
*
- * @param tree
- * is the current tree to return the row for.
- * @param path
- * is the path used to find the row.
+ * @param tree is the current tree to return the row for.
+ * @param path is the path used to find the row.
* @return the row that the last item identified in path is visible at. Will
* return -1 if any of the elments in the path are not currently
* visible.
*/
public int getRowForPath(JTree tree, TreePath path)
{
- int row = 0;
- Object dest = path.getLastPathComponent();
- int rowCount = getRowCount(tree);
- if (currentVisiblePath != null)
- {
- Object[] nodes = currentVisiblePath.getPath();
- while (row < rowCount)
- {
- if (dest.equals(nodes[row]))
- return row;
- row++;
- }
- }
- return -1;
+ return treeState.getRowForPath(path);
}
/**
* Returns the number of rows that are being displayed.
*
- * @param tree
- * is the current tree to return the number of rows for.
+ * @param tree is the current tree to return the number of rows for.
* @return the number of rows being displayed.
*/
public int getRowCount(JTree tree)
{
- if (currentVisiblePath != null)
- return currentVisiblePath.getPathCount();
- return 0;
+ return treeState.getRowCount();
}
/**
@@ -766,35 +716,21 @@ public class BasicTreeUI extends TreeUI
* valid path. If you need to test if the returned object is exactly at x,y
* you should get the bounds for the returned path and test x,y against that.
*
- * @param tree
- * the tree to search for the closest path
- * @param x
- * is the x coordinate of the location to search
- * @param y
- * is the y coordinate of the location to search
+ * @param tree the tree to search for the closest path
+ * @param x is the x coordinate of the location to search
+ * @param y is the y coordinate of the location to search
* @return the tree path closes to x,y.
*/
public TreePath getClosestPathForLocation(JTree tree, int x, int y)
{
- int row = Math.round(y / getMaxHeight(tree));
- TreePath path = getPathForRow(tree, row);
-
- // no row is visible at this node
- while (row > 0 && path == null)
- {
- --row;
- path = getPathForRow(tree, row);
- }
-
- return path;
+ return treeState.getPathClosestTo(x, y);
}
/**
* Returns true if the tree is being edited. The item that is being edited can
* be returned by getEditingPath().
*
- * @param tree
- * is the tree to check for editing.
+ * @param tree is the tree to check for editing.
* @return true if the tree is being edited.
*/
public boolean isEditing(JTree tree)
@@ -807,8 +743,7 @@ public class BasicTreeUI extends TreeUI
* being edited. Returns true if the editor allows the editing session to
* stop.
*
- * @param tree
- * is the tree to stop the editing on
+ * @param tree is the tree to stop the editing on
* @return true if the editor allows the editing session to stop.
*/
public boolean stopEditing(JTree tree)
@@ -818,32 +753,29 @@ public class BasicTreeUI extends TreeUI
completeEditing(false, false, true);
finish();
}
- return !isEditing(tree);
+ return ! isEditing(tree);
}
/**
* Cancels the current editing session.
*
- * @param tree
- * is the tree to cancel the editing session on.
+ * @param tree is the tree to cancel the editing session on.
*/
public void cancelEditing(JTree tree)
- {
- // There is no need to send the cancel message to the editor,
- // as the cancellation event itself arrives from it. This would
- // only be necessary when cancelling the editing programatically.
- completeEditing(false, false, false);
- finish();
+ {
+ // There is no need to send the cancel message to the editor,
+ // as the cancellation event itself arrives from it. This would
+ // only be necessary when cancelling the editing programatically.
+ completeEditing(false, false, false);
+ finish();
}
/**
* Selects the last item in path and tries to edit it. Editing will fail if
* the CellEditor won't allow it for the selected item.
*
- * @param tree
- * is the tree to edit on.
- * @param path
- * is the path in tree to edit on.
+ * @param tree is the tree to edit on.
+ * @param path is the path in tree to edit on.
*/
public void startEditingAtPath(JTree tree, TreePath path)
{
@@ -853,8 +785,7 @@ public class BasicTreeUI extends TreeUI
/**
* Returns the path to the element that is being editted.
*
- * @param tree
- * is the tree to get the editing path from.
+ * @param tree is the tree to get the editing path from.
* @return the path that is being edited.
*/
public TreePath getEditingPath(JTree tree)
@@ -902,7 +833,8 @@ public class BasicTreeUI extends TreeUI
/**
* Creates an instance of NodeDimensions that is able to determine the size of
- * a given node in the tree.
+ * a given node in the tree. The node dimensions must be created before
+ * configuring the layout cache.
*
* @return the NodeDimensions of a given node in the tree
*/
@@ -1018,7 +950,7 @@ public class BasicTreeUI extends TreeUI
*/
protected AbstractLayoutCache createLayoutCache()
{
- return new FixedHeightLayoutCache();
+ return new VariableHeightLayoutCache();
}
/**
@@ -1152,8 +1084,7 @@ public class BasicTreeUI extends TreeUI
* by getting the expanded descendants from the tree and forwarding to the
* tree state.
*
- * @param path
- * the path used to update the expanded states
+ * @param path the path used to update the expanded states
*/
protected void updateExpandedDescendants(TreePath path)
{
@@ -1165,8 +1096,7 @@ public class BasicTreeUI extends TreeUI
/**
* Returns a path to the last child of <code>parent</code>
*
- * @param parent
- * is the topmost path to specified
+ * @param parent is the topmost path to specified
* @return a path to the last child of parent
*/
protected TreePath getLastChildPath(TreePath parent)
@@ -1212,11 +1142,13 @@ public class BasicTreeUI extends TreeUI
/**
* Resets the treeState instance based on the tree we're providing the look
- * and feel for.
+ * and feel for. The node dimensions handler is required and must be created
+ * in advance.
*/
protected void configureLayoutCache()
{
treeState = createLayoutCache();
+ treeState.setNodeDimensions(nodeDimensions);
}
/**
@@ -1236,42 +1168,19 @@ public class BasicTreeUI extends TreeUI
*/
protected void updateCachedPreferredSize()
{
- int maxWidth = 0;
- updateCurrentVisiblePath();
- boolean isLeaf = false;
- if (currentVisiblePath != null)
- {
- Object[] path = currentVisiblePath.getPath();
- for (int i = 0; i < path.length; i++)
- {
- TreePath curr = new TreePath(getPathToRoot(path[i], 0));
- Rectangle bounds = getPathBounds(tree, curr);
- if (treeModel != null)
- isLeaf = treeModel.isLeaf(path[i]);
- if (!isLeaf && hasControlIcons())
- bounds.width += getCurrentControlIcon(curr).getIconWidth();
- maxWidth = Math.max(maxWidth, bounds.x + bounds.width);
- }
-
- maxHeight = 0;
- maxHeight = getMaxHeight(tree);
- preferredSize = new Dimension(maxWidth, (maxHeight * path.length));
- }
- else
- preferredSize = new Dimension(0, 0);
- validCachedPreferredSize = true;
+ validCachedPreferredSize = false;
}
/**
* Messaged from the VisibleTreeNode after it has been expanded.
*
- * @param path
- * is the path that has been expanded.
+ * @param path is the path that has been expanded.
*/
protected void pathWasExpanded(TreePath path)
{
validCachedPreferredSize = false;
- tree.repaint();
+ treeState.setExpandedState(path, true);
+ tree.repaint();
}
/**
@@ -1280,6 +1189,7 @@ public class BasicTreeUI extends TreeUI
protected void pathWasCollapsed(TreePath path)
{
validCachedPreferredSize = false;
+ treeState.setExpandedState(path, false);
tree.repaint();
}
@@ -1345,8 +1255,7 @@ public class BasicTreeUI extends TreeUI
/**
* Converts the modifiers.
*
- * @param mod -
- * modifier to convert
+ * @param mod - modifier to convert
* @returns the new modifier
*/
private int convertModifiers(int mod)
@@ -1354,27 +1263,27 @@ public class BasicTreeUI extends TreeUI
if ((mod & KeyEvent.SHIFT_DOWN_MASK) != 0)
{
mod |= KeyEvent.SHIFT_MASK;
- mod &= ~KeyEvent.SHIFT_DOWN_MASK;
+ mod &= ~ KeyEvent.SHIFT_DOWN_MASK;
}
if ((mod & KeyEvent.CTRL_DOWN_MASK) != 0)
{
mod |= KeyEvent.CTRL_MASK;
- mod &= ~KeyEvent.CTRL_DOWN_MASK;
+ mod &= ~ KeyEvent.CTRL_DOWN_MASK;
}
if ((mod & KeyEvent.META_DOWN_MASK) != 0)
{
mod |= KeyEvent.META_MASK;
- mod &= ~KeyEvent.META_DOWN_MASK;
+ mod &= ~ KeyEvent.META_DOWN_MASK;
}
if ((mod & KeyEvent.ALT_DOWN_MASK) != 0)
{
mod |= KeyEvent.ALT_MASK;
- mod &= ~KeyEvent.ALT_DOWN_MASK;
+ mod &= ~ KeyEvent.ALT_DOWN_MASK;
}
if ((mod & KeyEvent.ALT_GRAPH_DOWN_MASK) != 0)
{
mod |= KeyEvent.ALT_GRAPH_MASK;
- mod &= ~KeyEvent.ALT_GRAPH_DOWN_MASK;
+ mod &= ~ KeyEvent.ALT_GRAPH_DOWN_MASK;
}
return mod;
}
@@ -1399,8 +1308,7 @@ public class BasicTreeUI extends TreeUI
/**
* Install the UI for the component
*
- * @param c
- * the component to install UI for
+ * @param c the component to install UI for
*/
public void installUI(JComponent c)
{
@@ -1419,6 +1327,8 @@ public class BasicTreeUI extends TreeUI
setModel(tree.getModel());
treeSelectionModel = tree.getSelectionModel();
+ setRootVisible(tree.isRootVisible());
+ treeState.setRootVisible(tree.isRootVisible());
completeUIInstall();
}
@@ -1436,8 +1346,7 @@ public class BasicTreeUI extends TreeUI
/**
* Uninstall the UI for the component
*
- * @param c
- * the component to uninstall UI for
+ * @param c the component to uninstall UI for
*/
public void uninstallUI(JComponent c)
{
@@ -1456,51 +1365,82 @@ public class BasicTreeUI extends TreeUI
* component is being painted. Subclasses should override this method and use
* the specified Graphics object to render the content of the component.
*
- * @param g
- * the Graphics context in which to paint
- * @param c
- * the component being painted; this argument is often ignored, but
+ * @param g the Graphics context in which to paint
+ * @param c the component being painted; this argument is often ignored, but
* might be used if the UI object is stateless and shared by multiple
* components
*/
public void paint(Graphics g, JComponent c)
{
JTree tree = (JTree) c;
- updateCurrentVisiblePath();
Rectangle clip = g.getClipBounds();
+
Insets insets = tree.getInsets();
- if (clip != null && treeModel != null && currentVisiblePath != null)
+ if (clip != null && treeModel != null)
{
int startIndex = tree.getClosestRowForLocation(clip.x, clip.y);
int endIndex = tree.getClosestRowForLocation(clip.x + clip.width,
clip.y + clip.height);
- paintVerticalPartOfLeg(g, clip, insets, currentVisiblePath);
for (int i = startIndex; i <= endIndex; i++)
{
- Object curr = currentVisiblePath.getPathComponent(i);
- boolean isLeaf = treeModel.isLeaf(curr);
- TreePath path = new TreePath(getPathToRoot(curr, 0));
-
+ TreePath path = treeState.getPathForRow(i);
+ boolean isLeaf = treeModel.isLeaf(path.getLastPathComponent());
boolean isExpanded = tree.isExpanded(path);
+
Rectangle bounds = getPathBounds(tree, path);
+
paintHorizontalPartOfLeg(g, clip, insets, bounds, path, i,
isExpanded, false, isLeaf);
paintRow(g, clip, insets, bounds, path, i, isExpanded, false,
isLeaf);
+ if (isLastChild(path))
+ paintVerticalPartOfLeg(g, clip, insets, path);
}
+
+ // Also paint dashes to the invisible nodes below:
+ int rows = treeState.getRowCount();
+
+ if (endIndex < rows)
+ for (int i = endIndex + 1; i < rows; i++)
+ {
+ TreePath path = treeState.getPathForRow(i);
+ if (isLastChild(path))
+ paintVerticalPartOfLeg(g, clip, insets, path);
+ }
+ }
+ }
+
+ /**
+ * Check if the path is referring to the last child of some parent.
+ */
+ private boolean isLastChild(TreePath path)
+ {
+ if (path instanceof GnuPath)
+ {
+ // Except the seldom case when the layout cache is changed, this
+ // optimized code will be executed.
+ return ((GnuPath) path).isLastChild;
+ }
+ else
+ {
+ // Non optimized general case.
+ TreePath parent = path.getParentPath();
+ if (parent == null)
+ return false;
+ int childCount = treeState.getVisibleChildCount(parent);
+ int p = treeModel.getIndexOfChild(parent, path.getLastPathComponent());
+ return p == childCount - 1;
}
}
/**
* Ensures that the rows identified by beginRow through endRow are visible.
*
- * @param beginRow
- * is the first row
- * @param endRow
- * is the last row
+ * @param beginRow is the first row
+ * @param endRow is the last row
*/
protected void ensureRowsAreVisible(int beginRow, int endRow)
{
@@ -1514,7 +1454,7 @@ public class BasicTreeUI extends TreeUI
for (int i = beginRow; i < endRow; i++)
{
TreePath path = getPathForRow(tree, i);
- if (!tree.isVisible(path))
+ if (! tree.isVisible(path))
tree.makeVisible(path);
}
}
@@ -1522,8 +1462,7 @@ public class BasicTreeUI extends TreeUI
/**
* Sets the preferred minimum size.
*
- * @param newSize
- * is the new preferred minimum size.
+ * @param newSize is the new preferred minimum size.
*/
public void setPreferredMinSize(Dimension newSize)
{
@@ -1537,15 +1476,17 @@ public class BasicTreeUI extends TreeUI
*/
public Dimension getPreferredMinSize()
{
- return preferredMinSize;
+ if (preferredMinSize == null)
+ return getPreferredSize(tree);
+ else
+ return preferredMinSize;
}
/**
* Returns the preferred size to properly display the tree, this is a cover
* method for getPreferredSize(c, false).
*
- * @param c
- * the component whose preferred size is being queried; this argument
+ * @param c the component whose preferred size is being queried; this argument
* is often ignored but might be used if the UI object is stateless
* and shared by multiple components
* @return the preferred size
@@ -1559,17 +1500,26 @@ public class BasicTreeUI extends TreeUI
* Returns the preferred size to represent the tree in c. If checkConsistancy
* is true, checkConsistancy is messaged first.
*
- * @param c
- * the component whose preferred size is being queried.
- * @param checkConsistancy
- * if true must check consistancy
+ * @param c the component whose preferred size is being queried.
+ * @param checkConsistancy if true must check consistancy
* @return the preferred size
*/
public Dimension getPreferredSize(JComponent c, boolean checkConsistancy)
{
- // FIXME: checkConsistancy not implemented, c not used
- if (!validCachedPreferredSize)
- updateCachedPreferredSize();
+ if (! validCachedPreferredSize)
+ {
+ // Add the scrollbar dimensions to the preferred size.
+ int sw = UIManager.getInt("ScrollBar.width");
+ preferredSize = new Dimension(treeState.getPreferredWidth(null),
+ treeState.getPreferredHeight());
+ validCachedPreferredSize = true;
+ System.out.println(sw+":"+preferredSize.width);
+ //preferredSize.width +=17;//+= sw;
+ // minus: 63 ok 62 ne ok
+ // plus: +10 dalinis +8 dalinis
+ // pref 173 bar 17
+ new Exception().printStackTrace();
+ }
return preferredSize;
}
@@ -1577,31 +1527,24 @@ public class BasicTreeUI extends TreeUI
* Returns the minimum size for this component. Which will be the min
* preferred size or (0,0).
*
- * @param c
- * the component whose min size is being queried.
+ * @param c the component whose min size is being queried.
* @returns the preferred size or null
*/
public Dimension getMinimumSize(JComponent c)
{
- Dimension min = getPreferredMinSize();
- if (min == null)
- return new Dimension();
- return min;
+ return preferredMinSize = getPreferredSize(c);
}
/**
* Returns the maximum size for the component, which will be the preferred
* size if the instance is currently in JTree or (0,0).
*
- * @param c
- * the component whose preferred size is being queried
+ * @param c the component whose preferred size is being queried
* @return the max size or null
*/
public Dimension getMaximumSize(JComponent c)
{
- if (c instanceof JTree)
- return ((JTree) c).getPreferredSize();
- return new Dimension();
+ return getPreferredSize(c);
}
/**
@@ -1622,12 +1565,9 @@ public class BasicTreeUI extends TreeUI
* cancelEditing. If messageTree is true, the treeModel is messaged with
* valueForPathChanged.
*
- * @param messageStop
- * message to stop editing
- * @param messageCancel
- * message to cancel editing
- * @param messageTree
- * message to treeModel
+ * @param messageStop message to stop editing
+ * @param messageCancel message to cancel editing
+ * @param messageTree message to treeModel
*/
protected void completeEditing(boolean messageStop, boolean messageCancel,
boolean messageTree)
@@ -1659,10 +1599,8 @@ public class BasicTreeUI extends TreeUI
* Will start editing for node if there is a cellEditor and shouldSelectCall
* returns true. This assumes that path is valid and visible.
*
- * @param path
- * is the path to start editing
- * @param event
- * is the MouseEvent performed on the path
+ * @param path is the path to start editing
+ * @param event is the MouseEvent performed on the path
* @return true if successful
*/
protected boolean startEditing(TreePath path, MouseEvent event)
@@ -1676,8 +1614,7 @@ public class BasicTreeUI extends TreeUI
updateCellEditor();
TreeCellEditor ed = getCellEditor();
- if (ed != null
- && (event == EDIT || ed.shouldSelectCell(event))
+ if (ed != null && (event == EDIT || ed.shouldSelectCell(event))
&& ed.isCellEditable(event))
{
Rectangle bounds = getPathBounds(tree, path);
@@ -1718,12 +1655,9 @@ public class BasicTreeUI extends TreeUI
* If the <code>mouseX</code> and <code>mouseY</code> are in the expand or
* collapse region of the row, this will toggle the row.
*
- * @param path
- * the path we are concerned with
- * @param mouseX
- * is the cursor's x position
- * @param mouseY
- * is the cursor's y position
+ * @param path the path we are concerned with
+ * @param mouseX is the cursor's x position
+ * @param mouseY is the cursor's y position
*/
protected void checkForClickInExpandControl(TreePath path, int mouseX,
int mouseY)
@@ -1737,12 +1671,9 @@ public class BasicTreeUI extends TreeUI
* the area of row that is used to expand/collpse the node and the node at row
* does not represent a leaf.
*
- * @param path
- * the path we are concerned with
- * @param mouseX
- * is the cursor's x position
- * @param mouseY
- * is the cursor's y position
+ * @param path the path we are concerned with
+ * @param mouseX is the cursor's x position
+ * @param mouseY is the cursor's y position
* @return true if the <code>mouseX</code> and <code>mouseY</code> fall in
* the area of row that is used to expand/collpse the node and the
* node at row does not represent a leaf.
@@ -1753,7 +1684,7 @@ public class BasicTreeUI extends TreeUI
boolean cntlClick = false;
int row = getRowForPath(tree, path);
- if (!isLeaf(row))
+ if (! isLeaf(row))
{
Rectangle bounds = getPathBounds(tree, path);
@@ -1769,12 +1700,9 @@ public class BasicTreeUI extends TreeUI
* Messaged when the user clicks the particular row, this invokes
* toggleExpandState.
*
- * @param path
- * the path we are concerned with
- * @param mouseX
- * is the cursor's x position
- * @param mouseY
- * is the cursor's y position
+ * @param path the path we are concerned with
+ * @param mouseX is the cursor's x position
+ * @param mouseY is the cursor's y position
*/
protected void handleExpandControlClick(TreePath path, int mouseX, int mouseY)
{
@@ -1787,8 +1715,7 @@ public class BasicTreeUI extends TreeUI
* invoked to scroll as many of the children to visible as possible (tries to
* scroll to last visible descendant of path).
*
- * @param path
- * the path we are concerned with
+ * @param path the path we are concerned with
*/
protected void toggleExpandState(TreePath path)
{
@@ -1802,8 +1729,7 @@ public class BasicTreeUI extends TreeUI
* Returning true signifies a mouse event on the node should toggle the
* selection of only the row under the mouse.
*
- * @param event
- * is the MouseEvent performed on the row.
+ * @param event is the MouseEvent performed on the row.
* @return true signifies a mouse event on the node should toggle the
* selection of only the row under the mouse.
*/
@@ -1816,8 +1742,7 @@ public class BasicTreeUI extends TreeUI
* Returning true signifies a mouse event on the node should select from the
* anchor point.
*
- * @param event
- * is the MouseEvent performed on the node.
+ * @param event is the MouseEvent performed on the node.
* @return true signifies a mouse event on the node should select from the
* anchor point.
*/
@@ -1831,8 +1756,7 @@ public class BasicTreeUI extends TreeUI
* the event. This is invoked after checkForClickInExpandControl, implying the
* location is not in the expand (toggle) control.
*
- * @param event
- * is the MouseEvent performed on the row.
+ * @param event is the MouseEvent performed on the row.
* @return true indicates the row under the mouse should be toggled based on
* the event.
*/
@@ -1848,10 +1772,8 @@ public class BasicTreeUI extends TreeUI
* selection is updated from the anchor point. Otherwise, the row is selected,
* and if the even specified a toggle event the row is expanded/collapsed.
*
- * @param path
- * is the path selected for an event
- * @param event
- * is the MouseEvent performed on the path.
+ * @param path is the path selected for an event
+ * @param event is the MouseEvent performed on the path.
*/
protected void selectPathForEvent(TreePath path, MouseEvent event)
{
@@ -1883,8 +1805,7 @@ public class BasicTreeUI extends TreeUI
/**
* Returns true if the node at <code>row</code> is a leaf.
*
- * @param row
- * is the row we are concerned with.
+ * @param row is the row we are concerned with.
* @return true if the node at <code>row</code> is a leaf.
*/
protected boolean isLeaf(int row)
@@ -1902,46 +1823,38 @@ public class BasicTreeUI extends TreeUI
* are pressed for the JTree. The actionPerformed method is called when a key
* that has been registered for the JTree is received.
*/
- class TreeAction extends AbstractAction
+ class TreeAction
+ extends AbstractAction
{
/**
* What to do when this action is called.
*
- * @param e
- * the ActionEvent that caused this action.
+ * @param e the ActionEvent that caused this action.
*/
public void actionPerformed(ActionEvent e)
{
+ String command = e.getActionCommand();
TreePath lead = tree.getLeadSelectionPath();
- if (e.getActionCommand().equals("selectPreviousChangeLead")
- || e.getActionCommand().equals("selectPreviousExtendSelection")
- || e.getActionCommand().equals("selectPrevious")
- || e.getActionCommand().equals("selectNext")
- || e.getActionCommand().equals("selectNextExtendSelection")
- || e.getActionCommand().equals("selectNextChangeLead"))
+ if (command.equals("selectPreviousChangeLead")
+ || command.equals("selectPreviousExtendSelection")
+ || command.equals("selectPrevious") || command.equals("selectNext")
+ || command.equals("selectNextExtendSelection")
+ || command.equals("selectNextChangeLead"))
(new TreeIncrementAction(0, "")).actionPerformed(e);
- else if (e.getActionCommand().equals("selectParent")
- || e.getActionCommand().equals("selectChild"))
+ else if (command.equals("selectParent") || command.equals("selectChild"))
(new TreeTraverseAction(0, "")).actionPerformed(e);
- else if (e.getActionCommand().equals("selectAll"))
+ else if (command.equals("selectAll"))
{
- TreePath[] paths = new TreePath[tree.getVisibleRowCount()];
-
- Object curr = getNextVisibleNode(treeModel.getRoot());
- int i = 0;
- while (curr != null && i < paths.length)
- {
- paths[i] = new TreePath(getPathToRoot(curr, 0));
- i++;
- }
-
+ TreePath[] paths = new TreePath[treeState.getRowCount()];
+ for (int i = 0; i < paths.length; i++)
+ paths[i] = treeState.getPathForRow(i);
tree.addSelectionPaths(paths);
}
- else if (e.getActionCommand().equals("startEditing"))
+ else if (command.equals("startEditing"))
tree.startEditingAtPath(lead);
- else if (e.getActionCommand().equals("toggle"))
+ else if (command.equals("toggle"))
{
if (tree.isEditing())
tree.stopEditing();
@@ -1949,14 +1862,14 @@ public class BasicTreeUI extends TreeUI
{
Object last = lead.getLastPathComponent();
TreePath path = new TreePath(getPathToRoot(last, 0));
- if (!treeModel.isLeaf(last))
+ if (! treeModel.isLeaf(last))
toggleExpandState(path);
}
}
- else if (e.getActionCommand().equals("clearSelection"))
+ else if (command.equals("clearSelection"))
tree.clearSelection();
- if (tree.isEditing() && !e.getActionCommand().equals("startEditing"))
+ if (tree.isEditing() && ! command.equals("startEditing"))
tree.stopEditing();
tree.scrollPathToVisible(lead);
@@ -1970,7 +1883,8 @@ public class BasicTreeUI extends TreeUI
* to the true receiver after altering the actionCommand property of the
* event.
*/
- private static class ActionListenerProxy extends AbstractAction
+ private static class ActionListenerProxy
+ extends AbstractAction
{
ActionListener target;
@@ -1992,11 +1906,12 @@ public class BasicTreeUI extends TreeUI
}
}
- /**
+ /**
* Updates the preferred size when scrolling, if necessary.
*/
- public class ComponentHandler extends ComponentAdapter implements
- ActionListener
+ public class ComponentHandler
+ extends ComponentAdapter
+ implements ActionListener
{
/**
* Timer used when inside a scrollpane and the scrollbar is adjusting
@@ -2017,8 +1932,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when the component's position changes.
*
- * @param e
- * the event that occurs when moving the component
+ * @param e the event that occurs when moving the component
*/
public void componentMoved(ComponentEvent e)
{
@@ -2048,8 +1962,7 @@ public class BasicTreeUI extends TreeUI
* Public as a result of Timer. If the scrollBar is null, or not adjusting,
* this stops the timer and updates the sizing.
*
- * @param ae
- * is the action performed
+ * @param ae is the action performed
*/
public void actionPerformed(ActionEvent ae)
{
@@ -2061,7 +1974,8 @@ public class BasicTreeUI extends TreeUI
* Listener responsible for getting cell editing events and updating the tree
* accordingly.
*/
- public class CellEditorHandler implements CellEditorListener
+ public class CellEditorHandler
+ implements CellEditorListener
{
/**
* Constructor
@@ -2075,8 +1989,7 @@ public class BasicTreeUI extends TreeUI
* Messaged when editing has stopped in the tree. Tells the listeners
* editing has stopped.
*
- * @param e
- * is the notification event
+ * @param e is the notification event
*/
public void editingStopped(ChangeEvent e)
{
@@ -2087,8 +2000,7 @@ public class BasicTreeUI extends TreeUI
* Messaged when editing has been canceled in the tree. This tells the
* listeners the editor has canceled editing.
*
- * @param e
- * is the notification event
+ * @param e is the notification event
*/
public void editingCanceled(ChangeEvent e)
{
@@ -2099,7 +2011,8 @@ public class BasicTreeUI extends TreeUI
/**
* Repaints the lead selection row when focus is lost/grained.
*/
- public class FocusHandler implements FocusListener
+ public class FocusHandler
+ implements FocusListener
{
/**
* Constructor
@@ -2113,8 +2026,7 @@ public class BasicTreeUI extends TreeUI
* Invoked when focus is activated on the tree we're in, redraws the lead
* row. Invoked when a component gains the keyboard focus.
*
- * @param e
- * is the focus event that is activated
+ * @param e is the focus event that is activated
*/
public void focusGained(FocusEvent e)
{
@@ -2125,8 +2037,7 @@ public class BasicTreeUI extends TreeUI
* Invoked when focus is deactivated on the tree we're in, redraws the lead
* row. Invoked when a component loses the keyboard focus.
*
- * @param e
- * is the focus event that is deactivated
+ * @param e is the focus event that is deactivated
*/
public void focusLost(FocusEvent e)
{
@@ -2138,7 +2049,8 @@ public class BasicTreeUI extends TreeUI
* This is used to get multiple key down events to appropriately genereate
* events.
*/
- public class KeyHandler extends KeyAdapter
+ public class KeyHandler
+ extends KeyAdapter
{
/** Key code that is being generated for. */
protected Action repeatKeyAction;
@@ -2160,8 +2072,7 @@ public class BasicTreeUI extends TreeUI
* user. Subsequent same key presses move the keyboard focus to the next
* object that starts with the same letter.
*
- * @param e
- * the key typed
+ * @param e the key typed
*/
public void keyTyped(KeyEvent e)
{
@@ -2171,8 +2082,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when a key has been pressed.
*
- * @param e
- * the key pressed
+ * @param e the key pressed
*/
public void keyPressed(KeyEvent e)
{
@@ -2182,8 +2092,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when a key has been released
*
- * @param e
- * the key released
+ * @param e the key released
*/
public void keyReleased(KeyEvent e)
{
@@ -2195,7 +2104,9 @@ public class BasicTreeUI extends TreeUI
* MouseListener is responsible for updating the selection based on mouse
* events.
*/
- public class MouseHandler extends MouseAdapter implements MouseMotionListener
+ public class MouseHandler
+ extends MouseAdapter
+ implements MouseMotionListener
{
/**
* Constructor
@@ -2208,11 +2119,10 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when a mouse button has been pressed on a component.
*
- * @param e
- * is the mouse event that occured
+ * @param e is the mouse event that occured
*/
public void mousePressed(MouseEvent e)
- {
+ {
// Any mouse click cancels the previous waiting edit action, initiated
// by the single click on the selected node.
if (startEditTimer != null)
@@ -2220,7 +2130,7 @@ public class BasicTreeUI extends TreeUI
startEditTimer.stop();
startEditTimer = null;
}
-
+
Point click = e.getPoint();
TreePath path = getClosestPathForLocation(tree, click.x, click.y);
@@ -2258,34 +2168,32 @@ public class BasicTreeUI extends TreeUI
if (inBounds)
{
TreePath currentLead = tree.getLeadSelectionPath();
- if (
- currentLead != null &&
- currentLead.equals(path) &&
- e.getClickCount() == 1 &&
- tree.isEditable()
- )
+ if (currentLead != null && currentLead.equals(path)
+ && e.getClickCount() == 1 && tree.isEditable())
{
// Schedule the editing session.
final TreePath editPath = path;
-
+
if (startEditTimer != null)
startEditTimer.stop();
-
- startEditTimer = new Timer(WAIT_TILL_EDITING,
- new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- startEditing(editPath, EDIT);
- }
- });
- startEditTimer.setRepeats(false);
- startEditTimer.start();
+
+ startEditTimer = new Timer(WAIT_TILL_EDITING,
+ new ActionListener()
+ {
+ public void actionPerformed(
+ ActionEvent e)
+ {
+ startEditing(editPath,
+ EDIT);
+ }
+ });
+ startEditTimer.setRepeats(false);
+ startEditTimer.start();
}
else
{
selectPath(tree, path);
- if (e.getClickCount() == 2 && !isLeaf(row))
+ if (e.getClickCount() == 2 && ! isLeaf(row))
toggleExpandState(path);
}
}
@@ -2309,8 +2217,7 @@ public class BasicTreeUI extends TreeUI
* the drag originated until the mouse button is released (regardless of
* whether the mouse position is within the bounds of the component).
*
- * @param e
- * is the mouse event that occured
+ * @param e is the mouse event that occured
*/
public void mouseDragged(MouseEvent e)
{
@@ -2321,8 +2228,7 @@ public class BasicTreeUI extends TreeUI
* Invoked when the mouse button has been moved on a component (with no
* buttons no down).
*
- * @param e
- * the mouse event that occured
+ * @param e the mouse event that occured
*/
public void mouseMoved(MouseEvent e)
{
@@ -2332,8 +2238,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when a mouse button has been released on a component.
*
- * @param e
- * is the mouse event that occured
+ * @param e is the mouse event that occured
*/
public void mouseReleased(MouseEvent e)
{
@@ -2346,7 +2251,8 @@ public class BasicTreeUI extends TreeUI
* events, until the mouse is released to the destination it is constructed
* with.
*/
- public class MouseInputHandler implements MouseInputListener
+ public class MouseInputHandler
+ implements MouseInputListener
{
/** Source that events are coming from */
protected Component source;
@@ -2357,12 +2263,9 @@ public class BasicTreeUI extends TreeUI
/**
* Constructor
*
- * @param source
- * that events are coming from
- * @param destination
- * that receives all events
- * @param e
- * is the event received
+ * @param source that events are coming from
+ * @param destination that receives all events
+ * @param e is the event received
*/
public MouseInputHandler(Component source, Component destination,
MouseEvent e)
@@ -2375,8 +2278,7 @@ public class BasicTreeUI extends TreeUI
* Invoked when the mouse button has been clicked (pressed and released) on
* a component.
*
- * @param e
- * mouse event that occured
+ * @param e mouse event that occured
*/
public void mouseClicked(MouseEvent e)
{
@@ -2386,8 +2288,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when a mouse button has been pressed on a component.
*
- * @param e
- * mouse event that occured
+ * @param e mouse event that occured
*/
public void mousePressed(MouseEvent e)
{
@@ -2397,8 +2298,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when a mouse button has been released on a component.
*
- * @param e
- * mouse event that occured
+ * @param e mouse event that occured
*/
public void mouseReleased(MouseEvent e)
{
@@ -2408,8 +2308,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when the mouse enters a component.
*
- * @param e
- * mouse event that occured
+ * @param e mouse event that occured
*/
public void mouseEntered(MouseEvent e)
{
@@ -2419,8 +2318,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when the mouse exits a component.
*
- * @param e
- * mouse event that occured
+ * @param e mouse event that occured
*/
public void mouseExited(MouseEvent e)
{
@@ -2433,8 +2331,7 @@ public class BasicTreeUI extends TreeUI
* the drag originated until the mouse button is released (regardless of
* whether the mouse position is within the bounds of the component).
*
- * @param e
- * mouse event that occured
+ * @param e mouse event that occured
*/
public void mouseDragged(MouseEvent e)
{
@@ -2445,8 +2342,7 @@ public class BasicTreeUI extends TreeUI
* Invoked when the mouse cursor has been moved onto a component but no
* buttons have been pushed.
*
- * @param e
- * mouse event that occured
+ * @param e mouse event that occured
*/
public void mouseMoved(MouseEvent e)
{
@@ -2467,7 +2363,8 @@ public class BasicTreeUI extends TreeUI
* BasicTreeUI method. X location does not include insets, that is handled in
* getPathBounds.
*/
- public class NodeDimensionsHandler extends AbstractLayoutCache.NodeDimensions
+ public class NodeDimensionsHandler
+ extends AbstractLayoutCache.NodeDimensions
{
/**
* Constructor
@@ -2483,16 +2380,11 @@ public class BasicTreeUI extends TreeUI
* bounds is null, a newly created Rectangle should be returned, otherwise
* the value should be placed in bounds and returned.
*
- * @param cell
- * the value to be represented
- * @param row
- * row being queried
- * @param depth
- * the depth of the row
- * @param expanded
- * true if row is expanded
- * @param size
- * a Rectangle containing the size needed to represent value
+ * @param cell the value to be represented
+ * @param row row being queried
+ * @param depth the depth of the row
+ * @param expanded true if row is expanded
+ * @param size a Rectangle containing the size needed to represent value
* @return containing the node dimensions, or null if node has no dimension
*/
public Rectangle getNodeDimensions(Object cell, int row, int depth,
@@ -2509,6 +2401,8 @@ public class BasicTreeUI extends TreeUI
{
size.x = getRowX(row, depth);
size.width = SwingUtilities.computeStringWidth(fm, s);
+ size.width = size.width + getCurrentControlIcon(null).getIconWidth()
+ + gap;
size.height = getMaxHeight(tree);
size.y = size.height * row;
}
@@ -2523,8 +2417,6 @@ public class BasicTreeUI extends TreeUI
*/
protected int getRowX(int row, int depth)
{
- if (row == 0)
- return 0;
return depth * rightChildIndent;
}
}// NodeDimensionsHandler
@@ -2533,7 +2425,8 @@ public class BasicTreeUI extends TreeUI
* PropertyChangeListener for the tree. Updates the appropriate varaible, or
* TreeState, based on what changes.
*/
- public class PropertyChangeHandler implements PropertyChangeListener
+ public class PropertyChangeHandler
+ implements PropertyChangeListener
{
/**
@@ -2547,15 +2440,15 @@ public class BasicTreeUI extends TreeUI
/**
* This method gets called when a bound property is changed.
*
- * @param event
- * A PropertyChangeEvent object describing the event source and the
- * property that has changed.
+ * @param event A PropertyChangeEvent object describing the event source and
+ * the property that has changed.
*/
public void propertyChange(PropertyChangeEvent event)
{
if ((event.getPropertyName()).equals("rootVisible"))
{
validCachedPreferredSize = false;
+ treeState.setRootVisible(tree.isRootVisible());
tree.repaint();
}
}
@@ -2565,8 +2458,8 @@ public class BasicTreeUI extends TreeUI
* Listener on the TreeSelectionModel, resets the row selection if any of the
* properties of the model change.
*/
- public class SelectionModelPropertyChangeHandler implements
- PropertyChangeListener
+ public class SelectionModelPropertyChangeHandler
+ implements PropertyChangeListener
{
/**
@@ -2580,9 +2473,8 @@ public class BasicTreeUI extends TreeUI
/**
* This method gets called when a bound property is changed.
*
- * @param event
- * A PropertyChangeEvent object describing the event source and the
- * property that has changed.
+ * @param event A PropertyChangeEvent object describing the event source and
+ * the property that has changed.
*/
public void propertyChange(PropertyChangeEvent event)
{
@@ -2593,7 +2485,8 @@ public class BasicTreeUI extends TreeUI
/**
* ActionListener that invokes cancelEditing when action performed.
*/
- public class TreeCancelEditingAction extends AbstractAction
+ public class TreeCancelEditingAction
+ extends AbstractAction
{
/**
@@ -2607,8 +2500,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when an action occurs.
*
- * @param e
- * event that occured
+ * @param e event that occured
*/
public void actionPerformed(ActionEvent e)
{
@@ -2630,7 +2522,8 @@ public class BasicTreeUI extends TreeUI
/**
* Updates the TreeState in response to nodes expanding/collapsing.
*/
- public class TreeExpansionHandler implements TreeExpansionListener
+ public class TreeExpansionHandler
+ implements TreeExpansionListener
{
/**
@@ -2644,25 +2537,23 @@ public class BasicTreeUI extends TreeUI
/**
* Called whenever an item in the tree has been expanded.
*
- * @param event
- * is the event that occured
+ * @param event is the event that occured
*/
public void treeExpanded(TreeExpansionEvent event)
{
validCachedPreferredSize = false;
- tree.repaint();
+ treeState.setExpandedState(event.getPath(), true);
}
/**
* Called whenever an item in the tree has been collapsed.
*
- * @param event
- * is the event that occured
+ * @param event is the event that occured
*/
public void treeCollapsed(TreeExpansionEvent event)
{
validCachedPreferredSize = false;
- tree.repaint();
+ treeState.setExpandedState(event.getPath(), false);
}
}// TreeExpansionHandler
@@ -2670,7 +2561,8 @@ public class BasicTreeUI extends TreeUI
* TreeHomeAction is used to handle end/home actions. Scrolls either the first
* or last cell to be visible based on direction.
*/
- public class TreeHomeAction extends AbstractAction
+ public class TreeHomeAction
+ extends AbstractAction
{
/** The direction, either home or end */
@@ -2679,10 +2571,8 @@ public class BasicTreeUI extends TreeUI
/**
* Constructor
*
- * @param direction -
- * it is home or end
- * @param name
- * is the name of the direction
+ * @param direction - it is home or end
+ * @param name is the name of the direction
*/
public TreeHomeAction(int direction, String name)
{
@@ -2692,8 +2582,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when an action occurs.
*
- * @param e
- * is the event that occured
+ * @param e is the event that occured
*/
public void actionPerformed(ActionEvent e)
{
@@ -2716,7 +2605,8 @@ public class BasicTreeUI extends TreeUI
* TreeIncrementAction is used to handle up/down actions. Selection is moved
* up or down based on direction.
*/
- public class TreeIncrementAction extends AbstractAction
+ public class TreeIncrementAction
+ extends AbstractAction
{
/** Specifies the direction to adjust the selection by. */
@@ -2725,10 +2615,8 @@ public class BasicTreeUI extends TreeUI
/**
* Constructor
*
- * @param direction
- * up or down
- * @param name
- * is the name of the direction
+ * @param direction up or down
+ * @param name is the name of the direction
*/
public TreeIncrementAction(int direction, String name)
{
@@ -2738,73 +2626,60 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when an action occurs.
*
- * @param e
- * is the event that occured
+ * @param e is the event that occured
*/
public void actionPerformed(ActionEvent e)
{
- Object last = tree.getLeadSelectionPath().getLastPathComponent();
+ TreePath currentPath = tree.getLeadSelectionPath();
+ int currentRow;
- if (e.getActionCommand().equals("selectPreviousChangeLead"))
- {
- Object prev = getPreviousVisibleNode(last);
+ if (currentPath != null)
+ currentRow = treeState.getRowForPath(currentPath);
+ else
+ currentRow = 0;
- if (prev != null)
- {
- TreePath newPath = new TreePath(getPathToRoot(prev, 0));
- selectPath(tree, newPath);
- tree.setLeadSelectionPath(newPath);
- }
+ int rows = treeState.getRowCount();
+
+ int nextRow = currentRow + 1;
+ int prevRow = currentRow - 1;
+ boolean hasNext = nextRow < rows;
+ boolean hasPrev = prevRow >= 0 && rows > 0;
+ TreePath newPath;
+ String command = e.getActionCommand();
+
+ if (command.equals("selectPreviousChangeLead") && hasPrev)
+ {
+ newPath = treeState.getPathForRow(prevRow);
+ selectPath(tree, newPath);
+ tree.setLeadSelectionPath(newPath);
}
- else if (e.getActionCommand().equals("selectPreviousExtendSelection"))
+ else if (command.equals("selectPreviousExtendSelection") && hasPrev)
{
- Object prev = getPreviousVisibleNode(last);
- if (prev != null)
- {
- TreePath newPath = new TreePath(getPathToRoot(prev, 0));
- tree.addSelectionPath(newPath);
- tree.setLeadSelectionPath(newPath);
- }
+ newPath = treeState.getPathForRow(prevRow);
+ tree.addSelectionPath(newPath);
+ tree.setLeadSelectionPath(newPath);
}
- else if (e.getActionCommand().equals("selectPrevious"))
+ else if (command.equals("selectPrevious") && hasPrev)
{
- Object prev = getPreviousVisibleNode(last);
-
- if (prev != null)
- {
- TreePath newPath = new TreePath(getPathToRoot(prev, 0));
- selectPath(tree, newPath);
- }
+ newPath = treeState.getPathForRow(prevRow);
+ selectPath(tree, newPath);
}
- else if (e.getActionCommand().equals("selectNext"))
+ else if (command.equals("selectNext") && hasNext)
{
- Object next = getNextVisibleNode(last);
-
- if (next != null)
- {
- TreePath newPath = new TreePath(getPathToRoot(next, 0));
- selectPath(tree, newPath);
- }
+ newPath = treeState.getPathForRow(nextRow);
+ selectPath(tree, newPath);
}
- else if (e.getActionCommand().equals("selectNextExtendSelection"))
+ else if (command.equals("selectNextExtendSelection") && hasNext)
{
- Object next = getNextVisibleNode(last);
- if (next != null)
- {
- TreePath newPath = new TreePath(getPathToRoot(next, 0));
- tree.addSelectionPath(newPath);
- tree.setLeadSelectionPath(newPath);
- }
+ newPath = treeState.getPathForRow(nextRow);
+ tree.addSelectionPath(newPath);
+ tree.setLeadSelectionPath(newPath);
}
- else if (e.getActionCommand().equals("selectNextChangeLead"))
+ else if (command.equals("selectNextChangeLead") && hasNext)
{
- Object next = getNextVisibleNode(last);
- if (next != null)
- {
- TreePath newPath = new TreePath(getPathToRoot(next, 0));
- selectPath(tree, newPath);
- tree.setLeadSelectionPath(newPath);
- }
+ newPath = treeState.getPathForRow(nextRow);
+ selectPath(tree, newPath);
+ tree.setLeadSelectionPath(newPath);
}
}
@@ -2823,7 +2698,8 @@ public class BasicTreeUI extends TreeUI
/**
* Forwards all TreeModel events to the TreeState.
*/
- public class TreeModelHandler implements TreeModelListener
+ public class TreeModelHandler
+ implements TreeModelListener
{
/**
* Constructor
@@ -2843,12 +2719,12 @@ public class BasicTreeUI extends TreeUI
* node(s). e.getChildIndices() returns the index(es) of the changed
* node(s).
*
- * @param e
- * is the event that occured
+ * @param e is the event that occured
*/
public void treeNodesChanged(TreeModelEvent e)
{
validCachedPreferredSize = false;
+ treeState.treeNodesChanged(e);
tree.repaint();
}
@@ -2857,12 +2733,12 @@ public class BasicTreeUI extends TreeUI
* get the parent of the new node(s). e.getChildIndices() returns the
* index(es) of the new node(s) in ascending order.
*
- * @param e
- * is the event that occured
+ * @param e is the event that occured
*/
public void treeNodesInserted(TreeModelEvent e)
{
validCachedPreferredSize = false;
+ treeState.treeNodesInserted(e);
tree.repaint();
}
@@ -2874,12 +2750,12 @@ public class BasicTreeUI extends TreeUI
* node(s). e.getChildIndices() returns, in ascending order, the index(es)
* the node(s) had before being deleted.
*
- * @param e
- * is the event that occured
+ * @param e is the event that occured
*/
public void treeNodesRemoved(TreeModelEvent e)
{
validCachedPreferredSize = false;
+ treeState.treeNodesRemoved(e);
tree.repaint();
}
@@ -2890,15 +2766,15 @@ public class BasicTreeUI extends TreeUI
* should become the new root of the tree. Use e.getPath() to get the path
* to the node. e.getChildIndices() returns null.
*
- * @param e
- * is the event that occured
+ * @param e is the event that occured
*/
public void treeStructureChanged(TreeModelEvent e)
{
if (e.getPath().length == 1
- && !e.getPath()[0].equals(treeModel.getRoot()))
+ && ! e.getPath()[0].equals(treeModel.getRoot()))
tree.expandPath(new TreePath(treeModel.getRoot()));
validCachedPreferredSize = false;
+ treeState.treeStructureChanged(e);
tree.repaint();
}
}// TreeModelHandler
@@ -2906,7 +2782,8 @@ public class BasicTreeUI extends TreeUI
/**
* TreePageAction handles page up and page down events.
*/
- public class TreePageAction extends AbstractAction
+ public class TreePageAction
+ extends AbstractAction
{
/** Specifies the direction to adjust the selection by. */
protected int direction;
@@ -2914,10 +2791,8 @@ public class BasicTreeUI extends TreeUI
/**
* Constructor
*
- * @param direction
- * up or down
- * @param name
- * is the name of the direction
+ * @param direction up or down
+ * @param name is the name of the direction
*/
public TreePageAction(int direction, String name)
{
@@ -2927,8 +2802,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when an action occurs.
*
- * @param e
- * is the event that occured
+ * @param e is the event that occured
*/
public void actionPerformed(ActionEvent e)
{
@@ -2950,7 +2824,8 @@ public class BasicTreeUI extends TreeUI
* Listens for changes in the selection model and updates the display
* accordingly.
*/
- public class TreeSelectionHandler implements TreeSelectionListener
+ public class TreeSelectionHandler
+ implements TreeSelectionListener
{
/**
* Constructor
@@ -2964,8 +2839,7 @@ public class BasicTreeUI extends TreeUI
* Messaged when the selection changes in the tree we're displaying for.
* Stops editing, messages super and displays the changed paths.
*
- * @param event
- * the event that characterizes the change.
+ * @param event the event that characterizes the change.
*/
public void valueChanged(TreeSelectionEvent event)
{
@@ -2977,13 +2851,13 @@ public class BasicTreeUI extends TreeUI
/**
* For the first selected row expandedness will be toggled.
*/
- public class TreeToggleAction extends AbstractAction
+ public class TreeToggleAction
+ extends AbstractAction
{
/**
* Constructor
*
- * @param name
- * is the name of <code>Action</code> field
+ * @param name is the name of <code>Action</code> field
*/
public TreeToggleAction(String name)
{
@@ -2993,8 +2867,7 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when an action occurs.
*
- * @param e
- * the event that occured
+ * @param e the event that occured
*/
public void actionPerformed(ActionEvent e)
{
@@ -3016,7 +2889,8 @@ public class BasicTreeUI extends TreeUI
* TreeTraverseAction is the action used for left/right keys. Will toggle the
* expandedness of a node, as well as potentially incrementing the selection.
*/
- public class TreeTraverseAction extends AbstractAction
+ public class TreeTraverseAction
+ extends AbstractAction
{
/**
* Determines direction to traverse, 1 means expand, -1 means collapse.
@@ -3026,10 +2900,8 @@ public class BasicTreeUI extends TreeUI
/**
* Constructor
*
- * @param direction
- * to traverse
- * @param name
- * is the name of the direction
+ * @param direction to traverse
+ * @param name is the name of the direction
*/
public TreeTraverseAction(int direction, String name)
{
@@ -3039,36 +2911,25 @@ public class BasicTreeUI extends TreeUI
/**
* Invoked when an action occurs.
*
- * @param e
- * the event that occured
+ * @param e the event that occured
*/
public void actionPerformed(ActionEvent e)
{
- Object last = tree.getLeadSelectionPath().getLastPathComponent();
+ TreePath current = tree.getLeadSelectionPath();
+ if (current == null)
+ return;
if (e.getActionCommand().equals("selectParent"))
- {
- TreePath path = new TreePath(getPathToRoot(last, 0));
- Object p = getParent(treeModel.getRoot(), last);
-
- if (!treeModel.isLeaf(last))
- toggleExpandState(path);
- else if (p != null)
- selectPath(tree, new TreePath(getPathToRoot(p, 0)));
- }
+ selectPath(tree, current.getParentPath());
else if (e.getActionCommand().equals("selectChild"))
{
- TreePath path = new TreePath(getPathToRoot(last, 0));
-
- if (!treeModel.isLeaf(last))
- toggleExpandState(path);
- else
- {
- Object next = getNextVisibleNode(last);
+ Object node = current.getLastPathComponent();
+ int nc = treeModel.getChildCount(node);
+ if (nc > 0)
+ node = treeModel.getChild(node, 0);
- if (next != null)
- selectPath(tree, new TreePath(getPathToRoot(next, 0)));
- }
+ TreePath path = current.pathByAddingChild(node);
+ selectPath(tree, path);
}
}
@@ -3113,10 +2974,8 @@ public class BasicTreeUI extends TreeUI
/**
* Returns the parent of the current node
*
- * @param root
- * is the root of the tree
- * @param node
- * is the current node
+ * @param root is the root of the tree
+ * @param node is the current node
* @return is the parent of the current node
*/
Object getParent(Object root, Object node)
@@ -3132,15 +2991,13 @@ public class BasicTreeUI extends TreeUI
/**
* Recursively checks the tree for the specified node, starting at the root.
*
- * @param root
- * is starting node to start searching at.
- * @param node
- * is the node to search for
+ * @param root is starting node to start searching at.
+ * @param node is the node to search for
* @return the parent node of node
*/
private Object findNode(Object root, Object node)
{
- if (!treeModel.isLeaf(root) && !root.equals(node))
+ if (! treeModel.isLeaf(root) && ! root.equals(node))
{
int size = treeModel.getChildCount(root);
for (int j = 0; j < size; j++)
@@ -3158,145 +3015,11 @@ public class BasicTreeUI extends TreeUI
}
/**
- * Get previous visible node in the tree. Package private for use in inner
- * classes.
- *
- * @param node -
- * current node
- * @return the next visible node in the JTree. Return null if there are no
- * more.
- */
- Object getPreviousVisibleNode(Object node)
- {
- if (currentVisiblePath != null)
- {
- Object[] nodes = currentVisiblePath.getPath();
- int i = 0;
- while (i < nodes.length && !node.equals(nodes[i]))
- i++;
- // return the next node
- if (i - 1 >= 0)
- return nodes[i - 1];
- }
- return null;
- }
-
- /**
- * Returns the next node in the tree Package private for use in inner classes.
- *
- * @param curr -
- * current node
- * @return the next node in the tree
- */
- Object getNextNode(Object curr)
- {
- if (!treeModel.isLeaf(curr) && treeModel.getChildCount(curr) > 0)
- return treeModel.getChild(curr, 0);
-
- Object node = curr;
- Object sibling = null;
- do
- {
- sibling = getNextSibling(node);
- node = getParent(treeModel.getRoot(), node);
- }
- while (sibling == null && node != null);
-
- return sibling;
- }
-
- /**
- * Returns the previous node in the tree Package private for use in inner
- * classes.
- *
- * @param node
- * current node
- * @return the previous node in the tree
- */
- Object getPreviousNode(Object node)
- {
- Object parent = getParent(treeModel.getRoot(), node);
- if (parent == null)
- return null;
-
- Object sibling = getPreviousSibling(node);
-
- if (sibling == null)
- return parent;
-
- int size = 0;
- if (!treeModel.isLeaf(sibling))
- size = treeModel.getChildCount(sibling);
- while (size > 0)
- {
- sibling = treeModel.getChild(sibling, size - 1);
- if (!treeModel.isLeaf(sibling))
- size = treeModel.getChildCount(sibling);
- else
- size = 0;
- }
-
- return sibling;
- }
-
- /**
- * Returns the next sibling in the tree Package private for use in inner
- * classes.
- *
- * @param node -
- * current node
- * @return the next sibling in the tree
- */
- Object getNextSibling(Object node)
- {
- Object parent = getParent(treeModel.getRoot(), node);
- if (parent == null)
- return null;
-
- int index = treeModel.getIndexOfChild(parent, node) + 1;
-
- int size = 0;
- if (!treeModel.isLeaf(parent))
- size = treeModel.getChildCount(parent);
- if (index == 0 || index >= size)
- return null;
-
- return treeModel.getChild(parent, index);
- }
-
- /**
- * Returns the previous sibling in the tree Package private for use in inner
- * classes.
- *
- * @param node -
- * current node
- * @return the previous sibling in the tree
- */
- Object getPreviousSibling(Object node)
- {
- Object parent = getParent(treeModel.getRoot(), node);
- if (parent == null)
- return null;
-
- int index = treeModel.getIndexOfChild(parent, node) - 1;
-
- int size = 0;
- if (!treeModel.isLeaf(parent))
- size = treeModel.getChildCount(parent);
- if (index < 0 || index >= size)
- return null;
-
- return treeModel.getChild(parent, index);
- }
-
- /**
* Selects the specified path in the tree depending on modes. Package private
* for use in inner classes.
*
- * @param tree
- * is the tree we are selecting the path in
- * @param path
- * is the path we are selecting
+ * @param tree is the tree we are selecting the path in
+ * @param path is the path we are selecting
*/
void selectPath(JTree tree, TreePath path)
{
@@ -3319,6 +3042,7 @@ public class BasicTreeUI extends TreeUI
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
}
+ tree.scrollPathToVisible(path);
}
}
@@ -3326,10 +3050,8 @@ public class BasicTreeUI extends TreeUI
* Returns the path from node to the root. Package private for use in inner
* classes.
*
- * @param node
- * the node to get the path to
- * @param depth
- * the depth of the tree to return a path for
+ * @param node the node to get the path to
+ * @param depth the depth of the tree to return a path for
* @return an array of tree nodes that represent the path to node.
*/
Object[] getPathToRoot(Object node, int depth)
@@ -3349,47 +3071,13 @@ public class BasicTreeUI extends TreeUI
}
/**
- * Returns the level of the node in the tree.
- *
- * @param node -
- * current node
- * @return the number of the level
- */
- int getLevel(Object node)
- {
- int count = -1;
-
- Object current = node;
-
- if (treeModel != null)
- {
- Object root = treeModel.getRoot();
- if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root)))
- count--;
-
- do
- {
- current = getParent(root, current);
- count++;
- }
- while (current != null);
- }
- return count;
- }
-
- /**
* Draws a vertical line using the given graphic context
*
- * @param g
- * is the graphic context
- * @param c
- * is the component the new line will belong to
- * @param x
- * is the horizonal position
- * @param top
- * specifies the top of the line
- * @param bottom
- * specifies the bottom of the line
+ * @param g is the graphic context
+ * @param c is the component the new line will belong to
+ * @param x is the horizonal position
+ * @param top specifies the top of the line
+ * @param bottom specifies the bottom of the line
*/
protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,
int bottom)
@@ -3402,16 +3090,11 @@ public class BasicTreeUI extends TreeUI
/**
* Draws a horizontal line using the given graphic context
*
- * @param g
- * is the graphic context
- * @param c
- * is the component the new line will belong to
- * @param y
- * is the vertical position
- * @param left
- * specifies the left point of the line
- * @param right
- * specifies the right point of the line
+ * @param g is the graphic context
+ * @param c is the component the new line will belong to
+ * @param y is the vertical position
+ * @param left specifies the left point of the line
+ * @param right specifies the right point of the line
*/
protected void paintHorizontalLine(Graphics g, JComponent c, int y, int left,
int right)
@@ -3424,16 +3107,11 @@ public class BasicTreeUI extends TreeUI
/**
* Draws an icon at around a specific position
*
- * @param c
- * is the component the new line will belong to
- * @param g
- * is the graphic context
- * @param icon
- * is the icon which will be drawn
- * @param x
- * is the center position in x-direction
- * @param y
- * is the center position in y-direction
+ * @param c is the component the new line will belong to
+ * @param g is the graphic context
+ * @param icon is the icon which will be drawn
+ * @param x is the center position in x-direction
+ * @param y is the center position in y-direction
*/
protected void drawCentered(Component c, Graphics g, Icon icon, int x, int y)
{
@@ -3451,14 +3129,10 @@ public class BasicTreeUI extends TreeUI
/**
* Draws a dashed horizontal line.
*
- * @param g -
- * the graphics configuration.
- * @param y -
- * the y location to start drawing at
- * @param x1 -
- * the x location to start drawing at
- * @param x2 -
- * the x location to finish drawing at
+ * @param g - the graphics configuration.
+ * @param y - the y location to start drawing at
+ * @param x1 - the x location to start drawing at
+ * @param x2 - the x location to finish drawing at
*/
protected void drawDashedHorizontalLine(Graphics g, int y, int x1, int x2)
{
@@ -3470,14 +3144,10 @@ public class BasicTreeUI extends TreeUI
/**
* Draws a dashed vertical line.
*
- * @param g -
- * the graphics configuration.
- * @param x -
- * the x location to start drawing at
- * @param y1 -
- * the y location to start drawing at
- * @param y2 -
- * the y location to finish drawing at
+ * @param g - the graphics configuration.
+ * @param x - the x location to start drawing at
+ * @param y1 - the y location to start drawing at
+ * @param y2 - the y location to finish drawing at
*/
protected void drawDashedVerticalLine(Graphics g, int x, int y1, int y2)
{
@@ -3490,22 +3160,15 @@ public class BasicTreeUI extends TreeUI
* Paints the expand (toggle) part of a row. The receiver should NOT modify
* clipBounds, or insets.
*
- * @param g -
- * the graphics configuration
+ * @param g - the graphics configuration
* @param clipBounds -
* @param insets -
- * @param bounds -
- * bounds of expand control
- * @param path -
- * path to draw control for
- * @param row -
- * row to draw control for
- * @param isExpanded -
- * is the row expanded
- * @param hasBeenExpanded -
- * has the row already been expanded
- * @param isLeaf -
- * is the path a leaf
+ * @param bounds - bounds of expand control
+ * @param path - path to draw control for
+ * @param row - row to draw control for
+ * @param isExpanded - is the row expanded
+ * @param hasBeenExpanded - has the row already been expanded
+ * @param isLeaf - is the path a leaf
*/
protected void paintExpandControl(Graphics g, Rectangle clipBounds,
Insets insets, Rectangle bounds,
@@ -3529,22 +3192,15 @@ public class BasicTreeUI extends TreeUI
* clipBounds, or insets. NOTE: parentRow can be -1 if the root is not
* visible.
*
- * @param g -
- * the graphics configuration
+ * @param g - the graphics configuration
* @param clipBounds -
* @param insets -
- * @param bounds -
- * bounds of the cell
- * @param path -
- * path to draw leg for
- * @param row -
- * row to start drawing at
- * @param isExpanded -
- * is the row expanded
- * @param hasBeenExpanded -
- * has the row already been expanded
- * @param isLeaf -
- * is the path a leaf
+ * @param bounds - bounds of the cell
+ * @param path - path to draw leg for
+ * @param row - row to start drawing at
+ * @param isExpanded - is the row expanded
+ * @param hasBeenExpanded - has the row already been expanded
+ * @param isLeaf - is the path a leaf
*/
protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
Insets insets, Rectangle bounds,
@@ -3562,37 +3218,22 @@ public class BasicTreeUI extends TreeUI
* Paints the vertical part of the leg. The receiver should NOT modify
* clipBounds, insets.
*
- * @param g -
- * the graphics configuration.
+ * @param g - the graphics configuration.
* @param clipBounds -
* @param insets -
- * @param path -
- * the path to draw the vertical part for.
+ * @param path - the path to draw the vertical part for.
*/
protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds,
Insets insets, TreePath path)
{
- int max = tree.getVisibleRowCount();
- for (int i = 0; i < max; i++)
+ Rectangle bounds = getPathBounds(tree, path);
+ TreePath parent = path.getParentPath();
+ if (parent != null)
{
- Object curr = path.getPathComponent(i);
- TreePath currPath = new TreePath(getPathToRoot(curr, 0));
- int numChild = treeModel.getChildCount(curr);
- if (numChild > 0 && tree.isExpanded(currPath))
- {
- Rectangle bounds = getPathBounds(tree, currPath);
- Rectangle lastChildBounds = getPathBounds(
- tree,
- new TreePath(
- getPathToRoot(
- treeModel.getChild(
- curr,
- numChild - 1),
- 0)));
- paintVerticalLine(g, tree, bounds.x + gap + 2, bounds.y
- + bounds.height - 2,
- lastChildBounds.y + lastChildBounds.height / 2);
- }
+ Rectangle parentBounds = getPathBounds(tree, parent);
+ paintVerticalLine(g, tree, parentBounds.x + gap + 2,
+ parentBounds.y + parentBounds.height / 2,
+ bounds.y + bounds.height / 2);
}
}
@@ -3600,22 +3241,15 @@ public class BasicTreeUI extends TreeUI
* Paints the renderer part of a row. The receiver should NOT modify
* clipBounds, or insets.
*
- * @param g -
- * the graphics configuration
+ * @param g - the graphics configuration
* @param clipBounds -
* @param insets -
- * @param bounds -
- * bounds of expand control
- * @param path -
- * path to draw control for
- * @param row -
- * row to draw control for
- * @param isExpanded -
- * is the row expanded
- * @param hasBeenExpanded -
- * has the row already been expanded
- * @param isLeaf -
- * is the path a leaf
+ * @param bounds - bounds of expand control
+ * @param path - path to draw control for
+ * @param row - row to draw control for
+ * @param isExpanded - is the row expanded
+ * @param hasBeenExpanded - has the row already been expanded
+ * @param isLeaf - is the path a leaf
*/
protected void paintRow(Graphics g, Rectangle clipBounds, Insets insets,
Rectangle bounds, TreePath path, int row,
@@ -3626,26 +3260,17 @@ public class BasicTreeUI extends TreeUI
boolean hasIcons = false;
Object node = path.getLastPathComponent();
- if (tree.isVisible(path))
- {
- if (!validCachedPreferredSize)
- updateCachedPreferredSize();
-
- paintExpandControl(g, clipBounds, insets, bounds, path, row,
- isExpanded, hasBeenExpanded, isLeaf);
-
- if (row != 0)
- bounds.x += gap;
- bounds.width = preferredSize.width + bounds.x;
- TreeCellRenderer dtcr = tree.getCellRenderer();
- if (dtcr == null)
- dtcr = createDefaultCellRenderer();
-
- Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
- isExpanded, isLeaf,
- row, tree.hasFocus());
- rendererPane.paintComponent(g, c, c.getParent(), bounds);
- }
+ paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded,
+ hasBeenExpanded, isLeaf);
+
+ TreeCellRenderer dtcr = tree.getCellRenderer();
+ if (dtcr == null)
+ dtcr = createDefaultCellRenderer();
+
+ Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
+ isExpanded, isLeaf, row,
+ tree.hasFocus());
+ rendererPane.paintComponent(g, c, c.getParent(), bounds);
}
/**
@@ -3660,16 +3285,11 @@ public class BasicTreeUI extends TreeUI
* Returns true if the expand (toggle) control should be drawn for the
* specified row.
*
- * @param path -
- * current path to check for.
- * @param row -
- * current row to check for.
- * @param isExpanded -
- * true if the path is expanded
- * @param hasBeenExpanded -
- * true if the path has been expanded already
- * @param isLeaf -
- * true if the row is a lead
+ * @param path - current path to check for.
+ * @param row - current row to check for.
+ * @param isExpanded - true if the path is expanded
+ * @param hasBeenExpanded - true if the path has been expanded already
+ * @param isLeaf - true if the row is a lead
*/
protected boolean shouldPaintExpandControl(TreePath path, int row,
boolean isExpanded,
@@ -3677,119 +3297,21 @@ public class BasicTreeUI extends TreeUI
boolean isLeaf)
{
Object node = path.getLastPathComponent();
- return (!isLeaf && getLevel(node) != 0 && hasControlIcons());
- }
-
- /**
- * Updates the cached current TreePath of all visible nodes in the tree.
- */
- void updateCurrentVisiblePath()
- {
- if (treeModel == null)
- return;
-
- Object next = treeModel.getRoot();
- if (next == null)
- return;
-
- TreePath rootPath = new TreePath(next);
- Rectangle bounds = getPathBounds(tree, rootPath);
-
- // If root is not a valid size to be visible, or is
- // not visible and the tree is expanded, then the next node acts
- // as the root
- if ((bounds.width == 0 && bounds.height == 0)
- || (!isRootVisible() && tree.isExpanded(new TreePath(next))))
- {
- next = getNextNode(next);
- rootPath = new TreePath(next);
- }
-
- Object root = next;
- TreePath current = null;
- while (next != null)
- {
- if (current == null)
- current = rootPath;
- else
- current = current.pathByAddingChild(next);
-
- do
- {
- TreePath path = new TreePath(getPathToRoot(next, 0));
- if ((tree.isVisible(path) && tree.isExpanded(path))
- || treeModel.isLeaf(next))
- next = getNextNode(next);
- else
- {
- Object pNext = next;
- next = getNextSibling(pNext);
- // if no next sibling, check parent's next sibling.
- if (next == null)
- {
- Object parent = getParent(root, pNext);
- while (next == null && parent != null)
- {
- next = getNextSibling(parent);
- if (next == null)
- parent = getParent(root, parent);
- }
- }
- }
- }
- while (next != null
- && !tree.isVisible(new TreePath(getPathToRoot(next, 0))));
- }
-
- currentVisiblePath = current;
- tree.setVisibleRowCount(getRowCount(tree));
-
- if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0
- && currentVisiblePath != null)
- selectPath(
- tree,
- new TreePath(
- getPathToRoot(
- currentVisiblePath.getPathComponent(0),
- 0)));
+ return (! isLeaf && hasControlIcons());
}
/**
- * Get next visible node in the currentVisiblePath. Package private for use in
- * inner classes.
- *
- * @param node
- * current node
- * @return the next visible node in the JTree. Return null if there are no
- * more.
+ * Finish the editing session.
*/
- Object getNextVisibleNode(Object node)
- {
- if (currentVisiblePath != null)
- {
- Object[] nodes = currentVisiblePath.getPath();
- int i = 0;
- while (i < nodes.length && !node.equals(nodes[i]))
- i++;
- // return the next node
- if (i + 1 < nodes.length)
- return nodes[i + 1];
- }
- return null;
- }
-
- /**
- * Finish the editing session.
- */
void finish()
{
editingPath = null;
- editingRow = -1;
+ editingRow = - 1;
stopEditingInCompleteEditing = false;
isEditing = false;
tree.removeAll();
validCachedPreferredSize = false;
-
+
// Repaint the region, where was the editing component.
tree.repaint(editingComponent.getParent().getBounds());
editingComponent = null;
diff --git a/javax/swing/tree/FixedHeightLayoutCache.java b/javax/swing/tree/FixedHeightLayoutCache.java
index 329adb93f..cb637c0df 100644
--- a/javax/swing/tree/FixedHeightLayoutCache.java
+++ b/javax/swing/tree/FixedHeightLayoutCache.java
@@ -197,7 +197,7 @@ public class FixedHeightLayoutCache
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(root, i);
- countRows(child, root, 0);
+ countRows(child, root, 1);
}
}
dirty = false;
@@ -213,7 +213,7 @@ public class FixedHeightLayoutCache
nodes.put(node, new NodeRecord(n.intValue(), depth, node, parent));
- if (expanded.contains(node))
+ if (expanded.contains(node) || parent == null)
{
int sc = treeModel.getChildCount(node);
int deeper = depth+1;
diff --git a/javax/swing/tree/VariableHeightLayoutCache.java b/javax/swing/tree/VariableHeightLayoutCache.java
index c4a7397a0..a1d8ef853 100644
--- a/javax/swing/tree/VariableHeightLayoutCache.java
+++ b/javax/swing/tree/VariableHeightLayoutCache.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package javax.swing.tree;
+import gnu.javax.swing.tree.GnuPath;
+
import java.awt.Rectangle;
import java.util.Enumeration;
import java.util.HashSet;
@@ -51,8 +53,11 @@ import javax.swing.event.TreeModelEvent;
* The fixed height tree layout. This class requires the NodeDimensions to be
* set and ignores the row height property.
*
+ * @specnote the methods, of this class, returning TreePath, actually returns
+ * the derived class GnuPath that provides additional information for optimized
+ * painting. See the GnuPath code for details.
+ *
* @author Audrius Meskauskas
- * @author Andrew Selkirk
*/
public class VariableHeightLayoutCache
extends AbstractLayoutCache
@@ -109,8 +114,23 @@ public class VariableHeightLayoutCache
*/
private TreePath path;
+ /**
+ * Get the path for this node. The derived class is returned,
+ * making check for the last child of some parent easier.
+ */
TreePath getPath()
{
+ boolean lastChild = false;
+ if (parent!=null)
+ {
+ int nc = treeModel.getChildCount(parent);
+ if (nc > 0)
+ {
+ int n = treeModel.getIndexOfChild(parent, node);
+ if (n == nc-1)
+ lastChild = true;
+ }
+ }
if (path == null)
{
LinkedList lpath = new LinkedList();
@@ -123,7 +143,7 @@ public class VariableHeightLayoutCache
else
rp = null;
}
- path = new TreePath(lpath.toArray());
+ path = new GnuPath(lpath.toArray(), lastChild);
}
return path;
}
@@ -162,6 +182,16 @@ public class VariableHeightLayoutCache
* If true, the row map must be recomputed before using.
*/
boolean dirty;
+
+ /**
+ * The cumulative height of all rows.
+ */
+ int totalHeight;
+
+ /**
+ * The maximal width.
+ */
+ int maximalWidth;
/**
* Creates the unitialised instance. Before using the class, the row height
@@ -193,6 +223,8 @@ public class VariableHeightLayoutCache
{
nodes.clear();
row2node.clear();
+
+ totalHeight = maximalWidth = 0;
Object root = treeModel.getRoot();
@@ -206,7 +238,7 @@ public class VariableHeightLayoutCache
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(root, i);
- countRows(child, root, 0);
+ countRows(child, root, 1);
}
}
dirty = false;
@@ -220,9 +252,11 @@ public class VariableHeightLayoutCache
Integer n = new Integer(row2node.size());
row2node.put(n, node);
- nodes.put(node, new NodeRecord(n.intValue(), depth, node, parent));
-
- if (expanded.contains(node))
+ NodeRecord nr = new NodeRecord(n.intValue(), depth, node, parent);
+ nodes.put(node, nr);
+
+ // For expanded nodes and for the root node.
+ if (expanded.contains(node) || parent == null)
{
int sc = treeModel.getChildCount(node);
int deeper = depth+1;
@@ -287,8 +321,7 @@ public class VariableHeightLayoutCache
* Get bounds for the given tree path.
*
* @param path the tree path
- * @param rect the rectangle, specifying the area where the path should be
- * displayed.
+ * @param rect the rectangle that will be reused to return the result.
* @return Rectangle the bounds of the last line, defined by the given path.
*/
public Rectangle getBounds(TreePath path, Rectangle rect)
@@ -298,8 +331,10 @@ public class VariableHeightLayoutCache
Object last = path.getLastPathComponent();
NodeRecord r = (NodeRecord) nodes.get(last);
if (r == null)
- // This node is not visible.
- return new Rectangle();
+ // This node is not visible.
+ {
+ rect.x = rect.y = rect.width = rect.height = 0;
+ }
else
{
if (r.bounds == null)
@@ -308,8 +343,10 @@ public class VariableHeightLayoutCache
r.isExpanded, rect);
r.bounds = dim;
}
- return r.bounds;
+
+ rect.setRect(r.bounds);
}
+ return rect;
}
/**
@@ -523,4 +560,42 @@ public class VariableHeightLayoutCache
rootVisible = visible;
dirty = true;
}
+
+ /**
+ * Get the sum of heights for all rows.
+ */
+ public int getPreferredHeight()
+ {
+ if (dirty)
+ update();
+ totalHeight = 0;
+ Enumeration en = nodes.elements();
+ while (en.hasMoreElements())
+ {
+ NodeRecord nr = (NodeRecord) en.nextElement();
+ Rectangle r = nr.getBounds();
+ totalHeight += r.height;
+ }
+ return totalHeight;
+ }
+
+ /**
+ * Get the maximal width.
+ */
+ public int getPreferredWidth(Rectangle value)
+ {
+ if (dirty)
+ update();
+
+ maximalWidth = 0;
+ Enumeration en = nodes.elements();
+ while (en.hasMoreElements())
+ {
+ NodeRecord nr = (NodeRecord) en.nextElement();
+ Rectangle r = nr.getBounds();
+ if (r.x + r.width > maximalWidth)
+ maximalWidth = r.x + r.width;
+ }
+ return maximalWidth;
+ }
}