jdk/src/java.desktop/share/classes/javax/swing/tree/DefaultMutableTreeNode.java
author ddehaven
Tue, 19 Aug 2014 10:32:16 -0700
changeset 26037 508779ce6619
parent 26001 jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java@991e1be0b235
parent 25859 jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java@3317bb8137f4
child 26353 b5e3b7fbf56d
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
22574
7f8ce0c8c20a 8032627: Add @SuppressWarnings("serial") to appropriate javax.swing classes
darcy
parents: 21593
diff changeset
     2
 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1843
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1843
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1843
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1843
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1843
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.swing.tree;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
   // ISSUE: this class depends on nothing in AWT -- move to java.util?
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
21593
4284575a978e 8027648: Type of overridden property is resolved incorrectly
malenkov
parents: 20458
diff changeset
    29
import java.beans.Transient;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * A <code>DefaultMutableTreeNode</code> is a general-purpose node in a tree data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * structure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * For examples of using default mutable tree nodes, see
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * <a
20455
f6f9a0c2796b 8020688: Broken links in documentation at http://docs.oracle.com/javase/6/docs/api/index.
mcherkas
parents: 5506
diff changeset
    39
 href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * in <em>The Java Tutorial.</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * A tree node may have at most one parent and 0 or more children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * <code>DefaultMutableTreeNode</code> provides operations for examining and modifying a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * node's parent and children and also operations for examining the tree that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * the node is a part of.  A node's tree is the set of all nodes that can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * reached by starting at the node and following all the possible links to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * parents and children.  A node with no parent is the root of its tree; a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * node with no children is a leaf.  A tree may consist of many subtrees,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * each node acting as the root for its own subtree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * This class provides enumerations for efficiently traversing a tree or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * subtree in various orders or for following the path between two nodes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * A <code>DefaultMutableTreeNode</code> may also hold a reference to a user object, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * use of which is left to the user.  Asking a <code>DefaultMutableTreeNode</code> for its
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * string representation with <code>toString()</code> returns the string
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * representation of its user object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * <b>This is not a thread safe class.</b>If you intend to use
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * a DefaultMutableTreeNode (or a tree of TreeNodes) in more than one thread, you
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * need to do your own synchronizing. A good convention to adopt is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * synchronizing on the root node of a tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * While DefaultMutableTreeNode implements the MutableTreeNode interface and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * will allow you to add in any implementation of MutableTreeNode not all
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * of the methods in DefaultMutableTreeNode will be applicable to all
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * MutableTreeNodes implementations. Especially with some of the enumerations
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * that are provided, using some of these methods assumes the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * DefaultMutableTreeNode contains only DefaultMutableNode instances. All
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * of the TreeNode/MutableTreeNode methods will behave as defined no
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * matter what implementations are added.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * <strong>Warning:</strong>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * Serialized objects of this class will not be compatible with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * future Swing releases. The current serialization support is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * appropriate for short term storage or RMI between applications running
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * the same version of Swing.  As of 1.4, support for long term storage
20458
f2423fb3fd19 8025840: Fix all the doclint warnings about trademark
cl
parents: 20455
diff changeset
    80
 * of all JavaBeans&trade;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * has been added to the <code>java.beans</code> package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * Please see {@link java.beans.XMLEncoder}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * @see MutableTreeNode
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * @author Rob Davis
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 */
22574
7f8ce0c8c20a 8032627: Add @SuppressWarnings("serial") to appropriate javax.swing classes
darcy
parents: 21593
diff changeset
    88
@SuppressWarnings("serial") // Same-version serialization only
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
    89
