defaultmutabletreenode.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 627 行 · 第 1/2 页

JAVA
627
字号
/* class DefaultMutableTreeNode
 *
 * Copyright (C) 2003  R M Pitman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package charvax.swing.tree;

import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Vector;

/**
 * A DefaultMutableTreeNode is a general-purpose node in a tree data structure.
 * <p>
 * 
 * A tree node may have at most one parent and 0 or more children.
 * DefaultMutableTreeNode provides operations for examining and modifying a
 * node's parent and children and also operations for examining the tree that
 * the node is a part of. A node's tree is the set of all nodes that can be
 * reached by starting at the node and following all the possible links to
 * parents and children. A node with no parent is the root of its tree; a node
 * with no children is a leaf. A tree may consist of many subtrees, each node
 * acting as the root for its own subtree.
 * <p>
 * 
 * This class provides enumerations for efficiently traversing a tree or
 * subtree in various orders or for following the path between two nodes. A
 * DefaultMutableTreeNode may also hold a reference to a user object, the use
 * of which is left to the user. Asking a DefaultMutableTreeNode for its string
 * representation with toString() returns the string representation of its user
 * object.
 */
public class DefaultMutableTreeNode implements MutableTreeNode {

    /**
     * Creates a tree node that has no parent and no children, but which allows
     * children.
     */
    DefaultMutableTreeNode() {
        this(null, true);
    }

    /**
     * Creates a tree node with no parent, no children, but which allows
     * children, and initializes it with the specified user object.
     */
    DefaultMutableTreeNode(Object userObject) {
        this(userObject, true);
    }

    /**
     * Creates a tree node with no parent, no children, initialized with the
     * specified user object, and that allows children only if specified.
     */
    DefaultMutableTreeNode(Object userObject, boolean allowsChildren) {
        _userObject = userObject;
        _allowsChildren = allowsChildren;
    }

    /**
     * Adds child to this MutableTreeNode at index. The setParent() method of
     * child will be called.
     */
    public void insert(MutableTreeNode child, int index) {
        if (!_allowsChildren)
                throw new IllegalStateException(
                        "TreeNode does not allow children");

        if (_children == null) _children = new Vector();

        _children.insertElementAt(child, index);
        child.setParent(this);
    }

    /**
     * Removes the child at index from this MutableTreeNode.
     */
    public void remove(int index) {
        MutableTreeNode node = (MutableTreeNode) _children.elementAt(index);
        if (node != null) this.remove(node);
    }

    /**
     * Removes node from this MutableTreeNode, giving it a null parent. The
     * setParent() method of "node" will be called.
     */
    public void remove(MutableTreeNode node) {
        _children.remove(node);
        node.setParent(null);
    }

    /**
     * Resets the user object of this MutableTreeNode to object.
     */
    public void setUserObject(Object object) {
        _userObject = object;
    }

    /**
     * Removes the subtree rooted at this node from the tree, giving this node
     * a null parent. Does nothing if this node is the root of its tree.
     */
    public void removeFromParent() {
        if (_parent == null) return;

        _parent.remove(this);
    }

    /**
     * Sets this node's parent to newParent but does not change the parent's
     * child array. This method is called from insert() and remove() to
     * reassign a child's parent, it should not be called from anywhere else.
     */
    public void setParent(MutableTreeNode newParent) {
        // This cast seems reasonable.
        _parent = (DefaultMutableTreeNode) newParent;
    }

    /**
     * Returns this node's parent or null if this node has no parent.
     */
    public TreeNode getParent() {
        return (TreeNode) _parent;
    }

    /**
     * Returns the child at the specified index in this node's child array.
     * 
     * @param index
     *            an index into this node's child array.
     * @return the TreeNode in this node's child array at the specified index
     */
    public TreeNode getChildAt(int index) {
        return (TreeNode) _children.elementAt(index);
    }

    /**
     * Returns the number of children of this node.
     */
    public int getChildCount() {
        if (_children == null) return 0;

        return _children.size();
    }

