Должны ли мы использовать EventQueue.invokeLater для любого обновления GUI в настольном приложении Java?
Я знаю, что с помощью этого метода параметр runnable передается в систему EventQueue. Но все ли обновления GUI должны выполняться с использованием этого метода? Я имею в виду, если я хочу сказать, изменить текст JButton, если я буду использовать что-то вроде этого:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
jButton1.setText("changed text");
}
});
Если я должен использовать этот подход, любой шаблон, который мы можем использовать, чтобы избежать этого повторяющегося кода?
3 ответа
Вам нужно только использовать invokeLater
когда вы хотите обновить свой пользовательский интерфейс из другого потока, который не является потоком пользовательского интерфейса (потоком отправки событий).
Предположим, у вас есть обработчик для нажатия кнопки, и вы хотите изменить текст метки, когда кто-то нажимает кнопку. Тогда можно сохранить текст метки напрямую. Это возможно, потому что обработчик для события нажатия кнопки выполняется в потоке пользовательского интерфейса.
Предположим, однако, что при следующем нажатии кнопки вы запускаете другой поток, который выполняет некоторую работу, и после завершения этой работы вы хотите обновить пользовательский интерфейс. Тогда вы используете invokeLater
, Этот метод гарантирует, что ваше обновление пользовательского интерфейса выполняется в потоке пользовательского интерфейса.
Так что во многих случаях вам не нужно invokeLater
, вы можете просто сделать обновления интерфейса напрямую. Если вы не уверены, вы можете использовать isDispatchThread
чтобы проверить, работает ли ваш текущий код в потоке отправки событий.
Это нужно делать только в том случае, если вы еще не в потоке отправки событий. Если вы не запустили новые потоки или не выполнили код из основного потока, весь ваш код, вероятно, уже выполняется из потока диспетчеризации событий, что делает это ненужным. Например, все обработчики событий пользовательского интерфейса вызываются в потоке диспетчеризации событий, поэтому вам не нужно делать это для кода, вызываемого оттуда.
Вместо того, чтобы по-настоящему избегать "повторяющихся" (Java-люди, вероятно, сказали бы, читаемый код без многих секретов), вы можете использовать функцию шаблонов Eclipse. у меня есть его, чтобы расширить две буквы "ил" в следующем блоке:
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
// do something.
} catch (Exception e) {
e.printStackTrace();
}
}
});
По-видимому, этот дизайн очереди рассылки не только рекомендуется, но и необходим. Это, пожалуй, самый шумный способ, которым я когда-либо видел на любом языке, когда я помещаю лямбду в очередь сообщений. Но это так. Это Ява. И в защиту Java, безусловно, из вышесказанного очевидно, что именно происходит. Я негодую на количество набираемых текстов, но единственное, что я могу придумать, чтобы избежать этого, - это макросы препроцессора C, и я держу пари, что людям на Java это не нравится. Расширение кода с помощью шаблонов более читабельно, поддерживается и не требует какой-либо черной магии.