Почему мое стандартное настольное Java-приложение JFrame использует EventQueue.invokeLater в основном методе?
Я использую последнюю версию Eclipse и GWT Designer, чтобы создать свинг-приложение на Java. Основная функция в моем окне приложения (которое является javax.swing.JFrame) в автоматическом режиме, сгенерированном инструментами, выглядит следующим образом:
/* launch the application */
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
AppWindow window = new AppWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
Это похоже на шум вокруг того, что могло быть просто так:
public static void main(String[] args) {
try {
AppWindow window = new AppWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
Я прочитал, что метод EventQueue.InvokeLater требуется в некоторых ситуациях, и другой вопрос спрашивает, где его использовать здесь.
Мой вопрос проще; Почему это автоматически в генераторе кода здесь? Почему main должен быстро вернуться и позволить окну приложения позже создать очередь событий? Разве блокировка не была бы точно смыслом? Почему автоматически сгенерированный дизайнер JFrame выполняет этот EventQueue? Я попытался увидеть некоторую разницу в запуске и отображении форм, выполняется ли этот код более простым или более сложным способом, и я могу лишь временно сделать вывод, что это имеет некоторые преимущества, которые не видны в крошечных демонстрационных приложениях, созданных новичками. как я, и что, возможно, в реальных сложных комплексных классах, основанных на Jframe, есть какая-то выгода для этой стратегии отсрочки / очереди?
2 ответа
В зависимости от вашего приложения и того, как оно используется, возможно, что что-то рисует на экране (и, таким образом, используя EventQueue
) до или во время звонка на ваш main
метод. Вызовы, которые изменяют любые компоненты пользовательского интерфейса, должны быть сделаны на Event Dispatch Thread
, и это включает в себя настройку приложения видимым.
Поэтому, чтобы быть в безопасности, рекомендуется запустить приложение на EDT
,
Почему это автоматически в генераторе кода здесь?
Это не повредит, его легко генерировать, и это считается хорошей практикой.
Почему main должен быстро вернуться и позволить окну приложения позже создать очередь событий?
Возможно, что main
метод вызывается из другого приложения, использующего EDT
и, возможно, уже нарисовал что-то на экране. Если вы подаете заявку прямо в main
, возможно, что ваше приложение может изменять какой-то компонент, который находится в процессе обработки чем-то на EDT
и потенциально уже нарисован на экране.
Поэтому, чтобы быть в безопасности на случай, если такая ситуация когда-либо случится, вы должны оставить это до EDT
нарисовать ваше приложение, чтобы оно могло делать это, когда оно не будет мешать чему-либо еще.
Разве блокировка не была бы точно смыслом?
Если что-то еще не зовет main
кроме процесса JVM, который ваш пользователь запустил, дважды щелкнув значок на рабочем столе, это не будет иметь значения, когда main
возвращается, пока на экране что-то есть.
Я могу лишь временно сделать вывод, что это имеет некоторые преимущества, которые не видны в крошечных демонстрационных приложениях, созданных такими новичками, как я
Вы правы - в большинстве случаев это, вероятно, не будет иметь значения, но я предполагаю, что они включили это, потому что это было легко генерировать и реализовывать, это не повредит, и это будет примером хорошей практики.
1) почему строит Swing GUI внутри try-catch-finally, я не вижу никаких причин для этого, разделить создание не поточно-безопасного GUI и не-поточно-безопасного кода на отдельные потоки,
2) Swing не является потокобезопасным, тогда правильным является то, что pack() + setVisible(true)
было бы
последние строки кода, связанные с GUI
завернутый в invokeLater
забыл примеры из некоторого кода. ПримерыДепоты, этот форум, другие форумы, уверен, что этот код работает, но с риском, что все может случиться
правильный запуск Swing GUI
например
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
AppWindow window = new AppWindow();
window.frame.setVisible(true);
}
});
}
3) есть ли Serializable, Custom L & F, а затем (лучше будет) обернуть в invokeAndWait