/[classpath]/classpath/javax/swing/JTree.java
ViewVC logotype

Diff of /classpath/javax/swing/JTree.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.24 by langel, Wed Jun 29 13:20:01 2005 UTC revision 1.25 by langel, Thu Jun 30 14:42:57 2005 UTC
# Line 1  Line 1 
1  /* JTree.java --  /*
2     Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.   * JTree.java -- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
3     *
4  This file is part of GNU Classpath.   * This file is part of GNU Classpath.
5     *
6  GNU Classpath is free software; you can redistribute it and/or modify   * GNU Classpath is free software; you can redistribute it and/or modify it
7  it under the terms of the GNU General Public License as published by   * under the terms of the GNU General Public License as published by the Free
8  the Free Software Foundation; either version 2, or (at your option)   * Software Foundation; either version 2, or (at your option) any later version.
9  any later version.   *
10     * GNU Classpath is distributed in the hope that it will be useful, but WITHOUT
11  GNU Classpath is distributed in the hope that it will be useful, but   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  WITHOUT ANY WARRANTY; without even the implied warranty of   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * details.
14  General Public License for more details.   *
15     * You should have received a copy of the GNU General Public License along with
16  You should have received a copy of the GNU General Public License   * GNU Classpath; see the file COPYING. If not, write to the Free Software
17  along with GNU Classpath; see the file COPYING.  If not, write to the   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   *
19  02111-1307 USA.   * Linking this library statically or dynamically with other modules is making a
20     * combined work based on this library. Thus, the terms and conditions of the
21  Linking this library statically or dynamically with other modules is   * GNU General Public License cover the whole combination.
22  making a combined work based on this library.  Thus, the terms and   *
23  conditions of the GNU General Public License cover the whole   * As a special exception, the copyright holders of this library give you
24  combination.   * permission to link this library with independent modules to produce an
25     * executable, regardless of the license terms of these independent modules, and
26  As a special exception, the copyright holders of this library give you   * to copy and distribute the resulting executable under terms of your choice,
27  permission to link this library with independent modules to produce an   * provided that you also meet, for each linked independent module, the terms
28  executable, regardless of the license terms of these independent   * and conditions of the license of that module. An independent module is a
29  modules, and to copy and distribute the resulting executable under   * module which is not derived from or based on this library. If you modify this
30  terms of your choice, provided that you also meet, for each linked   * library, you may extend this exception to your version of the library, but
31  independent module, the terms and conditions of the license of that   * you are not obligated to do so. If you do not wish to do so, delete this
32  module.  An independent module is a module which is not derived from   * exception statement from your version.
33  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. */  
   
