Starchy
Starchy

Reputation: 93

Why is my GUI unresponsive while a SwingWorker thread runs?

I have a SwingWorker thread with an IOBound task which is totally locking up the interface while it runs. Swapping out the normal workload for a counter loop has the same result. The SwingWorker looks basically like this:

public class BackupWorker extends SwingWorker<String, String> {

private static String uname = null;
private static String pass = null;
private static String filename = null;
static String status = null;

BackupWorker (String uname, String pass, String filename) {
    this.uname = uname;
    this.pass = pass;
    this.filename = filename;
}

@Override
protected String doInBackground() throws Exception {
            BackupObject bak = newBackupObject(uname,pass,filename);
    return "Done!";
}

}

The code that kicks it off lives in a class that extends JFrame:

    public void actionPerformed(ActionEvent event) {
    String cmd = event.getActionCommand();

    if (BACKUP.equals(cmd)) { 
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {

                final StatusFrame statusFrame = new StatusFrame();
                statusFrame.setVisible(true);

                SwingUtilities.invokeLater(new Runnable() {
                    public void run () {
                        statusFrame.beginBackup(uname,pass,filename);
                    }
                });
            }
        });
    }
}

Here's the interesting part of StatusFrame:

public void beginBackup(final String uname, final String pass, final String filename) {
    worker = new BackupWorker(uname, pass, filename);
    worker.execute();

    try {
        System.out.println(worker.get());
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}

}

So far as I can see, everything "long-running" is handled by the worker, and everything that touches the GUI on the EDT. Have I tangled things up somewhere, or am I expecting too much of SwingWorker?

Upvotes: 1

Views: 1726

Answers (2)

camickr
camickr

Reputation: 324088

Read the section from the Swing tutorial on Tasks That Have Interim Results for a working example. You will see that the get(...) method is invoked from within the process(...) method that is overridden in the SwingWorker class.

Upvotes: 0

Ash
Ash

Reputation: 9426

I think the problem is due to the call to SwingWorker.get() in your beginBackup method. Take a look at the docs for this method:

Waits if necessary for the computation to complete, and then retrieves its result.

This is a blocking call, hence your GUI becomes unresponsive.

(Also, is there any particular reason why you're doing an invokeLater from within an invokeLater call? You're already running on the EDT.)

Upvotes: 6

Related Questions