I have made a simple test case that fails the same way as my main application. The key element is that my code issues lots of nodeChanged() calls and occasionally generates an error. My simple test case causes it to happen quickly. Build the testcase and while its running, expand and collapse the "SubRoot" folder a bunch of times.
Eventually a null pointer or array index error will occur. Do I need to do something here to make it thread-safe?
I see you're performing actions on the user interface from a thread that isn't the Event Dispatcher Thread. You should read Concurrency in Swing. But I don't really get what you're trying to do. The "while (true)" causes the code to loop forever, basically claiming a lot of resources. If you then do a lot in the GUI (in the proper way) you will cause it to hang, as the EDT will be handling your node changes constantly and can no longer handle anything else.
Thanks for the pointer to the reading material. My application is not nearly as offensive as the test case. The test case just makes it fail quicker.
The real application's while loop is more like:
This gives sort of an odometer effect to the node labels, and one can see from the tree which folder has the most action as the odometer is rolling faster there.
The trouble arises when the uses expands or collapses the node. If you take the sleep out, it is easier to make it fail. If I use the tree.repaint() the text in the
node gets the funny behavior depicted in the attached jpg.
So now the question is "How does a worker thread notify the UI that the node has changed and needs to be repainted?"
Check out SwingWorker. The reading from the socket will be done in the doInBackground method. You then publish(...) something in doInBackground which you will handle in the process method on the EDT. Here and here are two examples of how you could do this.