I try to dynamically add nodes to a Java Swing JTree
, and the user should be able to browse and to collapse hierarchy while nodes are constantly added. When I add a Thread.sleep(10)
in my loop, it works fine; but this is a dirty hack...
Here is the stripped down code that triggers this problem. Whenever I run this and doubleclick on the root node to expand/collapse it (while nodes are added), I get an ArrayIndexOutOfBoundsException
. When I add a Thread.sleep(10)
this does not happen. I guess this is a threading issue, but I have no idea how to synchronize this? Any hints would be greatly appreciated!
public static void main(String[] args) throws InterruptedException {
final JFrame frame = new JFrame();
frame.setSize(600, 800);
frame.setVisible(true);
MutableTreeNode root = new DefaultMutableTreeNode("root");
final DefaultTreeModel model = new DefaultTreeModel(root);
final JTree tree = new JTree(model);
frame.add(new JScrollPane(tree));
while (true) {
MutableTreeNode child = new DefaultMutableTreeNode("test");
model.insertNodeInto(child, root, root.getChildCount());
tree.expandRow(tree.getRowCount() - 1);
// uncommenting this to make it work
// Thread.sleep(10);
}
}
I want to use this for a search-on-typing application, so giving (almost) instant results is essential for me.
EDIT: Thanks for the quick answers! SwingUtilities.invokeLater()
solves the problem.
I now do this:
- Add 100 items within
SwingUtilities.invokeLater();
After 100 items, I run this so that the GUI can get updated:
// just wait so that all events in the queue can be processed SwingUtilities.invokeAndWait(new Runnable() { public void run() { }; });
This way I have a very responsive GUI and it works perfectly. Thanks!