Traversing all nodes of a multi-leveled JTree
Asked Answered
P

3

7

I have a JTree with DefaultTreeModel. I need to get to each node of it.

Imagine I have this tree:

[A]
 |-[B]
 |-[C]
 |-[D]
 |  |-[E]
 |     |-[F]
 |     |-[G]
 |     |-[H]
 |-[I]
 |-[J]
 |-[K]

I need to traverse it and print out:

   ---[A]---
   >[B]
   >[C]
   >---[D]---
   >>---[E]---
   >>>[F]
   >>>[G]
   >>>[H]
   >>+++[E]+++
   >+++[D]+++
   >[I]
   >[J]
   >[K]
   ---[A]---

So, I'm using

  java.util.Enumeration en = root.preorderEnumeration();

  while (en.hasMoreElements()) {}

But I can't come up with a working function. I need to put ---NODE NAME--- when starting a node and end the node with +++NODE NAME+++ and I can't menage to do that. I got it working to a point if only the a Parent node is not the last element of another Parent. But it breaks when the last node is also a parent. Any help would be appreciated.

Edit:

And now I noticed it wasn't even working as well as I thought. Here is my current output:

----root (81)----
name
time
displaySize
----New Group1----
BaseX
BaseY
----New Group2----
BaseRadius
----New Group3----
Angle
DistanceFromCenter
++++New Group3++++
PlayerSpeed
MouseX
MouseY
++++New Group3++++
PlayerX
PlayerY
BonusSpawned
actorTags
++++New Group3++++
BonusTime
BonusWhich
+++root+++

Edit2:

while (en.hasMoreElements()) {

    nodeTemp = node;
    node = (DefaultMutableTreeNode) en.nextElement();

    String nodeName = node.toString();

    if (node.getChildCount() > 0) {

        System.out.println("---" + nodeName + "---");

    } else {

        if (nodeTemp.getChildCount() == 0 && nodeTemp.getParent() != node.getParent()) {
            System.out.println("+++" + nodeName + "+++");
            loopCount++;

        }

        System.out.println(nodeName);

    }

    loopCount++;

}
Phonetist answered 15/1, 2014 at 3:12 Comment(2)
What do you have so far and what does it output?Marnimarnia
@JavaDevil I updated the question but as you see it is not working at all, all the group endings are the same. I just can't get my head around this.Phonetist
M
3

Using recursion you could do something like this psuedocode

  1. Start at root
  2. If is a leaf - Print node name and return
  3. Print --- node name ----
  4. If node has children - recurse with each child (starting at 2)
  5. Print +++ Node name ++++

Edit My Version of a recursive method

public static void print(DefaultMutableTreeNode aNode)
{
    String name = aNode.toString();
    int level= aNode.getLevel();
    String placement = "";
    while (level > 0)
    {
        placement += ">";
        level--;
    }
    if(aNode.isLeaf())
    {
        System.out.println(placement + name);
        return;
    }

    System.out.println(placement + "--- " + name + " ---");
    for(int i = 0 ; i < aNode.getChildCount() ; i++)
    {
        print((DefaultMutableTreeNode)aNode.getChildAt(i));
    }
    System.out.println(placement + "+++ " + name + " +++");
}

This will give you > for the levels also for example my output was:

--- A ---
>--- B ---
>>C
>>--- D ---
>>>E
>>+++ D +++
>+++ B +++
>F
>G
>H
+++ A +++
Marnimarnia answered 15/1, 2014 at 3:33 Comment(4)
That is sort of like what I've been doing but how should I store the name of the outer nodes as I go deep? I'll need the group name which I start with "---" to end it with "+++". Look at my output, it closes every group with the most inner one (3)Phonetist
If you are using a recursive method then you don't need to store anything. Could you edit to include your code that you haveMarnimarnia
I updated the code. And I'm not sure I get what you mean. How do I know when I'm leaving a Group so that I add System.out.println("+++" + nodeName + "+++");Phonetist
It was way too simpler than I thought, thanks for pointing me to recursive functions.Phonetist
P
4

I solved it by ditching the Enumeration and building my own function:

    DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
    DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();

    printNode(root);

public void printNode(DefaultMutableTreeNode node) {

    int childCount = node.getChildCount();

    System.out.println("---" + node.toString() + "---");

    for (int i = 0; i < childCount; i++) {

        DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) node.getChildAt(i);
        if (childNode.getChildCount() > 0) {
            printNode(childNode);
        } else {
            System.out.println(childNode.toString());
        }

    }

    System.out.println("+++" + node.toString() + "+++");

}
Phonetist answered 15/1, 2014 at 5:29 Comment(3)
Nice work, I was just going to edit my post to include a similar function which does the same thing!Marnimarnia
Thanks! Now I'm looking for making it prettier. I want to add the char '>' to the beginning of node names if they are a leaf. There should be 2 '>' if its parent also has a parent and so on. I failed until now but I think I need a coffee first. :) And if I fail later again can post here again for your suggestion?Phonetist
See my original post - I added that yo my methodMarnimarnia
M
3

Using recursion you could do something like this psuedocode

  1. Start at root
  2. If is a leaf - Print node name and return
  3. Print --- node name ----
  4. If node has children - recurse with each child (starting at 2)
  5. Print +++ Node name ++++

Edit My Version of a recursive method

public static void print(DefaultMutableTreeNode aNode)
{
    String name = aNode.toString();
    int level= aNode.getLevel();
    String placement = "";
    while (level > 0)
    {
        placement += ">";
        level--;
    }
    if(aNode.isLeaf())
    {
        System.out.println(placement + name);
        return;
    }

    System.out.println(placement + "--- " + name + " ---");
    for(int i = 0 ; i < aNode.getChildCount() ; i++)
    {
        print((DefaultMutableTreeNode)aNode.getChildAt(i));
    }
    System.out.println(placement + "+++ " + name + " +++");
}

This will give you > for the levels also for example my output was:

--- A ---
>--- B ---
>>C
>>--- D ---
>>>E
>>+++ D +++
>+++ B +++
>F
>G
>H
+++ A +++
Marnimarnia answered 15/1, 2014 at 3:33 Comment(4)
That is sort of like what I've been doing but how should I store the name of the outer nodes as I go deep? I'll need the group name which I start with "---" to end it with "+++". Look at my output, it closes every group with the most inner one (3)Phonetist
If you are using a recursive method then you don't need to store anything. Could you edit to include your code that you haveMarnimarnia
I updated the code. And I'm not sure I get what you mean. How do I know when I'm leaving a Group so that I add System.out.println("+++" + nodeName + "+++");Phonetist
It was way too simpler than I thought, thanks for pointing me to recursive functions.Phonetist
M
-2

Websearch "depth first tree walk" and/or "breadth first tree walk". The former is more common, but there are applications for the latter.

If the tree nodes are doubly-linked (if nodes can reach their parents as well as children), there are depth-first solutions whose only state is the current node. Otherwise, you'll need to maintain a stack (either as a data structure, or by walking recursively) so you can go back up after running out of siblings at a given level of a branch.

Margravine answered 15/1, 2014 at 3:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.