为什么我的GUI在SwingWorker线程运行时没有响应?

时间:2010-06-06 05:17:50

标签: java user-interface swing swingworker

我有一个带有IOBound任务的SwingWorker线程,它在运行时完全锁定了界面。更换计数器循环的正常工作负载具有相同的结果。 SwingWorker看起来基本上是这样的:

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!";
}

}

启动它的代码存在于扩展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);
                    }
                });
            }
        });
    }
}

这是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();
    }
}

}

据我所知,“长时间运行”的所有内容都由工作人员处理,以及触及EDT上GUI的所有内容。我是否曾在某处纠结过,或者我对SwingWorker的期望过高?

2 个答案:

答案 0 :(得分:6)

我认为问题是由于SwingWorker.get()方法中对beginBackup的调用造成的。看看docs for this method

  

必要时等待计算   完成,然后检索它   结果

这是一个阻止调用,因此您的GUI变得没有响应。

(另外,有没有什么特别的原因可以让你在invokeLater电话中进行invokeLater?你已经在EDT上运行了。)

答案 1 :(得分:0)

阅读Tasks That Have Interim Results上Swing教程中的部分以获取工作示例。您将看到在SwingWorker类中重写的process(...)方法中调用get(...)方法。