user5011356
user5011356

Reputation:

Java Swing Tree with Streaming Updates

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

Answers (1)

trashgod
trashgod

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

Related Questions