SwingWorker должен быть вложенным классом?

Я задаюсь вопросом если SwingWorker должен быть вложенный класс в моем основном GUI. Я сделал бы это внешним классом для хранения в стороне GUI от любой моей логики программ.

Я пытался сделать SwingWorker внешний класс, который хорошо работает для процесса, к сожалению, я не могу получить доступ ни к одному из своих полей GUI от класса SwingWorker. Каждый раз, когда я пытаюсь получить доступ к атрибуту, такой как маркировка или безотносительно из SwingWorker done() метод я получаю nullPointer исключение.

Любой совет очень ценился бы!


В первую очередь, большое спасибо Jeff! Хорошо работает до сих пор, даже при том, что я не мог следовать за Вами на второй опции, которую Вы представили. Одна из моих фоновых задач вычисляет определенный размер (длинное значение), таким образом, было бы хорошо получить то значение от моего GUI.

Вы предложили работать с методами считывания и методами set, но к сожалению у меня нет идеи о том, как реализовать их в классе SwingWorker.

Я попробовал его как это:

public void setSize(long totalSize) {
     this.totalSize = totalSize;
}
public long getTotalSize() {
     return totalSize;
}

Метод set вызывается в конце doInBackground() метод. К сожалению, я не могу использовать get() метод от моего GUI.

final MySwingWorker w = new MySwingWorker();
Runnable r = new Runnable() {
    public void run() {
        // do something with w.get()
    }
};
w.setRunnable(r);
w.execute();

Создание объекта "w" не работает в моем случае, поскольку конструктор требует объекта Выполнимых. Я пропускаю что-то? Отнеситесь ласково ко мне, это - первый раз, когда я работаю с SwingWorker.:) Снова, большое спасибо за Вашу справку!

5
задан Peter 18 February 2010 в 18:05
поделиться

1 ответ

Вы можете сделать SwingWorker внешним классом. Однако, как и любой другой класс, если он не может видеть переменные (например, метку, которую вы хотите установить), конечно, он не сможет ее установить. Одна вещь, которую вы можете сделать, - это передать работнику Runnable, который он выполнит по завершении.

public class MySwingWorker extends SwingWorker {

   private final Runnable r;
   public MySwingWorker(Runnable r) {
       this.r = r;
   }
   public void doInBackground() {...}
   public void done() { r.run(); }
 }

Теперь из графического интерфейса вы можете сделать что-то вроде

Runnable updateLabel = new Runnable() {
       public void run() {
           label.setText("myValue");
       }
};
SwingWorker w = new MySwingWorker(updateLabel);
w.execute();

Это становится немного сложнее, если вы хотите использовать результат SwingWorker, хотя это возможно. Вместо того, чтобы передавать Runnable конструктору Swing Worker, у вас будет метод установки, и тогда это будет что-то вроде:

final MySwingWorker w = new MySwingWorker();
Runnable r = new Runnable() {
    public void run() {
        // do something with w.get()
    }
};
w.setRunnable(r);
w.execute();

В любом случае Runnable работает аналогично закрытию, которое выполняется, когда worker завершает работу.

6
ответ дан 14 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: