BeanInfoEmbryo.java, [...]: Rename enum to e because enum is a keyword in Java 1.5.
[gcc.git] / libjava / javax / swing / tree / DefaultMutableTreeNode.java
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 */
97 public DefaultMutableTreeNode() {
98 // TODO
99 } // DefaultMutableTreeNode()
100
101 /**
102 * Constructor DefaultMutableTreeNode
103 * @param value0 TODO
104 */
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 */
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 */
128 public Object clone() {
129 return null; // TODO
130 } // clone()
131
132 /**
133 * toString
134 * @returns String
135 */
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 */
147 public void add(MutableTreeNode child) {
148 children.add(child);
149 child.setParent(this);
150 } // add()
151
152 /**
153 * getParent
154 * @returns TreeNode
155 */
156 public TreeNode getParent() {
157 return parent;
158 } // getParent()
159
160 /**
161 * remove
162 * @param value0 TODO
163 */
164 public void remove(int index) {
165 children.remove(index);
166 } // remove()
167
168 /**
169 * remove
170 * @param value0 TODO
171 */
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 */
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 */
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 */
200 public void insert(MutableTreeNode node, int index) {
201 children.insertElementAt(node, index);
202 } // insert()
203
204 /**
205 * getPath
206 * @returns TreeNode[]
207 */
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 */
236 public Enumeration children() {
237 return children.elements();
238 } // children()
239
240 /**
241 * setParent
242 * @param value0 TODO
243 */
244 public void setParent(MutableTreeNode node) {
245 parent = node;
246 } // setParent()
247
248 /**
249 * getChildAt
250 * @param value0 TODO
251 * @returns TreeNode
252 */
253 public TreeNode getChildAt(int index) {
254 return (TreeNode) children.elementAt(index);
255 } // getChildAt()
256
257 /**
258 * getChildCount
259 * @returns int
260 */
261 public int getChildCount() {
262 return children.size();
263 } // getChildCount()
264
265 /**
266 * getIndex
267 * @param value0 TODO
268 * @returns int
269 */
270 public int getIndex(TreeNode node) {
271 return children.indexOf(node);
272 } // getIndex()
273
274 /**
275 * setAllowsChildren
276 * @param value0 TODO
277 */
278 public void setAllowsChildren(boolean allowsChildren) {
279 this.allowsChildren = allowsChildren;
280 } // setAllowsChildren()
281
282 /**
283 * getAllowsChildren
284 * @returns boolean
285 */
286 public boolean getAllowsChildren() {
287 return allowsChildren;
288 } // getAllowsChildren()
289
290 /**
291 * setUserObject
292 * @param value0 TODO
293 */
294 public void setUserObject(Object userObject) {
295 this.userObject = userObject;
296 } // setUserObject()
297
298 /**
299 * getUserObject
300 * @returns Object
301 */
302 public Object getUserObject() {
303 return userObject;
304 } // getUserObject()
305
306 /**
307 * removeFromParent
308 */
309 public void removeFromParent() {
310 parent = null;
311 // TODO
312 } // removeFromParent()
313
314 /**
315 * removeAllChildren
316 */
317 public void removeAllChildren() {
318 children.removeAllElements();
319 } // removeAllChildren()
320
321 /**
322 * isNodeAncestor
323 * @param value0 TODO
324 * @returns boolean
325 */
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 */
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 */
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 */
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 */
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
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
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 */
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 */
615 protected TreeNode[] getPathToRoot(TreeNode value0, int value1) {
616 return null; // TODO
617 } // getPathToRoot()
618
619 /**
620 * getUserObjectPath
621 * @returns Object[]
622 */
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 */
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 */
670 public boolean isRoot() {
671 return (parent == null);
672 } // isRoot()
673
674 /**
675 * getNextNode
676 * @returns DefaultMutableTreeNode
677 */
678 public DefaultMutableTreeNode getNextNode() {
679 return null; // TODO
680 } // getNextNode()
681
682 /**
683 * getPreviousNode
684 * @returns DefaultMutableTreeNode
685 */
686 public DefaultMutableTreeNode getPreviousNode() {
687 return null; // TODO
688 } // getPreviousNode()
689
690 /**
691 * preorderEnumeration
692 * @returns Enumeration
693 */
694 public Enumeration preorderEnumeration() {
695 return null; // TODO
696 } // preorderEnumeration()
697
698 /**
699 * postorderEnumeration
700 * @returns Enumeration
701 */
702 public Enumeration postorderEnumeration() {
703 return null; // TODO
704 } // postorderEnumeration()
705
706 /**
707 * breadthFirstEnumeration
708 * @returns Enumeration
709 */
710 public Enumeration breadthFirstEnumeration() {
711 return null; // TODO
712 } // breadthFirstEnumeration()
713
714 /**
715 * depthFirstEnumeration
716 * @returns Enumeration
717 */
718 public Enumeration depthFirstEnumeration() {
719 return null; // TODO
720 } // depthFirstEnumeration()
721
722 /**
723 * pathFromAncestorEnumeration
724 * @param value0 TODO
725 * @returns Enumeration
726 */
727 public Enumeration pathFromAncestorEnumeration(TreeNode value0) {
728 return null; // TODO
729 } // pathFromAncestorEnumeration()
730
731 /**
732 * isNodeChild
733 * @param value0 TODO
734 * @returns boolean
735 */
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 */
764 public TreeNode getFirstChild() {
765 return (TreeNode) children.firstElement();
766 } // getFirstChild()
767
768 /**
769 * getLastChild
770 * @returns TreeNode
771 */
772 public TreeNode getLastChild() {
773 return (TreeNode) children.lastElement();
774 } // getLastChild()
775
776 /**
777 * getChildAfter
778 * @param value0 TODO
779 * @returns TreeNode
780 */
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 */
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 */
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 */
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 */
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 */
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 */
934 public boolean isLeaf() {
935 return (children.size() == 0); // TODO: check allowsChildren??
936 } // isLeaf()
937
938 /**
939 * getFirstLeaf
940 * @returns DefaultMutableTreeNode
941 */
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 */
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 */
981 public DefaultMutableTreeNode getNextLeaf() {
982 return null; // TODO
983 } // getNextLeaf()
984
985 /**
986 * getPreviousLeaf
987 * @returns DefaultMutableTreeNode
988 */
989 public DefaultMutableTreeNode getPreviousLeaf() {
990 return null; // TODO
991 } // getPreviousLeaf()
992
993 /**
994 * getLeafCount
995 * @returns int
996 */
997 public int getLeafCount() {
998
999 // Variables
1000 Enumeration e;
1001 int count;
1002 TreeNode current;
1003
1004 // Get Enumeration of all descendants
1005 e = depthFirstEnumeration();
1006
1007 // Process Nodes
1008 count = 0;
1009 while (e.hasMoreElements() == true) {
1010 current = (TreeNode) e.nextElement();
1011 if (current.isLeaf() == true) {
1012 count++;
1013 } // if
1014 } // if
1015
1016 return count;
1017
1018 } // getLeafCount()
1019
1020
1021 } // DefaultMutableTreeNode