diff options
Diffstat (limited to 'javax/swing/plaf/basic/BasicTreeUI.java')
-rw-r--r-- | javax/swing/plaf/basic/BasicTreeUI.java | 1225 |
1 files changed, 660 insertions, 565 deletions
diff --git a/javax/swing/plaf/basic/BasicTreeUI.java b/javax/swing/plaf/basic/BasicTreeUI.java index 0ccc0f5be..74bd6110b 100644 --- a/javax/swing/plaf/basic/BasicTreeUI.java +++ b/javax/swing/plaf/basic/BasicTreeUI.java @@ -1,39 +1,39 @@ /* BasicTreeUI.java -- - Copyright (C) 2002, 2004, 2005 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. */ + Copyright (C) 2002, 2004, 2005 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 javax.swing.plaf.basic; @@ -90,6 +90,7 @@ import javax.swing.plaf.TreeUI; 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; @@ -106,128 +107,138 @@ import javax.swing.tree.TreeSelectionModel; * @author Sascha Brawer (brawer@dandelis.ch) * @author Lillian Angel (langel@redhat.com) */ -public class BasicTreeUI extends TreeUI +public class BasicTreeUI + extends TreeUI { /** Collapse Icon for the tree. */ protected transient Icon collapsedIcon; - + /** Expanded Icon for the tree. */ protected transient Icon expandedIcon; - + /** Distance between left margin and where vertical dashes will be drawn. */ protected int leftChildIndent; - + /** * Distance between leftChildIndent and where cell contents will be drawn. */ protected int rightChildIndent; - + /** * Total fistance that will be indented. The sum of leftChildIndent and * rightChildIndent . */ protected int totalChildIndent; - + /** Minimum preferred size. */ protected Dimension preferredMinsize; - + /** Index of the row that was last selected. */ protected int lastSelectedRow; - + /** Component that we're going to be drawing onto. */ protected JTree tree; - + /** Renderer that is being used to do the actual cell drawing. */ protected transient TreeCellRenderer currentCellRenderer; - + /** * Set to true if the renderer that is currently in the tree was created by * this instance. */ protected boolean createdRenderer; - + /** Editor for the tree. */ protected transient TreeCellEditor cellEditor; - + /** * Set to true if editor that is currently in the tree was created by this * instance. */ protected boolean createdCellEditor; - + /** * Set to false when editing and shouldSelectCall() returns true meaning the * node should be selected before editing, used in completeEditing. */ protected boolean stopEditingInCompleteEditing; - + /** Used to paint the TreeCellRenderer. */ protected CellRendererPane rendererPane; - + /** Size needed to completely display all the nodes. */ protected Dimension preferredSize; - + /** Is the preferredSize valid? */ protected boolean validCachedPreferredSize; - + /** Object responsible for handling sizing and expanded issues. */ protected AbstractLayoutCache treeState; - + /** Used for minimizing the drawing of vertical lines. */ protected Hashtable drawingCache; - + /** * True if doing optimizations for a largeModel. Subclasses that don't * support this may wish to override createLayoutCache to not return a * FixedHeightLayoutCache instance. */ protected boolean largeModel; - + /** Responsible for telling the TreeState the size needed for a node. */ protected AbstractLayoutCache.NodeDimensions nodeDimensions; - + /** Used to determine what to display. */ protected TreeModel treeModel; - + /** Model maintaining the selection. */ protected TreeSelectionModel treeSelectionModel; - + /** * How much the depth should be offset to properly calculate x locations. * This is based on whether or not the root is visible, and if the root * handles are visible. */ protected int depthOffset; - + /** * When editing, this will be the Component that is doing the actual editing. */ protected Component editingComponent; - + /** Path that is being edited. */ protected TreePath editingPath; - + /** * Row that is being edited. Should only be referenced if editingComponent is * null. */ protected int editingRow; - + /** Set to true if the editor has a different size than the renderer. */ protected boolean editorHasDifferentSize; - + /** Listeners */ private PropertyChangeListener propertyChangeListener; + private FocusListener focusListener; + private TreeSelectionListener treeSelectionListener; + private MouseInputListener mouseInputListener; + private KeyListener keyListener; + private PropertyChangeListener selectionModelPropertyChangeListener; + private ComponentListener componentListener; + private CellEditorListener cellEditorListener; + private TreeExpansionListener treeExpansionListener; + private TreeModelListener treeModelListener; - + /** * Creates a new BasicTreeUI object. */ @@ -239,7 +250,7 @@ public class BasicTreeUI extends TreeUI nodeDimensions = createNodeDimensions(); rendererPane = createCellRendererPane(); configureLayoutCache(); - + propertyChangeListener = createPropertyChangeListener(); focusListener = createFocusListener(); treeSelectionListener = createTreeSelectionListener(); @@ -250,13 +261,13 @@ public class BasicTreeUI extends TreeUI cellEditorListener = createCellEditorListener(); treeExpansionListener = createTreeExpansionListener(); treeModelListener = createTreeModelListener(); - + createdRenderer = true; createdCellEditor = true; editingRow = -1; lastSelectedRow = -1; } - + /** * Returns an instance of the UI delegate for the specified component. * @@ -268,7 +279,7 @@ public class BasicTreeUI extends TreeUI { return new BasicTreeUI(); } - + /** * Returns the Hash color. * @@ -278,7 +289,7 @@ public class BasicTreeUI extends TreeUI { return UIManager.getLookAndFeelDefaults().getColor("Tree.hash"); } - + /** * Sets the Hash color. * @@ -287,9 +298,9 @@ public class BasicTreeUI extends TreeUI protected void setHashColor(Color color) { // FIXME: not implemented - + } - + /** * Sets the left child's indent value. * @@ -299,7 +310,7 @@ public class BasicTreeUI extends TreeUI { leftChildIndent = newAmount; } - + /** * Returns the indent value for the left child. * @@ -309,7 +320,7 @@ public class BasicTreeUI extends TreeUI { return leftChildIndent; } - + /** * Sets the right child's indent value. * @@ -319,7 +330,7 @@ public class BasicTreeUI extends TreeUI { rightChildIndent = newAmount; } - + /** * Returns the indent value for the right child. * @@ -329,7 +340,7 @@ public class BasicTreeUI extends TreeUI { return rightChildIndent; } - + /** * Sets the expanded icon. * @@ -339,7 +350,7 @@ public class BasicTreeUI extends TreeUI { expandedIcon = newG; } - + /** * Returns the current expanded icon. * @@ -349,7 +360,7 @@ public class BasicTreeUI extends TreeUI { return expandedIcon; } - + /** * Sets the collapsed icon. * @@ -359,7 +370,7 @@ public class BasicTreeUI extends TreeUI { collapsedIcon = newG; } - + /** * Returns the current collapsed icon. * @@ -369,7 +380,7 @@ public class BasicTreeUI extends TreeUI { return collapsedIcon; } - + /** * Updates the componentListener, if necessary. * @@ -384,7 +395,7 @@ public class BasicTreeUI extends TreeUI tree.addComponentListener(componentListener); } } - + /** * Returns true if largeModel is set * @@ -394,7 +405,7 @@ public class BasicTreeUI extends TreeUI { return largeModel; } - + /** * Sets the row height. * @@ -404,7 +415,7 @@ public class BasicTreeUI extends TreeUI { treeState.setRowHeight(rowHeight); } - + /** * Returns the current row height. * @@ -414,7 +425,7 @@ public class BasicTreeUI extends TreeUI { return treeState.getRowHeight(); } - + /** * Sets the TreeCellRenderer to <code>tcr</code>. This invokes * <code>updateRenderer</code>. @@ -424,9 +435,10 @@ public class BasicTreeUI extends TreeUI protected void setCellRenderer(TreeCellRenderer tcr) { currentCellRenderer = tcr; + tree.setCellRenderer(tcr); updateRenderer(); } - + /** * Return currentCellRenderer, which will either be the trees renderer, or * defaultCellRenderer, which ever was not null. @@ -437,10 +449,10 @@ public class BasicTreeUI extends TreeUI { if (currentCellRenderer != null) return currentCellRenderer; - + return createDefaultCellRenderer(); } - + /** * Sets the tree's model. * @@ -449,9 +461,9 @@ public class BasicTreeUI extends TreeUI protected void setModel(TreeModel model) { tree.setModel(model); - treeModel = model; + treeModel = tree.getModel(); } - + /** * Returns the tree's model * @@ -461,7 +473,7 @@ public class BasicTreeUI extends TreeUI { return treeModel; } - + /** * Sets the root to being visible. * @@ -471,7 +483,7 @@ public class BasicTreeUI extends TreeUI { tree.setRootVisible(newValue); } - + /** * Returns true if the root is visible. * @@ -481,7 +493,7 @@ public class BasicTreeUI extends TreeUI { return tree.isRootVisible(); } - + /** * Determines whether the node handles are to be displayed. * @@ -491,7 +503,7 @@ public class BasicTreeUI extends TreeUI { tree.setShowsRootHandles(newValue); } - + /** * Returns true if the node handles are to be displayed. * @@ -501,7 +513,7 @@ public class BasicTreeUI extends TreeUI { return tree.getShowsRootHandles(); } - + /** * Sets the cell editor. * @@ -511,7 +523,7 @@ public class BasicTreeUI extends TreeUI { cellEditor = editor; } - + /** * Returns the <code>TreeCellEditor</code> for this tree. * @@ -521,7 +533,7 @@ public class BasicTreeUI extends TreeUI { return cellEditor; } - + /** * Configures the receiver to allow, or not allow, editing. * @@ -531,7 +543,7 @@ public class BasicTreeUI extends TreeUI { tree.setEditable(newValue); } - + /** * Returns true if the receiver allows editing. * @@ -541,7 +553,7 @@ public class BasicTreeUI extends TreeUI { return tree.isEditable(); } - + /** * Resets the selection model. The appropriate listeners are installed on the * model. @@ -556,7 +568,7 @@ public class BasicTreeUI extends TreeUI tree.setSelectionModel(treeSelectionModel); } } - + /** * Returns the current selection model. * @@ -566,7 +578,7 @@ public class BasicTreeUI extends TreeUI { return treeSelectionModel; } - + /** * Returns the Rectangle enclosing the label portion that the last item in * path will be drawn to. Will return null if any component in path is @@ -583,17 +595,19 @@ public class BasicTreeUI extends TreeUI { Object cell = path.getLastPathComponent(); TreeModel mod = tree.getModel(); - TreeNode root = (TreeNode) mod.getRoot(); - if (!tree.isRootVisible() - && tree.isExpanded(new TreePath(root))) - root = getNextNode(root); - - Point loc = getCellLocation(0, 0, tree, mod, cell, root); - return getCellBounds(loc.x, loc.y, cell); + if (mod != null) + { + Object root = mod.getRoot(); + if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root))) + root = getNextNode(root); + + Point loc = getCellLocation(0, 0, tree, mod, cell, root); + return getCellBounds(loc.x, loc.y, cell); + } } return null; } - + /** * Returns the path for passed in row. If row is not visible null is * returned. @@ -605,22 +619,25 @@ public class BasicTreeUI extends TreeUI */ public TreePath getPathForRow(JTree tree, int row) { - TreeNode node = ((TreeNode) (tree.getModel()).getRoot()); - if (!tree.isRootVisible() - && tree.isExpanded(new TreePath(getPathToRoot(node, 0)))) - node = getNextNode(node); - - for (int i = 0; i < row; i++) - node = getNextVisibleNode(node); - - // in case nothing was found - if (node == null) - return null; - - // something was found - return new TreePath(getPathToRoot(node, 0)); + TreeModel mod = tree.getModel(); + if (mod != 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)); + } + return null; } - + /** * 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. @@ -638,7 +655,7 @@ public class BasicTreeUI extends TreeUI // expand/collapse is not implemented return path.getPathCount() - 1; } - + /** * Returns the number of rows that are being displayed. * @@ -647,23 +664,24 @@ public class BasicTreeUI extends TreeUI */ public int getRowCount(JTree tree) { - TreeNode node = ((TreeNode) (tree.getModel()) - .getRoot()); - if (!tree.isRootVisible() - && tree.isExpanded(new TreePath((getPathToRoot(node, 0))))) - node = getNextNode(node); - + TreeModel mod = tree.getModel(); int count = 0; - - while (node != null) + if (mod != null) { - count++; - node = getNextVisibleNode(node); + 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; } - + /** * Returns the path to the node that is closest to x,y. If there is nothing * currently visible this will return null, otherwise it'll always return a @@ -679,20 +697,20 @@ public class BasicTreeUI extends TreeUI { //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); - + // no row is visible at this node while (row > 0 && path == null) { --row; path = getPathForRow(tree, row); } - + return path; } - + /** * Returns true if the tree is being edited. The item that is being edited * can be returned by getEditingPath(). @@ -705,7 +723,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return false; } - + /** * Stops the current editing session. This has no effect if the tree is not * being edited. Returns true if the editor allows the editing session to @@ -719,7 +737,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return false; } - + /** * Cancels the current editing session. * @@ -729,7 +747,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * 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. @@ -741,7 +759,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Returns the path to the element that is being editted. * @@ -753,7 +771,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return null; } - + /** * Invoked after the tree instance variable has been set, but before any * default/listeners have been installed. @@ -762,7 +780,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Invoked from installUI after all the defaults/listeners have been * installed. @@ -771,7 +789,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Invoked from uninstallUI after all the defaults/listeners have been * uninstalled. @@ -780,7 +798,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Installs the subcomponents of the tree, which is the renderer pane. */ @@ -788,7 +806,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Creates an instance of NodeDimensions that is able to determine the size * of a given node in the tree. @@ -800,7 +818,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return null; } - + /** * Creates a listener that is reponsible for the updates the UI based on how * the tree changes. @@ -811,7 +829,7 @@ public class BasicTreeUI extends TreeUI { return new PropertyChangeHandler(); } - + /** * Creates the listener responsible for updating the selection based on mouse * events. @@ -822,7 +840,7 @@ public class BasicTreeUI extends TreeUI { return new MouseHandler(); } - + /** * Creates the listener that is responsible for updating the display when * focus is lost/grained. @@ -833,7 +851,7 @@ public class BasicTreeUI extends TreeUI { return new FocusHandler(); } - + /** * Creates the listener reponsible for getting key events from the tree. * @@ -843,7 +861,7 @@ public class BasicTreeUI extends TreeUI { return new KeyHandler(); } - + /** * Creates the listener responsible for getting property change events from * the selection model. @@ -855,7 +873,7 @@ public class BasicTreeUI extends TreeUI { return new SelectionModelPropertyChangeHandler(); } - + /** * Creates the listener that updates the display based on selection change * methods. @@ -866,7 +884,7 @@ public class BasicTreeUI extends TreeUI { return new TreeSelectionHandler(); } - + /** * Creates a listener to handle events from the current editor * @@ -876,7 +894,7 @@ public class BasicTreeUI extends TreeUI { return new CellEditorHandler(); } - + /** * Creates and returns a new ComponentHandler. This is used for the large * model to mark the validCachedPreferredSize as invalid when the component @@ -888,7 +906,7 @@ public class BasicTreeUI extends TreeUI { return new ComponentHandler(); } - + /** * Creates and returns the object responsible for updating the treestate when * a nodes expanded state changes. @@ -899,7 +917,7 @@ public class BasicTreeUI extends TreeUI { return new TreeExpansionHandler(); } - + /** * Creates the object responsible for managing what is expanded, as well as * the size of nodes. @@ -910,7 +928,7 @@ public class BasicTreeUI extends TreeUI { return new FixedHeightLayoutCache(); } - + /** * Returns the renderer pane that renderer components are placed in. * @@ -920,7 +938,7 @@ public class BasicTreeUI extends TreeUI { return new CellRendererPane(); } - + /** * Creates a default cell editor. * @@ -928,10 +946,12 @@ public class BasicTreeUI extends TreeUI */ protected TreeCellEditor createDefaultCellEditor() { - return new DefaultTreeCellEditor(tree, - (DefaultTreeCellRenderer) createDefaultCellRenderer(), cellEditor); + return new DefaultTreeCellEditor( + tree, + (DefaultTreeCellRenderer) createDefaultCellRenderer(), + cellEditor); } - + /** * Returns the default cell renderer that is used to do the stamping of each * node. @@ -943,7 +963,7 @@ public class BasicTreeUI extends TreeUI { return new DefaultTreeCellRenderer(); } - + /** * Returns a listener that can update the tree when the model changes. * @@ -953,7 +973,7 @@ public class BasicTreeUI extends TreeUI { return new TreeModelHandler(); } - + /** * Uninstall all registered listeners */ @@ -967,7 +987,7 @@ public class BasicTreeUI extends TreeUI tree.removePropertyChangeListener(selectionModelPropertyChangeListener); tree.removeComponentListener(componentListener); tree.removeTreeExpansionListener(treeExpansionListener); - + TreeCellEditor tce = tree.getCellEditor(); if (tce != null) tce.removeCellEditorListener(cellEditorListener); @@ -975,14 +995,14 @@ public class BasicTreeUI extends TreeUI if (tm != null) tm.removeTreeModelListener(treeModelListener); } - + /** * Uninstall all keyboard actions. */ protected void uninstallKeyboardActions() { } - + /** * Uninstall the rendererPane. */ @@ -990,7 +1010,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * The vertical element of legs between nodes starts at the bottom of the * parent node by default. This method makes the leg start below that. @@ -1002,7 +1022,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return 0; } - + /** * The horizontal element of legs between nodes starts at the right of the * left-hand side of the child node by default. This method makes the leg end @@ -1015,7 +1035,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return 0; } - + /** * Make all the nodes that are expanded in JTree expanded in LayoutCache. * This invokes update ExpandedDescendants with the root path. @@ -1024,7 +1044,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Updates the expanded state of all the descendants of the <code>path</code> * by getting the expanded descendants from the tree and forwarding to the @@ -1036,7 +1056,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Returns a path to the last child of <code>parent</code> * @@ -1047,7 +1067,7 @@ public class BasicTreeUI extends TreeUI { return ((TreePath) parent.getLastPathComponent()); } - + /** * Updates how much each depth should be offset by. */ @@ -1055,7 +1075,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Updates the cellEditor based on editability of the JTree that we're * contained in. Ig the tree is editable but doesn't have a cellEditor, a @@ -1065,7 +1085,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Messaged from the tree we're in when the renderer has changed. */ @@ -1073,7 +1093,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Resets the treeState instance based on the tree we're providing the look * and feel for. @@ -1082,7 +1102,7 @@ public class BasicTreeUI extends TreeUI { treeState = createLayoutCache(); } - + /** * Marks the cached size as being invalid, and messages the tree with * <code>treeDidChange</code>. @@ -1091,7 +1111,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Updates the <code>preferredSize</code> instance variable, which is * returned from <code>getPreferredSize()</code>. For left to right @@ -1103,7 +1123,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Messaged from the VisibleTreeNode after it has been expanded. * @@ -1113,7 +1133,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Messaged from the VisibleTreeNode after it has collapsed */ @@ -1121,7 +1141,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Install all defaults for the tree. * @@ -1130,24 +1150,24 @@ public class BasicTreeUI extends TreeUI protected void installDefaults(JTree tree) { UIDefaults defaults = UIManager.getLookAndFeelDefaults(); - + tree.setFont(defaults.getFont("Tree.font")); tree.setForeground(defaults.getColor("Tree.foreground")); tree.setBackground(defaults.getColor("Tree.background")); tree.setOpaque(true); - + rightChildIndent = defaults.getInt("Tree.rightChildIndent"); leftChildIndent = defaults.getInt("Tree.leftChildIndent"); setRowHeight(defaults.getInt("Tree.rowHeight")); } - + /** * Install all keyboard actions for this */ protected void installKeyboardActions() { } - + /** * Install all listeners for this */ @@ -1162,9 +1182,10 @@ public class BasicTreeUI extends TreeUI tree.addComponentListener(componentListener); cellEditor.addCellEditorListener(cellEditorListener); tree.addTreeExpansionListener(treeExpansionListener); - treeModel.addTreeModelListener(treeModelListener); + if (treeModel != null) + treeModel.addTreeModelListener(treeModelListener); } - + /** * Install the UI for the component * @@ -1175,15 +1196,17 @@ public class BasicTreeUI extends TreeUI super.installUI(c); installDefaults((JTree) c); tree = (JTree) c; - setModel(tree.getModel()); + TreeModel mod = tree.getModel(); + setModel(mod); tree.setRootVisible(true); - tree.expandPath(new TreePath(tree.getModel().getRoot())); + if (mod != null) + tree.expandPath(new TreePath(mod.getRoot())); treeSelectionModel = tree.getSelectionModel(); installListeners(); installKeyboardActions(); completeUIInstall(); } - + /** * Uninstall the defaults for the tree * @@ -1191,13 +1214,11 @@ public class BasicTreeUI extends TreeUI */ protected void uninstallDefaults(JTree tree) { - UIDefaults defaults = UIManager.getLookAndFeelDefaults(); tree.setFont(null); tree.setForeground(null); tree.setBackground(null); - tree.setCellRenderer(null); } - + /** * Uninstall the UI for the component * @@ -1211,7 +1232,7 @@ public class BasicTreeUI extends TreeUI tree = null; completeUIUninstall(); } - + /** * Paints the specified component appropriate for the look and feel. This * method is invoked from the ComponentUI.update method when the specified @@ -1227,17 +1248,20 @@ public class BasicTreeUI extends TreeUI { JTree tree = (JTree) c; TreeModel mod = tree.getModel(); - Object root = mod.getRoot(); - - if (!tree.isRootVisible()) - tree.expandPath(new TreePath(root)); - - paintRecursive(g, 0, 0, 0, 0, tree, mod, root); - - if (hasControlIcons()) - paintControlIcons(g, 0, 0, 0, 0, tree, mod, root); - } - + if (mod != null) + { + Object root = mod.getRoot(); + + if (!tree.isRootVisible()) + tree.expandPath(new TreePath(root)); + + paintRecursive(g, 0, 0, 0, 0, tree, mod, root); + + if (hasControlIcons()) + paintControlIcons(g, 0, 0, 0, 0, tree, mod, root); + } + } + /** * Ensures that the rows identified by beginRow through endRow are visible. * @@ -1248,7 +1272,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Sets the preferred minimum size. * @@ -1258,7 +1282,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Gets the preferred minimum size. * @@ -1269,7 +1293,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return null; } - + /** * Returns the preferred size to properly display the tree, this is a cover * method for getPreferredSize(c, false). @@ -1283,7 +1307,7 @@ public class BasicTreeUI extends TreeUI { return getPreferredSize(c, false); } - + /** * Returns the preferred size to represent the tree in c. If checkConsistancy * is true, checkConsistancy is messaged first. @@ -1295,26 +1319,30 @@ public class BasicTreeUI extends TreeUI public Dimension getPreferredSize(JComponent c, boolean checkConsistancy) { // FIXME: checkConsistancy not implemented, c not used - TreeNode node = ((TreeNode) (tree.getModel()) - .getRoot()); + TreeModel model = tree.getModel(); int maxWidth = 0; int count = 0; - if (node != null) + if (model != null) { - maxWidth = (int) (getCellBounds(0, 0, node).getWidth()); - while (node != null) + Object node = model.getRoot(); + if (node != null) { - count++; - TreeNode nextNode = getNextVisibleNode(node); - if (nextNode != null) - maxWidth = Math.max(maxWidth, (int) (getCellBounds(0, 0, nextNode) - .getWidth())); - node = nextNode; + 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)); } - + /** * Returns the minimum size for this component. Which will be the min * preferred size or (0,0). @@ -1327,7 +1355,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return 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). @@ -1340,7 +1368,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return getPreferredSize(c); } - + /** * Messages to stop the editing session. If the UI the receiver is providing * the look and feel for returns true from @@ -1352,7 +1380,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Stops the editing session. If messageStop is true, the editor is messaged * with stopEditing, if messageCancel is true the editor is messaged with @@ -1368,7 +1396,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Will start editing for node if there is a cellEditor and shouldSelectCall * returns true. This assumes that path is valid and visible. @@ -1382,7 +1410,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return false; } - + /** * If the <code>mouseX</code> and <code>mouseY</code> are in the expand * or collapse region of the row, this will toggle the row. @@ -1396,7 +1424,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Returns 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 @@ -1415,7 +1443,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return false; } - + /** * Messaged when the user clicks the particular row, this invokes * toggleExpandState. @@ -1428,7 +1456,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Expands path if it is not expanded, or collapses row if it is expanded. If * expanding a path and JTree scroll on expand, ensureRowsAreVisible is @@ -1441,7 +1469,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Returning true signifies a mouse event on the node should toggle the * selection of only the row under the mouse. @@ -1455,7 +1483,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return false; } - + /** * Returning true signifies a mouse event on the node should select from the * anchor point. @@ -1469,7 +1497,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return false; } - + /** * Returning true indicates the row under the mouse should be toggled based * on the event. This is invoked after checkForClickInExpandControl, implying @@ -1484,7 +1512,7 @@ public class BasicTreeUI extends TreeUI // FIXME: not implemented return false; } - + /** * Messaged to update the selection based on a MouseEvent over a particular * row. If the even is a toggle selection event, the row is either selected, @@ -1500,7 +1528,7 @@ public class BasicTreeUI extends TreeUI { // FIXME: not implemented } - + /** * Returns true if the node at <code>row</code> is a leaf. * @@ -1512,37 +1540,33 @@ public class BasicTreeUI extends TreeUI TreePath pathForRow = getPathForRow(tree, row); if (pathForRow == null) return true; - + Object node = pathForRow.getLastPathComponent(); - - if (node instanceof TreeNode) - return ((TreeNode) node).isLeaf(); - else - return true; + return tree.getModel().isLeaf(node); } - + /** * Updates the preferred size when scrolling, if necessary. */ public class ComponentHandler - extends ComponentAdapter - implements ActionListener + extends ComponentAdapter + implements ActionListener { /** * Timer used when inside a scrollpane and the scrollbar is adjusting */ protected Timer timer; - + /** ScrollBar that is being adjusted */ protected JScrollBar scrollBar; - + /** * Constructor */ public ComponentHandler() { } - + /** * Invoked when the component's position changes. * @@ -1551,7 +1575,7 @@ public class BasicTreeUI extends TreeUI public void componentMoved(ComponentEvent e) { } - + /** * Creats, if necessary, and starts a Timer to check if needed to resize * the bounds @@ -1559,7 +1583,7 @@ public class BasicTreeUI extends TreeUI protected void startTimer() { } - + /** * Returns the JScrollPane housing the JTree, or null if one isn't found. * @@ -1569,7 +1593,7 @@ public class BasicTreeUI extends TreeUI { return null; } - + /** * Public as a result of Timer. If the scrollBar is null, or not * adjusting, this stops the timer and updates the sizing. @@ -1580,13 +1604,13 @@ public class BasicTreeUI extends TreeUI { } }// ComponentHandler - + /** * Listener responsible for getting cell editing events and updating the tree * accordingly. */ public class CellEditorHandler - implements CellEditorListener + implements CellEditorListener { /** * Constructor @@ -1594,7 +1618,7 @@ public class BasicTreeUI extends TreeUI public CellEditorHandler() { } - + /** * Messaged when editing has stopped in the tree. Tells the listeners * editing has stopped. @@ -1604,7 +1628,7 @@ public class BasicTreeUI extends TreeUI public void editingStopped(ChangeEvent e) { } - + /** * Messaged when editing has been canceled in the tree. This tells the * listeners the editor has canceled editing. @@ -1615,12 +1639,12 @@ public class BasicTreeUI extends TreeUI { } }// CellEditorHandler - + /** * Repaints the lead selection row when focus is lost/grained. */ public class FocusHandler - implements FocusListener + implements FocusListener { /** * Constructor @@ -1628,7 +1652,7 @@ public class BasicTreeUI extends TreeUI public FocusHandler() { } - + /** * Invoked when focus is activated on the tree we're in, redraws the lead * row. Invoked when a component gains the keyboard focus. @@ -1638,7 +1662,7 @@ public class BasicTreeUI extends TreeUI public void focusGained(FocusEvent e) { } - + /** * Invoked when focus is deactivated on the tree we're in, redraws the * lead row. Invoked when a component loses the keyboard focus. @@ -1649,27 +1673,27 @@ public class BasicTreeUI extends TreeUI { } }// FocusHandler - + /** * This is used to get multiple key down events to appropriately genereate * events. */ public class KeyHandler - extends KeyAdapter + extends KeyAdapter { /** Key code that is being generated for. */ protected Action repeatKeyAction; - + /** Set to true while keyPressed is active */ protected boolean isKeyDown; - + /** * Constructor */ public KeyHandler() { } - + /** * Invoked when a key has been typed. Moves the keyboard focus to the * first element whose first letter matches the alphanumeric key pressed @@ -1681,7 +1705,7 @@ public class BasicTreeUI extends TreeUI public void keyTyped(KeyEvent e) { } - + /** * Invoked when a key has been pressed. * @@ -1689,63 +1713,84 @@ public class BasicTreeUI extends TreeUI */ public void keyPressed(KeyEvent e) { + TreeModel mod = BasicTreeUI.this.tree.getModel(); TreePath start = BasicTreeUI.this.tree.getLeadSelectionPath(); - TreeNode last = null; + Object last = null; if (start != null) - last = (TreeNode) start.getLastPathComponent(); - + last = start.getLastPathComponent(); + if (last != null) { // DOWN, KP_DOWN if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_KP_DOWN) { - TreeNode next = (TreeNode) BasicTreeUI.this. - getNextVisibleNode(last); + Object next = BasicTreeUI.this.getNextVisibleNode(last); if (next != null) { TreePath newPath = new TreePath(getPathToRoot(next, 0)); BasicTreeUI.this.selectPath(BasicTreeUI.this.tree, newPath); if (e.isControlDown()) tree.setLeadSelectionPath(newPath); - else if (!next.isLeaf() && e.isShiftDown()) + else if (!mod.isLeaf(next) && e.isShiftDown()) { BasicTreeUI.this.tree.expandPath(newPath); + try + { + BasicTreeUI.this.tree.fireTreeWillExpand(newPath); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeExpanded(newPath); } } } // UP, KP_UP else if (e.getKeyCode() == KeyEvent.VK_UP - || e.getKeyCode() == KeyEvent.VK_KP_UP) + || e.getKeyCode() == KeyEvent.VK_KP_UP) { - TreeNode prev = (TreeNode) BasicTreeUI.this. - getPreviousVisibleNode(last); - + Object prev = BasicTreeUI.this.getPreviousVisibleNode(last); + if (prev != null) { TreePath newPath = new TreePath(getPathToRoot(prev, 0)); BasicTreeUI.this.selectPath(BasicTreeUI.this.tree, - new TreePath(getPathToRoot(prev, 0))); + new TreePath(getPathToRoot(prev, + 0))); if (e.isControlDown()) tree.setLeadSelectionPath(newPath); - else if (!prev.isLeaf() && e.isShiftDown()) + else if (!mod.isLeaf(prev) && e.isShiftDown()) { BasicTreeUI.this.tree.expandPath(newPath); + try + { + BasicTreeUI.this.tree.fireTreeWillExpand(newPath); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeExpanded(newPath); } } } // LEFT, KP_LEFT else if (e.getKeyCode() == KeyEvent.VK_LEFT - || e.getKeyCode() == KeyEvent.VK_KP_LEFT) + || e.getKeyCode() == KeyEvent.VK_KP_LEFT) { TreePath path = new TreePath(getPathToRoot(last, 0)); - TreeNode p = last.getParent(); - - if (!last.isLeaf() && BasicTreeUI.this.tree.isExpanded(path)) + Object p = getParent(mod.getRoot(), last); + + if (!mod.isLeaf(last) && BasicTreeUI.this.tree.isExpanded(path)) { BasicTreeUI.this.tree.collapsePath(path); + try + { + BasicTreeUI.this.tree.fireTreeWillCollapse(path); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeCollapsed(path); } else if (p != null) @@ -1754,46 +1799,70 @@ public class BasicTreeUI extends TreeUI } // RIGHT, KP_RIGHT else if (e.getKeyCode() == KeyEvent.VK_RIGHT - || e.getKeyCode() == KeyEvent.VK_KP_RIGHT) + || e.getKeyCode() == KeyEvent.VK_KP_RIGHT) { TreePath path = new TreePath(getPathToRoot(last, 0)); - - if (!last.isLeaf() && BasicTreeUI.this.tree.isCollapsed(path)) + + if (!mod.isLeaf(last) && BasicTreeUI.this.tree.isCollapsed(path)) { BasicTreeUI.this.tree.expandPath(path); + try + { + BasicTreeUI.this.tree.fireTreeWillExpand(path); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeExpanded(path); } else { - TreeNode next = (TreeNode) BasicTreeUI.this. - getNextVisibleNode(last); - + Object next = BasicTreeUI.this.getNextVisibleNode(last); + if (next != null) - BasicTreeUI.this.selectPath(BasicTreeUI.this.tree, - new TreePath(getPathToRoot(next, 0))); + BasicTreeUI.this.selectPath( + BasicTreeUI.this.tree, + new TreePath( + getPathToRoot( + next, + 0))); } } // Enter else if (e.getKeyCode() == KeyEvent.VK_ENTER) { TreePath path = new TreePath(getPathToRoot(last, 0)); - if (!last.isLeaf()) + if (!mod.isLeaf(last)) { if (BasicTreeUI.this.tree.isExpanded(path)) { BasicTreeUI.this.tree.collapsePath(path); + try + { + BasicTreeUI.this.tree.fireTreeWillCollapse(path); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeCollapsed(path); } else { BasicTreeUI.this.tree.expandPath(path); + try + { + BasicTreeUI.this.tree.fireTreeWillExpand(path); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeExpanded(path); } } } } } - + /** * Invoked when a key has been released * @@ -1803,14 +1872,14 @@ public class BasicTreeUI extends TreeUI { } }// KeyHandler - + /** * MouseListener is responsible for updating the selevtion based on mouse * events. */ public class MouseHandler - extends MouseAdapter - implements MouseMotionListener + extends MouseAdapter + implements MouseMotionListener { /** * Constructor @@ -1818,7 +1887,7 @@ public class BasicTreeUI extends TreeUI public MouseHandler() { } - + /** * Invoked when a mouse button has been pressed on a component. * @@ -1827,7 +1896,7 @@ public class BasicTreeUI extends TreeUI public void mousePressed(MouseEvent e) { } - + /** * Invoked when a mouse button is pressed on a component and then dragged. * MOUSE_DRAGGED events will continue to be delivered to the component @@ -1840,7 +1909,7 @@ public class BasicTreeUI extends TreeUI public void mouseDragged(MouseEvent e) { } - + /** * Invoked when the mouse button has been moved on a component (with no * buttons no down). @@ -1850,7 +1919,7 @@ public class BasicTreeUI extends TreeUI public void mouseMoved(MouseEvent e) { } - + /** * Invoked when a mouse button has been released on a component. * @@ -1860,27 +1929,27 @@ public class BasicTreeUI extends TreeUI { } }// 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 + implements MouseInputListener { /** Source that events are coming from */ protected Component source; - + /** Destination that receives all events. */ protected Component destination; - + /** Number of mouse clicks on a non-leaf */ private int clickCount = 0; - + /** The last non-leaf cell that was clicked */ private Object lastClicked = null; - + /** * Constructor * @@ -1892,7 +1961,7 @@ public class BasicTreeUI extends TreeUI MouseEvent e) { } - + /** * Invoked when the mouse button has been clicked (pressed and released) * on a component. @@ -1903,28 +1972,28 @@ public class BasicTreeUI extends TreeUI { Point click = e.getPoint(); int row = Math.round(click.y / BasicTreeUI.this.getRowHeight()); - TreePath path = BasicTreeUI.this.getClosestPathForLocation(tree, - click.x, click.y); - + TreePath path = BasicTreeUI.this.getClosestPathForLocation(tree, click.x, + click.y); + if (path != null) { boolean inBounds = false; boolean cntlClick = false; Rectangle bounds = BasicTreeUI.this.getPathBounds( - BasicTreeUI.this.tree, path); - + BasicTreeUI.this.tree, + path); + bounds.x -= rightChildIndent - 4; bounds.width += rightChildIndent + 4; - + if (bounds.contains(click.x, click.y)) inBounds = true; else if (BasicTreeUI.this.hasControlIcons() - && (click.x < (bounds.x - rightChildIndent + 5) && - click.x > (bounds.x - rightChildIndent - 5))) + && (click.x < (bounds.x - rightChildIndent + 5) && click.x > (bounds.x + - rightChildIndent - 5))) cntlClick = true; - - if ((inBounds || cntlClick) - && BasicTreeUI.this.tree.isVisible(path)) + + if ((inBounds || cntlClick) && BasicTreeUI.this.tree.isVisible(path)) { if (!cntlClick && !BasicTreeUI.this.isLeaf(row)) { @@ -1937,7 +2006,7 @@ public class BasicTreeUI extends TreeUI clickCount = 1; } } - + if (clickCount == 2 || cntlClick == true) { clickCount = 0; @@ -1946,20 +2015,34 @@ public class BasicTreeUI extends TreeUI if (BasicTreeUI.this.tree.isExpanded(path)) { BasicTreeUI.this.tree.collapsePath(path); + try + { + BasicTreeUI.this.tree.fireTreeWillCollapse(path); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeCollapsed(path); } else { BasicTreeUI.this.tree.expandPath(path); + try + { + BasicTreeUI.this.tree.fireTreeWillExpand(path); + } + catch (ExpandVetoException ev) + { + } BasicTreeUI.this.tree.fireTreeExpanded(path); } } - + BasicTreeUI.this.selectPath(BasicTreeUI.this.tree, path); } } } - + /** * Invoked when a mouse button has been pressed on a component. * @@ -1968,7 +2051,7 @@ public class BasicTreeUI extends TreeUI public void mousePressed(MouseEvent e) { } - + /** * Invoked when a mouse button has been released on a component. * @@ -1977,7 +2060,7 @@ public class BasicTreeUI extends TreeUI public void mouseReleased(MouseEvent e) { } - + /** * Invoked when the mouse enters a component. * @@ -1986,7 +2069,7 @@ public class BasicTreeUI extends TreeUI public void mouseEntered(MouseEvent e) { } - + /** * Invoked when the mouse exits a component. * @@ -1995,7 +2078,7 @@ public class BasicTreeUI extends TreeUI public void mouseExited(MouseEvent e) { } - + /** * Invoked when a mouse button is pressed on a component and then dragged. * MOUSE_DRAGGED events will continue to be delivered to the component @@ -2008,7 +2091,7 @@ public class BasicTreeUI extends TreeUI public void mouseDragged(MouseEvent e) { } - + /** * Invoked when the mouse cursor has been moved onto a component but no * buttons have been pushed. @@ -2018,7 +2101,7 @@ public class BasicTreeUI extends TreeUI public void mouseMoved(MouseEvent e) { } - + /** * Removes event from the source */ @@ -2026,14 +2109,14 @@ public class BasicTreeUI extends TreeUI { } }// MouseInputHandler - + /** * Class responsible for getting size of node, method is forwarded to * BasicTreeUI method. X location does not include insets, that is handled in * getPathBounds. */ public class NodeDimensionsHandler - extends AbstractLayoutCache.NodeDimensions + extends AbstractLayoutCache.NodeDimensions { /** * Constructor @@ -2041,7 +2124,7 @@ public class BasicTreeUI extends TreeUI public NodeDimensionsHandler() { } - + /** * Responsible for getting the size of a particular node. * @@ -2058,7 +2141,7 @@ public class BasicTreeUI extends TreeUI { return null; } - + /** * Returns the amount to indent the given row * @@ -2069,22 +2152,22 @@ public class BasicTreeUI extends TreeUI return 0; } }// NodeDimensionsHandler - + /** * PropertyChangeListener for the tree. Updates the appropriate varaible, or * TreeState, based on what changes. */ public class PropertyChangeHandler - implements PropertyChangeListener + implements PropertyChangeListener { - + /** * Constructor */ public PropertyChangeHandler() { } - + /** * This method gets called when a bound property is changed. * @@ -2095,22 +2178,22 @@ public class BasicTreeUI extends TreeUI { } }// PropertyChangeHandler - + /** * Listener on the TreeSelectionModel, resets the row selection if any of the * properties of the model change. */ public class SelectionModelPropertyChangeHandler - implements PropertyChangeListener + implements PropertyChangeListener { - + /** * Constructor */ public SelectionModelPropertyChangeHandler() { } - + /** * This method gets called when a bound property is changed. * @@ -2121,21 +2204,21 @@ public class BasicTreeUI extends TreeUI { } }// SelectionModelPropertyChangeHandler - + /** * ActionListener that invokes cancelEditing when action performed. */ public class TreeCancelEditingAction - extends AbstractAction + extends AbstractAction { - + /** * Constructor */ public TreeCancelEditingAction() { } - + /** * Invoked when an action occurs. * @@ -2144,7 +2227,7 @@ public class BasicTreeUI extends TreeUI public void actionPerformed(ActionEvent e) { } - + /** * Returns true if the action is enabled. * @@ -2155,21 +2238,21 @@ public class BasicTreeUI extends TreeUI return false; } }// TreeCancelEditingAction - + /** * Updates the TreeState in response to nodes expanding/collapsing. */ public class TreeExpansionHandler - implements TreeExpansionListener + implements TreeExpansionListener { - + /** * Constructor */ public TreeExpansionHandler() { } - + /** * Called whenever an item in the tree has been expanded. * @@ -2179,7 +2262,7 @@ public class BasicTreeUI extends TreeUI { BasicTreeUI.this.tree.repaint(); } - + /** * Called whenever an item in the tree has been collapsed. * @@ -2190,18 +2273,18 @@ public class BasicTreeUI extends TreeUI BasicTreeUI.this.tree.repaint(); } }// TreeExpansionHandler - + /** * 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 + extends AbstractAction { - + /** direction is either home or end */ protected int direction; - + /** * Constructor * @@ -2211,7 +2294,7 @@ public class BasicTreeUI extends TreeUI public TreeHomeAction(int direction, String name) { } - + /** * Invoked when an action occurs. * @@ -2220,7 +2303,7 @@ public class BasicTreeUI extends TreeUI public void actionPerformed(ActionEvent e) { } - + /** * Returns true if the action is enabled. * @@ -2231,18 +2314,18 @@ public class BasicTreeUI extends TreeUI return false; } }// TreeHomeAction - + /** * TreeIncrementAction is used to handle up/down actions. Selection is moved * up or down based on direction. */ public class TreeIncrementAction - extends AbstractAction + extends AbstractAction { - + /** Specifies the direction to adjust the selection by. */ protected int direction; - + /** * Constructor * @@ -2252,7 +2335,7 @@ public class BasicTreeUI extends TreeUI public TreeIncrementAction(int direction, String name) { } - + /** * Invoked when an action occurs. * @@ -2261,7 +2344,7 @@ public class BasicTreeUI extends TreeUI public void actionPerformed(ActionEvent e) { } - + /** * Returns true if the action is enabled. * @@ -2272,12 +2355,12 @@ public class BasicTreeUI extends TreeUI return false; } }// TreeIncrementAction - + /** * Forwards all TreeModel events to the TreeState. */ public class TreeModelHandler - implements TreeModelListener + implements TreeModelListener { /** * Constructor @@ -2285,7 +2368,7 @@ public class BasicTreeUI extends TreeUI public TreeModelHandler() { } - + /** * Invoked after a node (or a set of siblings) has changed in some way. * The node(s) have not changed locations in the tree or altered their @@ -2301,7 +2384,7 @@ public class BasicTreeUI extends TreeUI public void treeNodesChanged(TreeModelEvent e) { } - + /** * Invoked after nodes have been inserted into the tree. Use e.getPath() * to get the parent of the new node(s). e.getChildIndices() returns the @@ -2312,7 +2395,7 @@ public class BasicTreeUI extends TreeUI public void treeNodesInserted(TreeModelEvent e) { } - + /** * Invoked after nodes have been removed from the tree. Note that if a * subtree is removed from the tree, this method may only be invoked once @@ -2326,7 +2409,7 @@ public class BasicTreeUI extends TreeUI public void treeNodesRemoved(TreeModelEvent e) { } - + /** * Invoked after the tree has drastically changed structure from a given * node down. If the path returned by e.getPath() is of length one and the @@ -2340,16 +2423,16 @@ public class BasicTreeUI extends TreeUI { } }// TreeModelHandler - + /** * TreePageAction handles page up and page down events. */ public class TreePageAction - extends AbstractAction + extends AbstractAction { /** Specifies the direction to adjust the selection by. */ protected int direction; - + /** * Constructor * @@ -2359,7 +2442,7 @@ public class BasicTreeUI extends TreeUI public TreePageAction(int direction, String name) { } - + /** * Invoked when an action occurs. * @@ -2368,7 +2451,7 @@ public class BasicTreeUI extends TreeUI public void actionPerformed(ActionEvent e) { } - + /** * Returns true if the action is enabled. * @@ -2379,13 +2462,13 @@ public class BasicTreeUI extends TreeUI return false; } }// TreePageAction - + /** * Listens for changes in the selection model and updates the display * accordingly. */ public class TreeSelectionHandler - implements TreeSelectionListener + implements TreeSelectionListener { /** * Constructor @@ -2393,7 +2476,7 @@ public class BasicTreeUI extends TreeUI public TreeSelectionHandler() { } - + /** * Messaged when the selection changes in the tree we're displaying for. * Stops editing, messages super and displays the changed paths. @@ -2404,12 +2487,12 @@ public class BasicTreeUI extends TreeUI { } }// TreeSelectionHandler - + /** * For the first selected row expandedness will be toggled. */ public class TreeToggleAction - extends AbstractAction + extends AbstractAction { /** * Constructor @@ -2419,7 +2502,7 @@ public class BasicTreeUI extends TreeUI public TreeToggleAction(String name) { } - + /** * Invoked when an action occurs. * @@ -2428,7 +2511,7 @@ public class BasicTreeUI extends TreeUI public void actionPerformed(ActionEvent e) { } - + /** * Returns true if the action is enabled. * @@ -2439,20 +2522,20 @@ public class BasicTreeUI extends TreeUI return false; } } // TreeToggleAction - + /** * 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 + extends AbstractAction { /** * Determines direction to traverse, 1 means expand, -1 means collapse. */ protected int direction; - + /** * Constructor * @@ -2462,7 +2545,7 @@ public class BasicTreeUI extends TreeUI public TreeTraverseAction(int direction, String name) { } - + /** * Invoked when an action occurs. * @@ -2471,7 +2554,7 @@ public class BasicTreeUI extends TreeUI public void actionPerformed(ActionEvent e) { } - + /** * Returns true if the action is enabled. * @@ -2482,7 +2565,7 @@ public class BasicTreeUI extends TreeUI return false; } } // TreeTraverseAction - + /** * Returns the cell bounds for painting selected cells * Package private for use in inner classes. @@ -2500,14 +2583,15 @@ public class BasicTreeUI extends TreeUI String s = cell.toString(); Font f = tree.getFont(); FontMetrics fm = tree.getToolkit().getFontMetrics(tree.getFont()); - + if (s != null) - return new Rectangle(x, y, SwingUtilities.computeStringWidth(fm, s) + 4, + return new Rectangle(x, y, + SwingUtilities.computeStringWidth(fm, s) + 4, fm.getHeight()); } return new Rectangle(x, y, 0, 0); } - + /** * Retrieves the location of some node, recursively starting at from * some node. @@ -2522,34 +2606,32 @@ public class BasicTreeUI extends TreeUI * * @return Point - the location of node */ - Point getCellLocation(int x, int y, JTree tree, TreeModel mod, - Object node, Object startNode) + Point getCellLocation(int x, int y, JTree tree, TreeModel mod, Object node, + Object startNode) { int rowHeight = getRowHeight(); if (startNode == null || startNode.equals(node)) { - if (!tree.isRootVisible() && tree.isExpanded(new TreePath(mod.getRoot()))) - return new Point(x + ((getLevel((TreeNode) node)) * - rightChildIndent), y); - - return new Point(x + ((getLevel((TreeNode) node) + 1) - * rightChildIndent), y); + 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(((TreeNode) startNode), - 0)))) + && tree.isExpanded(new TreePath(getPathToRoot(startNode, 0))) + && mod.getChildCount(startNode) > 0) { Object child = mod.getChild(startNode, 0); if (child != null) - return getCellLocation(x, y + rowHeight, tree, mod, - node, child); + return getCellLocation(x, y + rowHeight, tree, mod, node, child); } - + return getCellLocation(x, y + rowHeight, tree, mod, node, - getNextVisibleNode((TreeNode) startNode)); + getNextVisibleNode(startNode)); } - + /** * Paints a node in the tree Package private for use in inner classes. * @@ -2562,61 +2644,28 @@ public class BasicTreeUI extends TreeUI void paintNode(Graphics g, int x, int y, JTree tree, Object node, boolean isLeaf) { - TreePath curr = new TreePath(getPathToRoot(((TreeNode) node), 0)); + TreePath curr = new TreePath(getPathToRoot(node, 0)); boolean selected = tree.isPathSelected(curr); boolean expanded = false; boolean hasIcons = false; - + if (tree.isVisible(curr)) { - DefaultTreeCellRenderer dtcr = (DefaultTreeCellRenderer) - createDefaultCellRenderer(); - + TreeCellRenderer dtcr = tree.getCellRenderer(); + if (dtcr == null) + dtcr = createDefaultCellRenderer(); + if (!isLeaf) expanded = tree.isExpanded(curr); - - Icon icon = null; - if (!isLeaf && expanded) - icon = dtcr.getOpenIcon(); - else if (!isLeaf && !expanded) - icon = dtcr.getClosedIcon(); - else - icon = dtcr.getLeafIcon(); - - if (icon.getIconHeight() > -1 && icon.getIconWidth() > -1) - hasIcons = true; - + Component c = dtcr.getTreeCellRendererComponent(tree, node, selected, - expanded, isLeaf, 0, false); - - if (hasIcons) - { - if (selected) - { - Rectangle cell = getPathBounds(tree, curr); - g.setColor(dtcr.getBackgroundSelectionColor()); - g.fillRect(cell.x + icon.getIconWidth()/2, cell.y, cell.width, - cell.height); - - if (curr.equals(tree.getLeadSelectionPath())) - { - g.setColor(UIManager.getLookAndFeelDefaults().getColor( - "Tree.selectionBorderColor")); - g.drawRect(cell.x + icon.getIconWidth()/2, cell.y, - cell.width, cell.height); - } - } - - g.translate(x, y); - c.paint(g); - g.translate(-x, -y); - } - else - rendererPane.paintComponent(g, c, c.getParent(), - getCellBounds(x, y, node)); + expanded, isLeaf, 0, + 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. @@ -2632,20 +2681,20 @@ public class BasicTreeUI extends TreeUI * * @return int - current descent of the tree */ - int paintRecursive(Graphics g, int indentation, int descent, - int childNumber, int depth, JTree tree, TreeModel mod, Object curr) + int paintRecursive(Graphics g, int indentation, int descent, int childNumber, + int depth, JTree tree, TreeModel mod, Object curr) { Rectangle clip = g.getClipBounds(); if (indentation > clip.x + clip.width + rightChildIndent || descent > clip.y + clip.height + getRowHeight()) return descent; - + int halfHeight = getRowHeight() / 2; int halfWidth = rightChildIndent / 2; int y0 = descent + halfHeight; int heightOfLine = descent + halfHeight; boolean isRootVisible = tree.isRootVisible(); - + if (mod.isLeaf(curr)) { paintNode(g, indentation + 4, descent, tree, curr, true); @@ -2659,42 +2708,41 @@ public class BasicTreeUI extends TreeUI descent += getRowHeight(); y0 += halfHeight; } - + int max = mod.getChildCount(curr); - if (tree.isExpanded(new TreePath(getPathToRoot(((TreeNode) curr), 0)))) + if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0)))) { - for (int i = 0; i < max; ++i) + for (int i = 0; i < max; i++) { int indent = indentation + rightChildIndent; if (!isRootVisible && depth == 0) indent = 0; - else if ((!isRootVisible && !curr.equals(mod.getRoot())) || - isRootVisible) + else if ((!isRootVisible && !curr.equals(mod.getRoot())) + || isRootVisible) { g.setColor(getHashColor()); heightOfLine = descent + halfHeight; - g.drawLine(indentation + halfWidth, heightOfLine, indentation - + rightChildIndent, heightOfLine); + g.drawLine(indentation + halfWidth, heightOfLine, + indentation + rightChildIndent, heightOfLine); } - - descent = paintRecursive(g, indent, - descent, i, depth + 1, tree, mod, - mod.getChild(curr, i)); + + descent = paintRecursive(g, indent, descent, i, depth + 1, + tree, mod, mod.getChild(curr, i)); } } } - - if (tree.isExpanded(new TreePath(getPathToRoot(((TreeNode) curr), 0)))) - if (y0 != heightOfLine) + + if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0)))) + if (y0 != heightOfLine && mod.getChildCount(curr) > 0) { g.setColor(getHashColor()); g.drawLine(indentation + halfWidth, y0, indentation + halfWidth, heightOfLine); } - + return descent; } - + /** * Recursively paints all the control icons on the tree. * Package private for use in inner classes. @@ -2711,51 +2759,49 @@ public class BasicTreeUI extends TreeUI * @return int - current descent of the tree */ int paintControlIcons(Graphics g, int indentation, int descent, - int childNumber, int depth, JTree tree, TreeModel mod, Object node) + int childNumber, 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"); + Icon ei = UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon"); + Icon ci = UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon"); Rectangle clip = g.getClipBounds(); if (indentation > clip.x + clip.width + rightChildIndent || descent > clip.y + clip.height + getRowHeight()) return descent; - + if (mod.isLeaf(node)) descent += rowHeight; - else + else { if (depth > 0 || tree.isRootVisible()) descent += rowHeight; - + int max = mod.getChildCount(node); - if (tree.isExpanded(new TreePath(getPathToRoot(((TreeNode) node), 0)))) + if (tree.isExpanded(new TreePath(getPathToRoot(node, 0)))) { if (!node.equals(mod.getRoot())) - drawCentered(tree, g, ei, indentation - rightChildIndent - 3, h); - - for (int i = 0; i < max; ++i) + ei.paintIcon(tree, g, indentation - rightChildIndent - 3, h); + + for (int i = 0; i < max; i++) { int indent = indentation + rightChildIndent; if (depth == 0 && !tree.isRootVisible()) indent = -1; - - descent = paintControlIcons(g, indent, - descent, i, depth + 1, tree, mod, - mod.getChild(node, i)); + + descent = paintControlIcons(g, indent, descent, i, depth + 1, + tree, mod, mod.getChild(node, i)); } } else if (!node.equals(mod.getRoot())) - drawCentered(tree, g, ei, indentation - rightChildIndent - 3, + ci.paintIcon(tree, g, indentation - rightChildIndent - 3, descent - getRowHeight()); } - + return descent; } - + /** * Returns true if the LookAndFeel implements the control icons * Package private for use in inner classes. @@ -2764,47 +2810,84 @@ public class BasicTreeUI extends TreeUI */ boolean hasControlIcons() { - if (UIManager.getLookAndFeelDefaults(). - getIcon("Tree.expandedIcon") == null || - UIManager.getLookAndFeelDefaults(). - getIcon("Tree.collapsedIcon") == null) + if (UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon") == null + || UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon") == null) return false; return true; } - + /** - * Get next visible node in the tree. - * Package private for use in inner classes. + * Returns the parent of 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) + { + if (root == null || node == null) + return null; + if (node instanceof TreeNode) + return ((TreeNode) node).getParent(); + return findNode(root, node); + } + + /** + * 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 + * @return the parent node of node + */ + private Object findNode(Object root, Object node) + { + TreeModel mod = tree.getModel(); + for (int i = 0; i < mod.getChildCount(root); 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. */ - TreeNode getNextVisibleNode(TreeNode node) + Object getNextVisibleNode(Object node) { - TreeNode next = null; + Object next = null; TreePath current = null; - + if (node != null) next = getNextNode(node); - + if (next != null) { current = new TreePath(getPathToRoot(next, 0)); if (tree.isVisible(current)) return next; - + while (next != null && !tree.isVisible(current)) { next = getNextNode(next); - + if (next != null) current = new TreePath(getPathToRoot(next, 0)); } } return next; } - + /** * Get previous visible node in the tree. * Package private for use in inner classes. @@ -2813,53 +2896,54 @@ public class BasicTreeUI extends TreeUI * @return the next visible node in the JTree. Return null if there are no * more. */ - TreeNode getPreviousVisibleNode(TreeNode node) + Object getPreviousVisibleNode(Object node) { - TreeNode prev = null; + Object prev = null; TreePath current = null; - + if (node != null) prev = getPreviousNode(node); - + if (prev != 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)); } } return prev; } - + /** * Returns the next node in the tree * Package private for use in inner classes. * - * @return TreeNode, the next node in the tree + * @param the current node + * @return the next node in the tree */ - TreeNode getNextNode(TreeNode curr) + Object getNextNode(Object curr) { - if (curr.getChildCount() != 0) - return curr.getChildAt(0); + TreeModel mod = tree.getModel(); + if (mod.getChildCount(curr) > 0) + return mod.getChild(curr, 0); + + Object node = curr; + Object sibling = null; - TreeNode node = curr; - TreeNode sibling; - do { sibling = getNextSibling(node); - node = node.getParent(); + node = getParent(mod.getRoot(), node); } - while (sibling == null && - node != null); - + while (sibling == null && node != null); + return sibling; } @@ -2867,69 +2951,75 @@ public class BasicTreeUI extends TreeUI * Returns the previous node in the tree * Package private for use in inner classes. * - * @return TreeNode, the previous node in the tree + * @param the current node + * @return the previous node in the tree */ - TreeNode getPreviousNode(TreeNode node) + Object getPreviousNode(Object node) { - TreeNode parent = node.getParent(); + TreeModel mod = tree.getModel(); + Object parent = getParent(mod.getRoot(), node); if (parent == null) return null; - - TreeNode sibling = getPreviousSibling(node); + + Object sibling = getPreviousSibling(node); if (sibling == null) return parent; - int size = sibling.getChildCount(); + int size = mod.getChildCount(sibling); while (size > 0) - { - sibling = sibling.getChildAt(size - 1); - size = sibling.getChildCount(); - } - + { + sibling = mod.getChild(sibling, size - 1); + size = mod.getChildCount(sibling); + } + return sibling; } - + /** * Returns the next sibling in the tree * Package private for use in inner classes. * - * @return TreeNode, the next sibling in the tree + * @param the current node + * @return the next sibling in the tree */ - TreeNode getNextSibling(TreeNode node) + Object getNextSibling(Object node) { - TreeNode parent = node.getParent(); + TreeModel mod = tree.getModel(); + Object parent = getParent(mod.getRoot(), node); if (parent == null) return null; - int index = parent.getIndex(node) + 1; - - if (index == parent.getChildCount()) + int index = mod.getIndexOfChild(parent, node) + 1; + + if (index == 0 || index >= mod.getChildCount(parent)) return null; - return parent.getChildAt(index); + return mod.getChild(parent, index); } /** * Returns the previous sibling in the tree * Package private for use in inner classes. - * - * @return TreeNode, the previous sibling in the tree + * + * @param the current node + * @return the previous sibling in the tree */ - TreeNode getPreviousSibling(TreeNode node) + Object getPreviousSibling(Object node) { - TreeNode parent = node.getParent(); + TreeModel mod = tree.getModel(); + Object parent = getParent(mod.getRoot(), node); if (parent == null) return null; - int index = parent.getIndex(node) - 1; + int index = mod.getIndexOfChild(parent, node) - 1; - if (index < 0) + if (index < 0 || index >= mod.getChildCount(parent)) return null; - return parent.getChildAt(index); + return mod.getChild(parent, index); } - + /** * Selects the specified path in the tree depending on modes. * Package private for use in inner classes. @@ -2943,15 +3033,13 @@ public class BasicTreeUI extends TreeUI { if (tree.isPathSelected(path)) tree.removeSelectionPath(path); - else if (tree.getSelectionModel().getSelectionMode() - == TreeSelectionModel.SINGLE_TREE_SELECTION) + else 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 } @@ -2964,7 +3052,7 @@ public class BasicTreeUI extends TreeUI } } } - + /** * Returns the path from node to the root. * Package private for use in inner classes. @@ -2974,41 +3062,43 @@ public class BasicTreeUI extends TreeUI * * @return an array of tree nodes that represent the path to node. */ - TreeNode[] getPathToRoot(TreeNode node, int depth) + Object[] getPathToRoot(Object node, int depth) { + TreeModel mod = tree.getModel(); if (node == null) { if (depth == 0) return null; - - return new TreeNode[depth]; + + return new Object[depth]; } - TreeNode[] path = getPathToRoot(node.getParent(), depth + 1); + Object[] path = getPathToRoot(getParent(mod.getRoot(), node), depth + 1); path[path.length - depth - 1] = node; return path; } - + /** * Returns the level of the node in the tree. * + * @param the current node * @return the number of the level */ - public int getLevel(TreeNode node) + int getLevel(Object node) { int count = -1; - TreeNode current = node; + Object current = node; do { - current = current.getParent(); + current = getParent(tree.getModel().getRoot(), current); count++; } while (current != null); return count; } - + /** * Draws a vertical line using the given graphic context * @@ -3018,10 +3108,12 @@ public class BasicTreeUI extends TreeUI * @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) { + protected void paintVerticalLine(Graphics g, JComponent c, int x, int top, + int bottom) + { g.drawLine(x, top, x, bottom); } - + /** * Draws a horizontal line using the given graphic context * @@ -3031,10 +3123,12 @@ public class BasicTreeUI extends TreeUI * @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) { + protected void paintHorizontalLine(Graphics g, JComponent c, int y, int left, + int right) + { g.drawLine(left, y, right, y); } - + /** * Draws an icon at around a specific position * @@ -3046,9 +3140,10 @@ public class BasicTreeUI extends TreeUI * * 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(JComponent 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); - } -} // BasicTreeUI
\ No newline at end of file + } +} // BasicTreeUI |