#java #swing #user-interface
Вопрос:
Я пытаюсь создать простой хронометр с графическим интерфейсом Java, но всякий раз, когда я нажимаю кнопку «Пуск», графический интерфейс зависает и не позволяет мне нажать кнопку «Стоп», но программа продолжает отлично работать на терминале.
Вот код моей кнопки «Пуск»:
startButton = new JButton();
startButton.setText("START");
startButton.setFont(new Font("RuneScape UF", Font.PLAIN, 16));
startButton.setFocusable(false);
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == startButton) {
System.out.println("Start button pressed!");
isRunning = true;
System.out.println(isRunning);
long startTime = System.currentTimeMillis();
while (isRunning) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
long elapsedTime = System.currentTimeMillis() - startTime;
long elapsedSeconds = elapsedTime / 1000;
if (elapsedSeconds == 60) {
elapsedSeconds = 0;
startTime = System.currentTimeMillis();
}
if ((elapsedSeconds % 60) == 0) {
minutesDisplay ;
}
if ((minutesDisplay % 60) == 0 amp;amp; stupidFix > 0) {
stupidFix ;
hoursDisplay ;
}
//System.out.println(elapsedSeconds);
String h = String.format("d", hoursDisplay);
String m = String.format("d", minutesDisplay);
String s = String.format("d", elapsedSeconds);
timePassed.setText(h ":" m ":" s);
System.out.println(h ":" m ":" s);
}
}
}
});
Комментарии:
1. Это связано с тем, что поток пользовательского интерфейса застрял в вашем
while (isRunning)
цикле, вам придется выполнить этот код в отдельном потоке2. Может быть, это будет полезно: docs.oracle.com/javase/tutorial/uiswing/concurrency/…
Ответ №1:
Вы используете прослушиватель while loop
действий внутри кнопки. Использование цикла while внутри прослушивателя действий кнопки считается тяжелой задачей.Вы должны использовать SwingWorker
для этого.
Вы можете посмотреть учебник по этому вопросу здесь:
https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html
Комментарии:
1. » Использование цикла while внутри прослушивателя действий кнопки считается тяжелой задачей.» Это только
Thread.sleep(..)
то, что будет блокировать EDT, поэтому не обязательно является «тяжелой» задачей. На самом деле, это лучше сделать, установив качелиTimer
для обновления времени. Обе ситуации описаны в ссылке, предоставленной Анастасией.