Updating ImageIcon in JTree without repainting the Tree?
Question
Basically I edit an attribute private string status="OK"
in the UserObject()
of a DefaultTreeNode()
.
I have a CustomRenderer which implements DefaultCellRenderer
, which sets the Icon by rendering the "OK" attribute of UserObject
of a TreeNode
.
Originally, when I select a node, the icon changes. I am using Tree.revalidate()
& Tree.repaint()
, and the change is being reflected.
However, I am not sure if this very efficient. What would be the proper way of doing this? I tried doing TreeModel.nodesChanged(new DefaultMutableTreeNode(myUserObject))
but the TreeNodeChanged event
will not fire.
So am I stuck to using repainting the entire tree everytime a userboject of a TreeNode is changed to see the graphic update?
Solution
Use the approach shown in TreeIconDemo2
to condition the renderer based on the model's value. For example,
private class MyRenderer extends DefaultTreeCellRenderer {
private Icon okIcon;
public MyRenderer(Icon okIcon) {
this.okIcon = okIcon;
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean exp, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(
tree, value, sel, exp, leaf, row, hasFocus);
YourMutableTreeNode node = (YourMutableTreeNode) value;
if (leaf && node.getStatus().equals("OK")) {
setIcon(okIcon);
}
return this;
}
}
Addendum: You can't simply invoke nodeChanged()
on a new TreeNode
that's not part of the tree; the new node has no parent. If you specify an existing node to nodeChanged()
, the notification will happen automatically. If needed, there's an example of searching a tree here.
OTHER TIPS
When you want the model to be updated, as you do here, you are correct that you want to call nodeChanged. What I think may be wrong is that you are passing in an entirely new node, which obviously doesn't match one found in the tree. Try passing in a reference to the node in the tree you modified - that way the model can find know which node you modified.