Prevent Swing GUI locking up during a background task Prevent Swing GUI locking up during a background task multithreading multithreading

Prevent Swing GUI locking up during a background task


The problem is, your long running task is blocking the Thread that keeps the GUI responsive.

What you will need to do is put the long running task on another thread.

Some common ways of doing this are using Timers or a SwingWorker.

The Java tutorials have lots of information regarding these things in their lesson in concurrency.

To make sure the first task finishes before the second, just put them both on the same thread. That way you won't have to worry about keeping two different threads timed correctly.

Here is a sample implementation of a SwingWorkerFor your case:

public class YourTaskSwingWorkerSwingWorker extends SwingWorker<List<Object>, Void> {    private List<Object> list    public YourClassSwingWorker(List<Object> theOriginalList){        list = theOriginalList;    }    @Override    public List<Object> doInBackground() {        // Do the first opperation on the list        // Do the second opperation on the list        return list;    }    @Override    public void done() {        // Update the GUI with the updated list.    }}

To use this code, when the event to modify the list is fired, create a new SwingWorker and tell it to start.


You are not returning the swing thread properly. I realize you are using callable/runnable but i'm guessing you are not doing it right (although you didn't post enough code to know for sure).

The basic structure would be:

swingMethod() { // Okay, this is a button callback, we now own the swing thread    Thread t=new Thread(new ActuallyDoStuff());    t.start();}public class ActuallyDoStuff() implements Runnable {    public void run() {        // this is where you actually do the work    }}

This is just off the top of my head, but I'm guessing that you either aren't doing the thread.start and are instead calling the run method directly, or you are doing something else in the first method that locks it up (like thread.join). Neither of these would free up the swing thread. The first method MUST return quickly, the run() method can take as long as it wants.

If you are doing a thread.join in the first method, then the thread is NOT being returned to the system!

Edit: (Second edit actually)I think to speak to the problem you are actually feeling--you might want to think more in terms of a model/view/controller system. The code you are writing is the controller (the view is generally considered to be the components on the screen--view/controller are usually very tightly bound).

When your controller gets the event, it should pass the work off to your model. The view is then out of the picture. It does not wait for the model, it's just done.

When your model is finished, it needs to then tell the controller to do something else. It does this through one of the invoke methods. This transfers control back to the controller and you go on your merry way. If you think about it this way, separating control and deliberately passing it back and forth doesn't feel so bulky, and it's actually very common to do it this way.


It sounds like the problem might be that you are waiting on the threads to finish from inside the GUI thread. Your GUI thread should not wait on these threads, instead you should have the worker threads invoke some method on the GUI thread that sets a flag. When both flags are set then you know both threads finished and you can do the graph.