View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/util/ChildrenDrivenMutableTree.java,v $
3    * $Revision: 1.7 $
4    *
5    * Copyright (C) 2001 Myles Chippendale
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     Myles Chippendale <mylesc At paneris.org>
42   */
43  package org.melati.util;
44  
45  import javax.swing.tree.DefaultMutableTreeNode;
46  import java.util.Vector;
47  import java.util.Enumeration;
48  import org.melati.poem.Treeable;
49  
50  /**
51   * A tree of <code>DefaultMutableTreeNode</code>s, 
52   * the <code>userObject</code>s of which
53   * are {@link Treeable} objects which supply their own
54   * <code>getChildren()</code> functions. 
55   * This is used to build the tree of
56   * <code>DefaultMutableTreeNode</code>s.
57   * <p>
58   * It also allows you to search the subtree for a particular
59   * {@link Treeable} object and returns the corresponding
60   * <code>DefaultMutableTreeNode</code> object if one exists.
61   *
62   * @see DefaultMutableTreeNode
63   *
64   * @since 04/10/2000
65   * @author Myles Chippendale
66   **/
67  
68  
69  public class ChildrenDrivenMutableTree {
70  
71      /**
72       * An enumeration that is always empty. This is used when an enumeration
73       * of a leaf node's children is requested.
74       */
75      public static final Enumeration EMPTY_ENUMERATION = 
76        DefaultMutableTreeNode.EMPTY_ENUMERATION; 
77  
78      /** root node */
79      protected DefaultMutableTreeNode root;
80  
81      /**
82       * Constructor.
83       */
84      public ChildrenDrivenMutableTree() {
85        this(null);
86      }
87  
88      /**
89       * Constructor.
90       * @param userObject the root
91       */
92      public ChildrenDrivenMutableTree(Treeable userObject) {
93        root = new DefaultMutableTreeNode(userObject);
94        buildTree();
95      }
96  
97      /**
98       * Compute the children.
99       */
100     public void buildTree() {
101       buildTree(computeChildren(root));
102     }
103 
104     /**
105      * Compute the children given the nodes.
106      * @param nodes an Enumeration of nodes
107      */
108     public void buildTree(Enumeration nodes) {
109       while (nodes.hasMoreElements())
110         buildTree(computeChildren((DefaultMutableTreeNode)nodes.nextElement()));
111     }
112 
113     private static Enumeration computeChildren(DefaultMutableTreeNode node) {
114       if (node == null)
115         return EMPTY_ENUMERATION;
116       Treeable[] kids = ((Treeable)node.getUserObject()).getChildren();
117       for(int i = 0; i<kids.length; i++) {
118           node.add(new DefaultMutableTreeNode(kids[i]));
119       }
120       return node.children();
121     }
122 
123 
124     /**
125      * Find a node in a tree.
126      * @param search the node object
127      * @return a tree node
128      */
129     public DefaultMutableTreeNode getTreeNodeFor(Treeable search) {
130 
131         Vector agenda = new Vector();
132         agenda.addElement(root);
133 
134         while (!agenda.isEmpty()) {
135             DefaultMutableTreeNode current =
136                 (DefaultMutableTreeNode)agenda.firstElement();
137             if (current == null)
138               return null;
139             if (current.getUserObject() == search)
140               return current;
141 
142             agenda.removeElementAt(0);
143             Enumeration kids = current.children();
144             while(kids.hasMoreElements()) {
145               agenda.addElement(kids.nextElement());
146             }
147         }
148         return null;
149     }
150 
151     /**
152      * @return the root
153      */
154     public DefaultMutableTreeNode getRoot() {
155       return root;
156     }
157 
158     /**
159      * Return an enumeration of nodes in preorder, whatever
160      * that means.
161      * <p>
162      * Root is first node. What is the difference
163      * from breadth first?
164      * @return the nodes
165      */
166     public Enumeration preorderEnumeration() {
167       return root.preorderEnumeration();
168     }
169 
170     /**
171      * Return an enumeration of nodes in postorder, whatever
172      * that means.
173      * <p>
174      * Leftmost leaf is first. What is the difference
175      * from depth first?
176      * @return the nodes
177      */
178     public Enumeration postorderEnumeration() {
179       return root.postorderEnumeration();
180     }
181 
182     /**
183      * @return an enumeration of nodes in breadth first order.
184      */
185     public Enumeration breadthFirstEnumeration() {
186       return root.breadthFirstEnumeration();
187     }
188 
189     /**
190      * @return an enumeration of nodes in depth first order.
191      */
192     public Enumeration depthFirstEnumeration() {
193       return root.depthFirstEnumeration();
194     }
195 }