Reputation:
I have a Swing tree that is changing as a result of a background thread that receives updates to the tree, in a streaming fashion. Updates can come quite fast and they can be complex. And they can come fast enough that previous updates have not yet been rendered. I would like the tree displayed in the GUI to be visually updated, as fast as practical, as the tree model updates are applied.
Currently I have code abstractly as below:
public void ReceiveStreamDocument(final Document d) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
ComplexChangeToTree(d);
TreeReload();
}
});
}
Now the complex change is time consuming, what I would like is:
public void ReceiveStreamDocument(final Document d) {
ComplexChangeToTree(d);
SwingUtilities.invokeLater(new Runnable(){
public void run(){
TreeReload();
}
});
}
However the problem appears to be that modifications to the tree structure are now outside of the swing thread and when the tree is actually re-rendered there can be exceptions thrown. It does not seem to help to have something like this:
public void ReceiveStreamDocument(final Document d) {
synchronized(root){
ComplexChangeToTree(d);
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
synchronized(root){
TreeReload();
}
}
});
}
The TreeReload() is not actually updating the display, but rather just signaling that the display should be updated. I believe I need to override a painting operation somewhere and synchronize root on that, but I'm not sure where, or how, or indeed what is the best practice.
Upvotes: 0
Views: 54
Reputation: 205775
The key to this is doing as much as possible in the background and firing as few tree model events as possible to the listening tree. Using SwingWorker
, collect updates in your implementation of doInBackground()
, where you can also do any parsing and rearranging that doesn't fire events from your TreeModel
. Invoke publish()
for results as they become available. A List
of accumulated results will be coalesced and passed to your implementation of process()
on the event dispatch thread at a sustainable rate, where you have another opportunity to optimize firing update events. A related question is examined here.
Upvotes: 1