Как вообще могут работать диалоги Swing?

Если вы открываете диалог в Swing, например JFileChooser, он выглядит примерно так, как этот псевдокод:

swing event thread {
  create dialog
  add listener to dialog close event {
    returnValue = somethingFromDialog
  }
  show dialog
  (wait until it is closed)
  return returnValue
}

Мой вопрос: как это может работать? Как видите, поток ожидает возврата, пока диалоговое окно не закроется. Это означает, что поток событий Swing заблокирован. Тем не менее, можно взаимодействовать с диалоговым окном, которое AFAIK требует, чтобы этот поток запускался.

Так как же это работает?


person Bart van Heukelom    schedule 12.06.2010    source источник


Ответы (2)


Это ветка AWT, а не Swing.

В любом случае AWT запускает цикл диспетчеризации в show. События ввода в заблокированные окна блокируются. События перерисовки, события для разблокированных окон и общие события отправляются как обычно.

В этом можно убедиться, добавив строку:

 Thread.dumpStack();

в равномерную обработку модального диалогового окна, или, что проще, из командной строки с помощью jstack или используйте _4 _ / _ 5_ в командном окне приложения.

Библиотека Foxtrot злоупотребляет этим, чтобы предоставить более процедурную (в отличие от управляемой событиями) модели. Он также используется подключаемым модулем WebStart / Java для предоставления диалогов для служб JNLP и других при вызове из приложения EDT.

person Tom Hawtin - tackline    schedule 12.06.2010

Существующий поток отправки событий блокируется, и поэтому swing создает другой поток, который перекачивает события. Тогда это поток отправки событий на время диалога.

Swing создает отдельный собственный поток для перекачки собственных оконных сообщений ОС. Это отдельно от потока событий AWT.

В Windows вы видите эти темы

  "AWT-Windows"   - the native UI thread
  "AWT-EventQueue-0" - the current AWT event dispatch thread

РЕДАКТИРОВАТЬ: отрицательный голос верен. Это неверно, по крайней мере, не во всех случаях.

Модальные диалоги часто сами заботятся о прокачке событий AWT. Если вы запустите код

SwingUtilities.invokeAndWait(new Runnable()
{
    public void run()
    {
        JOptionPane.showInputDialog("hello");
    }
});

а затем прервите, глядя на потоки, вы увидите только один поток EventQueue. Метод show () JOptionPane сам перекачивает события.

Такие фреймворки, как Spin и Foxtrot, используют тот же подход - они позволяют вам создать длительный метод блокировки на EDT. , но поддерживайте течение событий, накачивая сами события. У Swing может быть несколько потоков отправки (я уверен, что это было в случае со старыми версиями Swing), но теперь, когда многоядерность является обычным явлением, проблемы с параллелизмом, в частности, обеспечение правильной публикации изменений в одном потоке для других потоков, означают, что использование нескольких EDT приводит к ошибкам в текущей реализации. См. Несколько потоков отправки событий Swing

person mdma    schedule 12.06.2010
comment
Это все объясняет. Проголосовали за ваш ответ, но кто-то другой проголосовал против обоих: - / - person Bart van Heukelom; 12.06.2010
comment
Редактирование должно полностью исправить информацию или удалить неверную информацию. Нет смысла говорить что-то другим, чтобы они прочитали, а потом отмечать, что сказанное выше неверно. Целью SO является создание базы знаний качественных ответов. - person Luke Usherwood; 07.09.2016
comment
Новый поток не запускается; «приостановленный» код остается в стеке вызовов, а код входит в новый цикл обработки событий EDT, который может продолжать обрабатывать события графического интерфейса пользователя, рисовать окна и так далее. 'OK' модальное диалоговое окно выходит из внутреннего цикла, после чего можно продолжить исходный код. - person Luke Usherwood; 07.09.2016