Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Traversing tree made from DefaultMutableTreeNode

We have a tree structure implemented using the DefaultMutableTreeNode specified in Java.

Is there any way of traversing it, that is inbuilt?

If not, please suggest other techniques.

like image 862
fixxxer Avatar asked Sep 24 '09 10:09

fixxxer


3 Answers

You have in theory four ways to walk the tree from a node (DefaultMutableTreeNode):

  • breadthFirstEnumeration
  • depthFirstEnumeration
  • preorderEnumeration
  • postorderEnumeration

but actually depth first is implemented as postorder.
The JavaDoc is a bit terse on the differences on these methods. I came here looking for an answer, but I ended by doing the test myself, with a code looking like:

  TreeModel model = tree.getModel();

  DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) model.getRoot();
  // Just changing enumeration kind here
  Enumeration<DefaultMutableTreeNode> en = rootNode.preorderEnumeration();
  while (en.hasMoreElements())
  {
     DefaultMutableTreeNode node = en.nextElement();
     TreeNode[] path = node.getPath();
     System.out.println((node.isLeaf() ? "  - " : "+ ") + path[path.length - 1]);
  }

I could have refined with indentation proportional to level, but it was just a quick hack.

So, what are the differences?

  • preorderEnumeration = from top of tree to bottom, as if you were using the down arrow to walk it
  • postorderEnumeration = depthFirstEnumeration = first list the deepest leafs of the first path, then their parent, then the deepest leafs of the second path, etc.
  • breadthFirstEnumeration = list the elements at the first level, then the elements at the second level, and so on

To be more concrete:

+ Root
  + Folder 1
    - Leaf F1
    - Leaf F1
 + Folder 2
    + Sub-folder 1
      - Leaf SF1
      - Leaf SF1
    + Sub-folder 2
      - Leaf SF2
      - Leaf SF2

♦ Preorder: as shown above
♦ DepthFirst/Postorder:
Leaf F1, Leaf F1, Folder 1
Leaf SF1, Leaf SF1, Sub-folder 1
Leaf SF 2, Leaf SF2, Sub-folder 2, Folder 2, Root
♦ BreathFirst:
Root
Folder 1, Folder 2
Leaf F1, Leaf F1, Sub-folder 1, Sub-folder 2
Leaf SF 1, Leaf SF 1, Leaf SF 2, Leaf SF 2

like image 172
PhiLho Avatar answered Oct 08 '22 16:10

PhiLho


If you mean you want to traverse the tree you can call breadthFirstEnumeration() or depthFirstEnumeration() in order to iterate over all nodes in the tree.

Example:

DefaultMutableTreeNode root = ...

Enumeration en = root.depthFirstEnumeration();
while (en.hasMoreElements()) {

  // Unfortunately the enumeration isn't genericised so we need to downcast
  // when calling nextElement():
  DefaultMutableTreeNode node = (DefaultMutableTreeNode) en.nextElement();
}
like image 32
Adamski Avatar answered Oct 08 '22 16:10

Adamski


Here's another description of the 3 enumeration Methods, that may be easier to understand.

en = root.breadthFirstEnumeration();
//Enumeration lists all nodes at depth 0 (aka root)
//Then all nodes at depth 1 (aka root's children, top to bottom ordering)
//Then all nodes at depth 2, and so on till max depth reached

en = root.preorderEnumeration(); 
//Imagine your JTree is fully expanded (where each node = a row)
//Enumeration will list nodes from top to bottom (regardless of leaf or not)

en = root.postorderEnumeration(); //Equivalent to root.depthFirstEnumeration();
//Imagine a fully expanded copy of your JTree (where each node = a row)
//This will allow you to visualize what Enumeration List will look like
while(treecopy.hasNodes() ) {
list 1st leaf sighted going from top to bottom, then remove that leaf }
//as the leafs are removed, branches then become leafs, and root is last enumerated.
like image 36
neokyle Avatar answered Oct 08 '22 14:10

neokyle