Почему люди запускают графический интерфейс 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 как положено.

Другие вопросы по тегам