JTree set node name as one of UserObject attribute

baizen picture baizen · Feb 24, 2012 · Viewed 8.1k times · Source

I'm using JTree to create tree view and add node to its root as following:

String nodeName = "node1";
DefaultMutableTreeNode child = new DefaultMutableTreeNode(nodeName);
root.add(child);

The UserObject for each node now has type of String. It shows "node1" as node name when display the tree.

However, I want to add UserObject to the node as an Object of the nodeObject class with 2 attributes:

private class nodeObject{
    private String nodeName;
    private boolean isSomethingElse;
    public nodeObject(String name, boolean something){
       nodeName = name;
       isSomethingElse = something;
    }
    public String getName(){
       return nodeName;
    }
    //Other setter/getter after these code
}

When I add this nodeObject to tree node:

nodeObject nodeObject = new nodeObject("node1",true);
DefaultMutableTreeNode child = new DefaultMutableTreeNode(nodeObject);
root.add(child);

It shows the object ID as node name. My question is, how i can set the node name as nodeObject.getName() so the tree can show "node1" as node name?

Any reply is much appreciated. Thank you!

Answer

JB Nizet picture JB Nizet · Feb 24, 2012

If this object is dedicated to the JTree, and is not used anywhere else, the easiest way is to override the toString() method and return the name from this method:

@Override
public String toString() {
    return this.nodeName;
}

If you want a different toString() method, that could be used to provide more information when debugging for example, then set a custom TreeCellRenderer to the tree. This custom could just extend DefaultTreeCellRenderer, and override the following method:

@Override
public Component getTreeCellRendererComponent(JTree tree,
                                              Object value,
                                              boolean sel,
                                              boolean expanded,
                                              boolean leaf,
                                              int row,
                                              boolean hasFocus) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
    NodeObject nodeObject = (NodeObject) node.getUserObject();
    return super.getTreeCellRendererComponent(tree,
                                              nodeObject.getName(),
                                              sel,
                                              expanded,
                                              leaf,
                                              row,
                                              hasFocus);
}

EDIT:

A third solution, as mentioned by aterai in the comments, is to subclass JTree and to override the convertValueToText() method, that the default renderer calls. See http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html for more details about trees.