How can I pause/sleep/wait in a java swing app?
Using Thread#sleep
method in swing applications in main thread will cause the GUI to freeze (since the thread sleeps, events cannot take place). Thread#sleep
method in swing applications is only allowed to be used only by SwingWorkers, and this in their #doInBackround
method.
In order to wait in a swing application (or do something periodically), you will have to use a Swing Timer. Take a look at an example i have made:
import java.awt.FlowLayout;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer; //Note the import
public class TimerExample extends JFrame {
private static final int TIMER_DELAY = 1000;
private Timer timer;
public TimerExample () {
super();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(200, 200);
setLocationRelativeTo(null);
getContentPane().setLayout(new FlowLayout());
timer = new Timer(TIMER_DELAY, e -> {
System.out.println("Current Time is: " + new Date(System.currentTimeMillis()));
});
//timer.setRepeats(false); //Do it once, or repeat it?
JButton button = new JButton("Start");
button.addActionListener(e -> timer.start());
getContentPane().add(button);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new TimerExample().setVisible(true));
}
}
Output after "Start" button is pressed:
Current Time is: Mon Feb 25 13:30:44 EET 2019
Current Time is: Mon Feb 25 13:30:45 EET 2019
Current Time is: Mon Feb 25 13:30:46 EET 2019
As you can see, Timer's action listener fires every second.
So in your case:
timer = new Timer(TIMER_DELAY, e -> {
if (currentIndexLabel != paint.length-1) {
upateLabels();
timer.restart(); //Do this check again after 1000ms
}
});
button.addActionListener(e -> timer.start());
How to delay an answer while not freezing the thread?
Consider using a Timer
to prevent main thread from freezing :
import javax.swing.*;
import java.awt.event.*;
ActionListener task = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
}
};
Timer countdown = new Timer(1000 ,task);
countdown.setRepeats(false);
countdown.start();
where 1000 is the delay time in milliseconds and inside the actionPerformed
function is where your code executes after the delay time set.
Java GUI, need to pause a method without freezing GUI aswell
You can't do it without creating a separate thread. Creating a thread in Java is easy. The only thing to pay attention to is that you can only touch the UI through the main thread. For this reason you need to use something like SwingUtilities.invokeLater().
Java: How to wait 1 second in a GUI
You shouldn't call the sleep()
method inside your gui thread, otherwise all your interface will freeze. You should use a separate thread instead and communicate with your gui thread to tell him when to update the interface.
The best way to work with threads in a Swing application is using the SwingWorker
object. In particular, it offer two hook methods that are process
and done
that are called directly in your gui thread and are a powerful way to publish progress done by your worker thread. In your case, you should do something like that:
SwingWorker<Void, String> worker = new SwingWorker<Void, String>(){
@Override
protected Void doInBackground() throws Exception {
this.publish("Everything");
Thread.sleep(1000);
this.publish("Everything is");
Thread.sleep(1000);
this.publish("Everything is Awesome!");
return null;
}
@Override
protected void process(List<String> res){
for(String text : res){
label.setText(text);
}
}
};
worker.execute();
P.S.: you can call the execute()
method only once on a worker object. If you want to call it multiple times you have to instantiate new objects.
Trying to pause program execution within an if statement (Swing)
That is because swing timer is asynchronous. So you have to put second line of your code (and all following logic) into action listener like:
mPlayerLastRollLabel.setText("Player rolled: ...");
Timer t = new Timer(5000, new ActionListener(){
public void actionPerformed(ActionEvent ae){
mPlayerLastRollLabel.setText("Player rolled: " + mFaceNumber);
}
});
t.setRepeats(false);
t.start();
Or you can put second half after sleep into separate function and call it from actionPerfomed method. Doing it this way instead of Thread.sleep you release graphical thread (which is one for all UI) until your sleeping time is up. If don't release graphical thread then your UI would freeze because there would be no thread to react to user actions.
How do I pause Java Simulation using Swing
You need to provide additional logic to your simulation thread that will accept "signals" from controlling (GUI) thread and wait for the next controlling signal to resume execution.
For example you can use volatile boolean isPaused
instance field in simulation thread. Set it to true/false to pause/resume simulation thread. In simulation thread implement corresponding logic:
public void run() {
while (true) {
simulate();
while (isPaused) {
Thread.sleep(100);
}
}
}
Related Topics
Mocking Time in Java 8's Java.Time API
How Pause and Then Resume a Thread
Execute Jsp Directly from Java
Calling a Java Method to Draw Graphics
Java: Jackson Polymorphic JSON Deserialization of an Object with an Interface Property
What Version of Javac Built My Jar
How Do Format a Phone Number as a String in Java
What Is the Actual Memory Place for Static Variables
Auto Adjust the Height of Rows in a Jtable
Why Does Collections.Sort Use Mergesort But Arrays.Sort Does Not
How to Tell Spring Boot Which Main Class to Use for the Executable Jar
Jtable + Sorting Specific Field