FileDocCategorySizeDatePackage
DefaultMutableTreeNode.javaAPI DocJaudiotagger 2.0.443980Wed Mar 30 16:11:42 BST 2011org.jaudiotagger.utils.tree

DefaultMutableTreeNode

public class DefaultMutableTreeNode extends Object implements Serializable, Cloneable, MutableTreeNode
A DefaultMutableTreeNode is a general-purpose node in a tree data structure. For examples of using default mutable tree nodes, see How to Use Trees in The Java Tutorial.

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.

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.

This is not a thread safe class.If you intend to use a DefaultMutableTreeNode (or a tree of TreeNodes) in more than one thread, you need to do your own synchronizing. A good convention to adopt is synchronizing on the root node of a tree.

While DefaultMutableTreeNode implements the MutableTreeNode interface and will allow you to add in any implementation of MutableTreeNode not all of the methods in DefaultMutableTreeNode will be applicable to all MutableTreeNodes implementations. Especially with some of the enumerations that are provided, using some of these methods assumes the DefaultMutableTreeNode contains only DefaultMutableNode instances. All of the TreeNode/MutableTreeNode methods will behave as defined no matter what implementations are added.

Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeansTM has been added to the java.beans package. Please see {@link java.beans.XMLEncoder}.

see
MutableTreeNode
version
1.25 03/23/10
author
Rob Davis

Fields Summary
public static final Enumeration
EMPTY_ENUMERATION
An enumeration that is always empty. This is used when an enumeration of a leaf node's children is requested.
protected MutableTreeNode
parent
this node's parent, or null if this node has no parent
protected Vector
children
array of children, may be null if this node has no children
protected transient Object
userObject
optional user object
protected boolean
allowsChildren
true if the node is able to have children
Constructors Summary
public DefaultMutableTreeNode()
Creates a tree node that has no parent and no children, but which allows children.



                        
      
	this(null);
    
public DefaultMutableTreeNode(Object userObject)
Creates a tree node with no parent, no children, but which allows children, and initializes it with the specified user object.

param
userObject an Object provided by the user that constitutes the node's data

	this(userObject, true);
    
public DefaultMutableTreeNode(Object userObject, boolean allowsChildren)
Creates a tree node with no parent, no children, initialized with the specified user object, and that allows children only if specified.

param
userObject an Object provided by the user that constitutes the node's data
param
allowsChildren if true, the node is allowed to have child nodes -- otherwise, it is always a leaf node

	super();
	parent = null;
	this.allowsChildren = allowsChildren;
	this.userObject = userObject;
    
Methods Summary
public voidadd(MutableTreeNode newChild)
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.

see
#insert
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

	if(newChild != null && newChild.getParent() == this)
	    insert(newChild, getChildCount() - 1);
	else
	    insert(newChild, getChildCount());
    
public java.util.EnumerationbreadthFirstEnumeration()
Creates and returns an enumeration that traverses the subtree rooted at this node in breadth-first order. The first node returned by the enumeration's nextElement() method is this node.

Modifying the tree by inserting, removing, or moving a node invalidates any enumerations created before the modification.

see
#depthFirstEnumeration
return
an enumeration for traversing the tree in breadth-first order

	return new BreadthFirstEnumeration(this);
    
public java.util.Enumerationchildren()
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.

return
an Enumeration of this node's children

	if (children == null) {
	    return EMPTY_ENUMERATION;
	} else {
	    return children.elements();
	}
    
public java.lang.Objectclone()
Overridden to make clone public. Returns a shallow copy of this node; the new node has no parent or children and has a reference to the same user object, if any.

return
a copy of this node

	DefaultMutableTreeNode newNode = null;

	try {
	    newNode = (DefaultMutableTreeNode)super.clone();

	    // shallow copy -- the new node has no parent or children
	    newNode.children = null;
	    newNode.parent = null;

	} catch (CloneNotSupportedException e) {
	    // Won't happen because we implement Cloneable
	    throw new Error(e.toString());
	}

	return newNode;
    
