Почему люди запускают графический интерфейс Java в очереди событий
В Java, чтобы создать и показать новый JFrame
Я просто делаю это:
public static void main(String[] args) {
new MyCustomFrameClass().setVisible(true);
}
Тем не менее, я видел много людей, делающих это так:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new MyCustomFrameClass().setVisible(true);
}
});
}
Зачем? Есть ли преимущества?
2 ответа
Правила, регулирующие то, что должно быть выполнено в EDT (я вижу, что "EDT" используется чаще, чем "Очередь событий"), изменились за время существования Java. И каждый раз, когда "правила" менялись, Sun советовала делать все больше и больше "связанных с GUI" работ над EDT.
Почему люди используют Java GUI на EDT?
Потому что официальные рекомендации рекомендуют это делать.
Потому что это поможет избежать многих ошибок, связанных с GUI.
Обратите внимание, и это не очень хорошо известно, что EDT действительно происходит сбой время от времени, потому что сам Swing имеет несколько ошибок. Каждое нетривиальное приложение Swing использует API-интерфейсы Swing, которые имеют, в общем-то, ошибки и, следовательно, время от времени EDT умирает.
Вы никогда не видите это, и это не вызывает беспокойства, потому что, когда EDT умирает, он автоматически перезапускается.
По сути, делайте все, что связано с GUI, на EDT и выполняйте все длительные операции вне EDT (чтобы не блокировать EDT).
РЕДАКТИРОВАТЬ Вы попросили привести пример того, как запустить длинную операцию за пределами EDT. Есть несколько способов сделать это. В простейшем случае вы просто создаете и запускаете новую тему из EDT. Вот один пример: обратный вызов слушателя должен вызываться, когда пользователь нажимает кнопку, мы знаем, что это должно произойти в EDT...
JButton jb = ...
jb.addActionListener( new ActionListener() {
public void actionPerformed( final ActionEvent e ) {
final Thread t = new Thread( new Runnable() {
public void run() {
// this shall get executed, after start() has been called, outside the EDT
}
});
t.start();
}
} );
Для более сложных примеров, вы хотите прочитать на SwingWorker и т. Д.
Эта строка изменяет компонент Swing, поскольку ваш пользовательский фрейм является подклассом JFrame
:
new MyCustomFrameClass().setVisible(true);
Как правило, вы никогда не должны изменять компонент Swing, если вы не участвуете в потоке рассылки событий (EDT).
Следующий код будет запускать все, что находится в Runnable
на EDT.
EventQueue.invokeLater(Runnable);
Теперь setVisible(true)
звонок будет на EDT как положено.