34    
35  package javax.swing;  package javax.swing;
36    
# Line 69  import javax.swing.tree.TreeNode; Line 65  import javax.swing.tree.TreeNode;
65  import javax.swing.tree.TreePath;  import javax.swing.tree.TreePath;
66  import javax.swing.tree.TreeSelectionModel;  import javax.swing.tree.TreeSelectionModel;
67    
68    public class JTree
69  public class JTree extends JComponent                  extends JComponent
70    implements Scrollable, Accessible                          implements Scrollable, Accessible
71  {  {
72    /**          /**
73     * Listens to the model of the JTree and updates the property           * Listens to the model of the JTree and updates the property
74     * <code>expandedState</code> if nodes are removed or changed.           * <code>expandedState</code> if nodes are removed or changed.
75     */           */
76    protected class TreeModelHandler          protected class TreeModelHandler
77      implements TreeModelListener                          implements
78    {                          TreeModelListener
79            {
80      /**  
81       * Creates a new instance of TreeModelHandler.                  /**
82       */                   * Creates a new instance of TreeModelHandler.
83      protected TreeModelHandler()                   */
84      {                  protected TreeModelHandler()
85      }                  {
86                    }
87      /**  
88       * Notifies when a node has changed in some ways. This does not include                  /**
89       * that a node has changed its location or changed it's children. It                   * Notifies when a node has changed in some ways. This does not include
90       * only means that some attributes of the node have changed that might                   * that a node has changed its location or changed it's children. It
91       * affect its presentation.                   * only means that some attributes of the node have changed that might
92       *                   * affect its presentation.
93       * This method is called after the actual change occured.                   *
94       *                   * This method is called after the actual change occured.
95       * @param ev the TreeModelEvent describing the change                   *
96       */                   * @param ev the TreeModelEvent describing the change
97      public void treeNodesChanged(TreeModelEvent ev)                   */
98      {                  public void treeNodesChanged(TreeModelEvent ev)
99        // nothing to do here                  {
100      }                          // nothing to do here
101                    }
102      /**  
103       * Notifies when a node is inserted into the tree.                  /**
104       *                   * Notifies when a node is inserted into the tree.
105       * This method is called after the actual change occured.                   *
106       *                   * This method is called after the actual change occured.
107       * @param ev the TreeModelEvent describing the change                   *
108       */                   * @param ev the TreeModelEvent describing the change
109      public void treeNodesInserted(TreeModelEvent ev)                   */
110      {                  public void treeNodesInserted(TreeModelEvent ev)
111        // nothing to do here                  {
112      }                          // nothing to do here
113                    }
114      /**  
115       * Notifies when a node is removed from the tree.                  /**
116       *                   * Notifies when a node is removed from the tree.
117       * This method is called after the actual change occured.                   *
118       *                   * This method is called after the actual change occured.
119       * @param ev the TreeModelEvent describing the change                   *
120       */                   * @param ev the TreeModelEvent describing the change
121      public void treeNodesRemoved(TreeModelEvent ev)                   */
122      {                  public void treeNodesRemoved(TreeModelEvent ev)
123        // TODO: The API docs suggest that this method should do something                  {
124        // but I cannot really see what has to be done here ...                          // TODO: The API docs suggest that this method should do something
125      }                          // but I cannot really see what has to be done here ...
126                    }
127      /**  
128       * Notifies when the structure of the tree is changed.                  /**
129       *                   * Notifies when the structure of the tree is changed.
130       * This method is called after the actual change occured.                   *
131       *                   * This method is called after the actual change occured.
132       * @param ev the TreeModelEvent describing the change                   *
133       */                   * @param ev the TreeModelEvent describing the change
134      public void treeStructureChanged(TreeModelEvent ev)                   */
135      {                  public void treeStructureChanged(TreeModelEvent ev)
136        // set state of new path                  {
137        TreePath path = ev.getTreePath();                          // set state of new path
138        setExpandedState(path, isExpanded(path));                          TreePath path = ev.getTreePath();
139      }                          setExpandedState(path, isExpanded(path));
140    } // TreeModelHandler                  }
141            } // TreeModelHandler
142    /**  
143     * This redirects TreeSelectionEvents and rewrites the source of it          /**
144     * to be this JTree. This is typically done when the tree model           * This redirects TreeSelectionEvents and rewrites the source of it to be
145     * generates an event, but the JTree object associated with that model           * this JTree. This is typically done when the tree model generates an
146     * should be listed as the actual source of the event.           * event, but the JTree object associated with that model should be listed
147     */           * as the actual source of the event.
148    protected class TreeSelectionRedirector           */
149      implements TreeSelectionListener, Serializable          protected class TreeSelectionRedirector
150    {                          implements
151      /** The serial version UID. */                          TreeSelectionListener,
152      private static final long serialVersionUID = -3505069663646241664L;                          Serializable
153            {
154      /**                  /** The serial version UID. */
155       * Creates a new instance of TreeSelectionRedirector                  private static final long serialVersionUID = -3505069663646241664L;
156       */  
157      protected TreeSelectionRedirector()                  /**
158      {                   * Creates a new instance of TreeSelectionRedirector
159      }                   */
160                    protected TreeSelectionRedirector()
161      /**                  {
162       * Notifies when the tree selection changes.                  }
163       *  
164       * @param ev the TreeSelectionEvent that describes the change                  /**
165       */                   * Notifies when the tree selection changes.
166      public void valueChanged(TreeSelectionEvent ev)                   *
167      {                   * @param ev the TreeSelectionEvent that describes the change
168        TreeSelectionEvent rewritten =                   */
169          (TreeSelectionEvent) ev.cloneWithSource(JTree.this);                  public void valueChanged(TreeSelectionEvent ev)
170        fireValueChanged(rewritten);                  {
171      }                          TreeSelectionEvent rewritten = (TreeSelectionEvent) ev
172    } // TreeSelectionRedirector                                          .cloneWithSource(JTree.this);
173                            fireValueChanged(rewritten);
174    /**                          JTree.this.repaint();
175     * A TreeModel that does not allow anything to be selected.                  }
176     */          } // TreeSelectionRedirector
177    protected static class EmptySelectionModel  
178      extends DefaultTreeSelectionModel          /**
179    {           * A TreeModel that does not allow anything to be selected.
180      /** The serial version UID. */           */
181      private static final long serialVersionUID = -5815023306225701477L;          protected static class EmptySelectionModel
182                            extends
183      /**                                  DefaultTreeSelectionModel
184       * The shared instance of this model.          {
185       */                  /** The serial version UID. */
186      protected static final EmptySelectionModel sharedInstance =                  private static final long serialVersionUID = -5815023306225701477L;
187      new EmptySelectionModel();  
188                    /**
189      /**                   * The shared instance of this model.
190       * Creates a new instance of EmptySelectionModel.                   */
191       */                  protected static final EmptySelectionModel sharedInstance = new EmptySelectionModel();
192      protected EmptySelectionModel()  
193      {                  /**
194      }                   * Creates a new instance of EmptySelectionModel.
195                     */
196      /**                  protected EmptySelectionModel()
197       * Returns the shared instance of EmptySelectionModel.                  {
198       *                  }
199       * @return the shared instance of EmptySelectionModel  
200       */                  /**
201      public static EmptySelectionModel sharedInstance()                   * Returns the shared instance of EmptySelectionModel.
202      {                   *
203        return sharedInstance;                   * @return the shared instance of EmptySelectionModel
204      }                   */
205                    public static EmptySelectionModel sharedInstance()
206      /**                  {
207       * This catches attempts to set a selection and sets nothing                          return sharedInstance;
208       * instead.                  }
209       *  
210       * @param paths not used here                  /**
211       */                   * This catches attempts to set a selection and sets nothing instead.
212      public void setSelectionPaths(TreePath[] paths)                   *
213      {                   * @param paths not used here
214        // we don't allow selections in this class                   */
215      }                  public void setSelectionPaths(TreePath[] paths)
216                    {
217      /**                          // we don't allow selections in this class
218       * This catches attempts to add something to the selection.                  }
219       *  
220       * @param paths not used here                  /**
221       */                   * This catches attempts to add something to the selection.
222      public void addSelectionPaths(TreePath[] paths)                   *
223      {                   * @param paths not used here
224        // we don't allow selections in this class                   */
225      }                  public void addSelectionPaths(TreePath[] paths)
226                    {
227      /**                          // we don't allow selections in this class
228       * This catches attempts to remove something from the selection.                  }
229       *  
230       * @param paths not used here                  /**
231       */                   * This catches attempts to remove something from the selection.
232      public void removeSelectionPaths(TreePath[] paths)                   *
233      {                   * @param paths not used here
234        // we don't allow selections in this class                   */
235      }                  public void removeSelectionPaths(TreePath[] paths)
236    }// EmptySelectionModel                  {
237                            // we don't allow selections in this class
238    private static final long serialVersionUID = 7559816092864483649L;                  }
239            }// EmptySelectionModel
240    public static final String CELL_EDITOR_PROPERTY = "cellEditor";  
241    public static final String CELL_RENDERER_PROPERTY = "cellRenderer";          private static final long serialVersionUID = 7559816092864483649L;
242    public static final String EDITABLE_PROPERTY = "editable";          public static final String CELL_EDITOR_PROPERTY = "cellEditor";
243    public static final String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing";          public static final String CELL_RENDERER_PROPERTY = "cellRenderer";
244    public static final String LARGE_MODEL_PROPERTY = "largeModel";          public static final String EDITABLE_PROPERTY = "editable";
245    public static final String ROOT_VISIBLE_PROPERTY = "rootVisible";          public static final String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing";
246    public static final String ROW_HEIGHT_PROPERTY = "rowHeight";          public static final String LARGE_MODEL_PROPERTY = "largeModel";
247    public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand";          public static final String ROOT_VISIBLE_PROPERTY = "rootVisible";
248    public static final String SELECTION_MODEL_PROPERTY = "selectionModel";          public static final String ROW_HEIGHT_PROPERTY = "rowHeight";
249    public static final String SHOWS_ROOT_HANDLES_PROPERTY = "showsRootHandles";          public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand";
250    public static final String TOGGLE_CLICK_COUNT_PROPERTY = "toggleClickCount";          public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
251    public static final String TREE_MODEL_PROPERTY = "model";          public static final String SHOWS_ROOT_HANDLES_PROPERTY = "showsRootHandles";
252    public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount";          public static final String TOGGLE_CLICK_COUNT_PROPERTY = "toggleClickCount";
253            public static final String TREE_MODEL_PROPERTY = "model";
254    /** @since 1.3 */          public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount";
255    public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath";  
256    /** @since 1.3 */          /** @since 1.3 */
257    public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath";          public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath";
258    /** @since 1.3 */  
259    public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths";          /** @since 1.3 */
260            public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath";
261    private static final Object EXPANDED = new Object();  
262    private static final Object COLLAPSED = new Object();          /** @since 1.3 */
263              public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths";
264    private boolean dragEnabled;          private static final Object EXPANDED = new Object();
265    private boolean expandsSelectedPaths;          private static final Object COLLAPSED = new Object();
266    private TreePath anchorSelectionPath;          private boolean dragEnabled;
267    private TreePath leadSelectionPath;          private boolean expandsSelectedPaths;
268            private TreePath anchorSelectionPath;
269    /*          private TreePath leadSelectionPath;
270     * This contains the state of all nodes in the tree. Al/ entries map the  
271     * TreePath of a note to to its state. Valid states are EXPANDED and          /*
272     * COLLAPSED.  Nodes not in this Hashtable are assumed state COLLAPSED.           * This contains the state of all nodes in the tree. Al/ entries map the
273     */           * TreePath of a note to to its state. Valid states are EXPANDED and
274    private Hashtable nodeStates;           * COLLAPSED. Nodes not in this Hashtable are assumed state COLLAPSED.
275             */
276    protected transient TreeCellEditor cellEditor;          private Hashtable nodeStates;
277    protected transient TreeCellRenderer cellRenderer;          protected transient TreeCellEditor cellEditor;
278    protected boolean editable;          protected transient TreeCellRenderer cellRenderer;
279    protected boolean invokesStopCellEditing;          protected boolean editable;
280    protected boolean largeModel;          protected boolean invokesStopCellEditing;
281    protected boolean rootVisible;          protected boolean largeModel;
282    protected int rowHeight;          protected boolean rootVisible;
283    protected boolean scrollsOnExpand;          protected int rowHeight;
284    protected transient TreeSelectionModel selectionModel;          protected boolean scrollsOnExpand;
285    protected boolean showsRootHandles;          protected transient TreeSelectionModel selectionModel;
286    protected int toggleClickCount;          protected boolean showsRootHandles;
287    protected transient TreeModel treeModel;          protected int toggleClickCount;
288    protected int visibleRowCount;          protected transient TreeModel treeModel;
289            protected int visibleRowCount;
290    /**  
291     * Handles TreeModelEvents to update the expandedState.          /**
292     */           * Handles TreeModelEvents to update the expandedState.
293    protected transient TreeModelListener treeModelListener;           */
294            protected transient TreeModelListener treeModelListener;
295    /**  
296     * Redirects TreeSelectionEvents so that the source is this JTree.          /**
297     */           * Redirects TreeSelectionEvents so that the source is this JTree.
298    protected TreeSelectionRedirector selectionRedirector =           */
299      new TreeSelectionRedirector();          protected TreeSelectionRedirector selectionRedirector =
300                                                                                    new TreeSelectionRedirector();
301    /**  
302     * Creates a new <code>JTree</code> object.          /**
303     */           * Creates a new <code>JTree</code> object.
304    public JTree()           */
305    {          public JTree()
306      this(createTreeModel(null));          {
307    }                  this(createTreeModel(null));
308            }
309    /**  
310     * Creates a new <code>JTree</code> object.          /**
311     *           * Creates a new <code>JTree</code> object.
312     * @param value the initial nodes in the tree           *
313     */           * @param value the initial nodes in the tree
314    public JTree(Hashtable value)           */
315    {          public JTree(Hashtable value)
316      this(createTreeModel(value));          {
317    }                  this(createTreeModel(value));
318            }
319    /**  
320     * Creates a new <code>JTree</code> object.          /**
321     *           * Creates a new <code>JTree</code> object.
322     * @param value the initial nodes in the tree           *
323     */           * @param value the initial nodes in the tree
324    public JTree(Object[] value)           */
325    {          public JTree(Object[] value)
326      this(createTreeModel(value));          {
327    }                  this(createTreeModel(value));
328            }
329    /**  
330     * Creates a new <code>JTree</code> object.          /**
331     *           * Creates a new <code>JTree</code> object.
332     * @param model the model to use           *
333     */           * @param model the model to use
334    public JTree(TreeModel model)           */
335    {          public JTree(TreeModel model)
336      setModel(model);          {
337      setSelectionModel(EmptySelectionModel.sharedInstance());                  setModel(model);
338      selectionModel.addTreeSelectionListener(selectionRedirector);                  setSelectionModel(EmptySelectionModel.sharedInstance());
339      setCellRenderer(new DefaultTreeCellRenderer());                  selectionModel.addTreeSelectionListener(selectionRedirector);
340      updateUI();                  setCellRenderer(new DefaultTreeCellRenderer());
341    }                  updateUI();
342            }
343    /**  
344     * Creates a new <code>JTree</code> object.          /**
345     *           * Creates a new <code>JTree</code> object.
346     * @param root the root node           *
347     */           * @param root the root node
348    public JTree(TreeNode root)           */
349    {          public JTree(TreeNode root)
350      this(root, false);          {
351    }                  this(root, false);
352            }
353    /**  
354     * Creates a new <code>JTree</code> object.          /**
355     *           * Creates a new <code>JTree</code> object.
356     * @param root the root node           *
357     * @param asksAllowChildren if false, all nodes without children are leaf nodes.           * @param root the root node
358     * If true, only nodes that do not allow children are leaf nodes.           * @param asksAllowChildren if false, all nodes without children are leaf
359     */           *        nodes. If true, only nodes that do not allow children are leaf
360    public JTree(TreeNode root, boolean asksAllowChildren)           *        nodes.
361    {           */
362      this(new DefaultTreeModel(root, asksAllowChildren));          public JTree(TreeNode root, boolean asksAllowChildren)
363    }          {
364                    this(new DefaultTreeModel(root, asksAllowChildren));
365    /**          }
366     * Creates a new <code>JTree</code> object.  
367     *          /**
368     * @param value the initial nodes in the tree           * Creates a new <code>JTree</code> object.
369     */           *
370    public JTree(Vector value)           * @param value the initial nodes in the tree
371    {           */
372      this(createTreeModel(value));          public JTree(Vector value)
373    }          {
374                    this(createTreeModel(value));
375    public static class DynamicUtilTreeNode          }
376      extends DefaultMutableTreeNode  
377    {          public static class DynamicUtilTreeNode
378      protected Object childValue;                          extends
379      protected boolean loadedChildren;                                  DefaultMutableTreeNode
380            {
381      /**                  protected Object childValue;
382       * Currently not set or used by this class.                  protected boolean loadedChildren;
383       * It might be set and used in later versions of this class.  
384       */                  /**
385      protected boolean hasChildren;                   * Currently not set or used by this class. It might be set and used in
386                         * later versions of this class.
387      public DynamicUtilTreeNode(Object value,                   */
388                                 Object children)                  protected boolean hasChildren;
389      {  
390        super(value);                  public DynamicUtilTreeNode(Object value, Object children)
391        childValue = children;                  {
392        loadedChildren = false;                          super(value);
393      }                          childValue = children;
394                            loadedChildren = false;
395      public int getChildCount()                  }
396      {  
397        loadChildren();                  public int getChildCount()
398        return super.getChildCount();                  {
399      }                          loadChildren();
400                            return super.getChildCount();
401      protected void loadChildren()                  }
402      {  
403        if (!loadedChildren)                  protected void loadChildren()
404          {                  {
405            createChildren(this, childValue);                          if (!loadedChildren)
406            loadedChildren = true;                          {
407          }                                  createChildren(this, childValue);
408      }                                  loadedChildren = true;
409                                }
410      public Enumeration children()                  }
411      {  
412        loadChildren();                  public Enumeration children()
413        return super.children();                  {
414      }                          loadChildren();
415                            return super.children();
416      /**                  }
417       * Returns the child node at position <code>pos</code>. Subclassed here  
418       * to load the children if necessary.                  /**
419       *                   * Returns the child node at position <code>pos</code>. Subclassed
420       * @param pos the position of the child node to fetch                   * here to load the children if necessary.
421       *                   *
422       * @return the childnode at the specified position                   * @param pos the position of the child node to fetch
423       */                   *
424      public TreeNode getChildAt(int pos)                   * @return the childnode at the specified position
425      {                   */
426        loadChildren();                  public TreeNode getChildAt(int pos)
427        return super.getChildAt(pos);                  {
428      }                          loadChildren();
429                            return super.getChildAt(pos);
430      public boolean isLeaf()                  }
431      {  
432        return (childValue == null ||                  public boolean isLeaf()
433                !(childValue instanceof Hashtable                  {
434                 || childValue instanceof Vector                          return (childValue == null || !(childValue instanceof Hashtable
435                 || childValue.getClass().isArray()));                                          || childValue instanceof Vector || childValue.getClass()
436      }                                          .isArray()));
437                    }
438      public static void createChildren(DefaultMutableTreeNode parent,  
439                                        Object children)                  public static void createChildren(DefaultMutableTreeNode parent,
440      {                                  Object children)
441        if (children instanceof Hashtable)                  {
442          {                          if (children instanceof Hashtable)
443            Hashtable tab = (Hashtable) children;                          {
444            Enumeration e = tab.keys();                                  Hashtable tab = (Hashtable) children;
445            while (e.hasMoreElements())                                  Enumeration e = tab.keys();
446              {                                  while (e.hasMoreElements())
447                Object key = e.nextElement();                                  {
448                Object val = tab.get(key);                                          Object key = e.nextElement();
449                parent.add(new DynamicUtilTreeNode(key, val));                                          Object val = tab.get(key);
450              }                                          parent.add(new DynamicUtilTreeNode(key, val));
451          }                                  }
452        else if (children instanceof Vector)                          } else if (children instanceof Vector)
453          {                          {
454            Iterator i = ((Vector)children).iterator();                                  Iterator i = ((Vector) children).iterator();
455            while (i.hasNext())                                  while (i.hasNext())
456              {                                  {
457                Object n = i.next();                                          Object n = i.next();
458                parent.add(new DynamicUtilTreeNode(n,n));                                          parent.add(new DynamicUtilTreeNode(n, n));
459              }                                  }
460          }                          } else if (children != null && children.getClass().isArray())
461        else if (children != null && children.getClass().isArray())                          {
462          {                                  Object[] arr = (Object[]) children;
463            Object[] arr = (Object[]) children;                                  for (int i = 0; i < arr.length; ++i)
464            for (int i = 0; i < arr.length; ++i)                                          parent.add(new DynamicUtilTreeNode(arr[i], arr[i]));
465              parent.add(new DynamicUtilTreeNode(arr[i], arr[i]));                          }
466        }                  }
467      }          }
468    }  
469            public int getRowForPath(TreePath path)
470    public int getRowForPath(TreePath path)          {
471    {                  TreeUI ui = getUI();
472      TreeUI ui = getUI();  
473                    if (ui != null)
474      if (ui != null)                          return ui.getRowForPath(this, path);
475        return ui.getRowForPath(this, path);  
476                    return -1;
477      return -1;          }
478    }  
479              public TreePath getPathForRow(int row)
480    public TreePath getPathForRow(int row)          {
481    {                  TreeUI ui = getUI();
482      TreeUI ui = getUI();                  return ui != null ? ui.getPathForRow(this, row) : null;
483      return ui != null ? ui.getPathForRow(this, row) : null;          }
484    }  
485            protected TreePath[] getPathBetweenRows(int index0, int index1)
486    protected TreePath[] getPathBetweenRows(int index0, int index1)          {
487    {                  TreeUI ui = getUI();
488      TreeUI ui = getUI();  
489                        if (ui == null)
490      if (ui == null)                          return null;
491        return null;  
492                        int minIndex = Math.min(index0, index1);
493      int minIndex = Math.min(index0, index1);                  int maxIndex = Math.max(index0, index1);
494      int maxIndex = Math.max(index0, index1);                  TreePath[] paths = new TreePath[maxIndex - minIndex + 1];
495      TreePath[] paths = new TreePath[maxIndex - minIndex + 1];  
496                        for (int i = minIndex; i <= maxIndex; ++i)
497      for (int i = minIndex; i <= maxIndex; ++i)                          paths[i - minIndex] = ui.getPathForRow(this, i);
498        paths[i - minIndex] = ui.getPathForRow(this, i);  
499                    return paths;
500      return paths;          }
501    }  
502              /**
503    /**           * Creates a new <code>TreeModel</code> object.
504     * Creates a new <code>TreeModel</code> object.           *
505     *           * @param value the values stored in the model
506     * @param value the values stored in the model           */
507     */          protected static TreeModel createTreeModel(Object value)
508    protected static TreeModel createTreeModel(Object value)          {
509    {                  return new DefaultTreeModel(new DynamicUtilTreeNode(value, value));
510      return new DefaultTreeModel(new DynamicUtilTreeNode(value, value));          }
511    }  
512            /**
513    /**           * Return the UI associated with this <code>JTree</code> object.
514     * Return the UI associated with this <code>JTree</code> object.           *
515     *           * @return the associated <code>TreeUI</code> object
516     * @return the associated <code>TreeUI</code> object           */
517     */          public TreeUI getUI()
518    public TreeUI getUI()          {
519    {                  return (TreeUI) ui;
520      return (TreeUI) ui;          }
521    }  
522            /**
523    /**           * Sets the UI associated with this <code>JTree</code> object.
524     * Sets the UI associated with this <code>JTree</code> object.           *
525     *           * @param ui the <code>TreeUI</code> to associate
526     * @param ui the <code>TreeUI</code> to associate           */
527     */          public void setUI(TreeUI ui)
528    public void setUI(TreeUI ui)          {
529    {                  super.setUI(ui);
530      super.setUI(ui);          }
531    }  
532            /**
533    /**           * This method resets the UI used to the Look and Feel defaults..
534     * This method resets the UI used to the Look and Feel defaults..           */
535     */          public void updateUI()
536    public void updateUI()          {
537    {                  setUI((TreeUI) UIManager.getUI(this));
538      setUI((TreeUI) UIManager.getUI(this));                  revalidate();
539      revalidate();                  repaint();
540      repaint();          }
541    }  
542            /**
543    /**           * This method returns the String ID of the UI class of Separator.
544     * This method returns the String ID of the UI class of  Separator.           *
545     *           * @return The UI class' String ID.
546     * @return The UI class' String ID.           */
547     */          public String getUIClassID()
548    public String getUIClassID()          {
549    {                  return "TreeUI";
550      return "TreeUI";          }
551    }  
552            /**
553    /**           * Gets the AccessibleContext associated with this
554     * Gets the AccessibleContext associated with this <code>JToggleButton</code>.           * <code>JToggleButton</code>.
555     *           *
556     * @return the associated context           * @return the associated context
557     */           */
558    public AccessibleContext getAccessibleContext()          public AccessibleContext getAccessibleContext()
559    {          {
560      return null;                  return null;
561    }          }
562    
563    /**          /**
564     * Returns the preferred viewport size..           * Returns the preferred viewport size..
565     *           *
566     * @return the preferred size           * @return the preferred size
567     */           */
568    public Dimension getPreferredScrollableViewportSize()          public Dimension getPreferredScrollableViewportSize()
569    {          {
570      return null;                  return null;
571    }          }
572    
573    public int getScrollableUnitIncrement(Rectangle visibleRect,          public int getScrollableUnitIncrement(Rectangle visibleRect,
574                                          int orientation, int direction)                          int orientation, int direction)
575    {          {
576      return 1;                  return 1;
577    }          }
578    
579    public int getScrollableBlockIncrement(Rectangle visibleRect,          public int getScrollableBlockIncrement(Rectangle visibleRect,
580                                           int orientation, int direction)                          int orientation, int direction)
581    {          {
582      return 1;                  return 1;
583    }          }
584    
585    public boolean getScrollableTracksViewportWidth()          public boolean getScrollableTracksViewportWidth()
586    {          {
587      return false;                  return false;
588    }          }
589    
590    public boolean getScrollableTracksViewportHeight()          public boolean getScrollableTracksViewportHeight()
591    {          {
592      return false;                  return false;
593    }          }
594    
595    /**          /**
596     * Adds a <code>TreeExpansionListener</code> object to the tree.           * Adds a <code>TreeExpansionListener</code> object to the tree.
597     *           *
598     * @param listener the listener to add           * @param listener the listener to add
599     */           */
600    public void addTreeExpansionListener(TreeExpansionListener listener)          public void addTreeExpansionListener(TreeExpansionListener listener)
601    {          {
602      listenerList.add(TreeExpansionListener.class, listener);                  listenerList.add(TreeExpansionListener.class, listener);
603    }          }
604    
605    /**          /**
606     * Removes a <code>TreeExpansionListener</code> object from the tree.           * Removes a <code>TreeExpansionListener</code> object from the tree.
607     *           *
608     * @param listener the listener to remove           * @param listener the listener to remove
609     */           */
610    public void removeTreeExpansionListener(TreeExpansionListener listener)          public void removeTreeExpansionListener(TreeExpansionListener listener)
611    {          {
612      listenerList.remove(TreeExpansionListener.class, listener);                  listenerList.remove(TreeExpansionListener.class, listener);
613    }          }
614    
615    /**          /**
616     * Returns all added <code>TreeExpansionListener</code> objects.           * Returns all added <code>TreeExpansionListener</code> objects.
617     *           *
618     * @return an array of listeners           * @return an array of listeners
619     */           */
620    public TreeExpansionListener[] getTreeExpansionListeners()          public TreeExpansionListener[] getTreeExpansionListeners()
621    {          {
622      return (TreeExpansionListener[]) getListeners(TreeExpansionListener.class);                  return (TreeExpansionListener[]) getListeners(TreeExpansionListener.class);
623    }          }
624    
625    /**          /**
626     * Notifies all listeners that the tree was collapsed.           * Notifies all listeners that the tree was collapsed.
627     *           *
628     * @param path the path to the node that was collapsed           * @param path the path to the node that was collapsed
629     */           */
630    public void fireTreeCollapsed(TreePath path)          public void fireTreeCollapsed(TreePath path)
631    {          {
632      TreeExpansionEvent event = new TreeExpansionEvent(this, path);                  TreeExpansionEvent event = new TreeExpansionEvent(this, path);
633      TreeExpansionListener[] listeners = getTreeExpansionListeners();                  TreeExpansionListener[] listeners = getTreeExpansionListeners();
634    
635      for (int index = 0; index < listeners.length; ++index)                  for (int index = 0; index < listeners.length; ++index)
636        listeners[index].treeCollapsed(event);                          listeners[index].treeCollapsed(event);
637    }          }
638      
639    /**          /**
640     * Notifies all listeners that the tree was expanded.           * Notifies all listeners that the tree was expanded.
641     *           *
642     * @param path the path to the node that was expanded           * @param path the path to the node that was expanded
643     */           */
644    public void fireTreeExpanded(TreePath path)          public void fireTreeExpanded(TreePath path)
645    {          {
646      TreeExpansionEvent event = new TreeExpansionEvent(this, path);                  TreeExpansionEvent event = new TreeExpansionEvent(this, path);
647      TreeExpansionListener[] listeners = getTreeExpansionListeners();                  TreeExpansionListener[] listeners = getTreeExpansionListeners();
648    
649      for (int index = 0; index < listeners.length; ++index)                  for (int index = 0; index < listeners.length; ++index)
650        listeners[index].treeExpanded(event);                          listeners[index].treeExpanded(event);
651    }          }
652    
653    /**          /**
654     * Adds a <code>TreeSelctionListener</code> object to the tree.           * Adds a <code>TreeSelctionListener</code> object to the tree.
655     *           *
656     * @param listener the listener to add           * @param listener the listener to add
657     */           */
658    public void addTreeSelectionListener(TreeSelectionListener listener)          public void addTreeSelectionListener(TreeSelectionListener listener)
659    {          {
660      listenerList.add(TreeSelectionListener.class, listener);                  listenerList.add(TreeSelectionListener.class, listener);
661    }          }
662    
663    /**          /**
664     * Removes a <code>TreeSelectionListener</code> object from the tree.           * Removes a <code>TreeSelectionListener</code> object from the tree.
665     *           *
666     * @param listener the listener to remove           * @param listener the listener to remove
667     */           */
668    public void removeTreeSelectionListener(TreeSelectionListener listener)          public void removeTreeSelectionListener(TreeSelectionListener listener)
669    {          {
670      listenerList.remove(TreeSelectionListener.class, listener);                  listenerList.remove(TreeSelectionListener.class, listener);
671    }          }
672    
673    /**          /**
674     * Returns all added <code>TreeSelectionListener</code> objects.           * Returns all added <code>TreeSelectionListener</code> objects.
675     *           *
676     * @return an array of listeners           * @return an array of listeners
677     */           */
678    public TreeSelectionListener[] getTreeSelectionListeners()          public TreeSelectionListener[] getTreeSelectionListeners()
679    {          {
680      return (TreeSelectionListener[]) getListeners(TreeSelectionListener.class);                  return (TreeSelectionListener[])
681    }                                          getListeners(TreeSelectionListener.class);
682            }
683    /**  
684     * Notifies all listeners when the selection of the tree changed.          /**
685     *           * Notifies all listeners when the selection of the tree changed.
686     * @param event the event to send           *
687     */           * @param event the event to send
688    protected void fireValueChanged(TreeSelectionEvent event)           */
689    {          protected void fireValueChanged(TreeSelectionEvent event)
690      TreeSelectionListener[] listeners = getTreeSelectionListeners();          {
691                    TreeSelectionListener[] listeners = getTreeSelectionListeners();
692      for (int index = 0; index < listeners.length; ++index)  
693        listeners[index].valueChanged(event);                  for (int index = 0; index < listeners.length; ++index)
694    }                          listeners[index].valueChanged(event);
695            }
696    /**  
697     * Adds a <code>TreeWillExpandListener</code> object to the tree.          /**
698     *           * Adds a <code>TreeWillExpandListener</code> object to the tree.
699     * @param listener the listener to add           *
700     */           * @param listener the listener to add
701    public void addTreeWillExpandListener(TreeWillExpandListener listener)           */
702    {          public void addTreeWillExpandListener(TreeWillExpandListener listener)
703      listenerList.add(TreeWillExpandListener.class, listener);          {
704    }                  listenerList.add(TreeWillExpandListener.class, listener);
705            }
706    /**  
707     * Removes a <code>TreeWillExpandListener</code> object from the tree.          /**
708     *           * Removes a <code>TreeWillExpandListener</code> object from the tree.
709     * @param listener the listener to remove           *
710     */           * @param listener the listener to remove
711    public void removeTreeWillExpandListener(TreeWillExpandListener listener)           */
712    {          public void removeTreeWillExpandListener(TreeWillExpandListener listener)
713      listenerList.remove(TreeWillExpandListener.class, listener);          {
714    }                  listenerList.remove(TreeWillExpandListener.class, listener);
715            }
716    /**  
717     * Returns all added <code>TreeWillExpandListener</code> objects.          /**
718     *           * Returns all added <code>TreeWillExpandListener</code> objects.
719     * @return an array of listeners           *
720     */           * @return an array of listeners
721    public TreeWillExpandListener[] getTreeWillExpandListeners()           */
722    {          public TreeWillExpandListener[] getTreeWillExpandListeners()
723      return (TreeWillExpandListener[]) getListeners(TreeWillExpandListener.class);          {
724    }                  return (TreeWillExpandListener[])
725                                            getListeners(TreeWillExpandListener.class);
726    /**          }
727     * Notifies all listeners that the tree will collapse.  
728     *          /**
729     * @param path the path to the node that will collapse           * Notifies all listeners that the tree will collapse.
730     */           *
731    public void fireTreeWillCollapse(TreePath path)           * @param path the path to the node that will collapse
732      throws ExpandVetoException           */
733    {          public void fireTreeWillCollapse(TreePath path) throws ExpandVetoException
734      TreeExpansionEvent event = new TreeExpansionEvent(this, path);          {
735      TreeWillExpandListener[] listeners = getTreeWillExpandListeners();                  TreeExpansionEvent event = new TreeExpansionEvent(this, path);
736                    TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
737      for (int index = 0; index < listeners.length; ++index)  
738        listeners[index].treeWillCollapse(event);                  for (int index = 0; index < listeners.length; ++index)
739    }                          listeners[index].treeWillCollapse(event);
740            }
741    /**  
742     * Notifies all listeners that the tree will expand.          /**
743     *           * Notifies all listeners that the tree will expand.
744     * @param path the path to the node that will expand           *
745     */           * @param path the path to the node that will expand
746    public void fireTreeWillExpand(TreePath path)           */
747      throws ExpandVetoException          public void fireTreeWillExpand(TreePath path) throws ExpandVetoException
748    {          {
749      TreeExpansionEvent event = new TreeExpansionEvent(this, path);                  TreeExpansionEvent event = new TreeExpansionEvent(this, path);
750      TreeWillExpandListener[] listeners = getTreeWillExpandListeners();                  TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
751    
752      for (int index = 0; index < listeners.length; ++index)                  for (int index = 0; index < listeners.length; ++index)
753        listeners[index].treeWillExpand(event);                          listeners[index].treeWillExpand(event);
754    }          }
755    
756    /**          /**
757     * Returns the model of this <code>JTree</code> object.           * Returns the model of this <code>JTree</code> object.
758     *           *
759     * @return the associated <code>TreeModel</code>           * @return the associated <code>TreeModel</code>
760     */           */
761    public TreeModel getModel()          public TreeModel getModel()
762    {          {
763      return treeModel;                  return treeModel;
764    }          }
765    
766    /**          /**
767     * Sets the model to use in <code>JTree</code>.           * Sets the model to use in <code>JTree</code>.
768     *           *
769     * @param model the <code>TreeModel</code> to use           * @param model the <code>TreeModel</code> to use
770     */           */
771    public void setModel(TreeModel model)          public void setModel(TreeModel model)
772    {          {
773      if (treeModel == model)                  if (treeModel == model)
774        return;                          return;
775    
776      TreeModel oldValue = treeModel;                  TreeModel oldValue = treeModel;
777      treeModel = model;                  treeModel = model;
778        
779      firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);                  firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
780    
781      // add treeModelListener to the new model                  // add treeModelListener to the new model
782      if (treeModelListener == null)                  if (treeModelListener == null)
783        treeModelListener = createTreeModelListener();                          treeModelListener = createTreeModelListener();
784      model.addTreeModelListener(treeModelListener);                  model.addTreeModelListener(treeModelListener);
785    }          }
786    
787    /**          /**
788     * Checks if this <code>JTree</code> object is editable.           * Checks if this <code>JTree</code> object is editable.
789     *           *
790     * @return <code>true</code> if this tree object is editable,           * @return <code>true</code> if this tree object is editable,
791     * <code>false</code> otherwise           *         <code>false</code> otherwise
792     */           */
793    public boolean isEditable()          public boolean isEditable()
794    {          {
795      return editable;                  return editable;
796    }          }
797    
798    /**          /**
799     * Sets the <code>editable</code> property.           * Sets the <code>editable</code> property.
800     *           *
801     * @param flag <code>true</code> to make this tree object editable,           * @param flag <code>true</code> to make this tree object editable,
802     * <code>false</code> otherwise           *        <code>false</code> otherwise
803     */           */
804    public void setEditable(boolean flag)          public void setEditable(boolean flag)
805    {          {
806      if (editable == flag)                  if (editable == flag)
807        return;                          return;
808    
809      boolean oldValue = editable;                  boolean oldValue = editable;
810      editable = flag;                  editable = flag;
811      firePropertyChange(EDITABLE_PROPERTY, oldValue, editable);                  firePropertyChange(EDITABLE_PROPERTY, oldValue, editable);
812    }          }
813    
814    /**          /**
815     * Checks if the root element is visible.           * Checks if the root element is visible.
816     *           *
817     * @return <code>true</code> if the root element is visible,           * @return <code>true</code> if the root element is visible,
818     * <code>false</code> otherwise           *         <code>false</code> otherwise
819     */           */
820    public boolean isRootVisible()          public boolean isRootVisible()
821    {          {
822      return rootVisible;                  return rootVisible;
823    }          }
824    
825    public void setRootVisible(boolean flag)          public void setRootVisible(boolean flag)
826    {          {
827      if (rootVisible == flag)                  if (rootVisible == flag)
828        return;                          return;
829        
830      boolean oldValue = rootVisible;                  boolean oldValue = rootVisible;
831      rootVisible = flag;                  rootVisible = flag;
832      firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);                  firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
833    }          }
834    
835    public boolean getShowsRootHandles()          public boolean getShowsRootHandles()
836    {          {
837      return showsRootHandles;                  return showsRootHandles;
838    }          }
839    
840    public void setShowsRootHandles(boolean flag)          public void setShowsRootHandles(boolean flag)
841    {          {
842      if (showsRootHandles == flag)                  if (showsRootHandles == flag)
843        return;                          return;
844    
845      boolean oldValue = showsRootHandles;                  boolean oldValue = showsRootHandles;
846      showsRootHandles = flag;                  showsRootHandles = flag;
847      firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, flag);                  firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, flag);
848    }          }
849    
850    public TreeCellEditor getCellEditor()          public TreeCellEditor getCellEditor()
851    {          {
852      return cellEditor;  
853    }                  return cellEditor;
854            }
855    public void setCellEditor(TreeCellEditor editor)  
856    {          public void setCellEditor(TreeCellEditor editor)
857      if (cellEditor == editor)          {
858        return;                  if (cellEditor == editor)
859                            return;
860      TreeCellEditor oldValue = cellEditor;  
861      cellEditor = editor;                  TreeCellEditor oldValue = cellEditor;
862      firePropertyChange(CELL_EDITOR_PROPERTY, oldValue, editor);                  cellEditor = editor;
863    }                  firePropertyChange(CELL_EDITOR_PROPERTY, oldValue, editor);
864              }
865    public TreeCellRenderer getCellRenderer()  
866    {          public TreeCellRenderer getCellRenderer()
867      return cellRenderer;          {
868    }                  return cellRenderer;
869              }
870    public void setCellRenderer(TreeCellRenderer newRenderer)  
871    {          public void setCellRenderer(TreeCellRenderer newRenderer)
872      if (cellRenderer == newRenderer)          {
873        return;                  if (cellRenderer == newRenderer)
874                            return;
875      TreeCellRenderer oldValue = cellRenderer;  
876      cellRenderer = newRenderer;                  TreeCellRenderer oldValue = cellRenderer;
877      firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, newRenderer);                  cellRenderer = newRenderer;
878    }                  firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, newRenderer);
879            }
880    public TreeSelectionModel getSelectionModel()  
881    {          public TreeSelectionModel getSelectionModel()
882      return selectionModel;          {
883    }                  return selectionModel;
884            }
885    public void setSelectionModel(TreeSelectionModel model)  
886    {          public void setSelectionModel(TreeSelectionModel model)
887      if (selectionModel == model)          {
888        return;                  if (selectionModel == model)
889                                return;
890      TreeSelectionModel oldValue = selectionModel;  
891      selectionModel = model;                  if (selectionModel != null)
892      firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, model);                          selectionModel.removeTreeSelectionListener(selectionRedirector);
893    }  
894                    TreeSelectionModel oldValue = selectionModel;
895    public int getVisibleRowCount()                  selectionModel = model;
896    {  
897      return visibleRowCount;                  if (selectionModel != null)
898    }                          selectionModel.addTreeSelectionListener(selectionRedirector);
899    
900    public void setVisibleRowCount(int rows)                  firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, model);
901    {                  revalidate();
902      if (visibleRowCount == rows)                  repaint();
903        return;          }
904    
905      int oldValue = visibleRowCount;          public int getVisibleRowCount()
906      visibleRowCount = rows;          {
907      firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldValue, rows);                  return visibleRowCount;
908    }          }
909    
910    public boolean isLargeModel()          public void setVisibleRowCount(int rows)
911    {          {
912      return largeModel;                  if (visibleRowCount == rows)
913    }                          return;
914    
915    public void setLargeModel(boolean large)                  int oldValue = visibleRowCount;
916    {                  visibleRowCount = rows;
917      if (largeModel == large)                  firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldValue, rows);
918        return;          }
919    
920      boolean oldValue = largeModel;          public boolean isLargeModel()
921      largeModel = large;          {
922      firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, large);                  return largeModel;
923    }          }
924    
925    public int getRowHeight()          public void setLargeModel(boolean large)
926    {          {
927      return rowHeight;                  if (largeModel == large)
928    }                          return;
929    
930    public void setRowHeight(int height)                  boolean oldValue = largeModel;
931    {                  largeModel = large;
932      if (rowHeight == height)                  firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, large);
933        return;          }
934        
935      int oldValue = rowHeight;          public int getRowHeight()
936      rowHeight = height;          {
937      firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, height);  
938    }                  return rowHeight;
939            }
940    public boolean isFixedRowHeight()  
941    {          public void setRowHeight(int height)
942      return rowHeight > 0;          {
943    }                  if (rowHeight == height)
944                            return;
945    public boolean getInvokesStopCellEditing()  
946    {                  int oldValue = rowHeight;
947      return invokesStopCellEditing;                  rowHeight = height;
948    }                  firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, height);
949            }
950    public void setInvokesStopCellEditing(boolean invoke)  
951    {          public boolean isFixedRowHeight()
952      if (invokesStopCellEditing == invoke)          {
953       return;                  return rowHeight > 0;
954            }
955      boolean oldValue = invokesStopCellEditing;  
956      invokesStopCellEditing = invoke;          public boolean getInvokesStopCellEditing()
957      firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY, oldValue, invoke);          {
958    }                  return invokesStopCellEditing;
959            }
960    /**  
961     * @since 1.3          public void setInvokesStopCellEditing(boolean invoke)
962     */          {
963    public int getToggleClickCount()                  if (invokesStopCellEditing == invoke)
964    {                          return;
965      return toggleClickCount;  
966    }                  boolean oldValue = invokesStopCellEditing;
967                    invokesStopCellEditing = invoke;
968    /**                  firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY,
969     * @since 1.3                                                                                                  oldValue, invoke);
970     */          }
971    public void setToggleClickCount(int count)  
972    {          /**
973      if (toggleClickCount == count)           * @since 1.3
974        return;           */
975                public int getToggleClickCount()
976      int oldValue = toggleClickCount;          {
977      toggleClickCount = count;                  return toggleClickCount;
978      firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count);          }
979    }  
980            /**
981    public void scrollPathToVisible(TreePath path)           * @since 1.3
982    {           */
983      if (path == null)          public void setToggleClickCount(int count)
984        return;          {
985                    if (toggleClickCount == count)
986      Rectangle rect = getPathBounds(path);                          return;
987    
988      if (rect == null)                  int oldValue = toggleClickCount;
989        return;                  toggleClickCount = count;
990                    firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count);
991      scrollRectToVisible(rect);          }
992    }  
993            public void scrollPathToVisible(TreePath path)
994    public void scrollRowToVisible(int row)          {
995    {                  if (path == null)
996      scrollPathToVisible(getPathForRow(row));                          return;
997    }  
998                      Rectangle rect = getPathBounds(path);
999    public boolean getScrollsOnExpand()  
1000    {                  if (rect == null)
1001      return scrollsOnExpand;                          return;
1002    }  
1003                    scrollRectToVisible(rect);
1004    public void setScrollsOnExpand(boolean scroll)          }
1005    {  
1006      if (scrollsOnExpand == scroll)          public void scrollRowToVisible(int row)
1007        return;          {
1008                    scrollPathToVisible(getPathForRow(row));
1009      boolean oldValue = scrollsOnExpand;          }
1010      scrollsOnExpand = scroll;  
1011      firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, scroll);          public boolean getScrollsOnExpand()
1012    }          {
1013                    return scrollsOnExpand;
1014    public void setSelectionPath(TreePath path)          }
1015    {  
1016      selectionModel.setSelectionPath(path);          public void setScrollsOnExpand(boolean scroll)
1017    }          {
1018                    if (scrollsOnExpand == scroll)
1019    public void setSelectionPaths(TreePath[] paths)                          return;
1020    {  
1021      selectionModel.setSelectionPaths(paths);                  boolean oldValue = scrollsOnExpand;
1022    }                  scrollsOnExpand = scroll;
1023                      firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, scroll);
1024    public void setSelectionRow(int row)          }
1025    {  
1026      TreePath path = getPathForRow(row);          public void setSelectionPath(TreePath path)
1027            {
1028      if (path != null)                  selectionModel.setSelectionPath(path);
1029        selectionModel.setSelectionPath(path);          }
1030    }  
1031            public void setSelectionPaths(TreePath[] paths)
1032    public void setSelectionRows(int[] rows)          {
1033    {                  selectionModel.setSelectionPaths(paths);
1034      // Make sure we have an UI so getPathForRow() does not return null.          }
1035      if (rows == null || getUI() == null)  
1036        return;          public void setSelectionRow(int row)
1037            {
1038      TreePath[] paths = new TreePath[rows.length];                  TreePath path = getPathForRow(row);
1039    
1040      for (int i = rows.length - 1; i >= 0; --i)                  if (path != null)
1041        paths[i] = getPathForRow(rows[i]);                          selectionModel.setSelectionPath(path);
1042            }
1043      setSelectionPaths(paths);  
1044    }          public void setSelectionRows(int[] rows)
1045            {
1046    public void setSelectionInterval(int index0, int index1)                  // Make sure we have an UI so getPathForRow() does not return null.
1047    {                  if (rows == null || getUI() == null)
1048      TreePath[] paths = getPathBetweenRows(index0, index1);                          return;
1049    
1050      if (paths != null)                  TreePath[] paths = new TreePath[rows.length];
1051        setSelectionPaths(paths);  
1052    }                  for (int i = rows.length - 1; i >= 0; --i)
1053                            paths[i] = getPathForRow(rows[i]);
1054    public void addSelectionPath(TreePath path)  
1055    {                  setSelectionPaths(paths);
1056      selectionModel.addSelectionPath(path);          }
1057    }  
1058            public void setSelectionInterval(int index0, int index1)
1059    public void addSelectionPaths(TreePath[] paths)          {
1060    {                  TreePath[] paths = getPathBetweenRows(index0, index1);
1061      selectionModel.addSelectionPaths(paths);  
1062    }                  if (paths != null)
1063                            setSelectionPaths(paths);
1064    public void addSelectionRow(int row)          }
1065    {  
1066      TreePath path = getPathForRow(row);          public void addSelectionPath(TreePath path)
1067            {
1068      if (path != null)                  selectionModel.addSelectionPath(path);
1069        selectionModel.addSelectionPath(path);          }
1070    }  
1071            public void addSelectionPaths(TreePath[] paths)
1072    public void addSelectionRows(int[] rows)          {
1073    {                  selectionModel.addSelectionPaths(paths);
1074      // Make sure we have an UI so getPathForRow() does not return null.          }
1075      if (rows == null || getUI() == null)  
1076        return;          public void addSelectionRow(int row)
1077            {
1078      TreePath[] paths = new TreePath[rows.length];                  TreePath path = getPathForRow(row);
1079    
1080      for (int i = rows.length - 1; i >= 0; --i)                  if (path != null)
1081        paths[i] = getPathForRow(rows[i]);                          selectionModel.addSelectionPath(path);
1082            }
1083      addSelectionPaths(paths);  
1084    }          public void addSelectionRows(int[] rows)
1085            {
1086    public void addSelectionInterval(int index0, int index1)                  // Make sure we have an UI so getPathForRow() does not return null.
1087    {                  if (rows == null || getUI() == null)
1088      TreePath[] paths = getPathBetweenRows(index0, index1);                          return;
1089    
1090      if (paths != null)                  TreePath[] paths = new TreePath[rows.length];
1091        addSelectionPaths(paths);  
1092    }                  for (int i = rows.length - 1; i >= 0; --i)
1093                            paths[i] = getPathForRow(rows[i]);
1094    public void removeSelectionPath(TreePath path)  
1095    {                  addSelectionPaths(paths);
1096      selectionModel.removeSelectionPath(path);          }
1097    }  
1098            public void addSelectionInterval(int index0, int index1)
1099    public void removeSelectionPaths(TreePath[] paths)          {
1100    {                  TreePath[] paths = getPathBetweenRows(index0, index1);
1101      selectionModel.removeSelectionPaths(paths);  
1102    }                  if (paths != null)
1103                            addSelectionPaths(paths);
1104    public void removeSelectionRow(int row)          }
1105    {  
1106      TreePath path = getPathForRow(row);          public void removeSelectionPath(TreePath path)
1107            {
1108      if (path != null)                  selectionModel.removeSelectionPath(path);
1109        selectionModel.removeSelectionPath(path);          }
1110    }  
1111            public void removeSelectionPaths(TreePath[] paths)
1112    public void removeSelectionRows(int[] rows)          {
1113    {                  selectionModel.removeSelectionPaths(paths);
1114      // Make sure we have an UI so getPathForRow() does not return null.          }
1115      if (rows == null || getUI() == null)  
1116        return;          public void removeSelectionRow(int row)
1117            {
1118      TreePath[] paths = new TreePath[rows.length];                  TreePath path = getPathForRow(row);
1119    
1120      for (int i = rows.length - 1; i >= 0; --i)                  if (path != null)
1121        paths[i] = getPathForRow(rows[i]);                          selectionModel.removeSelectionPath(path);
1122            }
1123      removeSelectionPaths(paths);  
1124    }          public void removeSelectionRows(int[] rows)
1125            {
1126    public void removeSelectionInterval(int index0, int index1)                  if (rows == null || getUI() == null)
1127    {                          return;
1128      TreePath[] paths = getPathBetweenRows(index0, index1);  
1129                    TreePath[] paths = new TreePath[rows.length];
1130      if (paths != null)  
1131        removeSelectionPaths(paths);                  for (int i = rows.length - 1; i >= 0; --i)
1132    }                          paths[i] = getPathForRow(rows[i]);
1133    
1134    public void clearSelection()                  removeSelectionPaths(paths);
1135    {          }
1136      selectionModel.clearSelection();  
1137    }          public void removeSelectionInterval(int index0, int index1)
1138              {
1139    public TreePath getLeadSelectionPath()                  TreePath[] paths = getPathBetweenRows(index0, index1);
1140    {  
1141      return leadSelectionPath;                  if (paths != null)
1142    }                          removeSelectionPaths(paths);
1143            }
1144    /**  
1145     * @since 1.3          public void clearSelection()
1146     */          {
1147    public void setLeadSelectionPath(TreePath path)                  selectionModel.clearSelection();
1148    {          }
1149      if (leadSelectionPath == path)  
1150        return;          public TreePath getLeadSelectionPath()
1151            {
1152      TreePath oldValue = leadSelectionPath;                  return leadSelectionPath;
1153      leadSelectionPath = path;          }
1154      firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);  
1155    }          /**
1156             * @since 1.3
1157    /**           */
1158     * @since 1.3          public void setLeadSelectionPath(TreePath path)
1159     */          {
1160    public TreePath getAnchorSelectionPath()                  if (leadSelectionPath == path)
1161    {                          return;
1162      return anchorSelectionPath;  
1163    }                  TreePath oldValue = leadSelectionPath;
1164                    leadSelectionPath = path;
1165    /**                  firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
1166     * @since 1.3          }
1167     */  
1168    public void setAnchorSelectionPath(TreePath path)          /**
1169    {           * @since 1.3
1170      if (anchorSelectionPath == path)           */
1171        return;          public TreePath getAnchorSelectionPath()
1172            {
1173      TreePath oldValue = anchorSelectionPath;                  return anchorSelectionPath;
1174      anchorSelectionPath = path;          }
1175      firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, path);  
1176    }          /**
1177             * @since 1.3
1178    public int getLeadSelectionRow()           */
1179    {          public void setAnchorSelectionPath(TreePath path)
1180      return selectionModel.getLeadSelectionRow();          {
1181    }                  if (anchorSelectionPath == path)
1182                            return;
1183    public int getMaxSelectionRow()  
1184    {                  TreePath oldValue = anchorSelectionPath;
1185      return selectionModel.getMaxSelectionRow();                  anchorSelectionPath = path;
1186    }                  firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, path);
1187            }
1188    public int getMinSelectionRow()  
1189    {          public int getLeadSelectionRow()
1190      return selectionModel.getMinSelectionRow();          {
1191    }                  return selectionModel.getLeadSelectionRow();
1192            }
1193    public int getSelectionCount()  
1194    {          public int getMaxSelectionRow()
1195      return selectionModel.getSelectionCount();          {
1196    }                  return selectionModel.getMaxSelectionRow();
1197            }
1198    public TreePath getSelectionPath()  
1199    {          public int getMinSelectionRow()
1200      return selectionModel.getSelectionPath();          {
1201    }                  return selectionModel.getMinSelectionRow();
1202            }
1203    public TreePath[] getSelectionPaths()  
1204    {          public int getSelectionCount()
1205      return selectionModel.getSelectionPaths();          {
1206    }                  return selectionModel.getSelectionCount();
1207            }
1208    public int[] getSelectionRows()  
1209    {          public TreePath getSelectionPath()
1210      return selectionModel.getSelectionRows();          {
1211    }                  return selectionModel.getSelectionPath();
1212            }
1213    public boolean isPathSelected(TreePath path)  
1214    {          public TreePath[] getSelectionPaths()
1215      return selectionModel.isPathSelected(path);          {
1216    }                  return selectionModel.getSelectionPaths();
1217            }
1218    public boolean isRowSelected(int row)  
1219    {          public int[] getSelectionRows()
1220      return selectionModel.isRowSelected(row);          {
1221    }                  return selectionModel.getSelectionRows();
1222            }
1223    public boolean isSelectionEmpty()  
1224    {          public boolean isPathSelected(TreePath path)
1225      return selectionModel.isSelectionEmpty();          {
1226    }                  return selectionModel.isPathSelected(path);
1227              }
1228    /**  
1229     * Return the value of the <code>dragEnabled</code> property.          public boolean isRowSelected(int row)
1230     *          {
1231     * @return the value                  return selectionModel.isPathSelected(getPathForRow(row));
1232     *          }
1233     * @since 1.4  
1234     */          public boolean isSelectionEmpty()
1235    public boolean getDragEnabled()          {
1236    {                  return selectionModel.isSelectionEmpty();
1237      return dragEnabled;          }
1238    }  
1239            /**
1240    /**           * Return the value of the <code>dragEnabled</code> property.
1241     * Set the <code>dragEnabled</code> property.           *
1242     *           * @return the value
1243     * @param enabled new value           *
1244     *           * @since 1.4
1245     * @since 1.4           */
1246     */          public boolean getDragEnabled()
1247    public void setDragEnabled(boolean enabled)          {
1248    {                  return dragEnabled;
1249      dragEnabled = enabled;          }
1250    }  
1251            /**
1252    public int getRowCount()           * Set the <code>dragEnabled</code> property.
1253    {           *
1254      TreeUI ui = getUI();           * @param enabled new value
1255             *
1256      if (ui != null)           * @since 1.4
1257        return ui.getRowCount(this);           */
1258                public void setDragEnabled(boolean enabled)
1259      return 0;          {
1260    }  
1261                      dragEnabled = enabled;
1262    public void collapsePath(TreePath path)          }
1263    {  
1264      setExpandedState(path, false);          public int getRowCount()
1265    }          {
1266                      TreeUI ui = getUI();
1267    public void collapseRow(int row)  
1268    {                  if (ui != null)
1269      if (row < 0 || row >= getRowCount())                          return ui.getRowCount(this);
1270        return;  
1271                    return 0;
1272      TreePath path = getPathForRow(row);          }
1273    
1274      if (path != null)          public void collapsePath(TreePath path)
1275        collapsePath(path);          {
1276    }                  setExpandedState(path, false);
1277            }
1278    public void expandPath(TreePath path)  
1279    {          public void collapseRow(int row)
1280      // Don't expand if last path component is a leaf node.          {
1281      if ((path == null)                  if (row < 0 || row >= getRowCount())
1282          || (treeModel.isLeaf(path.getLastPathComponent())))                          return;
1283        return;  
1284                    TreePath path = getPathForRow(row);
1285      setExpandedState(path, true);  
1286    }                  if (path != null)
1287                              collapsePath(path);
1288    public void expandRow(int row)          }
1289    {  
1290      if (row < 0 || row >= getRowCount())          public void expandPath(TreePath path)
1291        return;          {
1292                    // Don't expand if last path component is a leaf node.
1293      TreePath path = getPathForRow(row);                  if ((path == null) || (treeModel.isLeaf(path.getLastPathComponent())))
1294                            return;
1295      if (path != null)  
1296        expandPath(path);                  setExpandedState(path, true);
1297    }          }
1298    
1299    public boolean isCollapsed(TreePath path)          public void expandRow(int row)
1300    {          {
1301      return ! isExpanded(path);                  if (row < 0 || row >= getRowCount())
1302    }                          return;
1303    
1304    public boolean isCollapsed(int row)                  TreePath path = getPathForRow(row);
1305    {  
1306      if (row < 0 || row >= getRowCount())                  if (path != null)
1307        return false;                          expandPath(path);
1308            }
1309      TreePath path = getPathForRow(row);  
1310            public boolean isCollapsed(TreePath path)
1311      if (path != null)          {
1312        return isCollapsed(path);                  return !isExpanded(path);
1313            }
1314      return false;  
1315    }          public boolean isCollapsed(int row)
1316            {
1317    public boolean isExpanded(TreePath path)                  if (row < 0 || row >= getRowCount())
1318    {                          return false;
1319      if (path == null)  
1320        return false;                  TreePath path = getPathForRow(row);
1321    
1322      Object state = nodeStates.get(path);                  if (path != null)
1323                            return isCollapsed(path);
1324      if ((state == null) || (state != EXPANDED))  
1325        return false;                  return false;
1326            }
1327      TreePath parent = path.getParentPath();  
1328            public boolean isExpanded(TreePath path)
1329      if (parent != null)          {
1330        return isExpanded(parent);                  if (path == null)
1331                                return false;
1332      return true;  
1333    }                  Object state = nodeStates.get(path);
1334      
1335    public boolean isExpanded(int row)                  if ((state == null) || (state != EXPANDED))
1336    {                          return false;
1337      if (row < 0 || row >= getRowCount())  
1338        return false;                  TreePath parent = path.getParentPath();
1339    
1340      TreePath path = getPathForRow(row);                  if (parent != null)
1341                            return isExpanded(parent);
1342      if (path != null)  
1343        return isExpanded(path);                  return true;
1344            }
1345      return false;  
1346    }          public boolean isExpanded(int row)
1347            {
1348    /**                  if (row < 0 || row >= getRowCount())
1349     * @since 1.3                          return false;
1350     */  
1351    public boolean getExpandsSelectedPaths()                  TreePath path = getPathForRow(row);
1352    {  
1353      return expandsSelectedPaths;                  if (path != null)
1354    }                          return isExpanded(path);
1355    
1356    /**                  return false;
1357     * @since 1.3          }
1358     */  
1359    public void setExpandsSelectedPaths(boolean flag)          /**
1360    {           * @since 1.3
1361      if (expandsSelectedPaths == flag)           */
1362        return;          public boolean getExpandsSelectedPaths()
1363            {
1364      boolean oldValue = expandsSelectedPaths;                  return expandsSelectedPaths;
1365      expandsSelectedPaths = flag;          }
1366      firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, flag);  
1367    }          /**
1368             * @since 1.3
1369    public Rectangle getPathBounds(TreePath path)           */
1370    {          public void setExpandsSelectedPaths(boolean flag)
1371      TreeUI ui = getUI();          {
1372                    if (expandsSelectedPaths == flag)
1373      if (ui == null)                          return;
1374        return null;  
1375                    boolean oldValue = expandsSelectedPaths;
1376      return ui.getPathBounds(this, path);                  expandsSelectedPaths = flag;
1377    }                  firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, flag);
1378            }
1379    public Rectangle getRowBounds(int row)  
1380    {          public Rectangle getPathBounds(TreePath path)
1381      TreePath path = getPathForRow(row);          {
1382                    TreeUI ui = getUI();
1383      if (path != null)  
1384        return getPathBounds(path);                  if (ui == null)
1385                            return null;
1386      return null;  
1387    }                  return ui.getPathBounds(this, path);
1388            }
1389    public boolean isEditing()  
1390    {          public Rectangle getRowBounds(int row)
1391      TreeUI ui = getUI();          {
1392                    TreePath path = getPathForRow(row);
1393      if (ui != null)  
1394        return ui.isEditing(this);                  if (path != null)
1395                            return getPathBounds(path);
1396      return false;  
1397    }                  return null;
1398            }
1399    public boolean stopEditing()  
1400    {          public boolean isEditing()
1401      TreeUI ui = getUI();          {
1402                    TreeUI ui = getUI();
1403      if (ui != null)  
1404        return ui.stopEditing(this);                  if (ui != null)
1405                            return ui.isEditing(this);
1406     return false;  
1407    }                  return false;
1408            }
1409    public void cancelEditing()  
1410    {          public boolean stopEditing()
1411      TreeUI ui = getUI();          {
1412                    TreeUI ui = getUI();
1413      if (ui != null)  
1414        ui.cancelEditing(this);                  if (ui != null)
1415    }                          return ui.stopEditing(this);
1416    
1417    public void startEditingAtPath(TreePath path)                  return false;
1418    {          }
1419      TreeUI ui = getUI();  
1420            public void cancelEditing()
1421      if (ui != null)          {
1422        ui.startEditingAtPath(this, path);                  TreeUI ui = getUI();
1423    }  
1424                    if (ui != null)
1425    public TreePath getEditingPath()                          ui.cancelEditing(this);
1426    {          }
1427      TreeUI ui = getUI();  
1428            public void startEditingAtPath(TreePath path)
1429      if (ui != null)          {
1430        return ui.getEditingPath(this);                  TreeUI ui = getUI();
1431    
1432      return null;                  if (ui != null)
1433    }                          ui.startEditingAtPath(this, path);
1434            }
1435    public TreePath getPathForLocation(int x, int y)  
1436    {          public TreePath getEditingPath()
1437      TreePath path = getClosestPathForLocation(x, y);          {
1438                    TreeUI ui = getUI();
1439      if (path != null)  
1440        {                  if (ui != null)
1441           Rectangle rect = getPathBounds(path);                          return ui.getEditingPath(this);
1442    
1443           if ((rect != null) && rect.contains(x, y))                  return null;
1444             return path;          }
1445        }  
1446            public TreePath getPathForLocation(int x, int y)
1447      return null;          {
1448    }                  TreePath path = getClosestPathForLocation(x, y);
1449    
1450    public int getRowForLocation(int x, int y)                  if (path != null)
1451    {                  {
1452      TreePath path = getPathForLocation(x, y);                          Rectangle rect = getPathBounds(path);
1453    
1454      if (path != null)                          if ((rect != null) && rect.contains(x, y))
1455        return getRowForPath(path);                                  return path;
1456                    }
1457      return -1;  
1458    }                  return null;
1459              }
1460    public TreePath getClosestPathForLocation(int x, int y)  
1461    {          public int getRowForLocation(int x, int y)
1462      TreeUI ui = getUI();          {
1463                    TreePath path = getPathForLocation(x, y);
1464      if (ui != null)  
1465        return ui.getClosestPathForLocation(this, x, y);                  if (path != null)
1466                                return getRowForPath(path);
1467      return null;  
1468    }                  return -1;
1469            }
1470    public int getClosestRowForLocation(int x, int y)  
1471    {          public TreePath getClosestPathForLocation(int x, int y)
1472      TreePath path = getClosestPathForLocation(x, y);          {
1473                    TreeUI ui = getUI();
1474      if (path != null)  
1475        return getRowForPath(path);                  if (ui != null)
1476                            return ui.getClosestPathForLocation(this, x, y);
1477      return -1;  
1478    }                  return null;
1479            }
1480    public Object getLastSelectedPathComponent()  
1481    {          public int getClosestRowForLocation(int x, int y)
1482      TreePath path = getSelectionPath();          {
1483                    TreePath path = getClosestPathForLocation(x, y);
1484      if (path != null)  
1485        return path.getLastPathComponent();                  if (path != null)
1486                            return getRowForPath(path);
1487      return null;  
1488    }                  return -1;
1489            }
1490    private void checkExpandParents(TreePath path)  
1491      throws ExpandVetoException          public Object getLastSelectedPathComponent()
1492    {          {
1493      TreePath parent = path.getParentPath();                  TreePath path = getSelectionPath();
1494    
1495      if (parent != null)                  if (path != null)
1496        checkExpandParents(parent);                          return path.getLastPathComponent();
1497    
1498      fireTreeWillExpand(path);                  return null;
1499    }          }
1500    
1501    private void doExpandParents(TreePath path, boolean state)          private void checkExpandParents(TreePath path) throws ExpandVetoException
1502    {          {
1503      TreePath parent = path.getParentPath();  
1504                    TreePath parent = path.getParentPath();
1505      if (isExpanded(parent))  
1506        return;                  if (parent != null)
1507                                checkExpandParents(parent);
1508      if (parent != null)  
1509        doExpandParents(parent, false);                  fireTreeWillExpand(path);
1510            }
1511      nodeStates.put(path, state ? EXPANDED : COLLAPSED);  
1512    }          private void doExpandParents(TreePath path, boolean state)
1513              {
1514    protected void setExpandedState(TreePath path, boolean state)                  TreePath parent = path.getParentPath();
1515    {  
1516      if (path == null)                  if (isExpanded(parent))
1517        return;                          return;
1518    
1519      TreePath parent = path.getParentPath();                  if (parent != null)
1520                            doExpandParents(parent, false);
1521      try  
1522        {                  nodeStates.put(path, state ? EXPANDED : COLLAPSED);
1523          while (parent != null)          }
1524            checkExpandParents(parent);  
1525        }          protected void setExpandedState(TreePath path, boolean state)
1526      catch (ExpandVetoException e)          {
1527        {                  if (path == null)
1528          // Expansion vetoed.                          return;
1529          return;  
1530        }                  TreePath parent = path.getParentPath();
1531    
1532      doExpandParents(path, state);                  try
1533    }                  {
1534                            while (parent != null)
1535    protected void clearToggledPaths()                                  checkExpandParents(parent);
1536    {                  } catch (ExpandVetoException e)
1537      nodeStates.clear();                  {
1538    }                          // Expansion vetoed.
1539                            return;
1540    protected Enumeration getDescendantToggledPaths(TreePath parent)                  }
1541    {  
1542      if (parent == null)                  doExpandParents(path, state);
1543        return null;          }
1544    
1545      Enumeration nodes = nodeStates.keys();          protected void clearToggledPaths()
1546      Vector result = new Vector();          {
1547                    nodeStates.clear();
1548      while (nodes.hasMoreElements())          }
1549        {  
1550          TreePath path = (TreePath) nodes.nextElement();          protected Enumeration getDescendantToggledPaths(TreePath parent)
1551            {
1552          if (path.isDescendant(parent))                  if (parent == null)
1553            result.addElement(path);                          return null;
1554        }  
1555                        Enumeration nodes = nodeStates.keys();
1556      return result.elements();                  Vector result = new Vector();
1557    }  
1558                    while (nodes.hasMoreElements())
1559    public boolean hasBeenExpanded(TreePath path)                  {
1560    {                          TreePath path = (TreePath) nodes.nextElement();
1561      if (path == null)  
1562        return false;                          if (path.isDescendant(parent))
1563                                    result.addElement(path);
1564      return nodeStates.get(path) != null;                  }
1565    }  
1566                    return result.elements();
1567    public boolean isVisible(TreePath path)          }
1568    {  
1569      if (path == null)          public boolean hasBeenExpanded(TreePath path)
1570        return false;          {
1571                    if (path == null)
1572      TreePath parent = path.getParentPath();                          return false;
1573    
1574      if (parent == null)                  return nodeStates.get(path) != null;
1575        return true; // Is root node.          }
1576    
1577      return isExpanded(parent);          public boolean isVisible(TreePath path)
1578    }          {
1579                    if (path == null)
1580    public void makeVisible(TreePath path)                          return false;
1581    {  
1582      if (path == null)                  TreePath parent = path.getParentPath();
1583        return;  
1584                    if (parent == null)
1585      expandPath(path.getParentPath());                          return true; // Is root node.
1586    }  
1587                    return isExpanded(parent);
1588    public boolean isPathEditable(TreePath path)          }
1589    {      
1590      return isEditable();          public void makeVisible(TreePath path)
1591    }          {
1592                    if (path == null)
1593    /**                          return;
1594     * Creates and returns an instance of {@link TreeModelHandler}.  
1595     *                  expandPath(path.getParentPath());
1596     * @returns an instance of {@link TreeModelHandler}          }
1597     */  
1598    protected TreeModelListener createTreeModelListener()          public boolean isPathEditable(TreePath path)
1599    {          {
1600      return new TreeModelHandler();                  return isEditable();
1601    }          }
1602    
1603    /**          /**
1604     * Returns a sample TreeModel that can be used in a JTree. This can           * Creates and returns an instance of {@link TreeModelHandler}.
1605     * be used in Bean- or GUI-Builders to show something interesting.           *
1606     *           * @returns an instance of {@link TreeModelHandler}
1607     * @return a sample TreeModel that can be used in a JTree           */
1608     */          protected TreeModelListener createTreeModelListener()
1609    protected static TreeModel getDefaultTreeModel()          {
1610    {                  return new TreeModelHandler();
1611      DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root node");          }
1612      DefaultMutableTreeNode child1 = new DefaultMutableTreeNode("Child node 1");  
1613      DefaultMutableTreeNode child11 =          /**
1614        new DefaultMutableTreeNode("Child node 1.1");           * Returns a sample TreeModel that can be used in a JTree. This can be used
1615      DefaultMutableTreeNode child12 =           * in Bean- or GUI-Builders to show something interesting.
1616        new DefaultMutableTreeNode("Child node 1.2");           *
1617      DefaultMutableTreeNode child13 =           * @return a sample TreeModel that can be used in a JTree
1618        new DefaultMutableTreeNode("Child node 1.3");           */
1619      DefaultMutableTreeNode child2 = new DefaultMutableTreeNode("Child node 2");          protected static TreeModel getDefaultTreeModel()
1620      DefaultMutableTreeNode child21 =          {
1621        new DefaultMutableTreeNode("Child node 2.1");                  DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root node");
1622      DefaultMutableTreeNode child22 =                  DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(
1623        new DefaultMutableTreeNode("Child node 2.2");                                  "Child node 1");
1624      DefaultMutableTreeNode child23 =                  DefaultMutableTreeNode child11 = new DefaultMutableTreeNode(
1625        new DefaultMutableTreeNode("Child node 2.3");                                  "Child node 1.1");
1626      DefaultMutableTreeNode child24 =                  DefaultMutableTreeNode child12 = new DefaultMutableTreeNode(
1627        new DefaultMutableTreeNode("Child node 2.4");                                  "Child node 1.2");
1628                    DefaultMutableTreeNode child13 = new DefaultMutableTreeNode(
1629      DefaultMutableTreeNode child3 = new DefaultMutableTreeNode("Child node 3");                                  "Child node 1.3");
1630      root.add(child1);                  DefaultMutableTreeNode child2 = new DefaultMutableTreeNode(
1631      root.add(child2);                                  "Child node 2");
1632      root.add(child3);                  DefaultMutableTreeNode child21 = new DefaultMutableTreeNode(
1633      child1.add(child11);                                  "Child node 2.1");
1634      child1.add(child12);                  DefaultMutableTreeNode child22 = new DefaultMutableTreeNode(
1635      child1.add(child13);                                  "Child node 2.2");
1636      child2.add(child21);                  DefaultMutableTreeNode child23 = new DefaultMutableTreeNode(
1637      child2.add(child22);                                  "Child node 2.3");
1638      child2.add(child23);                  DefaultMutableTreeNode child24 = new DefaultMutableTreeNode(
1639      child2.add(child24);                                  "Child node 2.4");
1640      return new DefaultTreeModel(root);  
1641    }                  DefaultMutableTreeNode child3 = new DefaultMutableTreeNode(
1642                                    "Child node 3");
1643    /**                  root.add(child1);
1644     * Converts the specified value to a String. This is used by the                  root.add(child2);
1645     * renderers of this JTree and its nodes.                  root.add(child3);
1646     *                  child1.add(child11);
1647     * This implementation simply returns <code>value.toString()</code> and                  child1.add(child12);
1648     * ignores all other parameters.                  child1.add(child13);
1649     * Subclass this method to control the conversion.                  child2.add(child21);
1650     *                  child2.add(child22);
1651     * @param value the value that is converted to a String                  child2.add(child23);
1652     * @param selected indicates if that value is selected or not                  child2.add(child24);
1653     * @param expanded indicates if that value is expanded or not                  return new DefaultTreeModel(root);
1654     * @param leaf indicates if that value is a leaf node or not          }
1655     * @param row the row of the node  
1656     * @param hasFocus indicates if that node has focus or not          /**
1657     */           * Converts the specified value to a String. This is used by the renderers
1658    public String convertValueToText(Object value, boolean selected,           * of this JTree and its nodes.
1659                                     boolean expanded, boolean leaf, int row,           *
1660                                     boolean hasFocus)           * This implementation simply returns <code>value.toString()</code> and
1661    {           * ignores all other parameters. Subclass this method to control the
1662      return value.toString();           * conversion.
1663    }           *
1664             * @param value the value that is converted to a String
1665    /**           * @param selected indicates if that value is selected or not
1666     * A String representation of this JTree. This is intended to be used           * @param expanded indicates if that value is expanded or not
1667     * for debugging. The returned string may be empty but may not be           * @param leaf indicates if that value is a leaf node or not
1668     * <code>null</code>.           * @param row the row of the node
1669     *           * @param hasFocus indicates if that node has focus or not
1670     * @return a String representation of this JTree           */
1671     */          public String convertValueToText(Object value, boolean selected,
1672    public String paramString()                          boolean expanded, boolean leaf, int row, boolean hasFocus)
1673    {          {
1674      // TODO: this is completely legal, but it would possibly be nice                  return value.toString();
1675      // to return some more content, like the tree structure, some properties          }
1676      // etc ...  
1677      return "";          /**
1678    }           * A String representation of this JTree. This is intended to be used for
1679             * debugging. The returned string may be empty but may not be
1680    /**           * <code>null</code>.
1681     * Returns all TreePath objects which are a descendants of           *
1682     * the given path and are exapanded at the moment of the           * @return a String representation of this JTree
1683     * execution of this method. If the state of any node           */
1684     * is beeing toggled while this method is executing this          public String paramString()
1685     * change may be left unaccounted.          {
1686     *                    // TODO: this is completely legal, but it would possibly be nice
1687     * @param path The parent of this request                  // to return some more content, like the tree structure, some properties
1688     * @return An Enumeration containing TreePath objects                  // etc ...
1689     */                  return "";
1690    public Enumeration getExpandedDescendants(TreePath path)          }
1691    {  
1692      Enumeration paths = nodeStates.keys();          /**
1693      Vector relevantPaths = new Vector();           * Returns all TreePath objects which are a descendants of the given path
1694      while(paths.hasMoreElements())           * and are exapanded at the moment of the execution of this method. If the
1695        {           * state of any node is beeing toggled while this method is executing this
1696          TreePath nextPath = (TreePath) paths.nextElement();           * change may be left unaccounted.
1697          if(nodeStates.get(nextPath) == EXPANDED &&           *
1698             path.isDescendant(nextPath))           * @param path The parent of this request
1699            {           * @return An Enumeration containing TreePath objects
1700              relevantPaths.add(nextPath);           */
1701            }          public Enumeration getExpandedDescendants(TreePath path)
1702        }          {
1703      return relevantPaths.elements();                  Enumeration paths = nodeStates.keys();
1704    }                  Vector relevantPaths = new Vector();
1705                    while (paths.hasMoreElements())
1706    /**                  {
1707     * Returns the next table element (beginning from the row                          TreePath nextPath = (TreePath) paths.nextElement();
1708     * <code>startingRow</code>                          if (nodeStates.get(nextPath) == EXPANDED
1709     * that starts with <code>prefix</code>. Searching is done in the direction                                          && path.isDescendant(nextPath))
1710     * specified by <code>bias</code>.                          {
1711     *                                  relevantPaths.add(nextPath);
1712     * @param prefix the prefix to search for in the cell values                          }
1713     * @param startingRow the index of the row where to start searching from                  }
1714     * @param bias the search direction, either {@link Position.Bias.Forward}                  return relevantPaths.elements();
1715     *     or {@link Position.Bias.Backward}          }
1716     *  
1717     * @return the path to the found element or -1 if no such element has          /**
1718     *     been found           * Returns the next table element (beginning from the row
1719     *           * <code>startingRow</code> that starts with <code>prefix</code>.
1720     * @throws IllegalArgumentException if prefix is <code>null</code> or           * Searching is done in the direction specified by <code>bias</code>.
1721     *     startingRow is not valid           *
1722     *           * @param prefix the prefix to search for in the cell values
1723     * @since 1.4           * @param startingRow the index of the row where to start searching from
1724     */           * @param bias the search direction, either {@link Position.Bias.Forward} or
1725    public TreePath getNextMatch(String prefix, int startingRow,           *        {@link Position.Bias.Backward}
1726                                 Position.Bias bias)           *
1727    {           * @return the path to the found element or -1 if no such element has been
1728      if (prefix == null)           *         found
1729        throw new IllegalArgumentException("The argument 'prefix' must not be"           *
1730                                           + " null.");           * @throws IllegalArgumentException if prefix is <code>null</code> or
1731      if (startingRow < 0)           *         startingRow is not valid
1732        throw new IllegalArgumentException("The argument 'startingRow' must not"           *
1733                                           + " be less than zero.");           * @since 1.4
1734             */
1735      int size = getRowCount();          public TreePath getNextMatch(String prefix, int startingRow,
1736      if (startingRow > size)                          Position.Bias bias)
1737        throw new IllegalArgumentException("The argument 'startingRow' must not"          {
1738                                           + " be greater than the number of"                  if (prefix == null)
1739                                           + " elements in the TreeModel.");                          throw new IllegalArgumentException(
1740                                            "The argument 'prefix' must not be" + " null.");
1741      TreePath foundPath = null;                  if (startingRow < 0)
1742      if (bias == Position.Bias.Forward)                          throw new IllegalArgumentException(
1743        {                                          "The argument 'startingRow' must not"
1744          for (int i = startingRow; i < size; i++)                                                          + " be less than zero.");
1745            {  
1746              TreePath path = getPathForRow(i);                  int size = getRowCount();
1747              Object o = path.getLastPathComponent();                  if (startingRow > size)
1748              // FIXME: in the following call to convertValueToText the                          throw new IllegalArgumentException(
1749              // last argument (hasFocus) should be done right.                                          "The argument 'startingRow' must not"
1750              String item = convertValueToText(o, isRowSelected(i),                                                          + " be greater than the number of"
1751                                               isExpanded(i),                                                          + " elements in the TreeModel.");
1752                                               treeModel.isLeaf(o), i, false);  
1753              if (item.startsWith(prefix))                  TreePath foundPath = null;
1754                {                  if (bias == Position.Bias.Forward)
1755                  foundPath = path;                  {
1756                  break;                          for (int i = startingRow; i < size; i++)
1757                }                          {
1758            }                                  TreePath path = getPathForRow(i);
1759        }                                  Object o = path.getLastPathComponent();
1760      else                                  // FIXME: in the following call to convertValueToText the
1761        {                                  // last argument (hasFocus) should be done right.
1762          for (int i = startingRow; i >= 0; i--)                                  String item = convertValueToText(o, isRowSelected(i),
1763            {                                                  isExpanded(i), treeModel.isLeaf(o), i, false);
1764              TreePath path = getPathForRow(i);                                  if (item.startsWith(prefix))
1765              Object o = path.getLastPathComponent();                                  {
1766              // FIXME: in the following call to convertValueToText the                                          foundPath = path;
1767              // last argument (hasFocus) should be done right.                                          break;
1768              String item = convertValueToText(o, isRowSelected(i),                                  }
1769                                               isExpanded(i),                          }
1770                                               treeModel.isLeaf(o), i, false);                  } else
1771              if (item.startsWith(prefix))                  {
1772                {                          for (int i = startingRow; i >= 0; i--)
1773                  foundPath = path;                          {
1774                  break;                                  TreePath path = getPathForRow(i);
1775                }                                  Object o = path.getLastPathComponent();
1776            }                                  // FIXME: in the following call to convertValueToText the
1777        }                                  // last argument (hasFocus) should be done right.
1778      return foundPath;                                  String item = convertValueToText(o, isRowSelected(i),
1779    }                                                  isExpanded(i), treeModel.isLeaf(o), i, false);
1780                                    if (item.startsWith(prefix))
1781    /**                                  {
1782     * Removes any paths in the current set of selected paths that are                                          foundPath = path;
1783     * descendants of <code>path</code>. If <code>includePath</code> is                                          break;
1784     * set to <code>true</code> and <code>path</code> itself is selected,                                  }
1785     * then it will be removed too.                          }
1786     *                  }
1787     * @param path the path from which selected descendants are to be                  return foundPath;
1788     *     removed          }
1789     * @param includePath if <code>true</code> then <code>path</code>  
1790     *     itself will also be remove if it's selected          /**
1791     *           * Removes any paths in the current set of selected paths that are
1792     * @return <code>true</code> if something has been removed,           * descendants of <code>path</code>. If <code>includePath</code> is set
1793     *     <code>false</code> otherwise           * to <code>true</code> and <code>path</code> itself is selected, then
1794     *           * it will be removed too.
1795     * @since 1.3           *
1796     */           * @param path the path from which selected descendants are to be removed
1797    protected boolean removeDescendantSelectedPaths(TreePath path,           * @param includePath if <code>true</code> then <code>path</code> itself
1798                                                      boolean includeSelected)           *        will also be remove if it's selected
1799    {           *
1800      boolean removedSomething = false;           * @return <code>true</code> if something has been removed,
1801      TreePath[] selected = getSelectionPaths();           *         <code>false</code> otherwise
1802      for (int index = 0; index < selected.length; index++)           *
1803        {           * @since 1.3
1804          if ((selected[index] == path && includeSelected)           */
1805              || (selected[index].isDescendant(path)))          protected boolean removeDescendantSelectedPaths(TreePath path,
1806            {                          boolean includeSelected)
1807              removeSelectionPath(selected[index]);          {
1808              removedSomething = true;                  boolean removedSomething = false;
1809            }                  TreePath[] selected = getSelectionPaths();
1810        }                  for (int index = 0; index < selected.length; index++)
1811      return removedSomething;                  {
1812    }                          if ((selected[index] == path && includeSelected)
1813                                            || (selected[index].isDescendant(path)))
1814                            {
1815                                    removeSelectionPath(selected[index]);
1816                                    removedSomething = true;
1817                            }
1818                    }
1819                    return removedSomething;
1820            }
1821  }  }

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26