public java.util.EnumerationdepthFirstEnumeration()
Creates and returns an enumeration that traverses the subtree rooted at this node in depth-first order. The first node returned by the enumeration's nextElement() method is the leftmost leaf. This is the same as a postorder traversal.

Modifying the tree by inserting, removing, or moving a node invalidates any enumerations created before the modification.

see
#breadthFirstEnumeration
see
#postorderEnumeration
return
an enumeration for traversing the tree in depth-first order

	return postorderEnumeration();
    
public booleangetAllowsChildren()
Returns true if this node is allowed to have children.

return
true if this node allows children, else false

	return allowsChildren;
    
public TreeNodegetChildAfter(TreeNode aChild)
Returns the child in this node's child array that immediately follows aChild, which must be a child of this node. If aChild is the last child, returns null. This method performs a linear search of this node's children for aChild and is O(n) where n is the number of children; to traverse the entire array of children, use an enumeration instead.

see
#children
exception
IllegalArgumentException if aChild is null or is not a child of this node
return
the child of this node that immediately follows aChild

	if (aChild == null) {
	    throw new IllegalArgumentException("argument is null");
	}

	int index = getIndex(aChild);		// linear search

	if (index == -1) {
	    throw new IllegalArgumentException("node is not a child");
	}

	if (index < getChildCount() - 1) {
	    return getChildAt(index + 1);
	} else {
	    return null;
	}
    
public TreeNodegetChildAt(int index)
Returns the child at the specified index in this node's child array.

param
index an index into this node's child array
exception
ArrayIndexOutOfBoundsException if index is out of bounds
return
the TreeNode in this node's child array at the specified index

	if (children == null) {
	    throw new ArrayIndexOutOfBoundsException("node has no children");
	}
	return (TreeNode)children.elementAt(index);
    
public TreeNodegetChildBefore(TreeNode aChild)
Returns the child in this node's child array that immediately precedes aChild, which must be a child of this node. If aChild is the first child, returns null. This method performs a linear search of this node's children for aChild and is O(n) where n is the number of children.

exception
IllegalArgumentException if aChild is null or is not a child of this node
return
the child of this node that immediately precedes aChild

	if (aChild == null) {
	    throw new IllegalArgumentException("argument is null");
	}

	int index = getIndex(aChild);		// linear search

	if (index == -1) {
	    throw new IllegalArgumentException("argument is not a child");
	}

	if (index > 0) {
	    return getChildAt(index - 1);
	} else {
	    return null;
	}
    
public intgetChildCount()
Returns the number of children of this node.

return
an int giving the number of children of this node

	if (children == null) {
	    return 0;
	} else {
	    return children.size();
	}
    
public intgetDepth()
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.

see
#getLevel
return
the depth of the tree whose root is this node

	Object	last = null;
	Enumeration	enum_ = breadthFirstEnumeration();
	
	while (enum_.hasMoreElements()) {
	    last = enum_.nextElement();
	}
	
	if (last == null) {
	    throw new Error ("nodes should be null");
	}
	
	return ((DefaultMutableTreeNode)last).getLevel() - getLevel();
    
public TreeNodegetFirstChild()
Returns this node's first child. If this node has no children, throws NoSuchElementException.

return
the first child of this node
exception
NoSuchElementException if this node has no children

	if (getChildCount() == 0) {
	    throw new NoSuchElementException("node has no children");
	}
	return getChildAt(0);
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetFirstLeaf()
Finds and returns the first leaf that is a descendant of this node -- either this node or its first child's first leaf. Returns this node if it is a leaf.

see
#isLeaf
see
#isNodeDescendant
return
the first leaf in the subtree rooted at this node

	DefaultMutableTreeNode node = this;

	while (!node.isLeaf()) {
	    node = (DefaultMutableTreeNode)node.getFirstChild();
	}

	return node;
    
