1 |
/* DefaultMutableTreeNode.java -- |
/* DefaultMutableTreeNode.java -- |
2 |
Copyright (C) 2002 Free Software Foundation, Inc. |
Copyright (C) 2002, 2004 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
38 |
|
|
39 |
package javax.swing.tree; |
package javax.swing.tree; |
40 |
|
|
41 |
|
import gnu.java.util.EmptyEnumeration; |
42 |
|
|
43 |
import java.io.IOException; |
import java.io.IOException; |
44 |
import java.io.ObjectInputStream; |
import java.io.ObjectInputStream; |
45 |
import java.io.ObjectOutputStream; |
import java.io.ObjectOutputStream; |
52 |
|
|
53 |
/** |
/** |
54 |
* DefaultMutableTreeNode |
* DefaultMutableTreeNode |
55 |
|
* |
56 |
* @author Andrew Selkirk |
* @author Andrew Selkirk |
57 |
*/ |
*/ |
58 |
public class DefaultMutableTreeNode |
public class DefaultMutableTreeNode |
59 |
implements Cloneable, MutableTreeNode, Serializable |
implements Cloneable, MutableTreeNode, Serializable |
60 |
{ |
{ |
61 |
static final long serialVersionUID = -4298474751201349152L; |
private static final long serialVersionUID = -4298474751201349152L; |
|
|
|
|
//------------------------------------------------------------- |
|
|
// Variables -------------------------------------------------- |
|
|
//------------------------------------------------------------- |
|
|
|
|
|
/** |
|
|
* EMPTY_ENUMERATION |
|
|
*/ |
|
|
public static final Enumeration EMPTY_ENUMERATION = null; // TODO |
|
|
|
|
|
/** |
|
|
* parent |
|
|
*/ |
|
|
protected MutableTreeNode parent = null; |
|
|
|
|
|
/** |
|
|
* children |
|
|
*/ |
|
|
protected Vector children = new Vector(); |
|
|
|
|
|
/** |
|
|
* userObject |
|
|
*/ |
|
|
protected transient Object userObject = ""; |
|
|
|
|
|
/** |
|
|
* allowsChildren |
|
|
*/ |
|
|
protected boolean allowsChildren = true; |
|
|
|
|
|
|
|
|
//------------------------------------------------------------- |
|
|
// Initialization --------------------------------------------- |
|
|
//------------------------------------------------------------- |
|
|
|
|
|
/** |
|
|
* Constructor DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode() { |
|
|
// TODO |
|
|
} // DefaultMutableTreeNode() |
|
|
|
|
|
/** |
|
|
* Constructor DefaultMutableTreeNode |
|
|
* @param value0 TODO |
|
|
*/ |
|
|
public DefaultMutableTreeNode(Object userObject) { |
|
|
this.userObject = userObject; |
|
|
} // DefaultMutableTreeNode() |
|
|
|
|
|
/** |
|
|
* Constructor DefaultMutableTreeNode |
|
|
* @param value0 TODO |
|
|
* @param value1 TODO |
|
|
*/ |
|
|
public DefaultMutableTreeNode(Object userObject, boolean allowsChildren) { |
|
|
this.userObject = userObject; |
|
|
this.allowsChildren = allowsChildren; |
|
|
} // DefaultMutableTreeNode() |
|
|
|
|
|
|
|
|
//------------------------------------------------------------- |
|
|
// Methods ---------------------------------------------------- |
|
|
//------------------------------------------------------------- |
|
|
|
|
|
/** |
|
|
* clone |
|
|
* @returns Object |
|
|
*/ |
|
|
public Object clone() { |
|
|
return null; // TODO |
|
|
} // clone() |
|
|
|
|
|
/** |
|
|
* toString |
|
|
* @returns String |
|
|
*/ |
|
|
public String toString() { |
|
|
if (userObject == null) { |
|
|
return null; |
|
|
} // if |
|
|
return userObject.toString(); |
|
|
} // toString() |
|
|
|
|
|
/** |
|
|
* add |
|
|
* @param value0 TODO |
|
|
*/ |
|
|
public void add(MutableTreeNode child) { |
|
|
children.add(child); |
|
|
child.setParent(this); |
|
|
} // add() |
|
|
|
|
|
/** |
|
|
* getParent |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getParent() { |
|
|
return parent; |
|
|
} // getParent() |
|
|
|
|
|
/** |
|
|
* remove |
|
|
* @param value0 TODO |
|
|
*/ |
|
|
public void remove(int index) { |
|
|
children.remove(index); |
|
|
} // remove() |
|
|
|
|
|
/** |
|
|
* remove |
|
|
* @param value0 TODO |
|
|
*/ |
|
|
public void remove(MutableTreeNode node) { |
|
|
children.remove(node); |
|
|
} // remove() |
|
|
|
|
|
/** |
|
|
* writeObject |
|
|
* @param value0 TODO |
|
|
* @exception IOException TODO |
|
|
*/ |
|
|
private void writeObject(ObjectOutputStream value0) throws IOException { |
|
|
// TODO |
|
|
} // writeObject() |
|
|
|
|
|
/** |
|
|
* readObject |
|
|
* @param value0 TODO |
|
|
* @exception IOException TODO |
|
|
* @exception ClassNotFoundException TODO |
|
|
*/ |
|
|
private void readObject(ObjectInputStream value0) throws IOException, ClassNotFoundException { |
|
|
// TODO |
|
|
} // readObject() |
|
|
|
|
|
/** |
|
|
* insert |
|
|
* @param value0 TODO |
|
|
* @param value1 TODO |
|
|
*/ |
|
|
public void insert(MutableTreeNode node, int index) { |
|
|
children.insertElementAt(node, index); |
|
|
} // insert() |
|
|
|
|
|
/** |
|
|
* getPath |
|
|
* @returns TreeNode[] |
|
|
*/ |
|
|
public TreeNode[] getPath() { |
|
|
|
|
|
// Variables |
|
|
TreeNode[] path; |
|
|
int size; |
|
|
int index; |
|
|
TreeNode current; |
|
|
|
|
|
// Determine length of Path |
|
|
size = getLevel() + 1; |
|
|
|
|
|
// Create Path |
|
|
path = new TreeNode[size]; |
|
|
current = this; |
|
|
for (index = size - 1; index >= 0; index--) { |
|
|
path[index] = current; |
|
|
current = current.getParent(); |
|
|
} // for |
|
|
|
|
|
// Return Path |
|
|
return path; |
|
|
|
|
|
} // getPath() |
|
|
|
|
|
/** |
|
|
* children |
|
|
* @returns Enumeration |
|
|
*/ |
|
|
public Enumeration children() { |
|
|
return children.elements(); |
|
|
} // children() |
|
|
|
|
|
/** |
|
|
* setParent |
|
|
* @param value0 TODO |
|
|
*/ |
|
|
public void setParent(MutableTreeNode node) { |
|
|
parent = node; |
|
|
} // setParent() |
|
|
|
|
|
/** |
|
|
* getChildAt |
|
|
* @param value0 TODO |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getChildAt(int index) { |
|
|
return (TreeNode) children.elementAt(index); |
|
|
} // getChildAt() |
|
|
|
|
|
/** |
|
|
* getChildCount |
|
|
* @returns int |
|
|
*/ |
|
|
public int getChildCount() { |
|
|
return children.size(); |
|
|
} // getChildCount() |
|
|
|
|
|
/** |
|
|
* getIndex |
|
|
* @param value0 TODO |
|
|
* @returns int |
|
|
*/ |
|
|
public int getIndex(TreeNode node) { |
|
|
return children.indexOf(node); |
|
|
} // getIndex() |
|
|
|
|
|
/** |
|
|
* setAllowsChildren |
|
|
* @param value0 TODO |
|
|
*/ |
|
|
public void setAllowsChildren(boolean allowsChildren) { |
|
|
this.allowsChildren = allowsChildren; |
|
|
} // setAllowsChildren() |
|
|
|
|
|
/** |
|
|
* getAllowsChildren |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean getAllowsChildren() { |
|
|
return allowsChildren; |
|
|
} // getAllowsChildren() |
|
|
|
|
|
/** |
|
|
* setUserObject |
|
|
* @param value0 TODO |
|
|
*/ |
|
|
public void setUserObject(Object userObject) { |
|
|
this.userObject = userObject; |
|
|
} // setUserObject() |
|
|
|
|
|
/** |
|
|
* getUserObject |
|
|
* @returns Object |
|
|
*/ |
|
|
public Object getUserObject() { |
|
|
return userObject; |
|
|
} // getUserObject() |
|
|
|
|
|
/** |
|
|
* removeFromParent |
|
|
*/ |
|
|
public void removeFromParent() { |
|
|
parent = null; |
|
|
// TODO |
|
|
} // removeFromParent() |
|
|
|
|
|
/** |
|
|
* removeAllChildren |
|
|
*/ |
|
|
public void removeAllChildren() { |
|
|
children.removeAllElements(); |
|
|
} // removeAllChildren() |
|
|
|
|
|
/** |
|
|
* isNodeAncestor |
|
|
* @param value0 TODO |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean isNodeAncestor(TreeNode node) { |
|
|
|
|
|
// Variables |
|
|
TreeNode current; |
|
|
|
|
|
// Sanity Check |
|
|
if (node == null) { |
|
|
return false; |
|
|
} // if |
|
|
|
|
|
// Search For Ancestor |
|
|
current = this; |
|
|
while (current != null && current != node) { |
|
|
current = current.getParent(); |
|
|
} // while |
|
|
|
|
|
// Check for Ancestor |
|
|
if (current == node) { |
|
|
return true; |
|
|
} // if |
|
|
|
|
|
// Otherwise, no |
|
|
return false; |
|
|
|
|
|
} // isNodeAncestor() |
|
|
|
|
|
/** |
|
|
* isNodeDescendant |
|
|
* @param value0 TODO |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean isNodeDescendant(DefaultMutableTreeNode node) { |
|
|
|
|
|
// Variables |
|
|
TreeNode current; |
|
|
|
|
|
// Sanity Check |
|
|
if (node == null) { |
|
|
return false; |
|
|
} // if |
|
|
|
|
|
// Search For Descendant |
|
|
current = node; |
|
|
while (current != null && current != this) { |
|
|
current = current.getParent(); |
|
|
} // while |
|
|
|
|
|
// Check for Descendant |
|
|
if (current == this) { |
|
|
return true; |
|
|
} // if |
|
|
|
|
|
// Otherwise, no |
|
|
return false; |
|
|
|
|
|
} // isNodeDescendant() |
|
|
|
|
|
/** |
|
|
* getSharedAncestor |
|
|
* @param value0 TODO |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getSharedAncestor(DefaultMutableTreeNode node) { |
|
|
|
|
|
// Variables |
|
|
ArrayList list; |
|
|
TreeNode current; |
|
|
|
|
|
// Get List of Path Elements for this node |
|
|
current = this; |
|
|
list = new ArrayList(); |
|
|
while (current != null) { |
|
|
list.add(current); |
|
|
current = current.getParent(); |
|
|
} // while |
|
|
|
|
|
// Check if any path element of node are in list |
|
|
current = node; |
|
|
while (current != null) { |
|
|
if (list.contains(current) == true) { |
|
|
return current; |
|
|
} // if |
|
|
current = current.getParent(); |
|
|
} // while |
|
|
|
|
|
// Unable to locate shared ancestor |
|
|
return null; |
|
|
|
|
|
} // getSharedAncestor() |
|
|
|
|
|
/** |
|
|
* isNodeRelated |
|
|
* @param value0 TODO |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean isNodeRelated(DefaultMutableTreeNode node) { |
|
|
|
|
|
// Sanity Check |
|
|
if (node == null) { |
|
|
return false; |
|
|
} // if |
|
|
|
|
|
// Check for the same root |
|
|
if (node.getRoot() == getRoot()) { |
|
|
return true; |
|
|
} // if |
|
|
|
|
|
// Nodes are not related |
|
|
return false; |
|
|
|
|
|
} // isNodeRelated() |
|
|
|
|
|
/** |
|
|
* getDepth |
|
|
* @returns int |
|
|
*/ |
|
|
public int getDepth() { |
|
|
|
|
|
// Variables |
|
|
TreeNode node; |
|
|
int depth; |
|
|
int current; |
|
|
int size; |
|
|
Stack stack; |
|
|
int index; |
|
|
|
|
|
// Check for children |
|
|
if (allowsChildren == false || children.size() == 0) { |
|
|
return 0; |
|
|
} // if |
|
|
|
|
|
// Process Depths |
|
|
stack = new Stack(); |
|
|
stack.push(new Integer(0)); |
|
|
node = getChildAt(0); |
|
|
//System.out.println(" * Descend: 0-0"); |
|
|
depth = 0; |
|
|
current = 1; |
|
|
while (stack.empty() == false) { |
|
|
|
|
|
// Check if node has children |
|
|
if (node.getChildCount() != 0) { |
|
|
node = node.getChildAt(0); |
|
|
stack.push(new Integer(0)); |
|
|
current++; |
|
|
// System.out.println(" * Descend: 0-" + current); |
|
|
|
|
|
// Check for next sibling |
|
|
} else { |
|
|
|
|
|
// Check Depth |
|
|
if (current > depth) { |
|
|
depth = current; |
|
|
} // if |
|
|
|
|
|
do { |
|
|
|
|
|
// Traverse to Parent |
|
|
node = node.getParent(); |
|
|
size = node.getChildCount(); |
|
|
current--; |
|
|
index = ((Integer) stack.pop()).intValue(); |
|
|
// System.out.println(" * Ascend from: " + index + "-" + current); |
|
|
index++; |
|
|
|
|
|
} while (index >= size && node != this); |
|
|
|
|
|
// Check for child |
|
|
if (index < size) { |
|
|
node = node.getChildAt(index); |
|
|
stack.push(new Integer(index)); |
|
|
current++; |
|
|
// System.out.println(" * Descend: " + index + "-" + current); |
|
|
} // if |
|
|
|
|
|
} // if |
|
|
|
|
|
} // while |
|
|
|
|
|
return depth; |
|
|
|
|
|
} // getDepth() |
|
|
|
|
|
static Random random = new Random(System.currentTimeMillis()); |
|
|
|
|
|
public static void growTree(DefaultMutableTreeNode root) { |
|
|
|
|
|
// Variables |
|
|
int index; |
|
|
DefaultMutableTreeNode node; |
|
|
DefaultMutableTreeNode current; |
|
|
|
|
|
current = root; |
|
|
index = 0; |
|
|
// while (current != root) { |
|
|
do { |
|
|
|
|
|
// if (random.nextInt(3) < 2) { |
|
|
if (random.nextBoolean()) { |
|
|
node = new DefaultMutableTreeNode(String.valueOf(index)); |
|
|
index++; |
|
|
current.add(node); |
|
|
current = node; |
|
|
} else { |
|
|
current = (DefaultMutableTreeNode) current.getParent(); |
|
|
} // if |
|
|
|
|
|
// } // while |
|
|
} while (current != root && current != null); |
|
|
|
|
|
System.out.println("Number of nodes: " + index); |
|
|
|
|
|
/* |
|
|
// Calc # children |
|
|
size = random.nextInt(4); |
|
|
|
|
|
for (index = 0; index < size; index++) { |
|
|
|
|
|
// Create Node |
|
|
node = new DefaultMutableTreeNode(String.valueOf(index)); |
|
|
growTree(node); |
|
|
|
|
|
// Add Node to root |
|
|
root.add(node); |
|
|
|
|
|
} // for |
|
|
*/ |
|
|
} // growTree() |
|
|
|
|
|
public static void main(String[] argv) { |
|
|
/* |
|
|
DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("node1"); |
|
|
DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("node2"); |
|
|
DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("node3"); |
|
|
DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("node4"); |
|
|
DefaultMutableTreeNode node5 = new DefaultMutableTreeNode("node5"); |
|
|
DefaultMutableTreeNode node6 = new DefaultMutableTreeNode("node6"); |
|
|
DefaultMutableTreeNode node7 = new DefaultMutableTreeNode("node7"); |
|
|
DefaultMutableTreeNode node8 = new DefaultMutableTreeNode("node8"); |
|
|
|
|
|
node1.add(node2); |
|
|
node1.add(node3); |
|
|
node2.add(node4); |
|
|
node2.add(node5); |
|
|
node3.add(node6); |
|
|
node3.add(node7); |
|
|
node5.add(node8); |
|
|
|
|
|
System.out.println("Depth (node1): " + node1.getDepth()); |
|
|
System.out.println("Depth (node2): " + node2.getDepth()); |
|
|
System.out.println("Depth (node3): " + node3.getDepth()); |
|
|
*/ |
|
|
|
|
|
System.out.println("Create tree..."); |
|
|
DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); |
|
|
growTree(root); |
|
|
System.out.println("Find depth..."); |
|
|
System.out.println("Depth (root): " + root.getDepth()); |
|
|
|
|
|
} // main |
|
|
|
|
|
/** |
|
|
* getLevel |
|
|
* @returns int |
|
|
*/ |
|
|
public int getLevel() { |
|
|
|
|
|
// Variables |
|
|
TreeNode current; |
|
|
int count; |
|
|
|
|
|
// Lookup Parent |
|
|
count = -1; |
|
|
current = this; |
|
|
do { |
|
|
current = current.getParent(); |
|
|
count++; |
|
|
} while (current != null); |
|
|
|
|
|
return count; |
|
|
|
|
|
} // getLevel() |
|
|
|
|
|
/** |
|
|
* getPathToRoot |
|
|
* @param value0 TODO |
|
|
* @param value1 TODO |
|
|
* @returns TreeNode[] |
|
|
*/ |
|
|
protected TreeNode[] getPathToRoot(TreeNode value0, int value1) { |
|
|
return null; // TODO |
|
|
} // getPathToRoot() |
|
|
|
|
|
/** |
|
|
* getUserObjectPath |
|
|
* @returns Object[] |
|
|
*/ |
|
|
public Object[] getUserObjectPath() { |
|
|
|
|
|
// Variables |
|
|
TreeNode[] path; |
|
|
Object[] object; |
|
|
int index; |
|
|
|
|
|
// Get Path for Tree Nodes |
|
|
path = getPath(); |
|
|
|
|
|
// Construct Object Path |
|
|
object = new Object[path.length]; |
|
|
for (index = 0; index < path.length; index++) { |
|
|
object[index] = ((DefaultMutableTreeNode) path[index]).getUserObject(); |
|
|
} // for |
|
|
|
|
|
// Return Object Path |
|
|
return object; |
|
|
|
|
|
} // getUserObjectPath() |
|
|
|
|
|
/** |
|
|
* getRoot |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getRoot() { |
|
|
|
|
|
// Variables |
|
|
TreeNode current; |
|
|
TreeNode check; |
|
|
|
|
|
// Lookup Parent |
|
|
current = this; |
|
|
check = current.getParent(); |
|
|
while (check != null) { |
|
|
current = check; |
|
|
check = current.getParent(); |
|
|
} // while |
|
|
|
|
|
return current; |
|
|
|
|
|
} // getRoot() |
|
|
|
|
|
/** |
|
|
* isRoot |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean isRoot() { |
|
|
return (parent == null); |
|
|
} // isRoot() |
|
|
|
|
|
/** |
|
|
* getNextNode |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getNextNode() { |
|
|
return null; // TODO |
|
|
} // getNextNode() |
|
|
|
|
|
/** |
|
|
* getPreviousNode |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getPreviousNode() { |
|
|
return null; // TODO |
|
|
} // getPreviousNode() |
|
|
|
|
|
/** |
|
|
* preorderEnumeration |
|
|
* @returns Enumeration |
|
|
*/ |
|
|
public Enumeration preorderEnumeration() { |
|
|
return null; // TODO |
|
|
} // preorderEnumeration() |
|
|
|
|
|
/** |
|
|
* postorderEnumeration |
|
|
* @returns Enumeration |
|
|
*/ |
|
|
public Enumeration postorderEnumeration() { |
|
|
return null; // TODO |
|
|
} // postorderEnumeration() |
|
|
|
|
|
/** |
|
|
* breadthFirstEnumeration |
|
|
* @returns Enumeration |
|
|
*/ |
|
|
public Enumeration breadthFirstEnumeration() { |
|
|
return null; // TODO |
|
|
} // breadthFirstEnumeration() |
|
|
|
|
|
/** |
|
|
* depthFirstEnumeration |
|
|
* @returns Enumeration |
|
|
*/ |
|
|
public Enumeration depthFirstEnumeration() { |
|
|
return null; // TODO |
|
|
} // depthFirstEnumeration() |
|
|
|
|
|
/** |
|
|
* pathFromAncestorEnumeration |
|
|
* @param value0 TODO |
|
|
* @returns Enumeration |
|
|
*/ |
|
|
public Enumeration pathFromAncestorEnumeration(TreeNode value0) { |
|
|
return null; // TODO |
|
|
} // pathFromAncestorEnumeration() |
|
|
|
|
|
/** |
|
|
* isNodeChild |
|
|
* @param value0 TODO |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean isNodeChild(TreeNode node) { |
|
|
|
|
|
// Variables |
|
|
TreeNode current; |
|
|
|
|
|
// Sanity Check |
|
|
if (node == null) { |
|
|
return false; |
|
|
} // if |
|
|
|
|
|
// Process Path |
|
|
current = node; |
|
|
while (current != null) { |
|
|
if (current == this) { |
|
|
return true; |
|
|
} // if |
|
|
current = current.getParent(); |
|
|
} // while |
|
|
|
|
|
// Node not located in path, not child |
|
|
return false; |
|
|
|
|
|
} // isNodeChild() |
|
|
|
|
|
/** |
|
|
* getFirstChild |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getFirstChild() { |
|
|
return (TreeNode) children.firstElement(); |
|
|
} // getFirstChild() |
|
|
|
|
|
/** |
|
|
* getLastChild |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getLastChild() { |
|
|
return (TreeNode) children.lastElement(); |
|
|
} // getLastChild() |
|
|
|
|
|
/** |
|
|
* getChildAfter |
|
|
* @param value0 TODO |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getChildAfter(TreeNode node) { |
|
|
|
|
|
// Variables |
|
|
int index; |
|
|
|
|
|
// Check node |
|
|
if (node == null || node.getParent() != this) { |
|
|
throw new IllegalArgumentException(); |
|
|
} // if |
|
|
|
|
|
// Get index of child node |
|
|
index = getIndex(node); |
|
|
|
|
|
// Check for child after |
|
|
index++; |
|
|
if (index == getChildCount()) { |
|
|
return null; |
|
|
} // if |
|
|
|
|
|
// Retrieve Child After |
|
|
return getChildAt(index); |
|
|
|
|
|
} // getChildAfter() |
|
|
|
|
|
/** |
|
|
* getChildBefore |
|
|
* @param value0 TODO |
|
|
* @returns TreeNode |
|
|
*/ |
|
|
public TreeNode getChildBefore(TreeNode node) { |
|
|
|
|
|
// Variables |
|
|
int index; |
|
|
|
|
|
// Check node |
|
|
if (node == null || node.getParent() != this) { |
|
|
throw new IllegalArgumentException(); |
|
|
} // if |
|
|
|
|
|
// Get index of child node |
|
|
index = getIndex(node); |
|
|
|
|
|
// Check for child before |
|
|
index--; |
|
|
if (index < 0) { |
|
|
return null; |
|
|
} // if |
|
|
|
|
|
// Retrieve Child Before |
|
|
return getChildAt(index); |
|
|
|
|
|
} // getChildBefore() |
|
|
|
|
|
/** |
|
|
* isNodeSibling |
|
|
* @param value0 TODO |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean isNodeSibling(TreeNode node) { |
|
|
|
|
|
// Check for null |
|
|
if (node == null) { |
|
|
return false; |
|
|
} // if |
|
|
|
|
|
// Check if nodes share a parent |
|
|
if (node.getParent() == getParent() && getParent() != null) { |
|
|
return true; |
|
|
} // if |
|
|
|
|
|
// Nodes are not siblings |
|
|
return false; |
|
|
|
|
|
} // isNodeSibling() |
|
|
|
|
|
/** |
|
|
* getSiblingCount |
|
|
* @returns int |
|
|
*/ |
|
|
public int getSiblingCount() { |
|
|
|
|
|
// Variables |
|
|
|
|
|
// Check for no parent |
|
|
if (parent == null) { |
|
|
return 1; |
|
|
} // if |
|
|
|
|
|
// Calculate sibling count from parent's child count |
|
|
return parent.getChildCount(); |
|
|
|
|
|
} // getSiblingCount() |
|
|
|
|
|
/** |
|
|
* getNextSibling |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getNextSibling() { |
|
|
|
|
|
// Variables |
|
|
int index; |
|
|
int size; |
|
|
|
|
|
// Check for Parent |
|
|
if (parent == null) { |
|
|
return null; |
|
|
} // if |
|
|
|
|
|
// Get Index of this node |
|
|
index = parent.getIndex(this); |
|
|
|
|
|
// Check for Next Sibling |
|
|
size = parent.getChildCount(); |
|
|
index++; |
|
|
if (index == size) { |
|
|
return null; |
|
|
} // if |
|
|
|
|
|
return (DefaultMutableTreeNode) parent.getChildAt(index); |
|
|
|
|
|
} // getNextSibling() |
|
|
|
|
|
/** |
|
|
* getPreviousSibling |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getPreviousSibling() { |
|
|
|
|
|
// Variables |
|
|
int index; |
|
|
|
|
|
// Check for Parent |
|
|
if (parent == null) { |
|
|
return null; |
|
|
} // if |
|
|
|
|
|
// Get Index of this node |
|
|
index = parent.getIndex(this); |
|
|
|
|
|
// Check for Previous Sibling |
|
|
index--; |
|
|
if (index < 0) { |
|
|
return null; |
|
|
} // if |
|
|
|
|
|
return (DefaultMutableTreeNode) parent.getChildAt(index); |
|
|
|
|
|
} // getPreviousSibling() |
|
|
|
|
|
/** |
|
|
* isLeaf |
|
|
* @returns boolean |
|
|
*/ |
|
|
public boolean isLeaf() { |
|
|
return (children.size() == 0); // TODO: check allowsChildren?? |
|
|
} // isLeaf() |
|
|
|
|
|
/** |
|
|
* getFirstLeaf |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getFirstLeaf() { |
|
|
|
|
|
// Variables |
|
|
TreeNode current; |
|
|
|
|
|
current = this; |
|
|
while (current.getChildCount() > 0) { |
|
|
current = current.getChildAt(0); |
|
|
} // while |
|
|
|
|
|
return (DefaultMutableTreeNode) current; |
|
|
|
|
|
} // getFirstLeaf() |
|
|
|
|
|
/** |
|
|
* getLastLeaf |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getLastLeaf() { |
|
|
|
|
|
// Variables |
|
|
TreeNode current; |
|
|
int size; |
|
|
|
|
|
current = this; |
|
|
size = current.getChildCount(); |
|
|
while (size > 0) { |
|
|
current = current.getChildAt(size - 1); |
|
|
size = current.getChildCount(); |
|
|
} // while |
|
|
|
|
|
return (DefaultMutableTreeNode) current; |
|
|
|
|
|
} // getLastLeaf() |
|
|
|
|
|
/** |
|
|
* getNextLeaf |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getNextLeaf() { |
|
|
return null; // TODO |
|
|
} // getNextLeaf() |
|
|
|
|
|
/** |
|
|
* getPreviousLeaf |
|
|
* @returns DefaultMutableTreeNode |
|
|
*/ |
|
|
public DefaultMutableTreeNode getPreviousLeaf() { |
|
|
return null; // TODO |
|
|
} // getPreviousLeaf() |
|
|
|
|
|
/** |
|
|
* getLeafCount |
|
|
* @returns int |
|
|
*/ |
|
|
public int getLeafCount() { |
|
|
|
|
|
// Variables |
|
|
Enumeration e; |
|
|
int count; |
|
|
TreeNode current; |
|
|
|
|
|
// Get Enumeration of all descendants |
|
|
e = depthFirstEnumeration(); |
|
|
|
|
|
// Process Nodes |
|
|
count = 0; |
|
|
while (e.hasMoreElements() == true) { |
|
|
current = (TreeNode) e.nextElement(); |
|
|
if (current.isLeaf() == true) { |
|
|
count++; |
|
|
} // if |
|
|
} // if |
|
|
|
|
|
return count; |
|
|
|
|
|
} // getLeafCount() |
|
|
|
|
62 |
|
|
63 |
} // DefaultMutableTreeNode |
/** |
64 |
|
* EMPTY_ENUMERATION |
65 |
|
*/ |
66 |
|
public static final Enumeration EMPTY_ENUMERATION = |
67 |
|
EmptyEnumeration.getInstance(); |
68 |
|
|
69 |
|
/** |
70 |
|
* parent |
71 |
|
*/ |
72 |
|
protected MutableTreeNode parent; |
73 |
|
|
74 |
|
/** |
75 |
|
* children |
76 |
|
*/ |
77 |
|
protected Vector children = new Vector(); |
78 |
|
|
79 |
|
/** |
80 |
|
* userObject |
81 |
|
*/ |
82 |
|
protected transient Object userObject; |
83 |
|
|
84 |
|
/** |
85 |
|
* allowsChildren |
86 |
|
*/ |
87 |
|
protected boolean allowsChildren; |
88 |
|
|
89 |
|
/** |
90 |
|
* Constructor DefaultMutableTreeNode |
91 |
|
*/ |
92 |
|
public DefaultMutableTreeNode() |
93 |
|
{ |
94 |
|
this(null, true); |
95 |
|
} |
96 |
|
|
97 |
|
/** |
98 |
|
* Constructor DefaultMutableTreeNode |
99 |
|
* |
100 |
|
* @param userObject TODO |
101 |
|
*/ |
102 |
|
public DefaultMutableTreeNode(Object userObject) |
103 |
|
{ |
104 |
|
this(userObject, true); |
105 |
|
} |
106 |
|
|
107 |
|
/** |
108 |
|
* Constructor DefaultMutableTreeNode |
109 |
|
* |
110 |
|
* @param userObject TODO |
111 |
|
* @param allowsChildren TODO |
112 |
|
*/ |
113 |
|
public DefaultMutableTreeNode(Object userObject, boolean allowsChildren) |
114 |
|
{ |
115 |
|
this.userObject = userObject; |
116 |
|
this.allowsChildren = allowsChildren; |
117 |
|
} |
118 |
|
|
119 |
|
/** |
120 |
|
* clone |
121 |
|
* |
122 |
|
* @return Object |
123 |
|
*/ |
124 |
|
public Object clone() |
125 |
|
{ |
126 |
|
try |
127 |
|
{ |
128 |
|
return super.clone(); |
129 |
|
// TODO: Do we need to do more here ? |
130 |
|
} |
131 |
|
catch (CloneNotSupportedException e) |
132 |
|
{ |
133 |
|
// This never happens. |
134 |
|
return null; |
135 |
|
} |
136 |
|
} |
137 |
|
|
138 |
|
/** |
139 |
|
* toString |
140 |
|
* |
141 |
|
* @return String |
142 |
|
*/ |
143 |
|
public String toString() |
144 |
|
{ |
145 |
|
if (userObject == null) |
146 |
|
return null; |
147 |
|
|
148 |
|
return userObject.toString(); |
149 |
|
} |
150 |
|
|
151 |
|
/** |
152 |
|
* add |
153 |
|
* |
154 |
|
* @param child TODO |
155 |
|
* |
156 |
|
* @throws IllegalArgumentException if <code>child</code> is null |
157 |
|
* @throws IllegalStateException if the node does not allow children |
158 |
|
*/ |
159 |
|
public void add(MutableTreeNode child) |
160 |
|
{ |
161 |
|
if (child == null) |
162 |
|
throw new IllegalArgumentException(); |
163 |
|
|
164 |
|
if (! allowsChildren) |
165 |
|
throw new IllegalStateException(); |
166 |
|
|
167 |
|
children.add(child); |
168 |
|
child.setParent(this); |
169 |
|
} |
170 |
|
|
171 |
|
/** |
172 |
|
* getParent |
173 |
|
* |
174 |
|
* @return TreeNode |
175 |
|
*/ |
176 |
|
public TreeNode getParent() |
177 |
|
{ |
178 |
|
return parent; |
179 |
|
} |
180 |
|
|
181 |
|
/** |
182 |
|
* remove |
183 |
|
* |
184 |
|
* @param index TODO |
185 |
|
*/ |
186 |
|
public void remove(int index) |
187 |
|
{ |
188 |
|
children.remove(index); |
189 |
|
} |
190 |
|
|
191 |
|
/** |
192 |
|
* remove |
193 |
|
* |
194 |
|
* @param node TODO |
195 |
|
*/ |
196 |
|
public void remove(MutableTreeNode node) |
197 |
|
{ |
198 |
|
children.remove(node); |
199 |
|
} |
200 |
|
|
201 |
|
/** |
202 |
|
* writeObject |
203 |
|
* |
204 |
|
* @param stream TODO |
205 |
|
* |
206 |
|
* @exception IOException If an error occurs |
207 |
|
*/ |
208 |
|
private void writeObject(ObjectOutputStream stream) |
209 |
|
throws IOException |
210 |
|
{ |
211 |
|
// TODO: Implement me. |
212 |
|
} |
213 |
|
|
214 |
|
/** |
215 |
|
* readObject |
216 |
|
* |
217 |
|
* @param stream TODO |
218 |
|
* |
219 |
|
* @exception IOException If an error occurs |
220 |
|
* @exception ClassNotFoundException TODO |
221 |
|
*/ |
222 |
|
private void readObject(ObjectInputStream stream) |
223 |
|
throws IOException, ClassNotFoundException |
224 |
|
{ |
225 |
|
// TODO: Implement me. |
226 |
|
} |
227 |
|
|
228 |
|
/** |
229 |
|
* insert |
230 |
|
* |
231 |
|
* @param node TODO |
232 |
|
* @param value TODO |
233 |
|
*/ |
234 |
|
public void insert(MutableTreeNode node, int index) |
235 |
|
{ |
236 |
|
children.insertElementAt(node, index); |
237 |
|
} |
238 |
|
|
239 |
|
/** |
240 |
|
* getPath |
241 |
|
* |
242 |
|
* @return an array of tree nodes |
243 |
|
*/ |
244 |
|
public TreeNode[] getPath() |
245 |
|
{ |
246 |
|
return getPathToRoot(this, 0); |
247 |
|
} |
248 |
|
|
249 |
|
/** |
250 |
|
* children |
251 |
|
* |
252 |
|
* @return an enumeration of tree nodes |
253 |
|
*/ |
254 |
|
public Enumeration children() |
255 |
|
{ |
256 |
|
if (children.size() == 0) |
257 |
|
return EMPTY_ENUMERATION; |
258 |
|
|
259 |
|
return children.elements(); |
260 |
|
} |
261 |
|
|
262 |
|
/** |
263 |
|
* setParent |
264 |
|
* |
265 |
|
* @param node TODO |
266 |
|
*/ |
267 |
|
public void setParent(MutableTreeNode node) |
268 |
|
{ |
269 |
|
parent = node; |
270 |
|
} |
271 |
|
|
272 |
|
/** |
273 |
|
* getChildAt |
274 |
|
* |
275 |
|
* @param index TODO |
276 |
|
* |
277 |
|
* @return TreeNode |
278 |
|
*/ |
279 |
|
public TreeNode getChildAt(int index) |
280 |
|
{ |
281 |
|
return (TreeNode) children.elementAt(index); |
282 |
|
} |
283 |
|
|
284 |
|
/** |
285 |
|
* getChildCount |
286 |
|
* |
287 |
|
* @return int |
288 |
|
*/ |
289 |
|
public int getChildCount() |
290 |
|
{ |
291 |
|
return children.size(); |
292 |
|
} |
293 |
|
|
294 |
|
/** |
295 |
|
* getIndex |
296 |
|
* |
297 |
|
* @param node TODO |
298 |
|
* |
299 |
|
* @return int |
300 |
|
*/ |
301 |
|
public int getIndex(TreeNode node) |
302 |
|
{ |
303 |
|
return children.indexOf(node); |
304 |
|
} |
305 |
|
|
306 |
|
/** |
307 |
|
* setAllowsChildren |
308 |
|
* |
309 |
|
* @param allowsChildren TODO |
310 |
|
*/ |
311 |
|
public void setAllowsChildren(boolean allowsChildren) |
312 |
|
{ |
313 |
|
this.allowsChildren = allowsChildren; |
314 |
|
} |
315 |
|
|
316 |
|
/** |
317 |
|
* getAllowsChildren |
318 |
|
* |
319 |
|
* @return boolean |
320 |
|
*/ |
321 |
|
public boolean getAllowsChildren() |
322 |
|
{ |
323 |
|
return allowsChildren; |
324 |
|
} |
325 |
|
|
326 |
|
/** |
327 |
|
* setUserObject |
328 |
|
* |
329 |
|
* @param userObject TODO |
330 |
|
*/ |
331 |
|
public void setUserObject(Object userObject) |
332 |
|
{ |
333 |
|
this.userObject = userObject; |
334 |
|
} |
335 |
|
|
336 |
|
/** |
337 |
|
* getUserObject |
338 |
|
* |
339 |
|
* @return Object |
340 |
|
*/ |
341 |
|
public Object getUserObject() |
342 |
|
{ |
343 |
|
return userObject; |
344 |
|
} |
345 |
|
|
346 |
|
/** |
347 |
|
* removeFromParent |
348 |
|
*/ |
349 |
|
public void removeFromParent() |
350 |
|
{ |
351 |
|
parent = null; |
352 |
|
} |
353 |
|
|
354 |
|
/** |
355 |
|
* removeAllChildren |
356 |
|
*/ |
357 |
|
public void removeAllChildren() |
358 |
|
{ |
359 |
|
children.removeAllElements(); |
360 |
|
} |
361 |
|
|
362 |
|
/** |
363 |
|
* isNodeAncestor |
364 |
|
* |
365 |
|
* @param node TODO |
366 |
|
* |
367 |
|
* @return boolean |
368 |
|
*/ |
369 |
|
public boolean isNodeAncestor(TreeNode node) |
370 |
|
{ |
371 |
|
if (node == null) |
372 |
|
return false; |
373 |
|
|
374 |
|
TreeNode current = this; |
375 |
|
|
376 |
|
while (current != null |
377 |
|
&& current != node) |
378 |
|
current = current.getParent(); |
379 |
|
|
380 |
|
return current == node; |
381 |
|
} |
382 |
|
|
383 |
|
/** |
384 |
|
* isNodeDescendant |
385 |
|
* |
386 |
|
* @param node0 TODO |
387 |
|
* |
388 |
|
* @return boolean |
389 |
|
*/ |
390 |
|
public boolean isNodeDescendant(DefaultMutableTreeNode node) |
391 |
|
{ |
392 |
|
if (node == null) |
393 |
|
return false; |
394 |
|
|
395 |
|
TreeNode current = node; |
396 |
|
|
397 |
|
while (current != null |
398 |
|
&& current != this) |
399 |
|
current = current.getParent(); |
400 |
|
|
401 |
|
return current == this; |
402 |
|
} |
403 |
|
|
404 |
|
/** |
405 |
|
* getSharedAncestor |
406 |
|
* |
407 |
|
* @param node TODO |
408 |
|
* |
409 |
|
* @return TreeNode |
410 |
|
*/ |
411 |
|
public TreeNode getSharedAncestor(DefaultMutableTreeNode node) |
412 |
|
{ |
413 |
|
TreeNode current = this; |
414 |
|
ArrayList list = new ArrayList(); |
415 |
|
|
416 |
|
while (current != null) |
417 |
|
{ |
418 |
|
list.add(current); |
419 |
|
current = current.getParent(); |
420 |
|
} |
421 |
|
|
422 |
|
current = node; |
423 |
|
|
424 |
|
while (current != null) |
425 |
|
{ |
426 |
|
if (list.contains(current)) |
427 |
|
return current; |
428 |
|
|
429 |
|
current = current.getParent(); |
430 |
|
} |
431 |
|
|
432 |
|
return null; |
433 |
|
} |
434 |
|
|
435 |
|
/** |
436 |
|
* isNodeRelated |
437 |
|
* |
438 |
|
* @param node TODO |
439 |
|
* |
440 |
|
* @return boolean |
441 |
|
*/ |
442 |
|
public boolean isNodeRelated(DefaultMutableTreeNode node) |
443 |
|
{ |
444 |
|
if (node == null) |
445 |
|
return false; |
446 |
|
|
447 |
|
return node.getRoot() == getRoot(); |
448 |
|
} |
449 |
|
|
450 |
|
/** |
451 |
|
* getDepth |
452 |
|
* |
453 |
|
* @return int |
454 |
|
*/ |
455 |
|
public int getDepth() |
456 |
|
{ |
457 |
|
if ((! allowsChildren) |
458 |
|
|| children.size() == 0) |
459 |
|
return 0; |
460 |
|
|
461 |
|
Stack stack = new Stack(); |
462 |
|
stack.push(new Integer(0)); |
463 |
|
TreeNode node = getChildAt(0); |
464 |
|
int depth = 0; |
465 |
|
int current = 1; |
466 |
|
|
467 |
|
while (! stack.empty()) |
468 |
|
{ |
469 |
|
if (node.getChildCount() != 0) |
470 |
|
{ |
471 |
|
node = node.getChildAt(0); |
472 |
|
stack.push(new Integer(0)); |
473 |
|
current++; |
474 |
|
} |
475 |
|
else |
476 |
|
{ |
477 |
|
if (current > depth) |
478 |
|
depth = current; |
479 |
|
|
480 |
|
int size; |
481 |
|
int index; |
482 |
|
|
483 |
|
do |
484 |
|
{ |
485 |
|
node = node.getParent(); |
486 |
|
size = node.getChildCount(); |
487 |
|
index = ((Integer) stack.pop()).intValue() + 1; |
488 |
|
current--; |
489 |
|
} |
490 |
|
while (index >= size |
491 |
|
&& node != this); |
492 |
|
|
493 |
|
if (index < size) |
494 |
|
{ |
495 |
|
node = node.getChildAt(index); |
496 |
|
stack.push(new Integer(index)); |
497 |
|
current++; |
498 |
|
} |
499 |
|
} |
500 |
|
} |
501 |
|
|
502 |
|
return depth; |
503 |
|
} |
504 |
|
|
505 |
|
static Random random = new Random(System.currentTimeMillis()); |
506 |
|
|
507 |
|
public static void growTree(DefaultMutableTreeNode root) |
508 |
|
{ |
509 |
|
DefaultMutableTreeNode node; |
510 |
|
|
511 |
|
DefaultMutableTreeNode current = root; |
512 |
|
int index = 0; |
513 |
|
|
514 |
|
do |
515 |
|
{ |
516 |
|
if (random.nextBoolean()) |
517 |
|
{ |
518 |
|
node = new DefaultMutableTreeNode(String.valueOf(index)); |
519 |
|
index++; |
520 |
|
current.add(node); |
521 |
|
current = node; |
522 |
|
} |
523 |
|
else |
524 |
|
{ |
525 |
|
current = (DefaultMutableTreeNode) current.getParent(); |
526 |
|
} |
527 |
|
} |
528 |
|
while (current != root |
529 |
|
&& current != null); |
530 |
|
} |
531 |
|
|
532 |
|
/** |
533 |
|
* getLevel |
534 |
|
* |
535 |
|
* @return int |
536 |
|
*/ |
537 |
|
public int getLevel() |
538 |
|
{ |
539 |
|
int count = -1; |
540 |
|
TreeNode current = this; |
541 |
|
|
542 |
|
do |
543 |
|
{ |
544 |
|
current = current.getParent(); |
545 |
|
count++; |
546 |
|
} |
547 |
|
while (current != null); |
548 |
|
|
549 |
|
return count; |
550 |
|
} |
551 |
|
|
552 |
|
/** |
553 |
|
* getPathToRoot |
554 |
|
* |
555 |
|
* @param node TODO |
556 |
|
* @param depth TODO |
557 |
|
* |
558 |
|
* @return TreeNode[] |
559 |
|
*/ |
560 |
|
protected TreeNode[] getPathToRoot(TreeNode node, int depth) |
561 |
|
{ |
562 |
|
if (node == null) |
563 |
|
{ |
564 |
|
if (depth == 0) |
565 |
|
return null; |
566 |
|
|
567 |
|
return new TreeNode[depth]; |
568 |
|
} |
569 |
|
|
570 |
|
TreeNode[] path = getPathToRoot(node.getParent(), depth + 1); |
571 |
|
path[depth] = node; |
572 |
|
return path; |
573 |
|
} |
574 |
|
|
575 |
|
/** |
576 |
|
* getUserObjectPath |
577 |
|
* |
578 |
|
* @return Object[] |
579 |
|
*/ |
580 |
|
public Object[] getUserObjectPath() |
581 |
|
{ |
582 |
|
TreeNode[] path = getPathToRoot(this, 0); |
583 |
|
Object[] object = new Object[path.length]; |
584 |
|
|
585 |
|
for (int index = 0; index < path.length; ++index) |
586 |
|
object[index] = ((DefaultMutableTreeNode) path[index]).getUserObject(); |
587 |
|
|
588 |
|
return object; |
589 |
|
} |
590 |
|
|
591 |
|
/** |
592 |
|
* getRoot |
593 |
|
* |
594 |
|
* @return TreeNode |
595 |
|
*/ |
596 |
|
public TreeNode getRoot() |
597 |
|
{ |
598 |
|
TreeNode current = this; |
599 |
|
TreeNode check = current.getParent(); |
600 |
|
|
601 |
|
while (check != null) |
602 |
|
{ |
603 |
|
current = check; |
604 |
|
check = current.getParent(); |
605 |
|
} |
606 |
|
|
607 |
|
return current; |
608 |
|
} |
609 |
|
|
610 |
|
/** |
611 |
|
* isRoot |
612 |
|
* |
613 |
|
* @return boolean |
614 |
|
*/ |
615 |
|
public boolean isRoot() |
616 |
|
{ |
617 |
|
return (parent == null); |
618 |
|
} |
619 |
|
|
620 |
|
/** |
621 |
|
* getNextNode |
622 |
|
* |
623 |
|
* @return DefaultMutableTreeNode |
624 |
|
*/ |
625 |
|
public DefaultMutableTreeNode getNextNode() |
626 |
|
{ |
627 |
|
// Return first child. |
628 |
|
if (getChildCount() != 0) |
629 |
|
return (DefaultMutableTreeNode) getChildAt(0); |
630 |
|
|
631 |
|
// Return next sibling (if needed the sibling of some parent). |
632 |
|
DefaultMutableTreeNode node = this; |
633 |
|
DefaultMutableTreeNode sibling; |
634 |
|
|
635 |
|
do |
636 |
|
{ |
637 |
|
sibling = node.getNextSibling(); |
638 |
|
node = (DefaultMutableTreeNode) node.getParent(); |
639 |
|
} |
640 |
|
while (sibling == null && |
641 |
|
node != null); |
642 |
|
|
643 |
|
// Return sibling. |
644 |
|
return sibling; |
645 |
|
} |
646 |
|
|
647 |
|
/** |
648 |
|
* getPreviousNode |
649 |
|
* |
650 |
|
* @return DefaultMutableTreeNode |
651 |
|
*/ |
652 |
|
public DefaultMutableTreeNode getPreviousNode() |
653 |
|
{ |
654 |
|
// Return null if no parent. |
655 |
|
if (parent == null) |
656 |
|
return null; |
657 |
|
|
658 |
|
DefaultMutableTreeNode sibling = getPreviousSibling(); |
659 |
|
|
660 |
|
// Return parent if no sibling. |
661 |
|
if (sibling == null) |
662 |
|
return (DefaultMutableTreeNode) parent; |
663 |
|
|
664 |
|
// Return last leaf of sibling. |
665 |
|
if (sibling.getChildCount() != 0) |
666 |
|
return sibling.getLastLeaf(); |
667 |
|
|
668 |
|
// Return sibling. |
669 |
|
return sibling; |
670 |
|
} |
671 |
|
|
672 |
|
/** |
673 |
|
* preorderEnumeration |
674 |
|
* |
675 |
|
* @return Enumeration |
676 |
|
*/ |
677 |
|
public Enumeration preorderEnumeration() |
678 |
|
{ |
679 |
|
return null; // TODO: Implement me. |
680 |
|
} |
681 |
|
|
682 |
|
/** |
683 |
|
* postorderEnumeration |
684 |
|
* |
685 |
|
* @return Enumeration |
686 |
|
*/ |
687 |
|
public Enumeration postorderEnumeration() |
688 |
|
{ |
689 |
|
return null; // TODO: Implement me. |
690 |
|
} |
691 |
|
|
692 |
|
/** |
693 |
|
* breadthFirstEnumeration |
694 |
|
* |
695 |
|
* @return Enumeration |
696 |
|
*/ |
697 |
|
public Enumeration breadthFirstEnumeration() |
698 |
|
{ |
699 |
|
return null; // TODO: Implement me. |
700 |
|
} |
701 |
|
|
702 |
|
/** |
703 |
|
* depthFirstEnumeration |
704 |
|
* |
705 |
|
* @return Enumeration |
706 |
|
*/ |
707 |
|
public Enumeration depthFirstEnumeration() |
708 |
|
{ |
709 |
|
return postorderEnumeration(); |
710 |
|
} |
711 |
|
|
712 |
|
/** |
713 |
|
* pathFromAncestorEnumeration |
714 |
|
* |
715 |
|
* @param node TODO |
716 |
|
* |
717 |
|
* @return Enumeration |
718 |
|
*/ |
719 |
|
public Enumeration pathFromAncestorEnumeration(TreeNode node) |
720 |
|
{ |
721 |
|
if (node == null) |
722 |
|
throw new IllegalArgumentException(); |
723 |
|
|
724 |
|
TreeNode parent = this; |
725 |
|
Vector nodes = new Vector(); |
726 |
|
nodes.add(this); |
727 |
|
|
728 |
|
while (parent != node && parent != null) |
729 |
|
{ |
730 |
|
parent = parent.getParent(); |
731 |
|
nodes.add(0, parent); |
732 |
|
} |
733 |
|
|
734 |
|
if (parent != node) |
735 |
|
throw new IllegalArgumentException(); |
736 |
|
|
737 |
|
return nodes.elements(); |
738 |
|
} |
739 |
|
|
740 |
|
/** |
741 |
|
* isNodeChild |
742 |
|
* |
743 |
|
* @param node TODO |
744 |
|
* |
745 |
|
* @return boolean |
746 |
|
*/ |
747 |
|
public boolean isNodeChild(TreeNode node) |
748 |
|
{ |
749 |
|
if (node == null) |
750 |
|
return false; |
751 |
|
|
752 |
|
return node.getParent() == this; |
753 |
|
} |
754 |
|
|
755 |
|
/** |
756 |
|
* getFirstChild |
757 |
|
* |
758 |
|
* @return TreeNode |
759 |
|
*/ |
760 |
|
public TreeNode getFirstChild() |
761 |
|
{ |
762 |
|
return (TreeNode) children.firstElement(); |
763 |
|
} |
764 |
|
|
765 |
|
/** |
766 |
|
* getLastChild |
767 |
|
* |
768 |
|
* @return TreeNode |
769 |
|
*/ |
770 |
|
public TreeNode getLastChild() |
771 |
|
{ |
772 |
|
return (TreeNode) children.lastElement(); |
773 |
|
} |
774 |
|
|
775 |
|
/** |
776 |
|
* getChildAfter |
777 |
|
* |
778 |
|
* @param node TODO |
779 |
|
* |
780 |
|
* @return TreeNode |
781 |
|
*/ |
782 |
|
public TreeNode getChildAfter(TreeNode node) |
783 |
|
{ |
784 |
|
if (node == null |
785 |
|
|| node.getParent() != this) |
786 |
|
throw new IllegalArgumentException(); |
787 |
|
|
788 |
|
int index = getIndex(node) + 1; |
789 |
|
|
790 |
|
if (index == getChildCount()) |
791 |
|
return null; |
792 |
|
|
793 |
|
return getChildAt(index); |
794 |
|
} |
795 |
|
|
796 |
|
/** |
797 |
|
* getChildBefore |
798 |
|
* |
799 |
|
* @param node TODO |
800 |
|
* |
801 |
|
* @return TreeNode |
802 |
|
*/ |
803 |
|
public TreeNode getChildBefore(TreeNode node) |
804 |
|
{ |
805 |
|
if (node == null |
806 |
|
|| node.getParent() != this) |
807 |
|
throw new IllegalArgumentException(); |
808 |
|
|
809 |
|
int index = getIndex(node) - 1; |
810 |
|
|
811 |
|
if (index < 0) |
812 |
|
return null; |
813 |
|
|
814 |
|
return getChildAt(index); |
815 |
|
} |
816 |
|
|
817 |
|
/** |
818 |
|
* isNodeSibling |
819 |
|
* |
820 |
|
* @param node TODO |
821 |
|
* |
822 |
|
* @return boolean |
823 |
|
*/ |
824 |
|
public boolean isNodeSibling(TreeNode node) |
825 |
|
{ |
826 |
|
if (node == null) |
827 |
|
return false; |
828 |
|
|
829 |
|
return (node.getParent() == getParent() |
830 |
|
&& getParent() != null); |
831 |
|
} |
832 |
|
|
833 |
|
/** |
834 |
|
* getSiblingCount |
835 |
|
* |
836 |
|
* @return int |
837 |
|
*/ |
838 |
|
public int getSiblingCount() |
839 |
|
{ |
840 |
|
if (parent == null) |
841 |
|
return 1; |
842 |
|
|
843 |
|
return parent.getChildCount(); |
844 |
|
} |
845 |
|
|
846 |
|
/** |
847 |
|
* getNextSibling |
848 |
|
* |
849 |
|
* @return DefaultMutableTreeNode |
850 |
|
*/ |
851 |
|
public DefaultMutableTreeNode getNextSibling() |
852 |
|
{ |
853 |
|
if (parent == null) |
854 |
|
return null; |
855 |
|
|
856 |
|
int index = parent.getIndex(this) + 1; |
857 |
|
|
858 |
|
if (index == parent.getChildCount()) |
859 |
|
return null; |
860 |
|
|
861 |
|
return (DefaultMutableTreeNode) parent.getChildAt(index); |
862 |
|
} |
863 |
|
|
864 |
|
/** |
865 |
|
* getPreviousSibling |
866 |
|
* |
867 |
|
* @return DefaultMutableTreeNode |
868 |
|
*/ |
869 |
|
public DefaultMutableTreeNode getPreviousSibling() |
870 |
|
{ |
871 |
|
if (parent == null) |
872 |
|
return null; |
873 |
|
|
874 |
|
int index = parent.getIndex(this) - 1; |
875 |
|
|
876 |
|
if (index < 0) |
877 |
|
return null; |
878 |
|
|
879 |
|
return (DefaultMutableTreeNode) parent.getChildAt(index); |
880 |
|
} |
881 |
|
|
882 |
|
/** |
883 |
|
* isLeaf |
884 |
|
* |
885 |
|
* @return boolean |
886 |
|
*/ |
887 |
|
public boolean isLeaf() |
888 |
|
{ |
889 |
|
return children.size() == 0; |
890 |
|
} |
891 |
|
|
892 |
|
/** |
893 |
|
* getFirstLeaf |
894 |
|
* |
895 |
|
* @return DefaultMutableTreeNode |
896 |
|
*/ |
897 |
|
public DefaultMutableTreeNode getFirstLeaf() |
898 |
|
{ |
899 |
|
TreeNode current = this; |
900 |
|
|
901 |
|
while (current.getChildCount() > 0) |
902 |
|
current = current.getChildAt(0); |
903 |
|
|
904 |
|
return (DefaultMutableTreeNode) current; |
905 |
|
} |
906 |
|
|
907 |
|
/** |
908 |
|
* getLastLeaf |
909 |
|
* |
910 |
|
* @return DefaultMutableTreeNode |
911 |
|
*/ |
912 |
|
public DefaultMutableTreeNode getLastLeaf() |
913 |
|
{ |
914 |
|
TreeNode current = this; |
915 |
|
int size = current.getChildCount(); |
916 |
|
|
917 |
|
while (size > 0) |
918 |
|
{ |
919 |
|
current = current.getChildAt(size - 1); |
920 |
|
size = current.getChildCount(); |
921 |
|
} |
922 |
|
|
923 |
|
return (DefaultMutableTreeNode) current; |
924 |
|
} |
925 |
|
|
926 |
|
/** |
927 |
|
* getNextLeaf |
928 |
|
* |
929 |
|
* @return DefaultMutableTreeNode |
930 |
|
*/ |
931 |
|
public DefaultMutableTreeNode getNextLeaf() |
932 |
|
{ |
933 |
|
if (parent == null) |
934 |
|
return null; |
935 |
|
|
936 |
|
return null; |
937 |
|
//return parent.getChildAfter(this); |
938 |
|
} |
939 |
|
|
940 |
|
/** |
941 |
|
* getPreviousLeaf |
942 |
|
* |
943 |
|
* @return DefaultMutableTreeNode |
944 |
|
*/ |
945 |
|
public DefaultMutableTreeNode getPreviousLeaf() |
946 |
|
{ |
947 |
|
if (parent == null) |
948 |
|
return null; |
949 |
|
|
950 |
|
return null; |
951 |
|
//return parent.getChildBefore(this); |
952 |
|
} |
953 |
|
|
954 |
|
/** |
955 |
|
* getLeafCount |
956 |
|
* |
957 |
|
* @return int |
958 |
|
*/ |
959 |
|
public int getLeafCount() |
960 |
|
{ |
961 |
|
int count = 0; |
962 |
|
Enumeration e = depthFirstEnumeration(); |
963 |
|
|
964 |
|
while (e.hasMoreElements()) |
965 |
|
{ |
966 |
|
TreeNode current = (TreeNode) e.nextElement(); |
967 |
|
|
968 |
|
if (current.isLeaf()) |
969 |
|
count++; |
970 |
|
} |
971 |
|
|
972 |
|
return count; |
973 |
|
} |
974 |
|
} |