ConcurrentModificationExceptions happen when you access the same List on two threads. Your TreeModel probably uses ArrayLists, Vectors, Hashtables, or something similiar to store the nodes.
My guess is that one of two things is happening:
1) Your TreeModel is constantly being queried by the JTree on the EDT thread every time it is rendered. This is unavoidable and how Swing works. If you are accessing the tree model, or underlying Lists on a different thread, you'll occasionally do it at the same time as a rendering and List throws the exception.
2) you have two swing workers running, each on their own threads. They are simultaneously updating/querying the List. Same problem as above.
I aggree with Tom that using SwingWorker to make your TreeModel "asynchronous" is a very tricky problem and should be avoided. But, to answer your question, I would look at the following piece of code. Notice how all query and update actions to the tree takes place in the "finished" method, which is always run on EDT. My guess is that you are doing gets/sets in the construct() method.
public TreeNode[] getChildren(TreeNode parent){
// Do all normal work you would do
...
// figure out if this parents children have not been fetched yet
boolean needToFetch = ....
if(needToFetch){
worker = new SwingWorker() {
public Object construct() {
// go fetch your children from whatever database, server, file...
// fetchNewChildren must NOT access the TreeModel or any of the underlying
// lists, because you will get a modification exception. This is what
// Tom meant by "Pass a set of arguments into the background thread
// that are not being used in the EDT"
return fetchNewChildNodes(parent);
}
public void finished() {
List<TreeNode> newNodes = (List<TreeNode>)get();
// insert the newly fetched nodes into the parent
// if done correclty, this will fire TreeModelChanged events
// so the tree should re-render, repaint, etc...
parent.addChildren(newNodes);
}
};
worker.start();
}