Methods Summary |
---|
public void | add(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.
if(newChild != null && newChild.getParent() == this)
insert(newChild, getChildCount() - 1);
else
insert(newChild, getChildCount());
|
public java.util.Enumeration | breadthFirstEnumeration()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.
return new BreadthFirstEnumeration(this);
|
public java.util.Enumeration | children()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.
if (children == null) {
return EMPTY_ENUMERATION;
} else {
return children.elements();
}
|
public java.lang.Object | clone()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.
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.Enumeration | depthFirstEnumeration()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.
return postorderEnumeration();
|
public boolean | getAllowsChildren()Returns true if this node is allowed to have children.
return allowsChildren;
|
public TreeNode | getChildAfter(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.
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 TreeNode | getChildAt(int index)Returns the child at the specified index in this node's child array.
if (children == null) {
throw new ArrayIndexOutOfBoundsException("node has no children");
}
return (TreeNode)children.elementAt(index);
|
public TreeNode | getChildBefore(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.
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 int | getChildCount()Returns the number of children of this node.
if (children == null) {
return 0;
} else {
return children.size();
}
|
public int | getDepth()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.
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 TreeNode | getFirstChild()Returns this node's first child. If this node has no children,
throws NoSuchElementException.
if (getChildCount() == 0) {
throw new NoSuchElementException("node has no children");
}
return getChildAt(0);
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getFirstLeaf()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.
DefaultMutableTreeNode node = this;
while (!node.isLeaf()) {
node = (DefaultMutableTreeNode)node.getFirstChild();
}
return node;
|
public int | getIndex(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.
if (aChild == null) {
throw new IllegalArgumentException("argument is null");
}
if (!isNodeChild(aChild)) {
return -1;
}
return children.indexOf(aChild); // linear search
|
public TreeNode | getLastChild()Returns this node's last child. If this node has no children,
throws NoSuchElementException.
if (getChildCount() == 0) {
throw new NoSuchElementException("node has no children");
}
return getChildAt(getChildCount()-1);
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getLastLeaf()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.
DefaultMutableTreeNode node = this;
while (!node.isLeaf()) {
node = (DefaultMutableTreeNode)node.getLastChild();
}
return node;
|
public int | getLeafCount()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.
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 int | getLevel()Returns the number of levels above this node -- the distance from
the root to this node. If this node is the root, returns 0.
TreeNode ancestor;
int levels = 0;
ancestor = this;
while((ancestor = ancestor.getParent()) != null){
levels++;
}
return levels;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getNextLeaf()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.
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.DefaultMutableTreeNode | getNextNode()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.
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.DefaultMutableTreeNode | getNextSibling()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.
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 TreeNode | getParent()Returns this node's parent 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 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.
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.DefaultMutableTreeNode | getPreviousLeaf()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.
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.DefaultMutableTreeNode | getPreviousNode()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.
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.DefaultMutableTreeNode | getPreviousSibling()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.
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 TreeNode | getRoot()Returns the root of the tree that contains this node. The root is
the ancestor with a null parent.
TreeNode ancestor = this;
TreeNode previous;
do {
previous = ancestor;
ancestor = ancestor.getParent();
} while (ancestor != null);
return previous;
|
public TreeNode | getSharedAncestor(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.
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 int | getSiblingCount()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 ).
TreeNode myParent = getParent();
if (myParent == null) {
return 1;
} else {
return myParent.getChildCount();
}
|
public java.lang.Object | getUserObject()Returns this node's user object.
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 void | insert(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.
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 boolean | isLeaf()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
return (getChildCount() == 0);
|
public boolean | isNodeAncestor(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.
if (anotherNode == null) {
return false;
}
TreeNode ancestor = this;
do {
if (ancestor == anotherNode) {
return true;
}
} while((ancestor = ancestor.getParent()) != null);
return false;
|
public boolean | isNodeChild(TreeNode aNode)Returns true if aNode is a child of this node. If
aNode is null, this method returns false.
boolean retval;
if (aNode == null) {
retval = false;
} else {
if (getChildCount() == 0) {
retval = false;
} else {
retval = (aNode.getParent() == this);
}
}
return retval;
|
public boolean | isNodeDescendant(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 .
if (anotherNode == null)
return false;
return anotherNode.isNodeAncestor(this);
|
public boolean | isNodeRelated(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.
return (aNode != null) && (getRoot() == aNode.getRoot());
|
public boolean | isNodeSibling(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.
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 boolean | isRoot()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 getParent() == null;
|
public java.util.Enumeration | pathFromAncestorEnumeration(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.
return new PathBetweenNodesEnumeration(ancestor, this);
|
public java.util.Enumeration | postorderEnumeration()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.
return new PostorderEnumeration(this);
|
public java.util.Enumeration | preorderEnumeration()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.
return new PreorderEnumeration(this);
|
private void | readObject(java.io.ObjectInputStream s)
Object[] tValues;
s.defaultReadObject();
tValues = (Object[])s.readObject();
if(tValues.length > 0 && tValues[0].equals("userObject"))
userObject = tValues[1];
|
public void | remove(MutableTreeNode aChild)Removes aChild from this node's child array, giving it a
null parent.
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 void | remove(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 .
MutableTreeNode child = (MutableTreeNode)getChildAt(childIndex);
children.removeElementAt(childIndex);
child.setParent(null);
|
public void | removeAllChildren()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 void | removeFromParent()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 void | setAllowsChildren(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.
if (allows != allowsChildren) {
allowsChildren = allows;
if (!allowsChildren) {
removeAllChildren();
}
}
|
public void | setParent(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.
parent = newParent;
|
public void | setUserObject(java.lang.Object userObject)Sets the user object for this node to userObject .
this.userObject = userObject;
|
public java.lang.String | toString()Returns the result of sending toString() to this node's
user object, or null if this node has no user object.
if (userObject == null) {
return null;
} else {
return userObject.toString();
}
|
private void | writeObject(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);
|