Link to home
Start Free TrialLog in
Avatar of michaelbrem
michaelbrem

asked on

fill a JTree

Hi!

I have to fill a JTree with data. The data are stored in a vecor (int, string). The int is the level number:

e.g.
1
2
3
3
4
4
3
2
1

The element with the number 1 is the root element. I can add this to the tree like this:
"root.add(new DefaultMutableTreeNode("Child 2"));"

But how can I add the other elements without using a variable name for them? I can have up to 10 levels. I need the tree only to display the in information. No actionlistener needs to be added.
Thanks in advance!
 
 
Avatar of expertmb
expertmb

you can do this by adding nodes recursively.
addNode(){
 //do something
 addNode();
}
Let's make some assumptions on the data here before preceeding. Your data should at least have two columns, one column represents its unique id (such as 1, 2, 3) or this is the value you want show, the other represents the value that is its immediate parent node in the tree. For example, if your data looks like following,

1, -1
2, 1
3, 1
4, 2

it means, 1 is the root of everyone (using -1 represents no root above), and 1 is the parent node of 2 and 3, while 2 is the parent node of 4. Your data might not be necessarily only restricted to integer. For example, you could have them look like

John, null
Joe, John
Dave, John
Jack, Joe

where "null" represents no root above.

As long as you have such structure, you could consider recursive method to add in nodes to the tree. Please note that tree is only one way of data representations. It cannot generate logic from irrelevant data, but only represent the logic within data in a more explicit way. Thus, you should have to have the logic in the data itself before depending on the tree to represent it.

If you need further help on how to write the recursive function, let this board know.
Avatar of michaelbrem

ASKER

Thank you for the hints so far. I'm not a "real" java programmer, I use java only as the interface for Prolog. I have problems to implement this in java. Any hints how to implement this using? I have started to create a new class:

class MyNode extends DefaultMutableTreeNode

but I'm not sure which functions I have to overwrite.

Thank you!
If you are not a Java programmer, please let me know if you are able to convert the data you want to display to the format as I described, say a 2-dimension array, first column contains the unique face value, second column contains the face value of its parent. As I said above, you don't have to think of how to add them to the tree, like you tried to customize DefaultMutableTreeNode. Once you have such logic in your data, you could simply write a function to add the data using existing DefaultMutableTreeNode.

If you say your face value may not be unique, say like following

John, null
Joe, John
Dave, John
Jack, Joe
John, Jack

which means another John may in the system that is under Jack. If so, you could do following,

1, -1, John
2, 1, Joe
3, 1, Dave
4, 2, Jack
5, 4, John

which means provide a two dimension array, first column is the unique key, second column is the parent's unique key, third column is the face value of the node.

The bottom of line is your data! Unless you come up your logic data structure here, there is no much ground to play around for the possible solution unless you are willing take conceptual suggestions rather than java code implementations.
Hi!

Thank you for your help. I have organized the data in a the way you suggest:

1, -1, John
2, 1, Joe
3, 1, Dave
4, 2, Jack
5, 4, John

The data are stored in a Vector(). I know how to handle the Vector class. The "only" think I need to know, how I can use the DefaultMutableTreeNode class to get the data into the tree.

Thank you very much!
Suppose you have a class called DataNode

public class DataNode implements Comparable
{
private int id;
private int pId;
private String faceValue;
public DataNode(int id, int pid, String faceValue)
{
this.id = id;
this.pid = pid;
this.faceValue = faceValue;
}
...
//Please put in the getter and setter method of each
// field here
...

public boolean equals(Object o)
{
if(o instanceof DataNode)
{
return this.id==((DataNode)o).id;
}
else
{
return false;
}
}

public String toString()
{
return faceValue;
}

public int compareTo(Object o)
{
if(o instanceof DataNode)
{
return this.id - ((DataNode)o).id;
}
else
{
throw new ClassCastException("Object of type '" + (o==null? "null" : o.getClass().getName())
+ "' is not comparable to DataNode Object.");
}
}
}

Then some place in ur program you have following,

Vector v = new Vector();
DataNode n = new DataNode(1, -1, "John");
v.add(n);
n = new DataNode(2, 1, "Joe");
v.add(n);
n = new DataNode(3, 1, "Dave");
v.add(n);
n = new DataNode(4, 2, "Jack");
v.add(n);
n = new DataNode(5, 4, "John");
v.add(n);

When above is ready, call following buildTreeNode method and expect the root of the tree back.

Such as
DefaultMutableTreeNode treeRoot = buildTreeNode(v);

Then, it is ur job to put this tree root to the tree.

----------------------------
DefaultMutableTreeNode buildTreeNode(Vector v)
{
DataNode n = findRoot(v);
DefaultMutableTreeNode root = new DefaultMutableTreeNode(n);
if(!v.isEmpty())
{
buildNextLevel(v, root, n);
}
return root;
}

DataNode findRoot(Vector v)
{
int size = v.size();
for(int i=0; i<size; i++)
{
DataNode n = (DataNode) v.get(i);
if(n.getPId()==-1)
{
//remove n from vector since no use further for it in the vector
v.remove(n);
return n;
}
return null;
}
}

void buildNextLevel(Vector v, DefaultMutableTreeNode root, DataNode n)
{
Vector nextLevel = getDataNodeVectorWithPID(v, n.getPId());
int size = nextLevel.size();
for(int i=0; i<size; i++)
{
DataNode child = (DataNode) nextLevel.get(i);
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
buildNextLevel(v, childNode, child);
root.add(childNode);
}
}

/**
*This function actually separate the given vector into two groups, one is the immediate next level with the given pid, the other is other nodes that is not.
*/
Vector getDataNodeVectorWithPID(Vector v, int pid)
{
Vector returnVector = new Vector();
int size = v.size();
for(int i=0; i<size; i++)
{
DataNode n = (DataNode) v.get(i);
if(n.getPId()==pid)
{
returnVector.add(n);
}

//remove all data nodes from v
v.removeAll(returnVector);
return returnVector;
}}
Hi!

Thank you for the provided code.
I've included it into my program. I have used your sample data.
Unfortunately there is only one item in the tree. The first one (John).

Vector v = new Vector();
DataNode n = new DataNode(1, -1, "John");
v.add(n);
n = new DataNode(2, 1, "Joe");
v.add(n);
n = new DataNode(3, 1, "Dave");
v.add(n);
n = new DataNode(4, 2, "Jack");
v.add(n);
n = new DataNode(5, 4, "John");
v.add(n);

DefaultMutableTreeNode treeRoot = buildTreeNode(v);
System.out.println("Vec: "+v.size());  //============> RETURNS 4
JTree tree1 = new JTree(treeRoot);
System.out.println("Tree: "+tree1.getRowCount());  //============> RETURNS 1
centerrightpanel.add("Center",tree1);


I've written the getPId function.

Thank you in advance!
Hi!

I have found and fixed 2 little mistakes. now it works.

The first one
=============

one of the two "}" in getDataNodeVectorWithPID should be before this code:

}
//remove all data nodes from v
v.removeAll(returnVector);
return returnVector;
}

instead of
//remove all data nodes from v
v.removeAll(returnVector);
return returnVector;
}}


The second one
==============

in function buildNextLevel:
getid() must be used instead of getPId() in this statement:

Vector nextLevel = getDataNodeVectorWithPID(v, n.getid());
in

Thank you again for your help!

ASKER CERTIFIED SOLUTION
Avatar of sct75
sct75

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes thank you. it works very good!