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

SwingUtilities.invokeLater

Мой вопрос связан с SwingUtilities.invokeLater. Когда я должен его использовать? Должен ли я использовать каждый раз, когда мне нужно обновлять компоненты GUI? Что он делает? Есть ли альтернатива этому, поскольку он не звучит интуитивно и добавляет, казалось бы, ненужный код?

4b9b3361

Ответ 1

Должен ли я использовать каждый раз, когда мне нужно обновлять компоненты графического интерфейса?

Нет, нет, если вы уже находитесь в потоке отправки событий (EDT), который всегда имеет место при реагировании на инициируемые пользователем события, такие как щелчки и выбор. (Методы actionPerformed и т.д., Всегда вызывается EDT.)

Если вы еще не на EDT и хотите обновлять GUI (если вы хотите обновить графический интерфейс из какого-то потока таймера или из какого-то сетевого потока и т.д.), вам придется запланировать обновление, которое будет выполнено по EDT. Для чего этот метод.

Качание в основном небезопасно. I.e., все взаимодействие с этим API должно выполняться в одном потоке (EDT). Если вам нужно делать обновления GUI из другого потока (поток таймера, сетевой поток,...), вам нужно использовать такие методы, как тот, который вы упомянули (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait,...).

Ответ 2

Swing is single threaded and all changes to the GUI must be done on EDT 

Основное использование для invokeLater()

  • Основные методы всегда должны быть завернуты в invokeLater()

  • Отложенное (но асинхронно) действие/событие в конце EventQueue,

  • Если EDT не существует, вам нужно создать новый EDT, используя invokeLater(). Вы можете проверить его с помощью if (SwingUtilities.isEventDispatchThread()) {...

  • Существует invokeAndWait(), но до сегодняшнего дня я (просто мое мнение) не может найти причину использования invokeAndWait() вместо invokeLater(), кроме жестких изменений в графическом интерфейсе (JTree и JTable), но только с Substance L & F (отлично подходит для проверки согласованности событий на EDT)

  • Основной материал: Concurrency в Swing

  • Весь вывод из фоновых задач должен быть заключен в invokeLater()

Ответ 3

Каждое приложение Swing имеет как минимум 2 потока:

  • Основной поток, выполняющий приложение
  • EDT (Event Dispatching Thread) - это поток, который обновляет пользовательский интерфейс (поэтому пользовательский интерфейс не будет зависеть).

Если вы хотите обновить пользовательский интерфейс, вы должны выполнить код в EDT. Такие методы, как SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait позволяют выполнять код по EDT.

Ответ 4

Мой вопрос на этот раз связан с SwingUtilities.invokeLater: когда его использовать?

Ключевым моментом для понимания является то, что Java имеет отдельный поток (EDT), обрабатывающий события, связанные с Swing.

Вы должны использовать invokeLater() для отображения основного JFrame настольного приложения (например) вместо того, чтобы пытаться сделать это в текущем потоке. Он также создаст контекст для изящного закрытия приложения позже.

Это для большинства приложений.

Должен ли я использовать каждый раз, когда мне нужно обновлять компоненты графического интерфейса? Что он делает?

Нет. Если вы измените компонент GUI, он инициирует событие, которое будет зарегистрировано для последующей отправки Swing. Если есть слушатель для этого события, поток EDT будет вызывать его где-то по дороге. Вам не нужно использовать invokeLater(), просто установите слушателей на компоненты правильно.

Имейте в виду, что этот поток - это те же кадры рисования потоков и т.д.... на вашем экране. Следовательно, слушатели не должны выполнять сложные/длинные/интенсивные задачи, иначе ваш экран замерзнет.

Есть ли альтернатива этому, поскольку он не звучит интуитивно и добавляет, казалось бы, лишний код?

Вам не нужно писать больше кода, чем отображать ваше приложение с помощью invokeLater() + прослушивателей, которые вас интересуют на компоненте. Остальное обрабатывается Swing.

Ответ 5

Большинство инициированных пользователем событий (клики, клавиатура) уже будут на EDT, поэтому вам не придется использовать SwingUtilities для этого. Это распространяется на множество случаев, за исключением потоков main() и рабочих потоков, которые обновляют EDT.