С помощью людей в 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();
}
});
}
}