public intgetIndex(TreeNode aChild)
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
exception
IllegalArgumentException if aChild is null
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

	if (aChild == null) {
	    throw new IllegalArgumentException("argument is null");
	}

	if (!isNodeChild(aChild)) {
	    return -1;
	}
	return children.indexOf(aChild);	// linear search
    
public TreeNodegetLastChild()
Returns this node's last child. If this node has no children, throws NoSuchElementException.

return
the last child of this node
exception
NoSuchElementException if this node has no children

	if (getChildCount() == 0) {
	    throw new NoSuchElementException("node has no children");
	}
	return getChildAt(getChildCount()-1);
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetLastLeaf()
Finds and returns the last leaf that is a descendant of this node -- either this node or its last child's last leaf. Returns this node if it is a leaf.

see
#isLeaf
see
#isNodeDescendant
return
the last leaf in the subtree rooted at this node

	DefaultMutableTreeNode node = this;

	while (!node.isLeaf()) {
	    node = (DefaultMutableTreeNode)node.getLastChild();
	}

	return node;
    
public intgetLeafCount()
Returns the total number of leaves that are descendants of this node. If this node is a leaf, returns 1. This method is O(n) where n is the number of descendants of this node.

see
#isNodeAncestor
return
the number of leaves beneath this node

	int count = 0;

	TreeNode node;
	Enumeration enum_ = breadthFirstEnumeration(); // order matters not

	while (enum_.hasMoreElements()) {
	    node = (TreeNode)enum_.nextElement();
	    if (node.isLeaf()) {
		count++;
	    }
	}

	if (count < 1) {
	    throw new Error("tree has zero leaves");
	}

	return count;
    
public intgetLevel()
Returns the number of levels above this node -- the distance from the root to this node. If this node is the root, returns 0.

see
#getDepth
return
the number of levels above this node

	TreeNode ancestor;
	int levels = 0;

	ancestor = this;
	while((ancestor = ancestor.getParent()) != null){
	    levels++;
	}

	return levels;
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetNextLeaf()
Returns the leaf after this node or null if this node is the last leaf in the tree.

In this implementation of the MutableNode interface, this operation is very inefficient. In order to determine the next node, this method first performs a linear search in the parent's child-list in order to find the current node.

That implementation makes the operation suitable for short traversals from a known position. But to traverse all of the leaves in the tree, you should use depthFirstEnumeration to enumerate the nodes in the tree and use isLeaf on each node to determine which are leaves.

see
#depthFirstEnumeration
see
#isLeaf
return
returns the next leaf past this node

	DefaultMutableTreeNode nextSibling;
	DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();

	if (myParent == null)
	    return null;

	nextSibling = getNextSibling();	// linear search

	if (nextSibling != null)
	    return nextSibling.getFirstLeaf();

	return myParent.getNextLeaf();	// tail recursion
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetNextNode()
Returns the node that follows this node in a preorder traversal of this node's tree. Returns null if this node is the last node of the traversal. This is an inefficient way to traverse the entire tree; use an enumeration, instead.

see
#preorderEnumeration
return
the node that follows this node in a preorder traversal, or null if this node is last

	if (getChildCount() == 0) {
	    // No children, so look for nextSibling
	    DefaultMutableTreeNode nextSibling = getNextSibling();

	    if (nextSibling == null) {
		DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)getParent();

		do {
		    if (aNode == null) {
			return null;
		    }

		    nextSibling = aNode.getNextSibling();
		    if (nextSibling != null) {
			return nextSibling;
		    }

		    aNode = (DefaultMutableTreeNode)aNode.getParent();
		} while(true);
	    } else {
		return nextSibling;
	    }
	} else {
	    return (DefaultMutableTreeNode)getChildAt(0);
	}
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetNextSibling()
Returns the next sibling of this node in the parent's children array. Returns null if this node has no parent or is the parent's last child. This method performs a linear search that is O(n) where n is the number of children; to traverse the entire array, use the parent's child enumeration instead.

