views:

101

answers:

2

Hello,

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?

+5  A: 

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.)

Ash
What threw me off here was preceding the `get()` with a `while (!worker.isDone())` and seeing the same unresponsiveness.I was seeing the GUI lock up before the `StatusFrame` finished drawing until I tried the ugly `Runnable` nesting. That issue is moot now.
Starchy
A: 

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.

camickr