java SwingWorker.doInBackground() не должен обращаться к элементам GUI

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

Вот скопированный контент

Рабочий процесс

В жизненном цикле SwingWorker участвуют три потока:

Текущий поток: в этом потоке вызывается метод execute(). Он планирует SwingWorker для выполнения в рабочем потоке и немедленно возвращается. Можно дождаться завершения работы SwingWorker, используя методы get.

Рабочий поток: в этом потоке вызывается метод doInBackground(). Именно здесь должны происходить все фоновые действия. Чтобы уведомить PropertyChangeListeners об изменениях связанных свойств, используйте методы firePropertyChange и getPropertyChangeSupport(). По умолчанию доступны два связанных свойства: состояние и ход выполнения.

Поток отправки событий: все действия, связанные с Swing, происходят в этом потоке. SwingWorker вызывает методы process и done() и уведомляет все прослушиватели PropertyChangeListeners в этом потоке.

Часто текущий поток является потоком отправки событий.

--

Рабочий поток не является EDT, поэтому код в doInBackground() не должен обращаться к элементам GUI. Правильно ли я понимаю?

Предыстория: у нас есть небольшой код, который использует SwingWorker, но doInBackground() создает FileChooser и вызывает setCurrentDirectory(). Я подозреваю, что это приводит меня к исключению почти так же, как http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6637181 (11 – Закрыто, это не дефект)


person Jayan    schedule 24.01.2012    source источник


Ответы (1)


да. Из фонового потока - как обычные потоки, так и SwingWorker.doInBackground вы не должны изменять пользовательский интерфейс, чтобы избежать различных неприятностей.

Вместо этого оберните изменения в Runnable и выполните их в EDT через SwingUtilities.invokeAndWait, SwingUtilities.invokeLater или — при использовании SwingWorker — через publish (из doInBackground). В методе process из SwingWorker, который выполняется EDT, вы можете получить доступ к графическому интерфейсу.

http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html

Лично я считаю, что invokeLater и invokeAndWait легче использовать во многих ситуациях. SwingWorker подходит, например, для индикаторы прогресса.

person Has QUIT--Anony-Mousse    schedule 24.01.2012
comment
Спасибо - мы делаем то, что вы написали в ответ почти во всех местах. Есть некоторые области, где код использует swingworker. Даже в этом случае обработка может быть разделена на доступ к графическому интерфейсу и часть, не связанную с графическим интерфейсом. - person Jayan; 24.01.2012
comment
Правильное выполнение разделения обычно повышает производительность и позволяет избежать проблем, поэтому настоятельно рекомендуется. - person Has QUIT--Anony-Mousse; 24.01.2012
comment
Учебное пособие @Jayan, в котором рассказывается о выводе из публикации/процесса/сделано, вы можете проверить, что если (isEventDispatchThread), пожалуйста, прочитайте stackoverflow.com/questions/7053865/ . +1 - person mKorbel; 24.01.2012