С помощью людей в qaru.site/info/373510/... мне удалось получить следующий рабочий код простого обратного отсчета графического интерфейса (который просто отображает окно, отсчитывающее секунды), Моя основная проблема с этим кодом - это материал invokeLater
.
Насколько я понимаю invokeLater
, он отправляет задачу в поток диспетчеризации событий (EDT), а затем EDT выполняет эту задачу всякий раз, когда она "может" (что бы это ни значило). Правильно ли это?
Насколько я понимаю, код работает следующим образом:
-
В методе
main
мы используемinvokeLater
, чтобы показать окно (методshowGUI
). Другими словами, код, отображающий окно, будет выполнен в EDT. -
В методе
main
мы также запускаемcounter
, а счетчик (по построению) выполняется в другом потоке (так что это не в случае диспетчерского потока). Правильно? -
counter
выполняется в отдельном потоке и периодически вызываетupdateGUI
.updateGUI
должен обновить GUI. И графический интерфейс работает в EDT. Таким образом,updateGUI
также должен быть выполнен в EDT. Именно по этой причине код дляupdateGUI
заключен вinvokeLater
. Это правильно?
Что мне непонятно, почему мы называем counter
из EDT. Во всяком случае, он не выполняется в EDT. Он запускается немедленно, там выполняется новый поток и counter
. Итак, почему мы не можем вызвать counter
в основном методе после блока invokeLater
?
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class CountdownNew {
static JLabel label;
// Method which defines the appearance of the window.
public static void showGUI() {
JFrame frame = new JFrame("Simple Countdown");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label = new JLabel("Some Text");
frame.add(label);
frame.pack();
frame.setVisible(true);
}
// Define a new thread in which the countdown is counting down.
public static Thread counter = new Thread() {
public void run() {
for (int i=10; i>0; i=i-1) {
updateGUI(i,label);
try {Thread.sleep(1000);} catch(InterruptedException e) {};
}
}
};
// A method which updates GUI (sets a new value of JLabel).
private static void updateGUI(final int i, final JLabel label) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
label.setText("You have " + i + " seconds.");
}
}
);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showGUI();
counter.start();
}
});
}
}