    /**
     * Returns the index of the specified child in this node's child array. If
     * the specified node is not a child of this node, returns -1. This method
     * performs a linear search and is O(n) where n is the number of children.
     * 
     * @param aChild
     *            the TreeNode to search for among this node's children.
     * @return an int giving the index of the node in this node's child array,
     *         or -1 if the specified node is a not a child of this node
     */
    public int getIndex(TreeNode aChild) {
        if (_children == null) return -1;

        return _children.indexOf(aChild);
    }

    /**
     * Creates and returns a forward-order enumeration of this node's children.
     * Modifying this node's child array invalidates any child enumerations
     * created before the modification.
     */
    public Enumeration children() {
        if (_children == null) return null;

        return _children.elements();
    }

    /**
     * Determines whether or not this node is allowed to have children. If
     * allows is false, all of this node's children are removed.
     * 
     * @param allows
     *            true if this node is allowed to have children.
     */
    public void setAllowsChildren(boolean allows) {
        _allowsChildren = allows;
    }

    /**
     * Returns true if this node is allowed to have children.
     */
    public boolean getAllowsChildren() {
        return _allowsChildren;
    }

    /**
     * Returns this node's user object.
     */
    public Object getUserObject() {
        return _userObject;
    }

    /**
     * Removes all of this node's children, setting their parents to null. If
     * this node has no children, this method does nothing.
     */
    public void removeAllChildren() {
        if (_children == null) return;

        Enumeration e = _children.elements();
        while (e.hasMoreElements()) {
            MutableTreeNode node = (MutableTreeNode) e.nextElement();
            node.setParent(null);
        }
        _children.removeAllElements();
    }

    /**
     * Removes newChild from its parent and makes it a child of this node by
     * adding it to the end of this node's child array.
     * 
     * @param newChild
     *            node to add as a child of this node.
     * @exception IllegalArgumentException
     *                if newChild is null.
     * @exception IllegalStateException
     *                if this node does not allow children.
     */
    public void add(MutableTreeNode newChild) {
        if (newChild == null)
                throw new IllegalArgumentException("child node is null");

        if (!_allowsChildren)
                throw new IllegalStateException(
                        "TreeNode does not allow children");

        newChild.setParent(this);
        if (_children == null) _children = new Vector();

        _children.add(newChild);
    }

    /**
     * Returns true if anotherNode is an ancestor of this node -- if it is this
     * node, this node's parent, or an ancestor of this node's parent. (Note
     * that a node is considered an ancestor of itself.) If anotherNode is
     * null, this method returns false. This operation is at worst O(h) where h
     * is the distance from the root to this node.
     * 
     * @param anotherNode
     *            node to test as an ancestor of this node
     * @return true if this node is a descendant of anotherNode.
     */
    public boolean isNodeAncestor(TreeNode anotherNode) {
        if (anotherNode == null) return false;

        if (anotherNode == this) return true;

        if (_parent == null) return false;

        TreeNode parent;
        for (parent = (TreeNode) _parent; parent != null; parent.getParent()) {

            if (parent == anotherNode) return true;
        }
        return false;
    }

    /**
     * Returns true if anotherNode is a descendant of this node -- if it is
     * this node, one of this node's children, or a descendant of one of this
     * node's children. Note that a node is considered a descendant of itself.
     * If anotherNode is null, returns false. This operation is at worst O(h)
     * where h is the distance from the root to anotherNode.
     * 
     * @param anotherNode
     *            node to test as a descendant of this node
     * @return true if this node is an ancestor of anotherNode.
     */
    public boolean isNodeDescendant(TreeNode anotherNode) {
        if (anotherNode == null) return false;

        if (anotherNode == this) return true;

        if (_children == null || _children.size() == 0) return false;

        TreeNode parent;
        for (parent = anotherNode.getParent(); parent != null; parent
                .getParent()) {
            if (parent == this) return true;
        }
        return false;
    }

    /**
     * Returns the depth of the tree rooted at this node -- the longest
     * distance from this node to a leaf. If this node has no children, returns 0.
     * This operation is much more expensive than getLevel() because it must
     * effectively traverse the entire tree rooted at this node.
     * 
     * @return the depth of the tree whose root is this node.
     */
    public int getDepth() {
        return this._depth(this, 0);
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?