see
#children
return
the sibling of this node that immediately follows this node

	DefaultMutableTreeNode retval;

	DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();

	if (myParent == null) {
	    retval = null;
	} else {
	    retval = (DefaultMutableTreeNode)myParent.getChildAfter(this);	// linear search
	}

	if (retval != null && !isNodeSibling(retval)) {
	    throw new Error("child of parent is not a sibling");
	}

	return retval;
    
public TreeNodegetParent()
Returns this node's parent or null if this node has no parent.

return
this node's parent TreeNode, or null if this node has no parent

	return parent;
    
public TreeNode[]getPath()
Returns the path from the root, to get to this node. The last element in the path is this node.

return
an array of TreeNode objects giving the path, where the first element in the path is the root and the last element is this node.

	return getPathToRoot(this, 0);
    
protected TreeNode[]getPathToRoot(TreeNode aNode, int depth)
Builds the parents of node up to and including the root node, where the original node is the last element in the returned array. The length of the returned array gives the node's depth in the tree.

param
aNode the TreeNode to get the path for
param
depth an int giving the number of steps already taken towards the root (on recursive calls), used to size the returned array
return
an array of TreeNodes giving the path from the root to the specified node

	TreeNode[]              retNodes;

	/* Check for null, in case someone passed in a null node, or
	   they passed in an element that isn't rooted at root. */
	if(aNode == null) {
	    if(depth == 0)
		return null;
	    else
		retNodes = new TreeNode[depth];
	}
	else {
	    depth++;
	    retNodes = getPathToRoot(aNode.getParent(), depth);
	    retNodes[retNodes.length - depth] = aNode;
	}
	return retNodes;
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetPreviousLeaf()
Returns the leaf before this node or null if this node is the first leaf in the tree.

In this implementation of the MutableNode interface, this operation is very inefficient. In order to determine the previous node, this method first performs a linear search in the parent's child-list in order to find the current node.

That implementation makes the operation suitable for short traversals from a known position. But to traverse all of the leaves in the tree, you should use depthFirstEnumeration to enumerate the nodes in the tree and use isLeaf on each node to determine which are leaves.

see
#depthFirstEnumeration
see
#isLeaf
return
returns the leaf before this node

	DefaultMutableTreeNode previousSibling;
	DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();

	if (myParent == null)
	    return null;

	previousSibling = getPreviousSibling();	// linear search

	if (previousSibling != null)
	    return previousSibling.getLastLeaf();

	return myParent.getPreviousLeaf();		// tail recursion
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetPreviousNode()
Returns the node that precedes this node in a preorder traversal of this node's tree. Returns null if this node is the first node of the traversal -- the root of the tree. This is an inefficient way to traverse the entire tree; use an enumeration, instead.

see
#preorderEnumeration
return
the node that precedes this node in a preorder traversal, or null if this node is the first

	DefaultMutableTreeNode previousSibling;
	DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();

	if (myParent == null) {
	    return null;
	}

	previousSibling = getPreviousSibling();

	if (previousSibling != null) {
	    if (previousSibling.getChildCount() == 0)
		return previousSibling;
	    else
		return previousSibling.getLastLeaf();
	} else {
	    return myParent;
	}
    
public org.jaudiotagger.utils.tree.DefaultMutableTreeNodegetPreviousSibling()
Returns the previous sibling of this node in the parent's children array. Returns null if this node has no parent or is the parent's first child. This method performs a linear search that is O(n) where n is the number of children.

return
the sibling of this node that immediately precedes this node

	DefaultMutableTreeNode retval;

	DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)getParent();

	if (myParent == null) {
	    retval = null;
	} else {
	    retval = (DefaultMutableTreeNode)myParent.getChildBefore(this);	// linear search
	}

	if (retval != null && !isNodeSibling(retval)) {
	    throw new Error("child of parent is not a sibling");
	}

	return retval;
    
