I'm trying to make a simple Java GUI chronometer, but whenever I press the start button the GUI freezes and won't allow me to click the stop button, but the program continues to run perfectly on the terminal.
Here is the code of my start button:
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 && stupidFix > 0) {
stupidFix++;
hoursDisplay++;
}
//System.out.println(elapsedSeconds);
String h = String.format("%02d", hoursDisplay);
String m = String.format("%02d", minutesDisplay);
String s = String.format("%02d", elapsedSeconds);
timePassed.setText(h + ":" + m + ":" + s);
System.out.println(h + ":" + m + ":" + s);
}
}
}
});
1 Answer 1
You are using a while loop
inside a button action listener.
Using a while loop inside a button action listener is considered a heavy task.You have to use SwingWorker
for this.
You can see the tutorial for it here:
https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html
answered Jun 3, 2021 at 3:47
1 Comment
Andrew Thompson
" Using a while loop inside a button action listener is considered a heavy task." It's only the
Thread.sleep(..)
that will will block the EDT, so is not necessarily a 'heavy' task. In fact, this is better done by establishing a Swing Timer
to update the time. Both situations are covered in the link provided by Anastasia.lang-java
while (isRunning)
loop, you'd have to execute that code in a separate thread