SwingUtilities.invokeLater
Мой вопрос связан с SwingUtilities.invokeLater
, Когда я должен использовать это? Нужно ли использовать каждый раз, когда мне нужно обновить компоненты графического интерфейса? Что именно это делает? Есть ли альтернатива этому, так как это не звучит интуитивно понятно и добавляет, казалось бы, ненужный код?
5 ответов
Нужно ли использовать каждый раз, когда мне нужно обновить компоненты графического интерфейса?
Нет, нет, если вы уже находитесь в потоке отправки событий (EDT), что всегда имеет место при ответе на инициируемые пользователем события, такие как щелчки и выборки. (The actionPerformed
методы и т. д. всегда вызываются EDT.)
Однако, если вы не используете EDT и хотите обновить GUI (если вы хотите обновить GUI из какого-либо потока таймера или из какого-либо сетевого потока и т. Д.), Вам нужно запланировать обновление, которое будет выполнять EDT., Вот для чего этот метод.
Качели в основном небезопасны. Т.е. все взаимодействие с этим API должно выполняться в одном потоке (EDT). Если вам нужно обновить GUI из другого потока (поток таймера, сетевой поток, ...), вам нужно использовать методы, такие как упомянутый вами (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, ...).
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()
за исключением жестких изменений в GUI (JTree & JTable), но только с Substance L & F (отлично подходит для тестирования согласованности событий в EDT)Основные вещи: параллелизм в Swing
Все выходные данные фоновых задач должны быть обернуты в
invokeLater()
Мой вопрос на этот раз связан с
SwingUtilities.invokeLater
: Когда я должен использовать это?
Важно понимать, что в Java есть отдельный поток (EDT), обрабатывающий события, связанные с Swing.
Вы должны использовать invokeLater()
отобразить основной JFrame
настольного приложения (например), вместо того, чтобы пытаться сделать это в текущем потоке. Это также создаст контекст для корректного закрытия приложения позже.
Вот и все для большинства приложений.
Нужно ли использовать каждый раз, когда мне нужно обновить компоненты графического интерфейса? Что именно это делает?
Нет. Если вы измените компонент GUI, он вызовет событие, которое зарегистрировано для последующей отправки Swing. Если для этого события есть прослушиватель, поток EDT вызовет его где-нибудь в будущем. Вам не нужно использовать invokeLater()
Просто установите ваши слушатели на компоненты правильно.
Имейте в виду, что эта нить - это та же самая нить, рисующая рамки и т. Д. Следовательно, слушатели не должны выполнять сложные / длинные / ресурсоемкие задачи, иначе ваш экран зависнет.
Есть ли альтернатива этому, так как это не звучит интуитивно понятно и добавляет, казалось бы, ненужный код?
Вам не нужно писать больше кода, чем отображать ваше приложение с invokeLater()
+ интересующие вас слушатели по компоненту. Остальное обрабатывает Swing.
Каждое приложение Swing имеет как минимум 2 потока:
- Основной поток, который выполняет приложение
- EDT (поток диспетчеризации событий) - это поток, который обновляет пользовательский интерфейс (чтобы пользовательский интерфейс не зависал).
Если вы хотите обновить пользовательский интерфейс, вы должны выполнить код в EDT. Такие методы, как SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait, позволяют выполнять код с помощью EDT.
Большинство инициируемых пользователем событий (щелчки, клавиатура) уже будут в EDT, поэтому вам не придется использовать SwingUtilities для этого. Это охватывает множество случаев, кроме вашего основного потока () и рабочих потоков, которые обновляют EDT.