summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java')
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java1327
1 files changed, 819 insertions, 508 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
index 6f714a39cb2..e967cd424fc 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
@@ -44,6 +44,7 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
@@ -62,6 +63,7 @@ import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.AbstractAction;
@@ -76,6 +78,7 @@ import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIDefaults;
@@ -89,6 +92,7 @@ import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
+import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TreeUI;
@@ -96,7 +100,6 @@ import javax.swing.text.Caret;
import javax.swing.tree.AbstractLayoutCache;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
-import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.FixedHeightLayoutCache;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
@@ -110,11 +113,11 @@ import javax.swing.tree.TreeSelectionModel;
* the Basic look and feel.
*
* @see javax.swing.JTree
- * @author Sascha Brawer (brawer@dandelis.ch)
+ *
* @author Lillian Angel (langel@redhat.com)
+ * @author Sascha Brawer (brawer@dandelis.ch)
*/
-public class BasicTreeUI
- extends TreeUI
+public class BasicTreeUI extends TreeUI
{
/** Collapse Icon for the tree. */
protected transient Icon collapsedIcon;
@@ -136,9 +139,6 @@ public class BasicTreeUI
*/
protected int totalChildIndent;
- /** Minimum preferred size. */
- protected Dimension preferredMinsize;
-
/** Index of the row that was last selected. */
protected int lastSelectedRow;
@@ -174,6 +174,9 @@ public class BasicTreeUI
/** Size needed to completely display all the nodes. */
protected Dimension preferredSize;
+
+ /** Minimum size needed to completely display all the nodes. */
+ protected Dimension preferredMinSize;
/** Is the preferredSize valid? */
protected boolean validCachedPreferredSize;
@@ -223,38 +226,38 @@ public class BasicTreeUI
/** Set to true if the editor has a different size than the renderer. */
protected boolean editorHasDifferentSize;
-
+
/** The action listener for the editor's Timer. */
- private Timer editorTimer = new EditorUpdateTimer();
+ Timer editorTimer = new EditorUpdateTimer();
/** The new value of the node after editing. */
- private Object newVal;
+ Object newVal;
/** The action bound to KeyStrokes. */
- private TreeAction action;
+ TreeAction action;
/** Boolean to keep track of editing. */
- private boolean isEditing;
+ boolean isEditing;
+
+ /** The bounds of the current cell. */
+ Rectangle bounds;
+
+ /** The current path of the visible nodes in the tree. */
+ TreePath currentVisiblePath;
+
+ /** The gap between the icon and text. */
+ int gap = 4;
/** Listeners */
private PropertyChangeListener propertyChangeListener;
-
private FocusListener focusListener;
-
private TreeSelectionListener treeSelectionListener;
-
- private MouseInputListener mouseInputListener;
-
+ private MouseListener mouseListener;
private KeyListener keyListener;
-
private PropertyChangeListener selectionModelPropertyChangeListener;
-
private ComponentListener componentListener;
-
- private CellEditorListener cellEditorListener;
-
+ CellEditorListener cellEditorListener;
private TreeExpansionListener treeExpansionListener;
-
private TreeModelListener treeModelListener;
/**
@@ -262,6 +265,7 @@ public class BasicTreeUI
*/
public BasicTreeUI()
{
+ validCachedPreferredSize = false;
drawingCache = new Hashtable();
nodeDimensions = createNodeDimensions();
configureLayoutCache();
@@ -269,7 +273,7 @@ public class BasicTreeUI
propertyChangeListener = createPropertyChangeListener();
focusListener = createFocusListener();
treeSelectionListener = createTreeSelectionListener();
- mouseInputListener = new MouseInputHandler(null, null, null);
+ mouseListener = createMouseListener();
keyListener = createKeyListener();
selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener();
componentListener = createComponentListener();
@@ -331,7 +335,7 @@ public class BasicTreeUI
*
* @return the indent value for the left child.
*/
- public int getLeftChildIndent(int newAmount)
+ public int getLeftChildIndent()
{
return leftChildIndent;
}
@@ -456,7 +460,6 @@ public class BasicTreeUI
protected void setCellRenderer(TreeCellRenderer tcr)
{
currentCellRenderer = tcr;
- tree.setCellRenderer(tcr);
updateRenderer();
}
@@ -625,14 +628,13 @@ public class BasicTreeUI
{
Object cell = path.getLastPathComponent();
- TreeModel mod = tree.getModel();
- if (mod != null)
+ if (treeModel != null)
{
- Object root = mod.getRoot();
+ Object root = treeModel.getRoot();
+
if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root)))
root = getNextNode(root);
-
- Point loc = getCellLocation(0, 0, tree, mod, cell, root);
+ Point loc = getCellLocation(0, 0, tree, treeModel, cell, root);
return getCellBounds(loc.x, loc.y, cell);
}
}
@@ -650,21 +652,11 @@ public class BasicTreeUI
*/
public TreePath getPathForRow(JTree tree, int row)
{
- TreeModel mod = tree.getModel();
- if (mod != null)
+ if (treeModel != null && currentVisiblePath != null)
{
- Object node = mod.getRoot();
- if (!tree.isRootVisible()
- && tree.isExpanded(new TreePath(getPathToRoot(node, 0))))
- node = getNextNode(node);
-
- for (int i = 0; i < row; i++)
- node = getNextVisibleNode(node);
-
- if (node == null)
- return null;
-
- return new TreePath(getPathToRoot(node, 0));
+ Object[] nodes = currentVisiblePath.getPath();
+ if (row < nodes.length)
+ return new TreePath(getPathToRoot(nodes[row], 0));
}
return null;
}
@@ -683,17 +675,20 @@ public class BasicTreeUI
*/
public int getRowForPath(JTree tree, TreePath path)
{
- int row = path.getPathCount();
- if (tree.isVisible(path))
- return row;
-
- path = path.getParentPath();
- while (row > 0 && !tree.isVisible(path))
+ int row = 0;
+ Object dest = path.getLastPathComponent();
+ int rowCount = getRowCount(tree);
+ if (currentVisiblePath != null)
{
- path = path.getParentPath();
- row--;
+ Object[] nodes = currentVisiblePath.getPath();
+ while (row < rowCount)
+ {
+ if (dest.equals(nodes[row]))
+ return row;
+ row++;
+ }
}
- return row;
+ return -1;
}
/**
@@ -705,22 +700,10 @@ public class BasicTreeUI
*/
public int getRowCount(JTree tree)
{
- TreeModel mod = tree.getModel();
- int count = 0;
- if (mod != null)
- {
- Object node = mod.getRoot();
- if (!tree.isRootVisible()
- && tree.isExpanded(new TreePath((getPathToRoot(node, 0)))))
- node = getNextNode(node);
-
- while (node != null)
- {
- count++;
- node = getNextVisibleNode(node);
- }
- }
- return count;
+ updateCurrentVisiblePath();
+ if (currentVisiblePath != null)
+ return currentVisiblePath.getPathCount();
+ return 0;
}
/**
@@ -739,9 +722,6 @@ public class BasicTreeUI
*/
public TreePath getClosestPathForLocation(JTree tree, int x, int y)
{
- // FIXME: what if root is hidden? should not depend on (0,0)
- // should start counting rows from where root is.
-
int row = Math.round(y / getRowHeight());
TreePath path = getPathForRow(tree, row);
@@ -828,7 +808,7 @@ public class BasicTreeUI
*/
protected void prepareForUIInstall()
{
- // FIXME: not implemented
+ // TODO: Implement this properly.
}
/**
@@ -837,7 +817,7 @@ public class BasicTreeUI
*/
protected void completeUIInstall()
{
- // FIXME: not implemented
+ // TODO: Implement this properly.
}
/**
@@ -846,7 +826,7 @@ public class BasicTreeUI
*/
protected void completeUIUninstall()
{
- // FIXME: not implemented
+ // TODO: Implement this properly.
}
/**
@@ -854,7 +834,10 @@ public class BasicTreeUI
*/
protected void installComponents()
{
- // FIXME: not implemented
+ currentCellRenderer = createDefaultCellRenderer();
+ rendererPane = createCellRendererPane();
+ createdRenderer = true;
+ setCellRenderer(currentCellRenderer);
}
/**
@@ -865,8 +848,7 @@ public class BasicTreeUI
*/
protected AbstractLayoutCache.NodeDimensions createNodeDimensions()
{
- // FIXME: not implemented
- return null;
+ return new NodeDimensionsHandler();
}
/**
@@ -1035,7 +1017,7 @@ public class BasicTreeUI
tree.removePropertyChangeListener(propertyChangeListener);
tree.removeFocusListener(focusListener);
tree.removeTreeSelectionListener(treeSelectionListener);
- tree.removeMouseListener(mouseInputListener);
+ tree.removeMouseListener(mouseListener);
tree.removeKeyListener(keyListener);
tree.removePropertyChangeListener(selectionModelPropertyChangeListener);
tree.removeComponentListener(componentListener);
@@ -1044,9 +1026,8 @@ public class BasicTreeUI
TreeCellEditor tce = tree.getCellEditor();
if (tce != null)
tce.removeCellEditorListener(cellEditorListener);
- TreeModel tm = tree.getModel();
- if (tm != null)
- tm.removeTreeModelListener(treeModelListener);
+ if (treeModel != null)
+ treeModel.removeTreeModelListener(treeModelListener);
}
/**
@@ -1054,6 +1035,7 @@ public class BasicTreeUI
*/
protected void uninstallKeyboardActions()
{
+ // TODO: Implement this properly.
}
/**
@@ -1061,7 +1043,10 @@ public class BasicTreeUI
*/
protected void uninstallComponents()
{
- // FIXME: not implemented
+ currentCellRenderer = null;
+ rendererPane = null;
+ createdRenderer = false;
+ setCellRenderer(currentCellRenderer);
}
/**
@@ -1072,8 +1057,7 @@ public class BasicTreeUI
*/
protected int getVerticalLegBuffer()
{
- // FIXME: not implemented
- return 0;
+ return getRowHeight() / 2;
}
/**
@@ -1085,17 +1069,17 @@ public class BasicTreeUI
*/
protected int getHorizontalLegBuffer()
{
- // FIXME: not implemented
- return 0;
+ return rightChildIndent / 2;
}
/**
* Make all the nodes that are expanded in JTree expanded in LayoutCache. This
- * invokes update ExpandedDescendants with the root path.
+ * invokes updateExpandedDescendants with the root path.
*/
protected void updateLayoutCacheExpandedNodes()
{
- // FIXME: not implemented
+ if (treeModel != null)
+ updateExpandedDescendants(new TreePath(treeModel.getRoot()));
}
/**
@@ -1108,7 +1092,9 @@ public class BasicTreeUI
*/
protected void updateExpandedDescendants(TreePath path)
{
- // FIXME: not implemented
+ Enumeration expanded = tree.getExpandedDescendants(path);
+ while (expanded.hasMoreElements())
+ treeState.setExpandedState(((TreePath) expanded.nextElement()), true);
}
/**
@@ -1128,7 +1114,7 @@ public class BasicTreeUI
*/
protected void updateDepthOffset()
{
- // FIXME: not implemented
+ depthOffset += getVerticalLegBuffer();
}
/**
@@ -1148,7 +1134,15 @@ public class BasicTreeUI
*/
protected void updateRenderer()
{
- // FIXME: not implemented
+ if (tree != null)
+ {
+ if(tree.getCellRenderer() == null)
+ {
+ if(currentCellRenderer == null)
+ currentCellRenderer = createDefaultCellRenderer();
+ tree.setCellRenderer(currentCellRenderer);
+ }
+ }
}
/**
@@ -1166,19 +1160,36 @@ public class BasicTreeUI
*/
protected void updateSize()
{
- // FIXME: not implemented
+ preferredSize = null;
+ updateCachedPreferredSize();
+ tree.treeDidChange();
}
/**
* Updates the <code>preferredSize</code> instance variable, which is
- * returned from <code>getPreferredSize()</code>. For left to right
- * orientations, the size is determined from the current AbstractLayoutCache.
- * For RTL orientations, the preferred size becomes the width minus the
- * minimum x position.
+ * returned from <code>getPreferredSize()</code>.
*/
protected void updateCachedPreferredSize()
{
- // FIXME: not implemented
+ int maxWidth = 0;
+ 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);
+ }
+ preferredSize = new Dimension(maxWidth, (getRowHeight() * path.length));
+ }
+ else preferredSize = new Dimension(0, 0);
+ validCachedPreferredSize = true;
}
/**
@@ -1189,7 +1200,9 @@ public class BasicTreeUI
*/
protected void pathWasExpanded(TreePath path)
{
- // FIXME: not implemented
+ validCachedPreferredSize = false;
+ tree.revalidate();
+ tree.repaint();
}
/**
@@ -1197,28 +1210,28 @@ public class BasicTreeUI
*/
protected void pathWasCollapsed(TreePath path)
{
- // FIXME: not implemented
+ validCachedPreferredSize = false;
+ tree.revalidate();
+ tree.repaint();
}
/**
* Install all defaults for the tree.
- *
- * @param tree
- * is the JTree to install defaults for
*/
- protected void installDefaults(JTree tree)
+ protected void installDefaults()
{
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- tree.setFont(defaults.getFont("Tree.font"));
- tree.setForeground(defaults.getColor("Tree.foreground"));
- tree.setBackground(defaults.getColor("Tree.background"));
+ LookAndFeel.installColorsAndFont(tree, "Tree.background",
+ "Tree.foreground", "Tree.font");
tree.setOpaque(true);
- rightChildIndent = defaults.getInt("Tree.rightChildIndent");
- leftChildIndent = defaults.getInt("Tree.leftChildIndent");
- setRowHeight(defaults.getInt("Tree.rowHeight"));
+ rightChildIndent = UIManager.getInt("Tree.rightChildIndent");
+ leftChildIndent = UIManager.getInt("Tree.leftChildIndent");
+ setRowHeight(UIManager.getInt("Tree.rowHeight"));
+ tree.setRowHeight(UIManager.getInt("Tree.rowHeight"));
tree.requestFocusInWindow(false);
+ tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand"));
+ setExpandedIcon(UIManager.getIcon("Tree.expandedIcon"));
+ setCollapsedIcon(UIManager.getIcon("Tree.collapsedIcon"));
}
/**
@@ -1229,7 +1242,7 @@ public class BasicTreeUI
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
InputMap focusInputMap = (InputMap) defaults.get("Tree.focusInputMap");
InputMapUIResource parentInputMap = new InputMapUIResource();
- ActionMap parentActionMap = new ActionMap();
+ ActionMap parentActionMap = new ActionMapUIResource();
action = new TreeAction();
Object keys[] = focusInputMap.allKeys();
@@ -1308,7 +1321,7 @@ public class BasicTreeUI
tree.addPropertyChangeListener(propertyChangeListener);
tree.addFocusListener(focusListener);
tree.addTreeSelectionListener(treeSelectionListener);
- tree.addMouseListener(mouseInputListener);
+ tree.addMouseListener(mouseListener);
tree.addKeyListener(keyListener);
tree.addPropertyChangeListener(selectionModelPropertyChangeListener);
tree.addComponentListener(componentListener);
@@ -1325,37 +1338,36 @@ public class BasicTreeUI
*/
public void installUI(JComponent c)
{
- super.installUI(c);
- installDefaults((JTree) c);
tree = (JTree) c;
+ prepareForUIInstall();
+ super.installUI(c);
+ installDefaults();
- currentCellRenderer = createDefaultCellRenderer();
- rendererPane = createCellRendererPane();
- createdRenderer = true;
-
+ installComponents();
+ installKeyboardActions();
+ installListeners();
+
setCellEditor(createDefaultCellEditor());
createdCellEditor = true;
isEditing = false;
-
+
TreeModel mod = tree.getModel();
setModel(mod);
- tree.setRootVisible(true);
if (mod != null)
- tree.expandPath(new TreePath(mod.getRoot()));
+ {
+ TreePath path = new TreePath(mod.getRoot());
+ if (!tree.isExpanded(path))
+ toggleExpandState(path);
+ }
treeSelectionModel = tree.getSelectionModel();
- installKeyboardActions();
- installListeners();
completeUIInstall();
}
/**
* Uninstall the defaults for the tree
- *
- * @param tree
- * to uninstall defaults for
*/
- protected void uninstallDefaults(JTree tree)
+ protected void uninstallDefaults()
{
tree.setFont(null);
tree.setForeground(null);
@@ -1370,10 +1382,12 @@ public class BasicTreeUI
*/
public void uninstallUI(JComponent c)
{
- uninstallDefaults((JTree) c);
+ prepareForUIUninstall();
+ uninstallDefaults();
uninstallKeyboardActions();
uninstallListeners();
tree = null;
+ uninstallComponents();
completeUIUninstall();
}
@@ -1393,20 +1407,16 @@ public class BasicTreeUI
public void paint(Graphics g, JComponent c)
{
JTree tree = (JTree) c;
-
- TreeModel mod = tree.getModel();
-
- if (mod != null)
+ if (currentVisiblePath == null)
+ updateCurrentVisiblePath();
+
+ if (currentVisiblePath != null && treeModel != null)
{
- Object root = mod.getRoot();
-
- if (!tree.isRootVisible())
- tree.expandPath(new TreePath(root));
-
- paintRecursive(g, 0, 0, 0, 0, tree, mod, root);
-
+ Object root = treeModel.getRoot();
+ paintRecursive(g, 0, 0, 0, tree, treeModel, root);
+
if (hasControlIcons())
- paintControlIcons(g, 0, 0, 0, 0, tree, mod, root);
+ paintControlIcons(g, 0, 0, 0, tree, treeModel, root);
}
}
@@ -1420,7 +1430,19 @@ public class BasicTreeUI
*/
protected void ensureRowsAreVisible(int beginRow, int endRow)
{
- // FIXME: not implemented
+ if (beginRow < endRow)
+ {
+ int temp = endRow;
+ endRow = beginRow;
+ beginRow = temp;
+ }
+
+ for (int i = beginRow; i < endRow; i++)
+ {
+ TreePath path = getPathForRow(tree, i);
+ if (!tree.isVisible(path))
+ tree.makeVisible(path);
+ }
}
/**
@@ -1431,7 +1453,7 @@ public class BasicTreeUI
*/
public void setPreferredMinSize(Dimension newSize)
{
- // FIXME: not implemented
+ preferredMinSize = newSize;
}
/**
@@ -1441,8 +1463,7 @@ public class BasicTreeUI
*/
public Dimension getPreferredMinSize()
{
- // FIXME: not implemented
- return null;
+ return preferredMinSize;
}
/**
@@ -1472,28 +1493,10 @@ public class BasicTreeUI
*/
public Dimension getPreferredSize(JComponent c, boolean checkConsistancy)
{
- // FIXME: checkConsistancy not implemented, c not used
- TreeModel model = tree.getModel();
- int maxWidth = 0;
- int count = 0;
- if (model != null)
- {
- Object node = model.getRoot();
- if (node != null)
- {
- maxWidth = (int) (getCellBounds(0, 0, node).getWidth());
- while (node != null)
- {
- count++;
- Object nextNode = getNextVisibleNode(node);
- if (nextNode != null)
- maxWidth = Math.max(maxWidth,
- (int) (getCellBounds(0, 0, nextNode).getWidth()));
- node = nextNode;
- }
- }
- }
- return new Dimension(maxWidth, (getRowHeight() * count));
+ // FIXME: checkConsistancy not implemented, c not used
+ if(!validCachedPreferredSize)
+ updateCachedPreferredSize();
+ return preferredSize;
}
/**
@@ -1506,8 +1509,10 @@ public class BasicTreeUI
*/
public Dimension getMinimumSize(JComponent c)
{
- // FIXME: not implemented
- return getPreferredSize(c);
+ Dimension min = getPreferredMinSize();
+ if (min == null)
+ return new Dimension();
+ return min;
}
/**
@@ -1520,8 +1525,9 @@ public class BasicTreeUI
*/
public Dimension getMaximumSize(JComponent c)
{
- // FIXME: not implemented
- return getPreferredSize(c);
+ if (c instanceof JTree)
+ return ((JTree) c).getPreferredSize();
+ return new Dimension();
}
/**
@@ -1565,7 +1571,7 @@ public class BasicTreeUI
}
if (messageTree)
- tree.getModel().valueForPathChanged(tree.getLeadSelectionPath(), newVal);
+ treeModel.valueForPathChanged(tree.getLeadSelectionPath(), newVal);
}
/**
@@ -1584,7 +1590,7 @@ public class BasicTreeUI
int y;
if (event == null)
{
- Rectangle bounds = getPathBounds(tree, path);
+ bounds = getPathBounds(tree, path);
x = bounds.x;
y = bounds.y;
}
@@ -1600,6 +1606,7 @@ public class BasicTreeUI
{
editingPath = path;
editingRow = tree.getRowForPath(editingPath);
+
Object val = editingPath.getLastPathComponent();
cellEditor.addCellEditorListener(cellEditorListener);
stopEditingInCompleteEditing = false;
@@ -1613,6 +1620,8 @@ public class BasicTreeUI
editingComponent.getParent().validate();
tree.add(editingComponent.getParent());
editingComponent.getParent().validate();
+ validCachedPreferredSize = false;
+ tree.revalidate();
((JTextField) editingComponent).requestFocusInWindow(false);
editorTimer.start();
return true;
@@ -1634,7 +1643,8 @@ public class BasicTreeUI
protected void checkForClickInExpandControl(TreePath path, int mouseX,
int mouseY)
{
- // FIXME: not implemented
+ if (isLocationInExpandControl(path, mouseX, mouseY))
+ toggleExpandState(path);
}
/**
@@ -1655,8 +1665,18 @@ public class BasicTreeUI
protected boolean isLocationInExpandControl(TreePath path, int mouseX,
int mouseY)
{
- // FIXME: not implemented
- return false;
+ boolean cntlClick = false;
+ int row = getRowForPath(tree, path);
+
+ if (!isLeaf(row))
+ {
+ bounds = getPathBounds(tree, path);
+
+ if (hasControlIcons() && (mouseX < bounds.x)
+ && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap)))
+ cntlClick = true;
+ }
+ return cntlClick;
}
/**
@@ -1672,7 +1692,7 @@ public class BasicTreeUI
*/
protected void handleExpandControlClick(TreePath path, int mouseX, int mouseY)
{
- // FIXME: not implemented
+ toggleExpandState(path);
}
/**
@@ -1686,7 +1706,11 @@ public class BasicTreeUI
*/
protected void toggleExpandState(TreePath path)
{
- // FIXME: not implemented
+ if (tree.isExpanded(path))
+ tree.collapsePath(path);
+ else
+ tree.expandPath(path);
+ updateCurrentVisiblePath();
}
/**
@@ -1700,8 +1724,8 @@ public class BasicTreeUI
*/
protected boolean isToggleSelectionEvent(MouseEvent event)
{
- // FIXME: not implemented
- return false;
+ return (tree.getSelectionModel().getSelectionMode() ==
+ TreeSelectionModel.SINGLE_TREE_SELECTION);
}
/**
@@ -1715,8 +1739,8 @@ public class BasicTreeUI
*/
protected boolean isMultiSelectEvent(MouseEvent event)
{
- // FIXME: not implemented
- return false;
+ return (tree.getSelectionModel().getSelectionMode() ==
+ TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
}
/**
@@ -1731,8 +1755,7 @@ public class BasicTreeUI
*/
protected boolean isToggleEvent(MouseEvent event)
{
- // FIXME: not implemented
- return false;
+ return true;
}
/**
@@ -1749,7 +1772,29 @@ public class BasicTreeUI
*/
protected void selectPathForEvent(TreePath path, MouseEvent event)
{
- // FIXME: not implemented
+ if (isToggleSelectionEvent(event))
+ {
+ if (tree.isPathSelected(path))
+ tree.removeSelectionPath(path);
+ else
+ {
+ tree.addSelectionPath(path);
+ tree.setAnchorSelectionPath(path);
+ }
+ }
+ else if (isMultiSelectEvent(event))
+ {
+ TreePath anchor = tree.getAnchorSelectionPath();
+ if (anchor != null)
+ {
+ int aRow = getRowForPath(tree, anchor);
+ tree.addSelectionInterval(aRow, getRowForPath(tree, path));
+ }
+ else
+ tree.addSelectionPath(path);
+ }
+ else
+ tree.addSelectionPath(path);
}
/**
@@ -1766,7 +1811,7 @@ public class BasicTreeUI
return true;
Object node = pathForRow.getLastPathComponent();
- return tree.getModel().isLeaf(node);
+ return treeModel.isLeaf(node);
}
/**
@@ -1800,9 +1845,9 @@ public class BasicTreeUI
(new TreeTraverseAction(0, "")).actionPerformed(e);
else if (e.getActionCommand().equals("selectAll"))
{
- TreePath[] paths = new TreePath[tree.getRowCount()];
+ TreePath[] paths = new TreePath[tree.getVisibleRowCount()];
- Object curr = getNextVisibleNode(tree.getModel().getRoot());
+ Object curr = getNextVisibleNode(treeModel.getRoot());
int i = 0;
while (curr != null && i < paths.length)
{
@@ -1822,13 +1867,8 @@ public class BasicTreeUI
{
Object last = lead.getLastPathComponent();
TreePath path = new TreePath(getPathToRoot(last, 0));
- if (!tree.getModel().isLeaf(last))
- {
- if (tree.isExpanded(path))
- tree.collapsePath(path);
- else
- tree.expandPath(path);
- }
+ if (!treeModel.isLeaf(last))
+ toggleExpandState(path);
}
}
else if (e.getActionCommand().equals("clearSelection"))
@@ -1920,8 +1960,7 @@ public class BasicTreeUI
/**
* Updates the preferred size when scrolling, if necessary.
*/
- public class ComponentHandler
- extends ComponentAdapter
+ public class ComponentHandler extends ComponentAdapter
implements ActionListener
{
/**
@@ -1937,6 +1976,7 @@ public class BasicTreeUI
*/
public ComponentHandler()
{
+ // Nothing to do here.
}
/**
@@ -1947,6 +1987,7 @@ public class BasicTreeUI
*/
public void componentMoved(ComponentEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -1955,6 +1996,7 @@ public class BasicTreeUI
*/
protected void startTimer()
{
+ // TODO: Implement this properly.
}
/**
@@ -1976,21 +2018,22 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent ae)
{
+ // TODO: Implement this properly.
}
- }// ComponentHandler
+ }
/**
* Listener responsible for getting cell editing events and updating the tree
* accordingly.
*/
- public class CellEditorHandler
- implements CellEditorListener
+ public class CellEditorHandler implements CellEditorListener
{
/**
* Constructor
*/
public CellEditorHandler()
{
+ // Nothing to do here.
}
/**
@@ -2023,6 +2066,9 @@ public class BasicTreeUI
isEditing = false;
tree.requestFocusInWindow(false);
editorTimer.stop();
+ validCachedPreferredSize = false;
+ tree.revalidate();
+ tree.repaint();
}
/**
@@ -2051,6 +2097,8 @@ public class BasicTreeUI
tree.requestFocusInWindow(false);
editorTimer.stop();
isEditing = false;
+ validCachedPreferredSize = false;
+ tree.revalidate();
tree.repaint();
}
}// CellEditorHandler
@@ -2066,6 +2114,7 @@ public class BasicTreeUI
*/
public FocusHandler()
{
+ // Nothing to do here.
}
/**
@@ -2077,6 +2126,7 @@ public class BasicTreeUI
*/
public void focusGained(FocusEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2088,8 +2138,9 @@ public class BasicTreeUI
*/
public void focusLost(FocusEvent e)
{
+ // TODO: Implement this properly.
}
- }// FocusHandler
+ }
/**
* This is used to get multiple key down events to appropriately genereate
@@ -2109,6 +2160,7 @@ public class BasicTreeUI
*/
public KeyHandler()
{
+ // Nothing to do here.
}
/**
@@ -2122,6 +2174,7 @@ public class BasicTreeUI
*/
public void keyTyped(KeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2132,6 +2185,7 @@ public class BasicTreeUI
*/
public void keyPressed(KeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2142,22 +2196,22 @@ public class BasicTreeUI
*/
public void keyReleased(KeyEvent e)
{
+ // TODO: What should be done here, if anything?
}
- }// KeyHandler
+ }
/**
* 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
*/
public MouseHandler()
{
+ // Nothing to do here.
}
/**
@@ -2168,6 +2222,57 @@ public class BasicTreeUI
*/
public void mousePressed(MouseEvent e)
{
+ Point click = e.getPoint();
+ TreePath path = getClosestPathForLocation(tree, click.x, click.y);
+
+ if (path != null)
+ {
+ bounds = getPathBounds(tree, path);
+ int row = getRowForPath(tree, path);
+ boolean cntlClick = isLocationInExpandControl(path, click.x, click.y);
+
+ boolean isLeaf = isLeaf(row);
+
+ TreeCellRenderer tcr = getCellRenderer();
+ Icon icon;
+ if (isLeaf)
+ icon = UIManager.getIcon("Tree.leafIcon");
+ else if (tree.isExpanded(path))
+ icon = UIManager.getIcon("Tree.openIcon");
+ else
+ icon = UIManager.getIcon("Tree.closedIcon");
+
+ if (tcr instanceof DefaultTreeCellRenderer)
+ {
+ Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon();
+ if (tmp != null)
+ icon = tmp;
+ }
+
+ // add gap*2 for the space before and after the text
+ if (icon != null)
+ bounds.width += icon.getIconWidth() + gap*2;
+
+ boolean inBounds = bounds.contains(click.x, click.y);
+ if ((inBounds || cntlClick) && tree.isVisible(path))
+ {
+ if (inBounds)
+ {
+ selectPath(tree, path);
+ if (e.getClickCount() == 2 && !isLeaf(row))
+ toggleExpandState(path);
+ }
+
+ if (cntlClick)
+ {
+ handleExpandControlClick(path, click.x, click.y);
+ if (cellEditor != null)
+ cellEditor.cancelCellEditing();
+ }
+ else if (tree.isEditable())
+ startEditing(path, e);
+ }
+ }
}
/**
@@ -2181,6 +2286,7 @@ public class BasicTreeUI
*/
public void mouseDragged(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2192,6 +2298,7 @@ public class BasicTreeUI
*/
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2202,16 +2309,16 @@ public class BasicTreeUI
*/
public void mouseReleased(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
- }// MouseHandler
+ }
/**
* MouseInputHandler handles passing all mouse events, including mouse motion
* 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;
@@ -2232,6 +2339,8 @@ public class BasicTreeUI
public MouseInputHandler(Component source, Component destination,
MouseEvent e)
{
+ this.source = source;
+ this.destination = destination;
}
/**
@@ -2243,6 +2352,7 @@ public class BasicTreeUI
*/
public void mouseClicked(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2253,42 +2363,7 @@ public class BasicTreeUI
*/
public void mousePressed(MouseEvent e)
{
- Point click = e.getPoint();
- int row = Math.round(click.y / getRowHeight());
- TreePath path = getClosestPathForLocation(tree, click.x, click.y);
-
- if (path != null)
- {
- boolean inBounds = false;
- boolean cntlClick = false;
- Rectangle bounds = getPathBounds(tree, path);
-
- bounds.x -= rightChildIndent - 4;
- bounds.width += rightChildIndent + 4;
-
- if (bounds.contains(click.x, click.y))
- inBounds = true;
- else if (hasControlIcons()
- && (click.x < (bounds.x - rightChildIndent + 5) &&
- click.x > (bounds.x - rightChildIndent - 5)))
- cntlClick = true;
-
- if ((inBounds || cntlClick) && tree.isVisible(path))
- {
- selectPath(tree, path);
-
- if ((e.getClickCount() == 2 || cntlClick) && !isLeaf(row))
- {
- if (tree.isExpanded(path))
- tree.collapsePath(path);
- else
- tree.expandPath(path);
- }
-
- if (!cntlClick && tree.isEditable())
- startEditing(path, e);
- }
- }
+ // TODO: What should be done here, if anything?
}
/**
@@ -2299,6 +2374,7 @@ public class BasicTreeUI
*/
public void mouseReleased(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2309,6 +2385,7 @@ public class BasicTreeUI
*/
public void mouseEntered(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2319,6 +2396,7 @@ public class BasicTreeUI
*/
public void mouseExited(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2332,6 +2410,7 @@ public class BasicTreeUI
*/
public void mouseDragged(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2343,6 +2422,7 @@ public class BasicTreeUI
*/
public void mouseMoved(MouseEvent e)
{
+ // TODO: What should be done here, if anything?
}
/**
@@ -2350,8 +2430,9 @@ public class BasicTreeUI
*/
protected void removeFromSource()
{
+ // TODO: Implement this properly.
}
- }// MouseInputHandler
+ }
/**
* Class responsible for getting size of node, method is forwarded to
@@ -2366,6 +2447,7 @@ public class BasicTreeUI
*/
public NodeDimensionsHandler()
{
+ // Nothing to do here.
}
/**
@@ -2413,6 +2495,7 @@ public class BasicTreeUI
*/
public PropertyChangeHandler()
{
+ // Nothing to do here.
}
/**
@@ -2424,8 +2507,15 @@ public class BasicTreeUI
*/
public void propertyChange(PropertyChangeEvent event)
{
+ if ((event.getPropertyName()).equals("rootVisible"))
+ {
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
+ tree.repaint();
+ }
}
- }// PropertyChangeHandler
+ }
/**
* Listener on the TreeSelectionModel, resets the row selection if any of the
@@ -2440,6 +2530,7 @@ public class BasicTreeUI
*/
public SelectionModelPropertyChangeHandler()
{
+ // Nothing to do here.
}
/**
@@ -2451,8 +2542,9 @@ public class BasicTreeUI
*/
public void propertyChange(PropertyChangeEvent event)
{
+ // TODO: What should be done here, if anything?
}
- }// SelectionModelPropertyChangeHandler
+ }
/**
* ActionListener that invokes cancelEditing when action performed.
@@ -2464,8 +2556,9 @@ public class BasicTreeUI
/**
* Constructor
*/
- public TreeCancelEditingAction()
+ public TreeCancelEditingAction(String name)
{
+ // TODO: Implement this properly.
}
/**
@@ -2476,6 +2569,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2485,9 +2579,10 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly.
return false;
}
- }// TreeCancelEditingAction
+ }
/**
* Updates the TreeState in response to nodes expanding/collapsing.
@@ -2501,6 +2596,7 @@ public class BasicTreeUI
*/
public TreeExpansionHandler()
{
+ // Nothing to do here.
}
/**
@@ -2511,6 +2607,9 @@ public class BasicTreeUI
*/
public void treeExpanded(TreeExpansionEvent event)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2522,6 +2621,9 @@ public class BasicTreeUI
*/
public void treeCollapsed(TreeExpansionEvent event)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
}// TreeExpansionHandler
@@ -2547,6 +2649,7 @@ public class BasicTreeUI
*/
public TreeHomeAction(int direction, String name)
{
+ // TODO: Implement this properly
}
/**
@@ -2557,6 +2660,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly
}
/**
@@ -2566,9 +2670,10 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly
return false;
}
- }// TreeHomeAction
+ }
/**
* TreeIncrementAction is used to handle up/down actions. Selection is moved
@@ -2591,6 +2696,7 @@ public class BasicTreeUI
*/
public TreeIncrementAction(int direction, String name)
{
+ // TODO: Implement this properly
}
/**
@@ -2606,11 +2712,11 @@ public class BasicTreeUI
if (e.getActionCommand().equals("selectPreviousChangeLead"))
{
Object prev = getPreviousVisibleNode(last);
-
+
if (prev != null)
{
TreePath newPath = new TreePath(getPathToRoot(prev, 0));
- selectPath(tree, new TreePath(getPathToRoot(prev, 0)));
+ selectPath(tree, newPath);
tree.setLeadSelectionPath(newPath);
}
}
@@ -2627,15 +2733,17 @@ public class BasicTreeUI
else if (e.getActionCommand().equals("selectPrevious"))
{
Object prev = getPreviousVisibleNode(last);
+
if (prev != null)
{
TreePath newPath = new TreePath(getPathToRoot(prev, 0));
- selectPath(tree, new TreePath(getPathToRoot(prev, 0)));
+ selectPath(tree, newPath);
}
}
else if (e.getActionCommand().equals("selectNext"))
{
Object next = getNextVisibleNode(last);
+
if (next != null)
{
TreePath newPath = new TreePath(getPathToRoot(next, 0));
@@ -2671,21 +2779,22 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly
return false;
}
- }// TreeIncrementAction
+ }
/**
* Forwards all TreeModel events to the TreeState.
*/
- public class TreeModelHandler
- implements TreeModelListener
+ public class TreeModelHandler implements TreeModelListener
{
/**
* Constructor
*/
public TreeModelHandler()
{
+ // Nothing to do here.
}
/**
@@ -2703,6 +2812,9 @@ public class BasicTreeUI
*/
public void treeNodesChanged(TreeModelEvent e)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2716,6 +2828,9 @@ public class BasicTreeUI
*/
public void treeNodesInserted(TreeModelEvent e)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2732,6 +2847,9 @@ public class BasicTreeUI
*/
public void treeNodesRemoved(TreeModelEvent e)
{
+ validCachedPreferredSize = false;
+ updateCurrentVisiblePath();
+ tree.revalidate();
tree.repaint();
}
@@ -2747,6 +2865,12 @@ public class BasicTreeUI
*/
public void treeStructureChanged(TreeModelEvent e)
{
+ if (e.getPath().length == 1
+ && !e.getPath()[0].equals(treeModel.getRoot()))
+ tree.expandPath(new TreePath(treeModel.getRoot()));
+ updateCurrentVisiblePath();
+ validCachedPreferredSize = false;
+ tree.revalidate();
tree.repaint();
}
}// TreeModelHandler
@@ -2754,8 +2878,7 @@ public class BasicTreeUI
/**
* 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;
@@ -2770,6 +2893,7 @@ public class BasicTreeUI
*/
public TreePageAction(int direction, String name)
{
+ this.direction = direction;
}
/**
@@ -2780,6 +2904,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2797,14 +2922,14 @@ public class BasicTreeUI
* Listens for changes in the selection model and updates the display
* accordingly.
*/
- public class TreeSelectionHandler
- implements TreeSelectionListener
+ public class TreeSelectionHandler implements TreeSelectionListener
{
/**
* Constructor
*/
public TreeSelectionHandler()
{
+ // Nothing to do here.
}
/**
@@ -2824,8 +2949,7 @@ public class BasicTreeUI
/**
* For the first selected row expandedness will be toggled.
*/
- public class TreeToggleAction
- extends AbstractAction
+ public class TreeToggleAction extends AbstractAction
{
/**
* Constructor
@@ -2835,6 +2959,7 @@ public class BasicTreeUI
*/
public TreeToggleAction(String name)
{
+ // Nothing to do here.
}
/**
@@ -2845,6 +2970,7 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
+ // TODO: Implement this properly.
}
/**
@@ -2862,8 +2988,7 @@ public class BasicTreeUI
* 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.
@@ -2880,6 +3005,7 @@ public class BasicTreeUI
*/
public TreeTraverseAction(int direction, String name)
{
+ this.direction = direction;
}
/**
@@ -2890,16 +3016,15 @@ public class BasicTreeUI
*/
public void actionPerformed(ActionEvent e)
{
- TreeModel mod = tree.getModel();
Object last = tree.getLeadSelectionPath().getLastPathComponent();
if (e.getActionCommand().equals("selectParent"))
{
TreePath path = new TreePath(getPathToRoot(last, 0));
- Object p = getParent(mod.getRoot(), last);
+ Object p = getParent(treeModel.getRoot(), last);
- if (!mod.isLeaf(last) && tree.isExpanded(path))
- tree.collapsePath(path);
+ if (!treeModel.isLeaf(last))
+ toggleExpandState(path);
else if (p != null)
selectPath(tree, new TreePath(getPathToRoot(p, 0)));
}
@@ -2907,8 +3032,8 @@ public class BasicTreeUI
{
TreePath path = new TreePath(getPathToRoot(last, 0));
- if (!mod.isLeaf(last) && tree.isCollapsed(path))
- tree.expandPath(path);
+ if (!treeModel.isLeaf(last))
+ toggleExpandState(path);
else
{
Object next = getNextVisibleNode(last);
@@ -2926,9 +3051,10 @@ public class BasicTreeUI
*/
public boolean isEnabled()
{
+ // TODO: Implement this properly
return false;
}
- } // TreeTraverseAction
+ }
/**
* Returns the cell bounds for painting selected cells Package private for use
@@ -2951,8 +3077,7 @@ public class BasicTreeUI
FontMetrics fm = tree.getToolkit().getFontMetrics(f);
if (s != null)
- return new Rectangle(x, y,
- SwingUtilities.computeStringWidth(fm, s) + 4,
+ return new Rectangle(x, y, SwingUtilities.computeStringWidth(fm, s),
fm.getHeight());
}
return new Rectangle(x, y, 0, 0);
@@ -2982,80 +3107,19 @@ public class BasicTreeUI
int rowHeight = getRowHeight();
if (startNode == null || startNode.equals(node))
{
- if (!tree.isRootVisible()
- && tree.isExpanded(new TreePath(mod.getRoot())))
- return new Point(x + ((getLevel(node)) * rightChildIndent), y);
-
- return new Point(x + ((getLevel(node) + 1) * rightChildIndent), y);
- }
-
- if (!mod.isLeaf(startNode)
- && tree.isExpanded(new TreePath(getPathToRoot(startNode, 0)))
- && !mod.isLeaf(startNode) && mod.getChildCount(startNode) > 0)
- {
- Object child = mod.getChild(startNode, 0);
- if (child != null)
- return getCellLocation(x, y + rowHeight, tree, mod, node, child);
+ int level = getLevel(node);
+ if (level == 0)
+ return new Point(x, y);
+ if (!tree.isRootVisible() &&
+ tree.isExpanded(new TreePath(mod.getRoot())))
+ return new Point(x + ((level - 1) * rightChildIndent), y);
+ return new Point(x + (level * rightChildIndent), y);
}
-
return getCellLocation(x, y + rowHeight, tree, mod, node,
getNextVisibleNode(startNode));
}
/**
- * Paints a node in the tree Package private for use in inner classes.
- *
- * @param g
- * the Graphics context in which to paint
- * @param x
- * the x location of the node
- * @param y
- * the y location of the node
- * @param tree
- * the tree to draw on
- * @param node
- * the object to draw
- */
- void paintNode(Graphics g, int x, int y, JTree tree, Object node,
- boolean isLeaf)
- {
- TreePath curr = new TreePath(getPathToRoot(node, 0));
- boolean selected = tree.isPathSelected(curr);
- boolean expanded = false;
- boolean hasIcons = false;
-
- if (tree.isVisible(curr))
- {
- if (!isLeaf)
- expanded = tree.isExpanded(curr);
-
- if (editingComponent != null && editingPath != null && isEditing(tree)
- && node.equals(editingPath.getLastPathComponent()))
- {
- Rectangle bounds = getPathBounds(tree, editingPath);
- rendererPane.paintComponent(g, editingComponent.getParent(), null,
- new Rectangle(0, 0, bounds.width,
- bounds.height));
- }
- else
- {
- TreeCellRenderer dtcr = tree.getCellRenderer();
- if (dtcr == null)
- dtcr = createDefaultCellRenderer();
-
- int row = getRowForPath(tree, curr);
-
- Component c = dtcr.getTreeCellRendererComponent(tree, node,
- selected, expanded,
- isLeaf, row, false);
-
- rendererPane.paintComponent(g, c, c.getParent(),
- getCellBounds(x, y, node));
- }
- }
- }
-
- /**
* Recursively paints all elements of the tree Package private for use in
* inner classes.
*
@@ -3065,8 +3129,6 @@ public class BasicTreeUI
* of the current object
* @param descent
* is the number of elements drawn
- * @param childNumber
- * is the index of the current child in the tree
* @param depth
* is the depth of the current object in the tree
* @param tree
@@ -3077,71 +3139,79 @@ public class BasicTreeUI
* is the current object to draw
* @return int - current descent of the tree
*/
- int paintRecursive(Graphics g, int indentation, int descent, int childNumber,
+ int paintRecursive(Graphics g, int indentation, int descent,
int depth, JTree tree, TreeModel mod, Object curr)
{
- Rectangle clip = g.getClipBounds();
+ Rectangle clip = tree.getVisibleRect();
if (indentation > clip.x + clip.width + rightChildIndent
|| descent > clip.y + clip.height + getRowHeight())
return descent;
+ TreePath path = new TreePath(getPathToRoot(curr, 0));
int halfHeight = getRowHeight() / 2;
int halfWidth = rightChildIndent / 2;
int y0 = descent + halfHeight;
int heightOfLine = descent + halfHeight;
+ int row = getRowForPath(tree, path);
boolean isRootVisible = tree.isRootVisible();
-
- if (mod.isLeaf(curr))
+ boolean isExpanded = tree.isExpanded(path);
+ boolean isLeaf = mod.isLeaf(curr);
+ Rectangle bounds = getPathBounds(tree, path);
+ Object root = mod.getRoot();
+
+ if (isLeaf)
{
- paintNode(g, indentation + 4, descent, tree, curr, true);
+ paintRow(g, clip, null, bounds, path, row, true, false, true);
descent += getRowHeight();
}
else
{
if (depth > 0 || isRootVisible)
{
- paintNode(g, indentation + 4, descent, tree, curr, false);
+ paintRow(g, clip, null, bounds, path, row, isExpanded, false, false);
descent += getRowHeight();
y0 += halfHeight;
}
-
- int max = 0;
- if (!mod.isLeaf(curr))
- max = mod.getChildCount(curr);
- if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
+
+ if (isExpanded)
{
+ int max = mod.getChildCount(curr);
for (int i = 0; i < max; i++)
{
+ Object child = mod.getChild(curr, i);
+ boolean childVis = tree.isVisible(new TreePath
+ (getPathToRoot(child, 0)));
int indent = indentation + rightChildIndent;
if (!isRootVisible && depth == 0)
indent = 0;
- else if ((!isRootVisible && !curr.equals(mod.getRoot()))
- || isRootVisible)
+ else if (isRootVisible ||
+ (!isRootVisible && !curr.equals(root)) && childVis)
{
g.setColor(getHashColor());
heightOfLine = descent + halfHeight;
- g.drawLine(indentation + halfWidth, heightOfLine,
- indentation + rightChildIndent, heightOfLine);
+ paintHorizontalLine(g, (JComponent) tree, heightOfLine,
+ indentation + halfWidth, indentation + rightChildIndent);
}
- descent = paintRecursive(g, indent, descent, i, depth + 1,
- tree, mod, mod.getChild(curr, i));
+ descent = paintRecursive(g, indent, descent, depth + 1,
+ tree, mod, child);
}
}
}
- if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
- if (y0 != heightOfLine && !mod.isLeaf(curr)
- && mod.getChildCount(curr) > 0)
+ if (isExpanded)
+ if (y0 != heightOfLine
+ && (mod.getChildCount(curr) > 0 &&
+ tree.isVisible(new TreePath(getPathToRoot(mod.getChild
+ (curr, 0), 0)))))
{
g.setColor(getHashColor());
- g.drawLine(indentation + halfWidth, y0, indentation + halfWidth,
- heightOfLine);
+ paintVerticalLine(g, (JComponent) tree, indentation + halfWidth, y0,
+ heightOfLine);
}
-
return descent;
}
-
+
/**
* Recursively paints all the control icons on the tree. Package private for
* use in inner classes.
@@ -3152,76 +3222,99 @@ public class BasicTreeUI
* of the current object
* @param descent
* is the number of elements drawn
- * @param childNumber
- * is the index of the current child in the tree
* @param depth
* is the depth of the current object in the tree
* @param tree
* is the tree to draw to
* @param mod
* is the TreeModel we are using to draw
- * @param curr
+ * @param node
* is the current object to draw
- * @return int - current descent of the tree
+ * @return int current descent of the tree
*/
int paintControlIcons(Graphics g, int indentation, int descent,
- int childNumber, int depth, JTree tree, TreeModel mod,
+ int depth, JTree tree, TreeModel mod,
Object node)
{
- int h = descent;
int rowHeight = getRowHeight();
- Icon ei = UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon");
- Icon ci = UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon");
- Rectangle clip = g.getClipBounds();
+ TreePath path = new TreePath(getPathToRoot(node, 0));
+ Icon icon = getCurrentControlIcon(path);
+
+ Rectangle clip = tree.getVisibleRect();
if (indentation > clip.x + clip.width + rightChildIndent
|| descent > clip.y + clip.height + getRowHeight())
return descent;
-
+
if (mod.isLeaf(node))
descent += rowHeight;
else
- {
+ {
+ if (!node.equals(mod.getRoot()) &&
+ (tree.isRootVisible() || getLevel(node) != 1))
+ {
+ int width = icon.getIconWidth();
+ int height = icon.getIconHeight() + 2;
+ int posX = indentation - rightChildIndent;
+ int posY = descent;
+ if (width > rightChildIndent)
+ posX -= gap;
+ else posX += width/2;
+
+ if (height < rowHeight)
+ posY += height/2;
+
+ icon.paintIcon(tree, g, posX, posY);
+ }
+
if (depth > 0 || tree.isRootVisible())
descent += rowHeight;
-
- int max = 0;
- if (!mod.isLeaf(node))
- max = mod.getChildCount(node);
- if (tree.isExpanded(new TreePath(getPathToRoot(node, 0))))
+
+ if (tree.isExpanded(path))
{
- if (!node.equals(mod.getRoot()))
- ei.paintIcon(tree, g, indentation - rightChildIndent - 3, h);
-
+ int max = 0;
+ if (!mod.isLeaf(node))
+ max = mod.getChildCount(node);
+
for (int i = 0; i < max; i++)
{
int indent = indentation + rightChildIndent;
+ Object child = mod.getChild(node, i);
if (depth == 0 && !tree.isRootVisible())
- indent = -1;
-
- descent = paintControlIcons(g, indent, descent, i, depth + 1,
- tree, mod, mod.getChild(node, i));
+ indent = 1;
+ if (tree.isVisible(new TreePath(getPathToRoot(child, 0))))
+ descent = paintControlIcons(g, indent, descent, depth + 1,
+ tree, mod, child);
}
}
- else if (!node.equals(mod.getRoot()))
- ci.paintIcon(tree, g, indentation - rightChildIndent - 3,
- descent - getRowHeight());
}
-
+
return descent;
}
/**
- * Returns true if the LookAndFeel implements the control icons Package
+ * Returns true if the LookAndFeel implements the control icons. Package
* private for use in inner classes.
*
- * @return true if control icons are visible
+ * @returns true if there are control icons
*/
boolean hasControlIcons()
{
- if (UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon") == null
- || UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon") == null)
- return false;
- return true;
+ if (expandedIcon != null || collapsedIcon != null)
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns control icon. It is null if the LookAndFeel does not implements the
+ * control icons. Package private for use in inner classes.
+ *
+ * @return control icon if it exists.
+ */
+ Icon getCurrentControlIcon(TreePath path)
+ {
+ if (tree.isExpanded(path))
+ return expandedIcon;
+ return collapsedIcon;
}
/**
@@ -3235,8 +3328,10 @@ public class BasicTreeUI
*/
Object getParent(Object root, Object node)
{
- if (root == null || node == null)
+ if (root == null || node == null ||
+ root.equals(node))
return null;
+
if (node instanceof TreeNode)
return ((TreeNode) node).getParent();
return findNode(root, node);
@@ -3253,113 +3348,69 @@ public class BasicTreeUI
*/
private Object findNode(Object root, Object node)
{
- TreeModel mod = tree.getModel();
- int size = 0;
- if (!mod.isLeaf(root))
- size = mod.getChildCount(root);
- for (int i = 0; i < size; i++)
- {
- if (mod.getIndexOfChild(root, node) != -1)
- return root;
-
- Object n = findNode(mod.getChild(root, i), node);
- if (n != null)
- return n;
- }
- return null;
- }
-
- /**
- * Get next visible node in the tree. Package private for use in inner
- * classes.
- *
- * @param the
- * current node
- * @return the next visible node in the JTree. Return null if there are no
- * more.
- */
- Object getNextVisibleNode(Object node)
- {
- Object next = null;
- TreePath current = null;
-
- if (node != null)
- next = getNextNode(node);
-
- if (next != null)
+ if (!treeModel.isLeaf(root) && !root.equals(node))
{
- current = new TreePath(getPathToRoot(next, 0));
- if (tree.isVisible(current))
- return next;
-
- while (next != null && !tree.isVisible(current))
+ int size = treeModel.getChildCount(root);
+ for (int j = 0; j < size; j++)
{
- next = getNextNode(next);
+ Object child = treeModel.getChild(root, j);
+ if (node.equals(child))
+ return root;
- if (next != null)
- current = new TreePath(getPathToRoot(next, 0));
+ Object n = findNode(child, node);
+ if (n != null)
+ return n;
}
}
- return next;
+ return null;
}
-
+
/**
* Get previous visible node in the tree. Package private for use in inner
* classes.
*
- * @param the
+ * @param node -
* current node
* @return the next visible node in the JTree. Return null if there are no
* more.
*/
Object getPreviousVisibleNode(Object node)
{
- Object prev = null;
- TreePath current = null;
-
- if (node != null)
- prev = getPreviousNode(node);
-
- if (prev != null)
+ updateCurrentVisiblePath();
+ if (currentVisiblePath != null)
{
- current = new TreePath(getPathToRoot(prev, 0));
- if (tree.isVisible(current))
- return prev;
-
- while (prev != null && !tree.isVisible(current))
- {
- prev = getPreviousNode(prev);
-
- if (prev != null)
- current = new TreePath(getPathToRoot(prev, 0));
- }
+ 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 prev;
+ return null;
}
/**
* Returns the next node in the tree Package private for use in inner classes.
*
- * @param the
+ * @param curr -
* current node
* @return the next node in the tree
*/
Object getNextNode(Object curr)
{
- TreeModel mod = tree.getModel();
- if (!mod.isLeaf(curr) && mod.getChildCount(curr) > 0)
- return mod.getChild(curr, 0);
+ 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(mod.getRoot(), node);
+ node = getParent(treeModel.getRoot(), node);
}
while (sibling == null && node != null);
-
+
return sibling;
}
@@ -3367,14 +3418,13 @@ public class BasicTreeUI
* Returns the previous node in the tree Package private for use in inner
* classes.
*
- * @param the
+ * @param node
* current node
* @return the previous node in the tree
*/
Object getPreviousNode(Object node)
{
- TreeModel mod = tree.getModel();
- Object parent = getParent(mod.getRoot(), node);
+ Object parent = getParent(treeModel.getRoot(), node);
if (parent == null)
return null;
@@ -3384,13 +3434,13 @@ public class BasicTreeUI
return parent;
int size = 0;
- if (!mod.isLeaf(sibling))
- size = mod.getChildCount(sibling);
+ if (!treeModel.isLeaf(sibling))
+ size = treeModel.getChildCount(sibling);
while (size > 0)
{
- sibling = mod.getChild(sibling, size - 1);
- if (!mod.isLeaf(sibling))
- size = mod.getChildCount(sibling);
+ sibling = treeModel.getChild(sibling, size - 1);
+ if (!treeModel.isLeaf(sibling))
+ size = treeModel.getChildCount(sibling);
else
size = 0;
}
@@ -3402,52 +3452,50 @@ public class BasicTreeUI
* Returns the next sibling in the tree Package private for use in inner
* classes.
*
- * @param the
+ * @param node -
* current node
* @return the next sibling in the tree
*/
Object getNextSibling(Object node)
{
- TreeModel mod = tree.getModel();
- Object parent = getParent(mod.getRoot(), node);
+ Object parent = getParent(treeModel.getRoot(), node);
if (parent == null)
return null;
- int index = mod.getIndexOfChild(parent, node) + 1;
+ int index = treeModel.getIndexOfChild(parent, node) + 1;
int size = 0;
- if (!mod.isLeaf(parent))
- size = mod.getChildCount(parent);
+ if (!treeModel.isLeaf(parent))
+ size = treeModel.getChildCount(parent);
if (index == 0 || index >= size)
return null;
- return mod.getChild(parent, index);
+ return treeModel.getChild(parent, index);
}
-
+
/**
* Returns the previous sibling in the tree Package private for use in inner
* classes.
*
- * @param the
+ * @param node -
* current node
* @return the previous sibling in the tree
*/
Object getPreviousSibling(Object node)
{
- TreeModel mod = tree.getModel();
- Object parent = getParent(mod.getRoot(), node);
+ Object parent = getParent(treeModel.getRoot(), node);
if (parent == null)
return null;
- int index = mod.getIndexOfChild(parent, node) - 1;
+ int index = treeModel.getIndexOfChild(parent, node) - 1;
int size = 0;
- if (!mod.isLeaf(parent))
- size = mod.getChildCount(parent);
+ if (!treeModel.isLeaf(parent))
+ size = treeModel.getChildCount(parent);
if (index < 0 || index >= size)
return null;
- return mod.getChild(parent, index);
+ return treeModel.getChild(parent, index);
}
/**
@@ -3463,22 +3511,24 @@ public class BasicTreeUI
{
if (path != null)
{
- if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
+ if (tree.getSelectionModel().getSelectionMode() ==
+ TreeSelectionModel.SINGLE_TREE_SELECTION)
{
+ tree.getSelectionModel().clearSelection();
tree.addSelectionPath(path);
tree.setLeadSelectionPath(path);
}
- else if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION)
+ else if (tree.getSelectionModel().getSelectionMode() ==
+ TreeSelectionModel.CONTIGUOUS_TREE_SELECTION)
{
// TODO
}
else
{
- tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
-
- tree.getSelectionModel().clearSelection();
tree.addSelectionPath(path);
tree.setLeadSelectionPath(path);
+ tree.getSelectionModel().setSelectionMode
+ (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
}
}
}
@@ -3495,7 +3545,6 @@ public class BasicTreeUI
*/
Object[] getPathToRoot(Object node, int depth)
{
- TreeModel mod = tree.getModel();
if (node == null)
{
if (depth == 0)
@@ -3504,7 +3553,7 @@ public class BasicTreeUI
return new Object[depth];
}
- Object[] path = getPathToRoot(getParent(mod.getRoot(), node), depth + 1);
+ Object[] path = getPathToRoot(getParent(treeModel.getRoot(), node), depth + 1);
path[path.length - depth - 1] = node;
return path;
}
@@ -3512,22 +3561,23 @@ public class BasicTreeUI
/**
* Returns the level of the node in the tree.
*
- * @param the
+ * @param node -
* current node
* @return the number of the level
*/
int getLevel(Object node)
{
int count = -1;
+
Object current = node;
do
{
- current = getParent(tree.getModel().getRoot(), current);
+ current = getParent(treeModel.getRoot(), current);
count++;
}
while (current != null);
-
+
return count;
}
@@ -3586,10 +3636,271 @@ public class BasicTreeUI
* is the center position in y-direction FIXME what to do if x <
* (icon.width / 2). Same with y
*/
- protected void drawCentered(JComponent c, Graphics g, Icon icon, int x, int y)
+ protected void drawCentered(Component c, Graphics g, Icon icon, int x, int y)
{
int beginPositionX = x - icon.getIconWidth() / 2;
int beginPositionY = y - icon.getIconHeight() / 2;
icon.paintIcon(c, g, beginPositionX, beginPositionY);
}
+
+ /**
+ * 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
+ */
+ protected void drawDashedHorizontalLine(Graphics g, int y, int x1, int x2)
+ {
+ for (int i = x1; i < x2; i += 2)
+ g.drawLine(i, y, i + 1, y);
+ }
+
+ /**
+ * 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
+ */
+ protected void drawDashedVerticalLine(Graphics g, int x, int y1, int y2)
+ {
+ for (int i = y1; i < y2; i += 2)
+ g.drawLine(x, i, x, i + 1);
+ }
+
+ /**
+ * Paints the expand (toggle) part of a row. The receiver should NOT modify
+ * clipBounds, or insets.
+ *
+ * @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
+ */
+ protected void paintExpandControl(Graphics g, Rectangle clipBounds,
+ Insets insets, Rectangle bounds,
+ TreePath path, int row,
+ boolean isExpanded, boolean hasBeenExpanded,
+ boolean isLeaf)
+ {
+ if (treeModel != null && hasControlIcons())
+ paintControlIcons(g, 0, 0, 0, tree, treeModel, path.getLastPathComponent());
+ }
+
+ /**
+ * Paints the horizontal part of the leg. The receiver should NOT modify
+ * clipBounds, or insets.
+ * NOTE: parentRow can be -1 if the root is not visible.
+ *
+ * @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
+ */
+ protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
+ Insets insets, Rectangle bounds,
+ TreePath path, int row,
+ boolean isExpanded, boolean hasBeenExpanded,
+ boolean isLeaf)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Paints the vertical part of the leg. The receiver should NOT modify
+ * clipBounds, insets.
+ *
+ * @param g - the graphics configuration.
+ * @param clipBounds -
+ * @param insets -
+ * @param path - the path to draw the vertical part for.
+ */
+ protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds,
+ Insets insets, TreePath path)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Paints the renderer part of a row. The receiver should NOT modify clipBounds,
+ * or insets.
+ *
+ * @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
+ */
+ protected void paintRow(Graphics g, Rectangle clipBounds,
+ Insets insets, Rectangle bounds,
+ TreePath path, int row,
+ boolean isExpanded, boolean hasBeenExpanded,
+ boolean isLeaf)
+ {
+ boolean selected = tree.isPathSelected(path);
+ boolean hasIcons = false;
+ Object node = path.getLastPathComponent();
+
+ if (tree.isVisible(path))
+ {
+ if (!validCachedPreferredSize)
+ updateCachedPreferredSize();
+ bounds.x += gap;
+ bounds.width = preferredSize.width + bounds.x;
+
+ if (editingComponent != null && editingPath != null && isEditing(tree)
+ && node.equals(editingPath.getLastPathComponent()))
+ {
+ rendererPane.paintComponent(g, editingComponent.getParent(), null,
+ bounds);
+ }
+ else
+ {
+ 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);
+ }
+ }
+ }
+
+ /**
+ * Prepares for the UI to uninstall.
+ */
+ protected void prepareForUIUninstall()
+ {
+ // TODO: Implement this properly.
+ }
+
+ /**
+ * 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
+ */
+ protected boolean shouldPaintExpandControl(TreePath path, int row,
+ boolean isExpanded,
+ boolean hasBeenExpanded,
+ boolean isLeaf)
+ {
+ Object node = path.getLastPathComponent();
+ if (treeModel != null && (!isLeaf && !node.equals(treeModel.getRoot())) &&
+ (tree.isRootVisible() || getLevel(node) != 1))
+ return true;
+ return false;
+ }
+
+ /**
+ * Updates the cached current TreePath of all visible
+ * nodes in the tree.
+ */
+ void updateCurrentVisiblePath()
+ {
+ if (treeModel == null)
+ return;
+
+ Object next = treeModel.getRoot();
+ Rectangle bounds = getCellBounds(0, 0, next);
+ boolean rootVisible = isRootVisible();
+
+ // 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) || (!rootVisible
+ && tree.isExpanded(new TreePath(next))))
+ next = getNextNode(next);
+
+ Object root = next;
+ TreePath current = null;
+ while (next != null)
+ {
+ if (current == null)
+ current = new TreePath(next);
+ 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(treeModel.getRoot(), next);
+ }
+ }
+ }
+ }
+ while (next != null &&
+ !tree.isVisible(new TreePath(getPathToRoot(next, 0))));
+ }
+
+ currentVisiblePath = current;
+ if (currentVisiblePath != null)
+ tree.setVisibleRowCount(currentVisiblePath.getPathCount());
+ else tree.setVisibleRowCount(0);
+
+ if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0 &&
+ currentVisiblePath != null)
+ selectPath(tree, new TreePath(getPathToRoot(currentVisiblePath.
+ getPathComponent(0), 0)));
+ }
+
+ /**
+ * 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.
+ */
+ 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;
+ }
} // BasicTreeUI
OpenPOWER on IntegriCloud