[SOLVED] Java: Delay (sleep, wait or whatever) within the ActionPerformed function
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Java: Delay (sleep, wait or whatever) within the ActionPerformed function
Hi all,
I've got this little game. There are two players, one of which is the machine.
When the player plays, the ActionPerformed (Java, Swing) function not only makes necessary changes on the Frame/Panel, but the machine also makes a move. I would like to insert a delay (a random delay if possible, between 500 and 2500 milliseconds) between the time the player makes the move and the time the machine does (which is not an "ActionPerformed") so as to give the human player the impression that the machine is thinking.
In other words, here's what I'd like (the code below does NOT work):
Code:
public void actionPerformed(ActionEvent ae){
System.out.println("This represents the change on the display corresponding to the human player's move");
sleep(1000); // or random delay between 500 and 2500 ms
System.out.println("This represents the machine's move, which is not an actual performed action or action event");
}
There must be an easy way to do this (maybe not?).
I've Google it but can't seem to find a simple solution.
Okay, you are right. I'd already tried that and initially thought it wouldn't work then played with it a bit (see code below). I now realize that my problem isn't quite what I described initially...
In the following code, I'd like the "X" to appear when the left button is pressed (immediately) and then a 2 second pause followed by the "O" appearing on the right-hand button. When running this little program, the System.out.println messages are displayed one after the other with the appropriate pause, however both the "X" and "O" appear at the same time in the window 2 seconds after the left-hand button is pressed:
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SleepTest implements ActionListener {
private JFrame window = new JFrame("SleepTest");
private JButton button1 = new JButton();
private JButton button2 = new JButton();
public SleepTest() {
window.setPreferredSize(new Dimension(300, 150));
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(button1);
window.add(button2);
button1.addActionListener(this);
button2.addActionListener(this);
window.setVisible(true);
window.setLayout(new GridLayout(1, 2));
window.pack();
}
public void actionPerformed(ActionEvent ae) {
button1.setText("X");
button1.setEnabled(false);
System.out
.println("PLAYER ACTION: This represents the change on the display corresponding to the human player's move");
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException ie) {
// ... Error message...
}
System.out
.println("MACHINE ACTION: This represents the machine's move, which is not an actual performed action or action event");
button2.setText("O");
}
public static void main(String[] args) {
new SleepTest();
}
}
If anybody out there could modify my code so that it does what I want it to do, I'd certainly appreciate it.
When running this little program, the System.out.println messages are displayed one after the other with the appropriate pause, however both the "X" and "O" appear at the same time in the window 2 seconds after the left-hand button is pressed:
It's because the repainting code happens in the same thread as the event handling. What you need to do is set a Timer to make the "O" later on (completely untested):
Code:
public class SleepTest implements ActionListener {
...
private JButton button2 = new JButton();
private ButtonTextSetter button2SetO = new ButtonTextSetter(button2, "O");
private Timer machineMoveTimer = new Timer(2000, button2SetO);
public SleepTest() {
machineMoveTimer.setRepeats(false);
...
}
...
public void actionPerformed(ActionEvent ae) {
button1.setText("X");
button1.setEnabled(false);
machineMoveTimer.restart();
}
...
}
class ButtonTextSetter implements ActionListener {
final AbstractButton button;
final String text;
ButtonTextSetter(AbstractButton button, String text) {
this.button = button;
this.text = text;
}
public void actionPerformed(ActionEvent ae) {
button.setText(text);
}
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.