Почему мой графический интерфейс не отвечает во время работы потока SwingWorker? - PullRequest
1 голос
/ 06 июня 2010

У меня есть поток SwingWorker с задачей IOBound, которая полностью блокирует интерфейс во время его работы. Замена нормальной рабочей нагрузки на цикл счетчика приводит к тому же результату. 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();
    }
}

}

Насколько я вижу, все "длительное" выполняется рабочим, и все, что касается GUI на EDT. Я что-то запутал или ожидаю слишком многого от SwingWorker?

Ответы [ 2 ]

6 голосов
/ 06 июня 2010

Я думаю, что проблема связана с вызовом SwingWorker.get() в вашем beginBackup методе. Посмотрите документы для этого метода :

Ожидает, если необходимо для вычисления для завершения, а затем извлекает его результат.

Это блокирующий вызов, поэтому ваш графический интерфейс перестает отвечать на запросы.

(Кроме того, есть ли конкретная причина, по которой вы делаете invokeLater из вызова invokeLater? Вы уже используете EDT.)

0 голосов
/ 06 июня 2010

Прочитайте раздел учебника по Swing по Задачи, которые имеют промежуточные результаты для рабочего примера. Вы увидите, что метод get (...) вызывается из метода process (...), который переопределен в классе SwingWorker.

...