public TreeNodegetRoot()
Returns the root of the tree that contains this node. The root is the ancestor with a null parent.

see
#isNodeAncestor
return
the root of the tree that contains this node

	TreeNode ancestor = this;
	TreeNode previous;

	do {
	    previous = ancestor;
	    ancestor = ancestor.getParent();
	} while (ancestor != null);

	return previous;
    
public TreeNodegetSharedAncestor(org.jaudiotagger.utils.tree.DefaultMutableTreeNode aNode)
Returns the nearest common ancestor to this node and aNode. Returns null, if no such ancestor exists -- if this node and aNode are in different trees or if aNode is null. A node is considered an ancestor of itself.

see
#isNodeAncestor
see
#isNodeDescendant
param
aNode node to find common ancestor with
return
nearest ancestor common to this node and aNode, or null if none

	if (aNode == this) {
	    return this;
	} else if (aNode == null) {
	    return null;
	}

	int		level1, level2, diff;
	TreeNode	node1, node2;
	
	level1 = getLevel();
	level2 = aNode.getLevel();
	
	if (level2 > level1) {
	    diff = level2 - level1;
	    node1 = aNode;
	    node2 = this;
	} else {
	    diff = level1 - level2;
	    node1 = this;
	    node2 = aNode;
	}

	// Go up the tree until the nodes are at the same level
	while (diff > 0) {
	    node1 = node1.getParent();
	    diff--;
	}
	
	// Move up the tree until we find a common ancestor.  Since we know
	// that both nodes are at the same level, we won't cross paths
	// unknowingly (if there is a common ancestor, both nodes hit it in
	// the same iteration).
	
	do {
	    if (node1 == node2) {
		return node1;
	    }
	    node1 = node1.getParent();
	    node2 = node2.getParent();
	} while (node1 != null);// only need to check one -- they're at the
	// same level so if one is null, the other is
	
	if (node1 != null || node2 != null) {
	    throw new Error ("nodes should be null");
	}
	
	return null;
    
public intgetSiblingCount()
Returns the number of siblings of this node. A node is its own sibling (if it has no parent or no siblings, this method returns 1).

return
the number of siblings of this node

	TreeNode myParent = getParent();

	if (myParent == null) {
	    return 1;
	} else {
	    return myParent.getChildCount();
	}
    
public java.lang.ObjectgetUserObject()
Returns this node's user object.

return
the Object stored at this node by the user
see
#setUserObject
see
#toString

	return userObject;
    
public java.lang.Object[]getUserObjectPath()
Returns the user object path, from the root, to get to this node. If some of the TreeNodes in the path have null user objects, the returned path will contain nulls.

	TreeNode[]          realPath = getPath();
	Object[]            retPath = new Object[realPath.length];

	for(int counter = 0; counter < realPath.length; counter++)
	    retPath[counter] = ((DefaultMutableTreeNode)realPath[counter])
		               .getUserObject();
	return retPath;
    
public voidinsert(MutableTreeNode newChild, int childIndex)
Removes newChild from its present parent (if it has a parent), sets the child's parent to this node, and then adds the child to this node's child array at index childIndex. newChild must not be null and must not be an ancestor of this node.

param
newChild the MutableTreeNode to insert under this node
param
childIndex the index in this node's child array where this node is to be inserted
exception
ArrayIndexOutOfBoundsException if childIndex is out of bounds
exception
IllegalArgumentException if newChild is null or is an ancestor of this node
exception
IllegalStateException if this node does not allow children
see
#isNodeDescendant

	if (!allowsChildren) {
	    throw new IllegalStateException("node does not allow children");
	} else if (newChild == null) {
	    throw new IllegalArgumentException("new child is null");
	} else if (isNodeAncestor(newChild)) {
	    throw new IllegalArgumentException("new child is an ancestor");
	}

	    MutableTreeNode oldParent = (MutableTreeNode)newChild.getParent();

	    if (oldParent != null) {
		oldParent.remove(newChild);
	    }
	    newChild.setParent(this);
	    if (children == null) {
		children = new Vector();
	    }
	    children.insertElementAt(newChild, childIndex);
    
