tags:

views:

242

answers:

2

I want to color(and give an icon to) a particular node of a JTree as opposed to in groups like OpenNode, LeafNode etc. How do I go about doing this?

+1  A: 

This tutorial from Sun shows how to set your own node-icons and how to differentiate between leaf- and non-leafs in a tree.

Bart Kiers
A: 

The easiest way to do this is to construct your JTree model using DefaultMutableTreeNodes and to set the "user object" value of certain node(s), and then use this value to determine the behaviour of the renderer when it encounters that node.

First we construct a simple model and pass it to the JTree constructor:

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Hello");
DefaultMutableTreeNode child1 = new DefaultMutableTreeNode("Goodbye");
DefaultMutableTreeNode child2 = new DefaultMutableTreeNode("Bonjour");

root.add(child1);
root.add(child2);

JTree tree = new JTree(root);

Now define a custom tree cell renderer:

TreeCellRenderer renderer = new DefaultTreeCellRenderer() {
  public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
    // Defer to superclass to create initial version of JLabel and then modify (below).
    JLabel ret = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

    // We know that value is a DefaultMutableTreeNode so this downcast is safe.
    MutableTreeNode node = (MutableTreeNode) value;

    // Inspect user object and change rendering based on this.
    if ("Hello".equals(node.getUserObject())) {
      ret.setIcon(...);
    }

    // Could also inspect whether node is a leaf node, etc.
    return ret;
  }
};
Adamski
Thanks. This function was what I was looking for.
Goutham
Is it possible to do it dynamically at runtime?
Tobias
Yes. Assuming you update one of your user object's state and you wish this change to cause the corresponding DefaultMutableTreeNode to be rendered differently you'll need to call nodeChanged on your AbstractTreeModel instance and pass in the node to be re-rendered.
Adamski