public class DefaultMutableTreeNode implements Cloneable,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
       MutableTreeNode, Serializable
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    private static final long serialVersionUID = -4298474751201349152L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * An enumeration that is always empty. This is used when an enumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * of a leaf node's children is requested.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    static public final Enumeration<TreeNode> EMPTY_ENUMERATION
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        = Collections.emptyEnumeration();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    /** this node's parent, or null if this node has no parent */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    protected MutableTreeNode   parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    /** array of children, may be null if this node has no children */
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   105
    protected Vector<TreeNode> children;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    /** optional user object */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    transient protected Object  userObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    /** true if the node is able to have children */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    protected boolean           allowsChildren;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Creates a tree node that has no parent and no children, but which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * allows children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    public DefaultMutableTreeNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        this(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * Creates a tree node with no parent, no children, but which allows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * children, and initializes it with the specified user object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * @param userObject an Object provided by the user that constitutes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     *                   the node's data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    public DefaultMutableTreeNode(Object userObject) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        this(userObject, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * Creates a tree node with no parent, no children, initialized with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * the specified user object, and that allows children only if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * specified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * @param userObject an Object provided by the user that constitutes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     *        the node's data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * @param allowsChildren if true, the node is allowed to have child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     *        nodes -- otherwise, it is always a leaf node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    public DefaultMutableTreeNode(Object userObject, boolean allowsChildren) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        parent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        this.allowsChildren = allowsChildren;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        this.userObject = userObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    //  Primitives
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * Removes <code>newChild</code> from its present parent (if it has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * parent), sets the child's parent to this node, and then adds the child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * to this node's child array at index <code>childIndex</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * <code>newChild</code> must not be null and must not be an ancestor of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * @param   newChild        the MutableTreeNode to insert under this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * @param   childIndex      the index in this node's child array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     *                          where this node is to be inserted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * @exception       ArrayIndexOutOfBoundsException  if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     *                          <code>childIndex</code> is out of bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * @exception       IllegalArgumentException        if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     *                          <code>newChild</code> is null or is an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     *                          ancestor of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * @exception       IllegalStateException   if this node does not allow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     *                                          children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * @see     #isNodeDescendant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    public void insert(MutableTreeNode newChild, int childIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        if (!allowsChildren) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            throw new IllegalStateException("node does not allow children");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        } else if (newChild == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            throw new IllegalArgumentException("new child is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        } else if (isNodeAncestor(newChild)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            throw new IllegalArgumentException("new child is an ancestor");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            MutableTreeNode oldParent = (MutableTreeNode)newChild.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            if (oldParent != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                oldParent.remove(newChild);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            newChild.setParent(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            if (children == null) {
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   190
                children = new Vector<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            children.insertElementAt(newChild, childIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * Removes the child at the specified index from this node's children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * and sets that node's parent to null. The child node to remove
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     * must be a <code>MutableTreeNode</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * @param   childIndex      the index in this node's child array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     *                          of the child to remove
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * @exception       ArrayIndexOutOfBoundsException  if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     *                          <code>childIndex</code> is out of bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    public void remove(int childIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        MutableTreeNode child = (MutableTreeNode)getChildAt(childIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        children.removeElementAt(childIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        child.setParent(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * Sets this node's parent to <code>newParent</code> but does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * change the parent's child array.  This method is called from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * <code>insert()</code> and <code>remove()</code> to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * reassign a child's parent, it should not be messaged from anywhere
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * else.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * @param   newParent       this node's new parent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     */
21593
4284575a978e 8027648: Type of overridden property is resolved incorrectly
malenkov
parents: 20458
diff changeset
   220
    @Transient
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    public void setParent(MutableTreeNode newParent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        parent = newParent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * Returns this node's parent or null if this node has no parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * @return  this node's parent TreeNode, or null if this node has no parent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    public TreeNode getParent() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        return parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * Returns the child at the specified index in this node's child array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * @param   index   an index into this node's child array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * @exception       ArrayIndexOutOfBoundsException  if <code>index</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     *                                          is out of bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * @return  the TreeNode in this node's child array at  the specified index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    public TreeNode getChildAt(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        if (children == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
            throw new ArrayIndexOutOfBoundsException("node has no children");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        }
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   246
        return children.elementAt(index);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * Returns the number of children of this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * @return  an int giving the number of children of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    public int getChildCount() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        if (children == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            return children.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * Returns the index of the specified child in this node's child array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * If the specified node is not a child of this node, returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     * <code>-1</code>.  This method performs a linear search and is O(n)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     * where n is the number of children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * @param   aChild  the TreeNode to search for among this node's children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * @exception       IllegalArgumentException        if <code>aChild</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     *                                                  is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * @return  an int giving the index of the node in this node's child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     *          array, or <code>-1</code> if the specified node is a not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     *          a child of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    public int getIndex(TreeNode aChild) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        if (aChild == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            throw new IllegalArgumentException("argument is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        if (!isNodeChild(aChild)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        return children.indexOf(aChild);        // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * Creates and returns a forward-order enumeration of this node's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * children.  Modifying this node's child array invalidates any child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * enumerations created before the modification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * @return  an Enumeration of this node's children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     */
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   293
    public Enumeration<TreeNode> children() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        if (children == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            return EMPTY_ENUMERATION;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            return children.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     * Determines whether or not this node is allowed to have children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * If <code>allows</code> is false, all of this node's children are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * Note: By default, a node allows children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * @param   allows  true if this node is allowed to have children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    public void setAllowsChildren(boolean allows) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        if (allows != allowsChildren) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            allowsChildren = allows;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            if (!allowsChildren) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                removeAllChildren();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * Returns true if this node is allowed to have children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * @return  true if this node allows children, else false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    public boolean getAllowsChildren() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        return allowsChildren;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * Sets the user object for this node to <code>userObject</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * @param   userObject      the Object that constitutes this node's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     *                          user-specified data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     * @see     #getUserObject
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     * @see     #toString
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    public void setUserObject(Object userObject) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        this.userObject = userObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * Returns this node's user object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     * @return  the Object stored at this node by the user
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     * @see     #setUserObject
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     * @see     #toString
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    public Object getUserObject() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        return userObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    //  Derived methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * Removes the subtree rooted at this node from the tree, giving this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * node a null parent.  Does nothing if this node is the root of its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
    public void removeFromParent() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        MutableTreeNode parent = (MutableTreeNode)getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        if (parent != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            parent.remove(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * Removes <code>aChild</code> from this node's child array, giving it a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * null parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * @param   aChild  a child of this node to remove
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     * @exception       IllegalArgumentException        if <code>aChild</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     *                                  is null or is not a child of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    public void remove(MutableTreeNode aChild) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        if (aChild == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            throw new IllegalArgumentException("argument is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        if (!isNodeChild(aChild)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            throw new IllegalArgumentException("argument is not a child");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        remove(getIndex(aChild));       // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * Removes all of this node's children, setting their parents to null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * If this node has no children, this method does nothing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    public void removeAllChildren() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        for (int i = getChildCount()-1; i >= 0; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            remove(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     * Removes <code>newChild</code> from its parent and makes it a child of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * this node by adding it to the end of this node's child array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * @see             #insert
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     * @param   newChild        node to add as a child of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     * @exception       IllegalArgumentException    if <code>newChild</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     *                                          is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * @exception       IllegalStateException   if this node does not allow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     *                                          children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    public void add(MutableTreeNode newChild) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        if(newChild != null && newChild.getParent() == this)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            insert(newChild, getChildCount() - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
            insert(newChild, getChildCount());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    //  Tree Queries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
     * Returns true if <code>anotherNode</code> is an ancestor of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * -- if it is this node, this node's parent, or an ancestor of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     * node's parent.  (Note that a node is considered an ancestor of itself.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     * If <code>anotherNode</code> is null, this method returns false.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     * operation is at worst O(h) where h is the distance from the root to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * @see             #isNodeDescendant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * @see             #getSharedAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     * @param   anotherNode     node to test as an ancestor of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * @return  true if this node is a descendant of <code>anotherNode</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    public boolean isNodeAncestor(TreeNode anotherNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        if (anotherNode == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        TreeNode ancestor = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            if (ancestor == anotherNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        } while((ancestor = ancestor.getParent()) != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * Returns true if <code>anotherNode</code> is a descendant of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * -- if it is this node, one of this node's children, or a descendant of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * one of this node's children.  Note that a node is considered a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * descendant of itself.  If <code>anotherNode</code> is null, returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * false.  This operation is at worst O(h) where h is the distance from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     * root to <code>anotherNode</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * @see     #isNodeAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * @see     #getSharedAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * @param   anotherNode     node to test as descendant of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * @return  true if this node is an ancestor of <code>anotherNode</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    public boolean isNodeDescendant(DefaultMutableTreeNode anotherNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        if (anotherNode == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        return anotherNode.isNodeAncestor(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * Returns the nearest common ancestor to this node and <code>aNode</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     * Returns null, if no such ancestor exists -- if this node and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     * <code>aNode</code> are in different trees or if <code>aNode</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     * null.  A node is considered an ancestor of itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
     * @see     #isNodeAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
     * @see     #isNodeDescendant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * @param   aNode   node to find common ancestor with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * @return  nearest ancestor common to this node and <code>aNode</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     *          or null if none
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    public TreeNode getSharedAncestor(DefaultMutableTreeNode aNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        if (aNode == this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
            return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        } else if (aNode == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        int             level1, level2, diff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        TreeNode        node1, node2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        level1 = getLevel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        level2 = aNode.getLevel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        if (level2 > level1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            diff = level2 - level1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            node1 = aNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
            node2 = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            diff = level1 - level2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
            node1 = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            node2 = aNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        // Go up the tree until the nodes are at the same level
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        while (diff > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            node1 = node1.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            diff--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        // Move up the tree until we find a common ancestor.  Since we know
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        // that both nodes are at the same level, we won't cross paths
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        // unknowingly (if there is a common ancestor, both nodes hit it in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        // the same iteration).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            if (node1 == node2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                return node1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
            node1 = node1.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            node2 = node2.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        } while (node1 != null);// only need to check one -- they're at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        // same level so if one is null, the other is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        if (node1 != null || node2 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            throw new Error ("nodes should be null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
     * Returns true if and only if <code>aNode</code> is in the same tree
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * as this node.  Returns false if <code>aNode</code> is null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     *
24495
a5c854a00679 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages
yan
parents: 22574
diff changeset
   537
     * @param   aNode node to find common ancestor with
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     * @see     #getSharedAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * @see     #getRoot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     * @return  true if <code>aNode</code> is in the same tree as this node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     *          false if <code>aNode</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    public boolean isNodeRelated(DefaultMutableTreeNode aNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        return (aNode != null) && (getRoot() == aNode.getRoot());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     * Returns the depth of the tree rooted at this node -- the longest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * distance from this node to a leaf.  If this node has no children,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     * returns 0.  This operation is much more expensive than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
     * <code>getLevel()</code> because it must effectively traverse the entire
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
     * tree rooted at this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
     * @see     #getLevel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * @return  the depth of the tree whose root is this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    public int getDepth() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        Object  last = null;
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   560
        Enumeration<TreeNode> enum_ = breadthFirstEnumeration();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        while (enum_.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            last = enum_.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        if (last == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            throw new Error ("nodes should be null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        return ((DefaultMutableTreeNode)last).getLevel() - getLevel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     * Returns the number of levels above this node -- the distance from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     * the root to this node.  If this node is the root, returns 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     * @see     #getDepth
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     * @return  the number of levels above this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    public int getLevel() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        TreeNode ancestor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        int levels = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        ancestor = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        while((ancestor = ancestor.getParent()) != null){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            levels++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        return levels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
      * Returns the path from the root, to get to this node.  The last
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
      * element in the path is this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
      *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
      * @return an array of TreeNode objects giving the path, where the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
      *         first element in the path is the root and the last
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
      *         element is this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    public TreeNode[] getPath() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        return getPathToRoot(this, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * Builds the parents of node up to and including the root node,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * where the original node is the last element in the returned array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     * The length of the returned array gives the node's depth in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     * tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     * @param aNode  the TreeNode to get the path for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     * @param depth  an int giving the number of steps already taken towards
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     *        the root (on recursive calls), used to size the returned array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * @return an array of TreeNodes giving the path from the root to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     *         specified node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
        TreeNode[]              retNodes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        /* Check for null, in case someone passed in a null node, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
           they passed in an element that isn't rooted at root. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        if(aNode == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
            if(depth == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                retNodes = new TreeNode[depth];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            depth++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            retNodes = getPathToRoot(aNode.getParent(), depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            retNodes[retNodes.length - depth] = aNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        return retNodes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
      * Returns the user object path, from the root, to get to this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
      * If some of the TreeNodes in the path have null user objects, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
      * returned path will contain nulls.
24495
a5c854a00679 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages
yan
parents: 22574
diff changeset
   642
      *
a5c854a00679 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages
yan
parents: 22574
diff changeset
   643
      * @return the user object path, from the root, to get to this node
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    public Object[] getUserObjectPath() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        TreeNode[]          realPath = getPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        Object[]            retPath = new Object[realPath.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        for(int counter = 0; counter < realPath.length; counter++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            retPath[counter] = ((DefaultMutableTreeNode)realPath[counter])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                               .getUserObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        return retPath;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     * Returns the root of the tree that contains this node.  The root is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     * the ancestor with a null parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * @see     #isNodeAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     * @return  the root of the tree that contains this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    public TreeNode getRoot() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        TreeNode ancestor = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        TreeNode previous;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            previous = ancestor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            ancestor = ancestor.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        } while (ancestor != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        return previous;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
     * Returns true if this node is the root of the tree.  The root is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     * the only node in the tree with a null parent; every tree has exactly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     * one root.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
     * @return  true if this node is the root of its tree
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
    public boolean isRoot() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        return getParent() == null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
     * Returns the node that follows this node in a preorder traversal of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     * node's tree.  Returns null if this node is the last node of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * traversal.  This is an inefficient way to traverse the entire tree; use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     * an enumeration, instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     * @see     #preorderEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     * @return  the node that follows this node in a preorder traversal, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     *          null if this node is last
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
    public DefaultMutableTreeNode getNextNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        if (getChildCount() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            // No children, so look for nextSibling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            DefaultMutableTreeNode nextSibling = getNextSibling();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            if (nextSibling == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
                    if (aNode == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                    nextSibling = aNode.getNextSibling();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                    if (nextSibling != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                        return nextSibling;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                    aNode = (DefaultMutableTreeNode)aNode.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                } while(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                return nextSibling;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            return (DefaultMutableTreeNode)getChildAt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
     * Returns the node that precedes this node in a preorder traversal of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
     * this node's tree.  Returns <code>null</code> if this node is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
     * first node of the traversal -- the root of the tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
     * This is an inefficient way to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
     * traverse the entire tree; use an enumeration, instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
     * @see     #preorderEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     * @return  the node that precedes this node in a preorder traversal, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
     *          null if this node is the first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
    public DefaultMutableTreeNode getPreviousNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        DefaultMutableTreeNode previousSibling;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        if (myParent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        previousSibling = getPreviousSibling();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        if (previousSibling != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            if (previousSibling.getChildCount() == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                return previousSibling;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                return previousSibling.getLastLeaf();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            return myParent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
     * Creates and returns an enumeration that traverses the subtree rooted at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     * this node in preorder.  The first node returned by the enumeration's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     * <code>nextElement()</code> method is this node.<P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
     * Modifying the tree by inserting, removing, or moving a node invalidates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
     * any enumerations created before the modification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
     * @see     #postorderEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     * @return  an enumeration for traversing the tree in preorder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     */
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   768
    public Enumeration<TreeNode> preorderEnumeration() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        return new PreorderEnumeration(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     * Creates and returns an enumeration that traverses the subtree rooted at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     * this node in postorder.  The first node returned by the enumeration's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     * <code>nextElement()</code> method is the leftmost leaf.  This is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     * same as a depth-first traversal.<P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     * Modifying the tree by inserting, removing, or moving a node invalidates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     * any enumerations created before the modification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
     * @see     #depthFirstEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
     * @see     #preorderEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
     * @return  an enumeration for traversing the tree in postorder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
     */
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   785
    public Enumeration<TreeNode> postorderEnumeration() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        return new PostorderEnumeration(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * Creates and returns an enumeration that traverses the subtree rooted at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     * this node in breadth-first order.  The first node returned by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
     * enumeration's <code>nextElement()</code> method is this node.<P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
     * Modifying the tree by inserting, removing, or moving a node invalidates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
     * any enumerations created before the modification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
     * @see     #depthFirstEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
     * @return  an enumeration for traversing the tree in breadth-first order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
     */
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   800
    public Enumeration<TreeNode> breadthFirstEnumeration() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        return new BreadthFirstEnumeration(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
     * Creates and returns an enumeration that traverses the subtree rooted at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
     * this node in depth-first order.  The first node returned by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
     * enumeration's <code>nextElement()</code> method is the leftmost leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
     * This is the same as a postorder traversal.<P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
     * Modifying the tree by inserting, removing, or moving a node invalidates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
     * any enumerations created before the modification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
     * @see     #breadthFirstEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
     * @see     #postorderEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
     * @return  an enumeration for traversing the tree in depth-first order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
     */
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   817
    public Enumeration<TreeNode> depthFirstEnumeration() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
        return postorderEnumeration();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     * Creates and returns an enumeration that follows the path from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
     * <code>ancestor</code> to this node.  The enumeration's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
     * <code>nextElement()</code> method first returns <code>ancestor</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
     * then the child of <code>ancestor</code> that is an ancestor of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
     * node, and so on, and finally returns this node.  Creation of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
     * enumeration is O(m) where m is the number of nodes between this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
     * and <code>ancestor</code>, inclusive.  Each <code>nextElement()</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
     * message is O(1).<P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
     * Modifying the tree by inserting, removing, or moving a node invalidates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
     * any enumerations created before the modification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
     *
24495
a5c854a00679 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages
yan
parents: 22574
diff changeset
   834
     * @param           ancestor the node to start enumeration from
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
     * @see             #isNodeAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
     * @see             #isNodeDescendant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
     * @exception       IllegalArgumentException if <code>ancestor</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
     *                                          not an ancestor of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
     * @return  an enumeration for following the path from an ancestor of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
     *          this node to this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
     */
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
   842
    public Enumeration<TreeNode> pathFromAncestorEnumeration(TreeNode ancestor) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        return new PathBetweenNodesEnumeration(ancestor, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    //  Child Queries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
     * Returns true if <code>aNode</code> is a child of this node.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
     * <code>aNode</code> is null, this method returns false.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
     *
24495
a5c854a00679 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages
yan
parents: 22574
diff changeset
   855
     * @param   aNode the node to determinate whether it is a child
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
     * @return  true if <code>aNode</code> is a child of this node; false if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
     *                  <code>aNode</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
    public boolean isNodeChild(TreeNode aNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        boolean retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        if (aNode == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
            retval = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
            if (getChildCount() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                retval = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                retval = (aNode.getParent() == this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
     * Returns this node's first child.  If this node has no children,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     * throws NoSuchElementException.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     * @return  the first child of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     * @exception       NoSuchElementException  if this node has no children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
    public TreeNode getFirstChild() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
        if (getChildCount() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
            throw new NoSuchElementException("node has no children");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
        return getChildAt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
     * Returns this node's last child.  If this node has no children,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
     * throws NoSuchElementException.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
     * @return  the last child of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
     * @exception       NoSuchElementException  if this node has no children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    public TreeNode getLastChild() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        if (getChildCount() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
            throw new NoSuchElementException("node has no children");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        return getChildAt(getChildCount()-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
     * Returns the child in this node's child array that immediately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
     * follows <code>aChild</code>, which must be a child of this node.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
     * <code>aChild</code> is the last child, returns null.  This method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
     * performs a linear search of this node's children for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
     * <code>aChild</code> and is O(n) where n is the number of children; to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
     * traverse the entire array of children, use an enumeration instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
     *
24495
a5c854a00679 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages
yan
parents: 22574
diff changeset
   914
     * @param           aChild the child node to look for next child after it
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
     * @see             #children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
     * @exception       IllegalArgumentException if <code>aChild</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
     *                                  null or is not a child of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     * @return  the child of this node that immediately follows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
     *          <code>aChild</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    public TreeNode getChildAfter(TreeNode aChild) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
        if (aChild == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
            throw new IllegalArgumentException("argument is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        int index = getIndex(aChild);           // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
        if (index == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
            throw new IllegalArgumentException("node is not a child");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
        if (index < getChildCount() - 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
            return getChildAt(index + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
     * Returns the child in this node's child array that immediately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
     * precedes <code>aChild</code>, which must be a child of this node.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
     * <code>aChild</code> is the first child, returns null.  This method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
     * performs a linear search of this node's children for <code>aChild</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
     * and is O(n) where n is the number of children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
     *
24495
a5c854a00679 8042089: Fix doclint warnings from javax.swing.tree and javax.swing.undo packages
yan
parents: 22574
diff changeset
   947
     * @param           aChild the child node to look for previous child before it
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
     * @exception       IllegalArgumentException if <code>aChild</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
     *                                          or is not a child of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
     * @return  the child of this node that immediately precedes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
     *          <code>aChild</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
    public TreeNode getChildBefore(TreeNode aChild) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
        if (aChild == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
            throw new IllegalArgumentException("argument is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        int index = getIndex(aChild);           // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        if (index == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            throw new IllegalArgumentException("argument is not a child");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        if (index > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
            return getChildAt(index - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
    //  Sibling Queries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
     * Returns true if <code>anotherNode</code> is a sibling of (has the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
     * same parent as) this node.  A node is its own sibling.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
     * <code>anotherNode</code> is null, returns false.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
     * @param   anotherNode     node to test as sibling of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
     * @return  true if <code>anotherNode</code> is a sibling of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    public boolean isNodeSibling(TreeNode anotherNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        boolean retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
        if (anotherNode == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
            retval = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
        } else if (anotherNode == this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
            retval = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
            TreeNode  myParent = getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
            retval = (myParent != null && myParent == anotherNode.getParent());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            if (retval && !((DefaultMutableTreeNode)getParent())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
                           .isNodeChild(anotherNode)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                throw new Error("sibling has different parent");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
        return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
     * Returns the number of siblings of this node.  A node is its own sibling
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
     * (if it has no parent or no siblings, this method returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
     * <code>1</code>).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
     * @return  the number of siblings of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
    public int getSiblingCount() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
        TreeNode myParent = getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
        if (myParent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
            return myParent.getChildCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
     * Returns the next sibling of this node in the parent's children array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
     * Returns null if this node has no parent or is the parent's last child.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
     * This method performs a linear search that is O(n) where n is the number
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
     * of children; to traverse the entire array, use the parent's child
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
     * enumeration instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
     * @see     #children
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
     * @return  the sibling of this node that immediately follows this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
    public DefaultMutableTreeNode getNextSibling() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
        DefaultMutableTreeNode retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
        DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
        if (myParent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
            retval = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
            retval = (DefaultMutableTreeNode)myParent.getChildAfter(this);      // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        if (retval != null && !isNodeSibling(retval)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            throw new Error("child of parent is not a sibling");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
        return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
     * Returns the previous sibling of this node in the parent's children
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
     * array.  Returns null if this node has no parent or is the parent's
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
     * first child.  This method performs a linear search that is O(n) where n
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
     * is the number of children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
     * @return  the sibling of this node that immediately precedes this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
    public DefaultMutableTreeNode getPreviousSibling() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
        DefaultMutableTreeNode retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
        DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
        if (myParent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
            retval = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
            retval = (DefaultMutableTreeNode)myParent.getChildBefore(this);     // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
        if (retval != null && !isNodeSibling(retval)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
            throw new Error("child of parent is not a sibling");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
        return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
    //  Leaf Queries
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
     * Returns true if this node has no children.  To distinguish between
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
     * nodes that have no children and nodes that <i>cannot</i> have
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
     * children (e.g. to distinguish files from empty directories), use this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
     * method in conjunction with <code>getAllowsChildren</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
     * @see     #getAllowsChildren
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
     * @return  true if this node has no children
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
    public boolean isLeaf() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
        return (getChildCount() == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
     * Finds and returns the first leaf that is a descendant of this node --
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
     * either this node or its first child's first leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
     * Returns this node if it is a leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
     * @see     #isLeaf
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
     * @see     #isNodeDescendant
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
     * @return  the first leaf in the subtree rooted at this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
    public DefaultMutableTreeNode getFirstLeaf() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
        DefaultMutableTreeNode node = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
        while (!node.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
            node = (DefaultMutableTreeNode)node.getFirstChild();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
     * Finds and returns the last leaf that is a descendant of this node --
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
     * either this node or its last child's last leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
     * Returns this node if it is a leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
     * @see     #isLeaf
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
     * @see     #isNodeDescendant
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
     * @return  the last leaf in the subtree rooted at this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
    public DefaultMutableTreeNode getLastLeaf() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
        DefaultMutableTreeNode node = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
        while (!node.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
            node = (DefaultMutableTreeNode)node.getLastChild();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
        return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
     * Returns the leaf after this node or null if this node is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
     * last leaf in the tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
     * In this implementation of the <code>MutableNode</code> interface,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
     * this operation is very inefficient. In order to determine the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
     * next node, this method first performs a linear search in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
     * parent's child-list in order to find the current node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
     * That implementation makes the operation suitable for short
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
     * traversals from a known position. But to traverse all of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
     * leaves in the tree, you should use <code>depthFirstEnumeration</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
     * to enumerate the nodes in the tree and use <code>isLeaf</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
     * on each node to determine which are leaves.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
     * @see     #depthFirstEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
     * @see     #isLeaf
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
     * @return  returns the next leaf past this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
    public DefaultMutableTreeNode getNextLeaf() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
        DefaultMutableTreeNode nextSibling;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
        DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
        if (myParent == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
        nextSibling = getNextSibling(); // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
        if (nextSibling != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
            return nextSibling.getFirstLeaf();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
        return myParent.getNextLeaf();  // tail recursion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
     * Returns the leaf before this node or null if this node is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
     * first leaf in the tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
     * In this implementation of the <code>MutableNode</code> interface,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
     * this operation is very inefficient. In order to determine the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
     * previous node, this method first performs a linear search in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
     * parent's child-list in order to find the current node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
     * That implementation makes the operation suitable for short
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
     * traversals from a known position. But to traverse all of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
     * leaves in the tree, you should use <code>depthFirstEnumeration</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
     * to enumerate the nodes in the tree and use <code>isLeaf</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
     * on each node to determine which are leaves.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
     * @see             #depthFirstEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
     * @see             #isLeaf
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
     * @return  returns the leaf before this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
    public DefaultMutableTreeNode getPreviousLeaf() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
        DefaultMutableTreeNode previousSibling;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
        DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
        if (myParent == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
        previousSibling = getPreviousSibling(); // linear search
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
        if (previousSibling != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
            return previousSibling.getLastLeaf();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
        return myParent.getPreviousLeaf();              // tail recursion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
     * Returns the total number of leaves that are descendants of this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
     * If this node is a leaf, returns <code>1</code>.  This method is O(n)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
     * where n is the number of descendants of this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
     * @see     #isNodeAncestor
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
     * @return  the number of leaves beneath this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
    public int getLeafCount() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
        int count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
        TreeNode node;
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1221
        Enumeration<TreeNode> enum_ = breadthFirstEnumeration(); // order matters not
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
        while (enum_.hasMoreElements()) {
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1224
            node = enum_.nextElement();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
            if (node.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                count++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
        if (count < 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
            throw new Error("tree has zero leaves");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
        return count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
    //  Overrides
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
     * Returns the result of sending <code>toString()</code> to this node's
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
     * user object, or the empty string if the node has no user object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
     * @see     #getUserObject
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
        if (userObject == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
            return "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
            return userObject.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
     * Overridden to make clone public.  Returns a shallow copy of this node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
     * the new node has no parent or children and has a reference to the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
     * user object, if any.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
     * @return  a copy of this node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
    public Object clone() {
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
  1264
        DefaultMutableTreeNode newNode;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
            newNode = (DefaultMutableTreeNode)super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
            // shallow copy -- the new node has no parent or children
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
            newNode.children = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
            newNode.parent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
        } catch (CloneNotSupportedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
            // Won't happen because we implement Cloneable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
            throw new Error(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
        return newNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
    // Serialization support.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
    private void writeObject(ObjectOutputStream s) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
        Object[]             tValues;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
        s.defaultWriteObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
        // Save the userObject, if its Serializable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
        if(userObject != null && userObject instanceof Serializable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
            tValues = new Object[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
            tValues[0] = "userObject";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
            tValues[1] = userObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
            tValues = new Object[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
        s.writeObject(tValues);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
    private void readObject(ObjectInputStream s)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
        throws IOException, ClassNotFoundException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
26001
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1301
        ObjectInputStream.GetField f = s.readFields();
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1302
        parent = (MutableTreeNode) f.get("parent", null);
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1303
        @SuppressWarnings("unchecked")
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1304
        Vector<TreeNode> newChildren = (Vector<TreeNode>) f.get("children", null);
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1305
        boolean newAllowsChildren = f.get("allowsChildren", false);
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1306
        if (!newAllowsChildren && newChildren != null && newChildren.size() > 0) {
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1307
            throw new IllegalStateException("node does not allow children");
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1308
        }
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1309
        children = newChildren;
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1310
        allowsChildren = newAllowsChildren;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
26001
991e1be0b235 8038937: Validate fields on Swing classes deserialization
alexsch
parents: 25568
diff changeset
  1312
        Object[]      tValues;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
        tValues = (Object[])s.readObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
        if(tValues.length > 0 && tValues[0].equals("userObject"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
            userObject = tValues[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
  1319
    private final class PreorderEnumeration implements Enumeration<TreeNode> {
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1320
        private final Stack<Enumeration<TreeNode>> stack = new Stack<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
        public PreorderEnumeration(TreeNode rootNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
            super();
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
  1324
            Vector<TreeNode> v = new Vector<TreeNode>(1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
            v.addElement(rootNode);     // PENDING: don't really need a vector
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
            stack.push(v.elements());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
        public boolean hasMoreElements() {
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
  1330
            return (!stack.empty() && stack.peek().hasMoreElements());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
        public TreeNode nextElement() {
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1334
            Enumeration<TreeNode> enumer = stack.peek();
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1335
            TreeNode    node = enumer.nextElement();
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1336
            @SuppressWarnings("unchecked")
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1337
            Enumeration<TreeNode> children = node.children();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
            if (!enumer.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
                stack.pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
            if (children.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
                stack.push(children);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
            return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
    }  // End of class PreorderEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
    final class PostorderEnumeration implements Enumeration<TreeNode> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
        protected TreeNode root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        protected Enumeration<TreeNode> children;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
        protected Enumeration<TreeNode> subtree;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
        public PostorderEnumeration(TreeNode rootNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
            super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
            root = rootNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
            children = root.children();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
            subtree = EMPTY_ENUMERATION;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
        public boolean hasMoreElements() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
            return root != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
        public TreeNode nextElement() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
            TreeNode retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
            if (subtree.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
                retval = subtree.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
            } else if (children.hasMoreElements()) {
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
  1374
                subtree = new PostorderEnumeration(children.nextElement());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
                retval = subtree.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
                retval = root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
                root = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
            return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
    }  // End of class PostorderEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
    final class BreadthFirstEnumeration implements Enumeration<TreeNode> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
        protected Queue queue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
        public BreadthFirstEnumeration(TreeNode rootNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
            super();
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
  1393
            Vector<TreeNode> v = new Vector<TreeNode>(1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
            v.addElement(rootNode);     // PENDING: don't really need a vector
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
            queue = new Queue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
            queue.enqueue(v.elements());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
        public boolean hasMoreElements() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
            return (!queue.isEmpty() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
                    ((Enumeration)queue.firstObject()).hasMoreElements());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
        public TreeNode nextElement() {
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1405
            Enumeration<?> enumer = (Enumeration)queue.firstObject();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            TreeNode    node = (TreeNode)enumer.nextElement();
25568
b906a74c6882 8043550: Fix raw and unchecked lint warnings in javax.swing.*
darcy
parents: 24495
diff changeset
  1407
            Enumeration<?> children = node.children();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
            if (!enumer.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
                queue.dequeue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
            if (children.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
                queue.enqueue(children);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
            return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
        // A simple queue with a linked list data structure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
        final class Queue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
            QNode head; // null if empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
            QNode tail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
            final class QNode {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
                public Object   object;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                public QNode    next;   // null if end
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                public QNode(Object object, QNode next) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
                    this.object = object;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                    this.next = next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
            public void enqueue(Object anObject) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
                if (head == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
                    head = tail = new QNode(anObject, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
                    tail.next = new QNode(anObject, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
                    tail = tail.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
            public Object dequeue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
                if (head == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
                    throw new NoSuchElementException("No more elements");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
                Object retval = head.object;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
                QNode oldHead = head;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
                head = head.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
                if (head == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
                    tail = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
                    oldHead.next = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
            public Object firstObject() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
                if (head == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
                    throw new NoSuchElementException("No more elements");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
                return head.object;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
            public boolean isEmpty() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
                return head == null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
        } // End of class Queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
    }  // End of class BreadthFirstEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
    final class PathBetweenNodesEnumeration implements Enumeration<TreeNode> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
        protected Stack<TreeNode> stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
        public PathBetweenNodesEnumeration(TreeNode ancestor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
                                           TreeNode descendant)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
            super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
            if (ancestor == null || descendant == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
                throw new IllegalArgumentException("argument is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
            TreeNode current;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
            stack = new Stack<TreeNode>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
            stack.push(descendant);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
            current = descendant;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
            while (current != ancestor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
                current = current.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                if (current == null && descendant != ancestor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
                    throw new IllegalArgumentException("node " + ancestor +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
                                " is not an ancestor of " + descendant);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
                stack.push(current);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
        public boolean hasMoreElements() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
            return stack.size() > 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
        public TreeNode nextElement() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
                return stack.pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
            } catch (EmptyStackException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
                throw new NoSuchElementException("No more elements");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
    } // End of class PathBetweenNodesEnumeration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
} // End of class DefaultMutableTreeNode