public booleanisLeaf()
Returns true if this node has no children. To distinguish between nodes that have no children and nodes that cannot have children (e.g. to distinguish files from empty directories), use this method in conjunction with getAllowsChildren

see
#getAllowsChildren
return
true if this node has no children

	return (getChildCount() == 0);
    
public booleanisNodeAncestor(TreeNode anotherNode)
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.

see
#isNodeDescendant
see
#getSharedAncestor
param
anotherNode node to test as an ancestor of this node
return
true if this node is a descendant of anotherNode

	if (anotherNode == null) {
	    return false;
	}

	TreeNode ancestor = this;

	do {
	    if (ancestor == anotherNode) {
		return true;
	    }
	} while((ancestor = ancestor.getParent()) != null);

	return false;
    
public booleanisNodeChild(TreeNode aNode)
Returns true if aNode is a child of this node. If aNode is null, this method returns false.

return
true if aNode is a child of this node; false if aNode is null

	boolean retval;

	if (aNode == null) {
	    retval = false;
	} else {
	    if (getChildCount() == 0) {
		retval = false;
	    } else {
		retval = (aNode.getParent() == this);
	    }
	}

	return retval;
    
public booleanisNodeDescendant(org.jaudiotagger.utils.tree.DefaultMutableTreeNode anotherNode)
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.

see
#isNodeAncestor
see
#getSharedAncestor
param
anotherNode node to test as descendant of this node
return
true if this node is an ancestor of anotherNode

	if (anotherNode == null)
	    return false;

	return anotherNode.isNodeAncestor(this);
    
public booleanisNodeRelated(org.jaudiotagger.utils.tree.DefaultMutableTreeNode aNode)
Returns true if and only if aNode is in the same tree as this node. Returns false if aNode is null.

see
#getSharedAncestor
see
#getRoot
return
true if aNode is in the same tree as this node; false if aNode is null

	return (aNode != null) && (getRoot() == aNode.getRoot());
    
public booleanisNodeSibling(TreeNode anotherNode)
Returns true if anotherNode is a sibling of (has the same parent as) this node. A node is its own sibling. If anotherNode is null, returns false.

param
anotherNode node to test as sibling of this node
return
true if anotherNode is a sibling of this node

	boolean retval;

	if (anotherNode == null) {
	    retval = false;
	} else if (anotherNode == this) {
	    retval = true;
	} else {
	    TreeNode  myParent = getParent();
	    retval = (myParent != null && myParent == anotherNode.getParent());

	    if (retval && !((DefaultMutableTreeNode)getParent())
		           .isNodeChild(anotherNode)) {
		throw new Error("sibling has different parent");
	    }
	}

	return retval;
    
public booleanisRoot()
Returns true if this node is the root of the tree. The root is the only node in the tree with a null parent; every tree has exactly one root.

return
true if this node is the root of its tree

	return getParent() == null;
    
public java.util.EnumerationpathFromAncestorEnumeration(TreeNode ancestor)
Creates and returns an enumeration that follows the path from ancestor to this node. The enumeration's nextElement() method first returns ancestor, then the child of ancestor that is an ancestor of this node, and so on, and finally returns this node. Creation of the enumeration is O(m) where m is the number of nodes between this node and ancestor, inclusive. Each nextElement() message is O(1).

Modifying the tree by inserting, removing, or moving a node invalidates any enumerations created before the modification.

see
#isNodeAncestor
see
#isNodeDescendant
exception
IllegalArgumentException if ancestor is not an ancestor of this node
return
an enumeration for following the path from an ancestor of this node to this one

	return new PathBetweenNodesEnumeration(ancestor, this);
    
