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