< prev index next >

src/java.desktop/share/classes/javax/swing/tree/DefaultTreeModel.java

Print this page




  25 
  26 package javax.swing.tree;
  27 
  28 import java.util.*;
  29 import java.beans.ConstructorProperties;
  30 import java.io.*;
  31 import javax.swing.event.*;
  32 
  33 /**
  34  * A simple tree data model that uses TreeNodes.
  35  * For further information and examples that use DefaultTreeModel,
  36  * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
  37  * in <em>The Java Tutorial.</em>
  38  * <p>
  39  * <strong>Warning:</strong>
  40  * Serialized objects of this class will not be compatible with
  41  * future Swing releases. The current serialization support is
  42  * appropriate for short term storage or RMI between applications running
  43  * the same version of Swing.  As of 1.4, support for long term storage
  44  * of all JavaBeans&trade;
  45  * has been added to the <code>java.beans</code> package.
  46  * Please see {@link java.beans.XMLEncoder}.
  47  *
  48  * @author Rob Davis
  49  * @author Ray Ryan
  50  * @author Scott Violet
  51  */
  52 @SuppressWarnings("serial") // Same-version serialization only
  53 public class DefaultTreeModel implements Serializable, TreeModel {
  54     /** Root of the tree. */
  55     protected TreeNode root;
  56     /** Listeners. */
  57     protected EventListenerList listenerList = new EventListenerList();
  58     /**
  59       * Determines how the <code>isLeaf</code> method figures
  60       * out if a node is a leaf node. If true, a node is a leaf
  61       * node if it does not allow children. (If it allows
  62       * children, it is not a leaf node, even if no children
  63       * are present.) That lets you distinguish between <i>folder</i>
  64       * nodes and <i>file</i> nodes in a file system, for example.
  65       * <p>
  66       * If this value is false, then any node which has no
  67       * children is a leaf node, and any node may acquire
  68       * children.
  69       *
  70       * @see TreeNode#getAllowsChildren
  71       * @see TreeModel#isLeaf
  72       * @see #setAsksAllowsChildren
  73       */
  74     protected boolean asksAllowsChildren;
  75 
  76 
  77     /**
  78       * Creates a tree in which any node can have children.
  79       *


 109       * @param newValue if true, getAllowsChildren() is messaged, otherwise
 110       *                 isLeaf() is messaged
 111       */
 112     public void setAsksAllowsChildren(boolean newValue) {
 113         asksAllowsChildren = newValue;
 114     }
 115 
 116     /**
 117       * Tells how leaf nodes are determined.
 118       *
 119       * @return true if only nodes which do not allow children are
 120       *         leaf nodes, false if nodes which have no children
 121       *         (even if allowed) are leaf nodes
 122       * @see #asksAllowsChildren
 123       */
 124     public boolean asksAllowsChildren() {
 125         return asksAllowsChildren;
 126     }
 127 
 128     /**
 129      * Sets the root to <code>root</code>. A null <code>root</code> implies
 130      * the tree is to display nothing, and is legal.
 131      *
 132      * @param root new value of tree root
 133      */
 134     public void setRoot(TreeNode root) {
 135         Object oldRoot = this.root;
 136         this.root = root;
 137         if (root == null && oldRoot != null) {
 138             fireTreeStructureChanged(this, null);
 139         }
 140         else {
 141             nodeStructureChanged(root);
 142         }
 143     }
 144 
 145     /**
 146      * Returns the root of the tree.  Returns null only if the tree has
 147      * no nodes.
 148      *
 149      * @return  the root of the tree
 150      */
 151     public Object getRoot() {
 152         return root;
 153     }
 154 
 155     /**
 156      * Returns the index of child in parent.
 157      * If either the parent or child is <code>null</code>, returns -1.
 158      * @param parent a note in the tree, obtained from this data source
 159      * @param child the node we are interested in
 160      * @return the index of the child in the parent, or -1
 161      *    if either the parent or the child is <code>null</code>
 162      */
 163     public int getIndexOfChild(Object parent, Object child) {
 164         if(parent == null || child == null)
 165             return -1;
 166         return ((TreeNode)parent).getIndex((TreeNode)child);
 167     }
 168 
 169     /**
 170      * Returns the child of <I>parent</I> at index <I>index</I> in the parent's
 171      * child array.  <I>parent</I> must be a node previously obtained from
 172      * this data source. This should not return null if <i>index</i>
 173      * is a valid index for <i>parent</i> (that is <i>index</i> &gt;= 0 &amp;&amp;
 174      * <i>index</i> &lt; getChildCount(<i>parent</i>)).
 175      *
 176      * @param   parent  a node in the tree, obtained from this data source
 177      * @return  the child of <I>parent</I> at index <I>index</I>
 178      */
 179     public Object getChild(Object parent, int index) {
 180         return ((TreeNode)parent).getChildAt(index);
 181     }
 182 
 183     /**
 184      * Returns the number of children of <I>parent</I>.  Returns 0 if the node
 185      * is a leaf or if it has no children.  <I>parent</I> must be a node
 186      * previously obtained from this data source.
 187      *
 188      * @param   parent  a node in the tree, obtained from this data source
 189      * @return  the number of children of the node <I>parent</I>
 190      */
 191     public int getChildCount(Object parent) {
 192         return ((TreeNode)parent).getChildCount();
 193     }
 194 
 195     /**
 196      * Returns whether the specified node is a leaf node.
 197      * The way the test is performed depends on the
 198      * <code>askAllowsChildren</code> setting.
 199      *
 200      * @param node the node to check
 201      * @return true if the node is a leaf node
 202      *
 203      * @see #asksAllowsChildren
 204      * @see TreeModel#isLeaf
 205      */
 206     public boolean isLeaf(Object node) {
 207         if(asksAllowsChildren)
 208             return !((TreeNode)node).getAllowsChildren();
 209         return ((TreeNode)node).isLeaf();
 210     }
 211 
 212     /**
 213      * Invoke this method if you've modified the {@code TreeNode}s upon which
 214      * this model depends. The model will notify all of its listeners that the
 215      * model has changed.
 216      */
 217     public void reload() {
 218         reload(root);


 453      * @param   l       the listener to add
 454      */
 455     public void addTreeModelListener(TreeModelListener l) {
 456         listenerList.add(TreeModelListener.class, l);
 457     }
 458 
 459     /**
 460      * Removes a listener previously added with <B>addTreeModelListener()</B>.
 461      *
 462      * @see     #addTreeModelListener
 463      * @param   l       the listener to remove
 464      */
 465     public void removeTreeModelListener(TreeModelListener l) {
 466         listenerList.remove(TreeModelListener.class, l);
 467     }
 468 
 469     /**
 470      * Returns an array of all the tree model listeners
 471      * registered on this model.
 472      *
 473      * @return all of this model's <code>TreeModelListener</code>s
 474      *         or an empty
 475      *         array if no tree model listeners are currently registered
 476      *
 477      * @see #addTreeModelListener
 478      * @see #removeTreeModelListener
 479      *
 480      * @since 1.4
 481      */
 482     public TreeModelListener[] getTreeModelListeners() {
 483         return listenerList.getListeners(TreeModelListener.class);
 484     }
 485 
 486     /**
 487      * Notifies all listeners that have registered interest for
 488      * notification on this event type.  The event instance
 489      * is lazily created using the parameters passed into
 490      * the fire method.
 491      *
 492      * @param source the source of the {@code TreeModelEvent};
 493      *               typically {@code this}


 628         // those that are interested in this event
 629         for (int i = listeners.length-2; i>=0; i-=2) {
 630             if (listeners[i]==TreeModelListener.class) {
 631                 // Lazily create the event:
 632                 if (e == null)
 633                     e = new TreeModelEvent(source, path);
 634                 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
 635             }
 636         }
 637     }
 638 
 639     /**
 640      * Returns an array of all the objects currently registered
 641      * as <code><em>Foo</em>Listener</code>s
 642      * upon this model.
 643      * <code><em>Foo</em>Listener</code>s are registered using the
 644      * <code>add<em>Foo</em>Listener</code> method.
 645      *
 646      * <p>
 647      *
 648      * You can specify the <code>listenerType</code> argument
 649      * with a class literal,
 650      * such as
 651      * <code><em>Foo</em>Listener.class</code>.
 652      * For example, you can query a
 653      * <code>DefaultTreeModel</code> <code>m</code>
 654      * for its tree model listeners with the following code:
 655      *
 656      * <pre>TreeModelListener[] tmls = (TreeModelListener[])(m.getListeners(TreeModelListener.class));</pre>
 657      *
 658      * If no such listeners exist, this method returns an empty array.
 659      *
 660      * @param <T> the listener type
 661      * @param listenerType the type of listeners requested
 662      * @return an array of all objects registered as
 663      *          <code><em>Foo</em>Listener</code>s on this component,
 664      *          or an empty array if no such
 665      *          listeners have been added
 666      * @exception ClassCastException if <code>listenerType</code>
 667      *          doesn't specify a class or interface that implements
 668      *          <code>java.util.EventListener</code>
 669      *
 670      * @see #getTreeModelListeners
 671      *
 672      * @since 1.3
 673      */
 674     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
 675         return listenerList.getListeners(listenerType);
 676     }
 677 
 678     // Serialization support.
 679     private void writeObject(ObjectOutputStream s) throws IOException {
 680         Vector<Object> values = new Vector<Object>();
 681 
 682         s.defaultWriteObject();
 683         // Save the root, if its Serializable.
 684         if(root != null && root instanceof Serializable) {
 685             values.addElement("root");
 686             values.addElement(root);
 687         }
 688         s.writeObject(values);




  25 
  26 package javax.swing.tree;
  27 
  28 import java.util.*;
  29 import java.beans.ConstructorProperties;
  30 import java.io.*;
  31 import javax.swing.event.*;
  32 
  33 /**
  34  * A simple tree data model that uses TreeNodes.
  35  * For further information and examples that use DefaultTreeModel,
  36  * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
  37  * in <em>The Java Tutorial.</em>
  38  * <p>
  39  * <strong>Warning:</strong>
  40  * Serialized objects of this class will not be compatible with
  41  * future Swing releases. The current serialization support is
  42  * appropriate for short term storage or RMI between applications running
  43  * the same version of Swing.  As of 1.4, support for long term storage
  44  * of all JavaBeans&trade;
  45  * has been added to the {@code java.beans} package.
  46  * Please see {@link java.beans.XMLEncoder}.
  47  *
  48  * @author Rob Davis
  49  * @author Ray Ryan
  50  * @author Scott Violet
  51  */
  52 @SuppressWarnings("serial") // Same-version serialization only
  53 public class DefaultTreeModel implements Serializable, TreeModel {
  54     /** Root of the tree. */
  55     protected TreeNode root;
  56     /** Listeners. */
  57     protected EventListenerList listenerList = new EventListenerList();
  58     /**
  59       * Determines how the {@code isLeaf} method figures
  60       * out if a node is a leaf node. If true, a node is a leaf
  61       * node if it does not allow children. (If it allows
  62       * children, it is not a leaf node, even if no children
  63       * are present.) That lets you distinguish between <i>folder</i>
  64       * nodes and <i>file</i> nodes in a file system, for example.
  65       * <p>
  66       * If this value is false, then any node which has no
  67       * children is a leaf node, and any node may acquire
  68       * children.
  69       *
  70       * @see TreeNode#getAllowsChildren
  71       * @see TreeModel#isLeaf
  72       * @see #setAsksAllowsChildren
  73       */
  74     protected boolean asksAllowsChildren;
  75 
  76 
  77     /**
  78       * Creates a tree in which any node can have children.
  79       *


 109       * @param newValue if true, getAllowsChildren() is messaged, otherwise
 110       *                 isLeaf() is messaged
 111       */
 112     public void setAsksAllowsChildren(boolean newValue) {
 113         asksAllowsChildren = newValue;
 114     }
 115 
 116     /**
 117       * Tells how leaf nodes are determined.
 118       *
 119       * @return true if only nodes which do not allow children are
 120       *         leaf nodes, false if nodes which have no children
 121       *         (even if allowed) are leaf nodes
 122       * @see #asksAllowsChildren
 123       */
 124     public boolean asksAllowsChildren() {
 125         return asksAllowsChildren;
 126     }
 127 
 128     /**
 129      * Sets the root to {@code root}. A null {@code root} implies
 130      * the tree is to display nothing, and is legal.
 131      *
 132      * @param root new value of tree root
 133      */
 134     public void setRoot(TreeNode root) {
 135         Object oldRoot = this.root;
 136         this.root = root;
 137         if (root == null && oldRoot != null) {
 138             fireTreeStructureChanged(this, null);
 139         }
 140         else {
 141             nodeStructureChanged(root);
 142         }
 143     }
 144 
 145     /**
 146      * Returns the root of the tree.  Returns null only if the tree has
 147      * no nodes.
 148      *
 149      * @return  the root of the tree
 150      */
 151     public Object getRoot() {
 152         return root;
 153     }
 154 
 155     /**
 156      * Returns the index of child in parent.
 157      * If either the parent or child is {@code null}, returns -1.
 158      * @param parent a note in the tree, obtained from this data source
 159      * @param child the node we are interested in
 160      * @return the index of the child in the parent, or -1
 161      *    if either the parent or the child is {@code null}
 162      */
 163     public int getIndexOfChild(Object parent, Object child) {
 164         if(parent == null || child == null)
 165             return -1;
 166         return ((TreeNode)parent).getIndex((TreeNode)child);
 167     }
 168 
 169     /**
 170      * Returns the child of <I>parent</I> at index <I>index</I> in the parent's
 171      * child array.  <I>parent</I> must be a node previously obtained from
 172      * this data source. This should not return null if <i>index</i>
 173      * is a valid index for <i>parent</i> (that is <i>index</i> &gt;= 0 &amp;&amp;
 174      * <i>index</i> &lt; getChildCount(<i>parent</i>)).
 175      *
 176      * @param   parent  a node in the tree, obtained from this data source
 177      * @return  the child of <I>parent</I> at index <I>index</I>
 178      */
 179     public Object getChild(Object parent, int index) {
 180         return ((TreeNode)parent).getChildAt(index);
 181     }
 182 
 183     /**
 184      * Returns the number of children of <I>parent</I>.  Returns 0 if the node
 185      * is a leaf or if it has no children.  <I>parent</I> must be a node
 186      * previously obtained from this data source.
 187      *
 188      * @param   parent  a node in the tree, obtained from this data source
 189      * @return  the number of children of the node <I>parent</I>
 190      */
 191     public int getChildCount(Object parent) {
 192         return ((TreeNode)parent).getChildCount();
 193     }
 194 
 195     /**
 196      * Returns whether the specified node is a leaf node.
 197      * The way the test is performed depends on the
 198      * {@code askAllowsChildren} setting.
 199      *
 200      * @param node the node to check
 201      * @return true if the node is a leaf node
 202      *
 203      * @see #asksAllowsChildren
 204      * @see TreeModel#isLeaf
 205      */
 206     public boolean isLeaf(Object node) {
 207         if(asksAllowsChildren)
 208             return !((TreeNode)node).getAllowsChildren();
 209         return ((TreeNode)node).isLeaf();
 210     }
 211 
 212     /**
 213      * Invoke this method if you've modified the {@code TreeNode}s upon which
 214      * this model depends. The model will notify all of its listeners that the
 215      * model has changed.
 216      */
 217     public void reload() {
 218         reload(root);


 453      * @param   l       the listener to add
 454      */
 455     public void addTreeModelListener(TreeModelListener l) {
 456         listenerList.add(TreeModelListener.class, l);
 457     }
 458 
 459     /**
 460      * Removes a listener previously added with <B>addTreeModelListener()</B>.
 461      *
 462      * @see     #addTreeModelListener
 463      * @param   l       the listener to remove
 464      */
 465     public void removeTreeModelListener(TreeModelListener l) {
 466         listenerList.remove(TreeModelListener.class, l);
 467     }
 468 
 469     /**
 470      * Returns an array of all the tree model listeners
 471      * registered on this model.
 472      *
 473      * @return all of this model's {@code TreeModelListener}s
 474      *         or an empty
 475      *         array if no tree model listeners are currently registered
 476      *
 477      * @see #addTreeModelListener
 478      * @see #removeTreeModelListener
 479      *
 480      * @since 1.4
 481      */
 482     public TreeModelListener[] getTreeModelListeners() {
 483         return listenerList.getListeners(TreeModelListener.class);
 484     }
 485 
 486     /**
 487      * Notifies all listeners that have registered interest for
 488      * notification on this event type.  The event instance
 489      * is lazily created using the parameters passed into
 490      * the fire method.
 491      *
 492      * @param source the source of the {@code TreeModelEvent};
 493      *               typically {@code this}


 628         // those that are interested in this event
 629         for (int i = listeners.length-2; i>=0; i-=2) {
 630             if (listeners[i]==TreeModelListener.class) {
 631                 // Lazily create the event:
 632                 if (e == null)
 633                     e = new TreeModelEvent(source, path);
 634                 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
 635             }
 636         }
 637     }
 638 
 639     /**
 640      * Returns an array of all the objects currently registered
 641      * as <code><em>Foo</em>Listener</code>s
 642      * upon this model.
 643      * <code><em>Foo</em>Listener</code>s are registered using the
 644      * <code>add<em>Foo</em>Listener</code> method.
 645      *
 646      * <p>
 647      *
 648      * You can specify the {@code listenerType} argument
 649      * with a class literal,
 650      * such as
 651      * <code><em>Foo</em>Listener.class</code>.
 652      * For example, you can query a
 653      * {@code DefaultTreeModel m}
 654      * for its tree model listeners with the following code:
 655      *
 656      * <pre>TreeModelListener[] tmls = (TreeModelListener[])(m.getListeners(TreeModelListener.class));</pre>
 657      *
 658      * If no such listeners exist, this method returns an empty array.
 659      *
 660      * @param <T> the listener type
 661      * @param listenerType the type of listeners requested
 662      * @return an array of all objects registered as
 663      *          <code><em>Foo</em>Listener</code>s on this component,
 664      *          or an empty array if no such
 665      *          listeners have been added
 666      * @exception ClassCastException if {@code listenerType}
 667      *          doesn't specify a class or interface that implements
 668      *          {@code java.util.EventListener}
 669      *
 670      * @see #getTreeModelListeners
 671      *
 672      * @since 1.3
 673      */
 674     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
 675         return listenerList.getListeners(listenerType);
 676     }
 677 
 678     // Serialization support.
 679     private void writeObject(ObjectOutputStream s) throws IOException {
 680         Vector<Object> values = new Vector<Object>();
 681 
 682         s.defaultWriteObject();
 683         // Save the root, if its Serializable.
 684         if(root != null && root instanceof Serializable) {
 685             values.addElement("root");
 686             values.addElement(root);
 687         }
 688         s.writeObject(values);


< prev index next >