This is just going to be a quick little post about how to get around redraw issues when you need to repaint a JTree in Java. Sometimes when you force a repaint with a JTree, the nodes are rendered with a “…” at the end of the node text (see picture below). This happens when the text that needs to be rendered is outside the bounds of the Node object being painted. This really only happens when the text that needs to be rendered has changed between the last rendered state and the new repaint.
I’ve run into this issue a number of times due to all my various JTree hacking in projects like CogZ, ZoomableJTrees, and now again in my Change Analysis plugin.
Typically to force a JTree to repaint, you might do something like this:
myTree.invalidate();
myTree.validate();
myTree.repaint();
This code will force a re-rendering of the JTree object, but if the node sizes needed to be re-calculated, the tree will end up displaying as in my screenshot above. So, my trick to get around this issue is to actually change the JTree row size before I call the repaint, this will force the JTree to recalculate all the node size bounds.
// call setRowHeight to force the sizes to recalculate
myTree.setRowHeight(DEFAULT_ROW_HEIGHT);
// repaint this puppy
myTree.repaint();
It’s a bit weird, but it works :-).
This comment has been removed by a blog administrator.
感謝大大的無私分享 讓小弟獲益良多 終於知道網上還有這麼多的好東西≧▽≦"
........................................
以簡單的行為愉悅他人的心靈,勝過千人低頭禱告........................................
this method is not always work I think you would better using DefaultTreeModel's insertNodeInto method, to guarantee repainting
not working 🙁
Works fine, but for me it also required "treeDidChange()", to allow the new node contents to be wider than the previous right edge. Thus, I have:
// call setRowHeight to force the sizes to recalculate
myTree.setRowHeight( -1 );
// and in case the tree bounds changed as well
mytree.treeDidChange();
// repaint this puppy
myTree.repaint();
(using Jython). Thanks. I had to do:
tree.rowHeight = tree.rowHeight + 1
tree.rowHeight = tree.rowHeight – 1
tree.repaint()
Just using
tree.rowHeight = tree.rowHeight
didn't work.
Incidentally, for any wondering about flicker this is to misunderstand how the EDT works: there is no change at all to the GUI until you get to the end of the EDT event.
what if you're not inserting (or deleting) anything? E.g. suppose multiple icons have changed, or suppose some of the JLabels have become bolded, thus becoming wider?