public java.util.EnumerationpostorderEnumeration()
Creates and returns an enumeration that traverses the subtree rooted at this node in postorder. The first node returned by the enumeration's nextElement() method is the leftmost leaf. This is the same as a depth-first traversal.

Modifying the tree by inserting, removing, or moving a node invalidates any enumerations created before the modification.

see
#depthFirstEnumeration
see
#preorderEnumeration
return
an enumeration for traversing the tree in postorder

	return new PostorderEnumeration(this);
    
public java.util.EnumerationpreorderEnumeration()
Creates and returns an enumeration that traverses the subtree rooted at this node in preorder. The first node returned by the enumeration's nextElement() method is this node.

Modifying the tree by inserting, removing, or moving a node invalidates any enumerations created before the modification.

see
#postorderEnumeration
return
an enumeration for traversing the tree in preorder

	return new PreorderEnumeration(this);
    
private voidreadObject(java.io.ObjectInputStream s)

	Object[]      tValues;

	s.defaultReadObject();

	tValues = (Object[])s.readObject();

	if(tValues.length > 0 && tValues[0].equals("userObject"))
	    userObject = tValues[1];
    
public voidremove(MutableTreeNode aChild)
Removes aChild from this node's child array, giving it a null parent.

param
aChild a child of this node to remove
exception
IllegalArgumentException if aChild is null or is not a child of this node

	if (aChild == null) {
	    throw new IllegalArgumentException("argument is null");
	}

	if (!isNodeChild(aChild)) {
	    throw new IllegalArgumentException("argument is not a child");
	}
	remove(getIndex(aChild));	// linear search
    
public voidremove(int childIndex)
Removes the child at the specified index from this node's children and sets that node's parent to null. The child node to remove must be a MutableTreeNode.

param
childIndex the index in this node's child array of the child to remove
exception
ArrayIndexOutOfBoundsException if childIndex is out of bounds

	MutableTreeNode child = (MutableTreeNode)getChildAt(childIndex);
	children.removeElementAt(childIndex);
	child.setParent(null);
    
public voidremoveAllChildren()
Removes all of this node's children, setting their parents to null. If this node has no children, this method does nothing.

	for (int i = getChildCount()-1; i >= 0; i--) {
	    remove(i);
	}
    
public voidremoveFromParent()
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.

	MutableTreeNode parent = (MutableTreeNode)getParent();
	if (parent != null) {
	    parent.remove(this);
	}
    
public voidsetAllowsChildren(boolean allows)
Determines whether or not this node is allowed to have children. If allows is false, all of this node's children are removed.

Note: By default, a node allows children.

param
allows true if this node is allowed to have children

	if (allows != allowsChildren) {
	    allowsChildren = allows;
	    if (!allowsChildren) {
		removeAllChildren();
	    }
	}
    
public voidsetParent(MutableTreeNode newParent)
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 messaged from anywhere else.

param
newParent this node's new parent

	parent = newParent;
    
public voidsetUserObject(java.lang.Object userObject)
Sets the user object for this node to userObject.

param
userObject the Object that constitutes this node's user-specified data
see
#getUserObject
see
#toString

	this.userObject = userObject;
    
public java.lang.StringtoString()
Returns the result of sending toString() to this node's user object, or null if this node has no user object.

see
#getUserObject

	if (userObject == null) {
	    return null;
	} else {
	    return userObject.toString();
	}
    
private voidwriteObject(java.io.ObjectOutputStream s)

	Object[]             tValues;

	s.defaultWriteObject();
	// Save the userObject, if its Serializable.
	if(userObject != null && userObject instanceof Serializable) {
	    tValues = new Object[2];
	    tValues[0] = "userObject";
	    tValues[1] = userObject;
	}
	else
	    tValues = new Object[0];
	s.writeObject(tValues);