Save This Page
Home » openjdk-7 » javax » swing » tree » [javadoc | source]
    1   /*
    2    * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.swing.tree;
   27   
   28   import java.io;
   29   import java.beans.ConstructorProperties;
   30   
   31   /**
   32    * {@code TreePath} represents an array of objects that uniquely
   33    * identify the path to a node in a tree. The elements of the array
   34    * are ordered with the root as the first element of the array. For
   35    * example, a file on the file system is uniquely identified based on
   36    * the array of parent directories and the name of the file. The path
   37    * {@code /tmp/foo/bar} could be represented by a {@code TreePath} as
   38    * {@code new TreePath(new Object[] {"tmp", "foo", "bar"})}.
   39    * <p>
   40    * {@code TreePath} is used extensively by {@code JTree} and related classes.
   41    * For example, {@code JTree} represents the selection as an array of
   42    * {@code TreePath}s. When used with {@code JTree}, the elements of the
   43    * path are the objects returned from the {@code TreeModel}. When {@code JTree}
   44    * is paired with {@code DefaultTreeModel}, the elements of the
   45    * path are {@code TreeNode}s. The following example illustrates extracting
   46    * the user object from the selection of a {@code JTree}:
   47    * <pre>
   48    *   DefaultMutableTreeNode root = ...;
   49    *   DefaultTreeModel model = new DefaultTreeModel(root);
   50    *   JTree tree = new JTree(model);
   51    *   ...
   52    *   TreePath selectedPath = tree.getSelectionPath();
   53    *   DefaultMutableTreeNode selectedNode =
   54    *       ((DefaultMutableTreeNode)selectedPath.getLastPathComponent()).
   55    *       getUserObject();
   56    * </pre>
   57    * Subclasses typically need override only {@code
   58    * getLastPathComponent}, and {@code getParentPath}. As {@code JTree}
   59    * internally creates {@code TreePath}s at various points, it's
   60    * generally not useful to subclass {@code TreePath} and use with
   61    * {@code JTree}.
   62    * <p>
   63    * While {@code TreePath} is serializable, a {@code
   64    * NotSerializableException} is thrown if any elements of the path are
   65    * not serializable.
   66    * <p>
   67    * For further information and examples of using tree paths,
   68    * see <a
   69    href="http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html">How to Use Trees</a>
   70    * in <em>The Java Tutorial.</em>
   71    * <p>
   72    * <strong>Warning:</strong>
   73    * Serialized objects of this class will not be compatible with
   74    * future Swing releases. The current serialization support is
   75    * appropriate for short term storage or RMI between applications running
   76    * the same version of Swing.  As of 1.4, support for long term storage
   77    * of all JavaBeans<sup><font size="-2">TM</font></sup>
   78    * has been added to the <code>java.beans</code> package.
   79    * Please see {@link java.beans.XMLEncoder}.
   80    *
   81    * @author Scott Violet
   82    * @author Philip Milne
   83    */
   84   public class TreePath extends Object implements Serializable {
   85       /** Path representing the parent, null if lastPathComponent represents
   86        * the root. */
   87       private TreePath           parentPath;
   88       /** Last path component. */
   89       private Object lastPathComponent;
   90   
   91       /**
   92        * Creates a {@code TreePath} from an array. The array uniquely
   93        * identifies the path to a node.
   94        *
   95        * @param path an array of objects representing the path to a node
   96        * @throws IllegalArgumentException if {@code path} is {@code null},
   97        *         empty, or contains a {@code null} value
   98        */
   99       @ConstructorProperties({"path"})
  100       public TreePath(Object[] path) {
  101           if(path == null || path.length == 0)
  102               throw new IllegalArgumentException("path in TreePath must be non null and not empty.");
  103           lastPathComponent = path[path.length - 1];
  104           if (lastPathComponent == null) {
  105               throw new IllegalArgumentException(
  106                   "Last path component must be non-null");
  107           }
  108           if(path.length > 1)
  109               parentPath = new TreePath(path, path.length - 1);
  110       }
  111   
  112       /**
  113        * Creates a {@code TreePath} containing a single element. This is
  114        * used to construct a {@code TreePath} identifying the root.
  115        *
  116        * @param lastPathComponent the root
  117        * @see #TreePath(Object[])
  118        * @throws IllegalArgumentException if {@code lastPathComponent} is
  119        *         {@code null}
  120        */
  121       public TreePath(Object lastPathComponent) {
  122           if(lastPathComponent == null)
  123               throw new IllegalArgumentException("path in TreePath must be non null.");
  124           this.lastPathComponent = lastPathComponent;
  125           parentPath = null;
  126       }
  127   
  128       /**
  129        * Creates a {@code TreePath} with the specified parent and element.
  130        *
  131        * @param parent the path to the parent, or {@code null} to indicate
  132        *        the root
  133        * @param lastPathComponent the last path element
  134        * @throws IllegalArgumentException if {@code lastPathComponent} is
  135        *         {@code null}
  136        */
  137       protected TreePath(TreePath parent, Object lastPathComponent) {
  138           if(lastPathComponent == null)
  139               throw new IllegalArgumentException("path in TreePath must be non null.");
  140           parentPath = parent;
  141           this.lastPathComponent = lastPathComponent;
  142       }
  143   
  144       /**
  145        * Creates a {@code TreePath} from an array. The returned
  146        * {@code TreePath} represents the elements of the array from
  147        * {@code 0} to {@code length - 1}.
  148        * <p>
  149        * This constructor is used internally, and generally not useful outside
  150        * of subclasses.
  151        *
  152        * @param path the array to create the {@code TreePath} from
  153        * @param length identifies the number of elements in {@code path} to
  154        *        create the {@code TreePath} from
  155        * @throws NullPointerException if {@code path} is {@code null}
  156        * @throws ArrayIndexOutOfBoundsException if {@code length - 1} is
  157        *         outside the range of the array
  158        * @throws IllegalArgumentException if any of the elements from
  159        *         {@code 0} to {@code length - 1} are {@code null}
  160        */
  161       protected TreePath(Object[] path, int length) {
  162           lastPathComponent = path[length - 1];
  163           if (lastPathComponent == null) {
  164               throw new IllegalArgumentException(
  165                   "Path elements must be non-null");
  166           }
  167           if(length > 1)
  168               parentPath = new TreePath(path, length - 1);
  169       }
  170   
  171       /**
  172        * Creates an empty {@code TreePath}.  This is provided for
  173        * subclasses that represent paths in a different
  174        * manner. Subclasses that use this constructor must override
  175        * {@code getLastPathComponent}, and {@code getParentPath}.
  176        */
  177       protected TreePath() {
  178       }
  179   
  180       /**
  181        * Returns an ordered array of the elements of this {@code TreePath}.
  182        * The first element is the root.
  183        *
  184        * @return an array of the elements in this {@code TreePath}
  185        */
  186       public Object[] getPath() {
  187           int            i = getPathCount();
  188           Object[]       result = new Object[i--];
  189   
  190           for(TreePath path = this; path != null; path = path.getParentPath()) {
  191               result[i--] = path.getLastPathComponent();
  192           }
  193           return result;
  194       }
  195   
  196       /**
  197        * Returns the last element of this path.
  198        *
  199        * @return the last element in the path
  200        */
  201       public Object getLastPathComponent() {
  202           return lastPathComponent;
  203       }
  204   
  205       /**
  206        * Returns the number of elements in the path.
  207        *
  208        * @return the number of elements in the path
  209        */
  210       public int getPathCount() {
  211           int        result = 0;
  212           for(TreePath path = this; path != null; path = path.getParentPath()) {
  213               result++;
  214           }
  215           return result;
  216       }
  217   
  218       /**
  219        * Returns the path element at the specified index.
  220        *
  221        * @param index the index of the element requested
  222        * @return the element at the specified index
  223        * @throws IllegalArgumentException if the index is outside the
  224        *         range of this path
  225        */
  226       public Object getPathComponent(int index) {
  227           int          pathLength = getPathCount();
  228   
  229           if(index < 0 || index >= pathLength)
  230               throw new IllegalArgumentException("Index " + index +
  231                                              " is out of the specified range");
  232   
  233           TreePath         path = this;
  234   
  235           for(int i = pathLength-1; i != index; i--) {
  236               path = path.getParentPath();
  237           }
  238           return path.getLastPathComponent();
  239       }
  240   
  241       /**
  242        * Compares this {@code TreePath} to the specified object. This returns
  243        * {@code true} if {@code o} is a {@code TreePath} with the exact
  244        * same elements (as determined by using {@code equals} on each
  245        * element of the path).
  246        *
  247        * @param o the object to compare
  248        */
  249       public boolean equals(Object o) {
  250           if(o == this)
  251               return true;
  252           if(o instanceof TreePath) {
  253               TreePath            oTreePath = (TreePath)o;
  254   
  255               if(getPathCount() != oTreePath.getPathCount())
  256                   return false;
  257               for(TreePath path = this; path != null;
  258                       path = path.getParentPath()) {
  259                   if (!(path.getLastPathComponent().equals
  260                         (oTreePath.getLastPathComponent()))) {
  261                       return false;
  262                   }
  263                   oTreePath = oTreePath.getParentPath();
  264               }
  265               return true;
  266           }
  267           return false;
  268       }
  269   
  270       /**
  271        * Returns the hash code of this {@code TreePath}. The hash code of a
  272        * {@code TreePath} is the hash code of the last element in the path.
  273        *
  274        * @return the hashCode for the object
  275        */
  276       public int hashCode() {
  277           return getLastPathComponent().hashCode();
  278       }
  279   
  280       /**
  281        * Returns true if <code>aTreePath</code> is a
  282        * descendant of this
  283        * {@code TreePath}. A {@code TreePath} {@code P1} is a descendant of a
  284        * {@code TreePath} {@code P2}
  285        * if {@code P1} contains all of the elements that make up
  286        * {@code P2's} path.
  287        * For example, if this object has the path {@code [a, b]},
  288        * and <code>aTreePath</code> has the path {@code [a, b, c]},
  289        * then <code>aTreePath</code> is a descendant of this object.
  290        * However, if <code>aTreePath</code> has the path {@code [a]},
  291        * then it is not a descendant of this object.  By this definition
  292        * a {@code TreePath} is always considered a descendant of itself.
  293        * That is, <code>aTreePath.isDescendant(aTreePath)</code> returns
  294        * {@code true}.
  295        *
  296        * @param aTreePath the {@code TreePath} to check
  297        * @return true if <code>aTreePath</code> is a descendant of this path
  298        */
  299       public boolean isDescendant(TreePath aTreePath) {
  300           if(aTreePath == this)
  301               return true;
  302   
  303           if(aTreePath != null) {
  304               int                 pathLength = getPathCount();
  305               int                 oPathLength = aTreePath.getPathCount();
  306   
  307               if(oPathLength < pathLength)
  308                   // Can't be a descendant, has fewer components in the path.
  309                   return false;
  310               while(oPathLength-- > pathLength)
  311                   aTreePath = aTreePath.getParentPath();
  312               return equals(aTreePath);
  313           }
  314           return false;
  315       }
  316   
  317       /**
  318        * Returns a new path containing all the elements of this path
  319        * plus <code>child</code>. <code>child</code> is the last element
  320        * of the newly created {@code TreePath}.
  321        *
  322        * @param child the path element to add
  323        * @throws NullPointerException if {@code child} is {@code null}
  324        */
  325       public TreePath pathByAddingChild(Object child) {
  326           if(child == null)
  327               throw new NullPointerException("Null child not allowed");
  328   
  329           return new TreePath(this, child);
  330       }
  331   
  332       /**
  333        * Returns the {@code TreePath} of the parent. A return value of
  334        * {@code null} indicates this is the root node.
  335        *
  336        * @return the parent path
  337        */
  338       public TreePath getParentPath() {
  339           return parentPath;
  340       }
  341   
  342       /**
  343        * Returns a string that displays and identifies this
  344        * object's properties.
  345        *
  346        * @return a String representation of this object
  347        */
  348       public String toString() {
  349           StringBuffer tempSpot = new StringBuffer("[");
  350   
  351           for(int counter = 0, maxCounter = getPathCount();counter < maxCounter;
  352               counter++) {
  353               if(counter > 0)
  354                   tempSpot.append(", ");
  355               tempSpot.append(getPathComponent(counter));
  356           }
  357           tempSpot.append("]");
  358           return tempSpot.toString();
  359       }
  360   }

Save This Page
Home » openjdk-7 » javax » swing » tree » [javadoc | source]