Подтвердить что ты не робот

Как могут работать диалоги 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 требует, чтобы этот поток работал.

Итак, как это работает?

4b9b3361

Ответ 1

Это AWT-нить, а не Swing's.

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

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

 Thread.dumpStack();

в четную обработку для модального диалога или более легко из командной строки с помощью jstack или использовать ctrl-\/ctrl-break в окне команд приложения.

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

Ответ 2

Существующий поток диспетчеризации событий блокируется, и поэтому 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), но теперь, когда многоядерность распространена, проблемы concurrency, в частности обеспечение изменений в одном потоке, правильно публикуются для других потоки, означают, что использование нескольких EDT создает ошибки в текущей реализации. Видеть Несколько событий рассылки событий Swing