Delay a code by given seconds - java

This a code written using java to delay the execution of the code by 5 seconds. But it is not working. either "this.jLabel2.setText("TDK");" statement not working. Can any one please help me to solve this problem.
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
this.jLabel2.setText("TDK");
boolean result=false;
result=stop();
if(result)
{
this.jLabel1.setText("MDK");
}
}
public boolean stop()
{
String current= new java.text.SimpleDateFormat("hh:mm"
+ ":ss").format(new java.util.Date(System.currentTimeMillis()));
String future=new java.text.SimpleDateFormat("hh:mm"
+ ":ss").format(new java.util.Date(System.currentTimeMillis()+5000));
while(!(current.equals(future)))
{
current= new java.text.SimpleDateFormat("hh:mm"
+ ":ss").format(new java.util.Date(System.currentTimeMillis()));
}
return true;
}

You are blocking the event dispatch thread (no, don't use Thread.sleep() either). Use a swing Timer:
Timer timer = new Timer(HIGHLIGHT_TIME, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jLabel1.setText("MDK");
}
});
timer.setRepeats(false);
timer.start();
where HIGHLIGHT_TIME is the time you want to delay setting the text.

Use the javax.swing.Timer with setRepeats set to false.

Related

button event doesn't work properly

I have some doubts about the use of the methods wait() and notify(). I have the next code which has some button events, the first time the user pushes the button it has to stop printing, and the second time it restarts printing again. I understand that is better to use Runnable instead of Thread, but I have to use Thread because of the requirements. The code works fine the first time the button is pushed but the second time it doesn´t, I want to use the wait() and the notify, but i don´t know how to do it with this particular code.
class Thr extends Thread{
private int count = 0;
private long pause;
private boolean canPrint = true;
private JTextArea textArea;
Thr(long miliseconds,JTextArea text){
pause = miliseconds;
textArea = text;
}
public void pushedButton(){
if(canPrint)
this.canPrint = false;
else
this.canPrint = true;
}
public void run()
{
while(this.canPrint)
{
try
{
this.printCounter();
Thread.sleep(pause);
this.count++;
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
public void printCounter(){
String time;
time = Integer.toString(count);
textArea.setText(time);
}
}
class Interface extends JFrame implements ActionListener{
private JTextArea textArea,textArea2;
private JButton button;
private Thr thread,threadEvent;
Interface()
{
textArea = new JTextArea(10,7);
textArea2 = new JTextArea(10,7);
thread = new Thr(2000,textArea);
threadEvent = new Thr(1000,textArea2);
button = new JButton("Pausar/Reanudar");
this.getContentPane().add(button,BorderLayout.SOUTH);
this.getContentPane().add(textArea,BorderLayout.WEST);
this.getContentPane().add(textArea2,BorderLayout.EAST);
thread.start();
threadEvent.start();
button.addActionListener(this);
}
public void actionPerformed(ActionEvent event)
{
threadEvent.pushedButton();
}
}
public class MensajesHilos {
public static void main(String[] args){
Interface i = new Interface();
i.setTitle("Control Threads");
i.setBounds(200, 200, 300, 240);
i.setVisible(true);
}
}
The way you have coded, if you want to achieve the desired result,
I feel the modification need to be done in run method,
public void run()
{
while(true)
{
if(this.canPrint){
try
{
this.printCounter();
Thread.sleep(pause);
this.count++;
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
in this way, your Thread will never go dead and toggle printing based on canPrint boolean value.
Also, make sure to declare canPrint variable volatile, so that changes to it will be directly written to main memory and reflected immediately.
"button event doesn´t work properly"
This is false, if you put a print statement in the actionPerformed method, you will see that it is called every time you press the button.
By the way note that you can simplify this
if(canPrint)
this.canPrint = false;
else
this.canPrint = true;
To
this.canPrint = !this.canPrint;
Note that it is a good practice to always put #Override anotation on top of overriden method.
#Override
public void actionPerformed(ActionEvent event)
{
threadEvent.pushedButton();
}
Now why don't you get the expected result ?
You ommit to call thread.pushedButton, so the canPrint will only be reseted in the threadEvent object, and will never be in thread.
Note that once the boolean are set to false, you will exit the loop and the process won't start back after even if you re-set the boolean value to true. This example will works using while(true) however, you should change the true to any sentinel value to handle the exit of the program as this will loop forever.
#Override
public void run()
{
while(true)
{
if(this.canPrint)
{
this.printCounter();
this.count++;
}
try
{
Thread.sleep(pause);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Also, make sure that pause is never 0 else you will eat all of the computer process.
Note that, as other stated, you should declare variables that are accessed in thread as volatile (canPrint) in your case.

Java - Trigger swing timer with a mouseEvent?

I'm trying to turn on the timer using mouseEntered event with MouseListener it doesn't seem to work. Am i doing somthing wrong? I'm new to Java. Thanks in advance!
int counter = 0;
Timer timer = new Timer(1000,this);
public void mouseEntered(e MouseEvent)
{
if(e.getComponent == mouseEnteredArea)
{
timer.start()
counter++;
if(counter == 10)
{
timer.stop();
}
}
}
What's happening is when the mouse enters the area, your code starts the timer, adds one to counter (so counter == 1), checks if counter is equal to 10. Since it isn't, the code then skips the if statement and exits the method.
It's difficult to tell your actual intentions from that question, so if that wasn't enough to help, please explain what you're trying to do.
I think you may not understand how the timer works. Basically the timer has an ActionListener. Every 1000 milliseconds (in your case), the actionPerformed will be called. So I believe the code you have above should be in the ActionListener, and just call timer.start() in the mouse method. Something like.
Timer timer = new Timer(1000, new ActionListener(){
private int counter = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (counter == 10) {
((Timer)e.getSource()).stop();
counter = 0;
} else {
System.out.println("Count: " + (++counter));
}
}
});
....
#Override
public void mouseEntered(MouseEvent e) {
timer.start();
}
Resources
How to Use Swing Timers
How to Write a Mouse Listener

How to change timer

I'm not sure how to change the timer in my program.
I want to control the timer as the program runs.
This is my code:
Timer timer = new Timer(Difficulty, new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if(p.GameOver==0)
{
if(p.s==1)
{
System.out.println("S");
p.moveSquare(p.SnakeHeadX,p.SnakeHeadY+p.SnakeHeadH);
p.eatBlueSquare(p.SnakeHeadX,p.SnakeHeadY);
p.Border(p.SnakeHeadX,p.SnakeHeadY);
p.Colision(p.SnakeHeadX,p.SnakeHeadY);
}
if(p.d==1)
{
System.out.println("D");
p.moveSquare(p.SnakeHeadX+p.SnakeHeadW,p.SnakeHeadY);
p.eatBlueSquare(p.SnakeHeadX,p.SnakeHeadY);
p.Border(p.SnakeHeadX,p.SnakeHeadY);
p.Colision(p.SnakeHeadX,p.SnakeHeadY);
}
if(p.a==1)
{
System.out.println("A");
p.moveSquare(p.SnakeHeadX - p.SnakeHeadW,p.SnakeHeadY);
p.eatBlueSquare(p.SnakeHeadX,p.SnakeHeadY);
p.Border(p.SnakeHeadX,p.SnakeHeadY);
p.Colision(p.SnakeHeadX,p.SnakeHeadY);
}
if(p.w==1)
{
System.out.println("W");
p.moveSquare(p.SnakeHeadX,p.SnakeHeadY-p.SnakeHeadH);
p.eatBlueSquare(p.SnakeHeadX,p.SnakeHeadY);
p.Border(p.SnakeHeadX,p.SnakeHeadY);
p.Colision(p.SnakeHeadX,p.SnakeHeadY);
}
}
}
});
timer.start();
If I change difficulty as the program runs there is no effect.
Just use timer.setDelay(Difficulty) every time you update the difficulty.
For more info about timer see this: http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html
you would have to cancel the current timer and then reinstantiate the timer with the correct value (where you would change the difficulty)

Java: Perform Action Every X Seconds

I've got a working Java program and I would like to draw an object on the display every X seconds. What is the best way to do this? I was thinking of using a for loop and some sleep statements, but I'm curious if there is an easier or more efficient way to go about this.
Thanks.
The simplest way would be to use a javax.swing.Timer
Timer timer = new Timer(X, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// Update the variables you need...
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
You might also like to have a read through
The Event Dispatching Thread
Concurrency in Swing
So you can understand why you should never use a while (true) { Thread.sleep(X) } call in Swing (inside the EDT)
ScheduledExecutorService might help here. The Javadoc shows example usage. Don't forget to call the shutdown method when you're finished.
Using Thread, this will draw a rectangle on the screen every XMilSeconds. This will stop after 5 runs. Edit the xMilSeconds for slower runs, and j > 4 for how many runs before stoping. It does freeze though, that I can't fix.
int i = 0;
private long xMilSeconds = 300;
private boolean paint;
public boolean running = true;
public void paint(Graphics g)
{
super.paint(g);
if(paint)
{
for(;i < i+1;)
{
g.drawRect(i+49,i+49,i+299,i+99);
g.setColor(Color.RED);
g.fillRect(i+49,i+49,i+299,i+99);
}
paint = false;
}
}
public void run()
{
while(running)
{
try
{
Thread.sleep(xSeconds);
paint = true;
repaint();
i++;
j++;
if(j > 4)
{
running = false;
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

Why is it so hard to stop a thread in Java?

I've come again in one of THOSE situations where it is just impossible to stop/destroy/suspend a thread. .interrupt() doesn't do the trick and .stop() and .suspend() are deprecated.
Very simple example:
public class TimerThread extends Thread {
private JPanel colorPanel;
public TimerThread(JPanel colorPanel) {
this.colorPanel = colorPanel;
}
public void run() {
while (true) {
try {
Thread.sleep(1000);
colorPanel.repaint();
} catch (Exception ex) {
//do Nothing
}
}
}
}
What this does is repaint a certain JPanel every second to change its colour. I want to start and stop the thread like this from another class:
timer = new Thread(new TimerThread(colorPanel));
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.interrupt();
}
});
Obviously (?) this doesn't work... I know I could use a Timer, a SwingWorker or declare the timer as timer = new TimerThread(colorPanel); and use a boolean instead of "true" in the run method, but I've been asked to declare timer as a "Thread" and nothing else.
To my surprise (or is this that stupid?), even this didn't work:
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer = new Thread(new TimerThread(colorPanel));
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.interrupt();
timer = null;
}
});
So my question is simple: How do you make threads Start/Pause/Resume/Stop in Java?
when you get an interrupt you should start the cleanup and return a.s.a.p. (or at the very least reset the interrupted status)
while (true) {
try {
Thread.sleep(1000);
colorPanel.repaint();
} catch(InterruptedException e){//from sleep
return;//i.e. stop
} catch (Exception ex) {
//do Nothing
}
}
another way is to check Thread.interrupted() in the condition (but you'll need to reset the interrupted status in the catch of InterruptedException
however in swing you can use javax.swing.Timer to let an event run every so often and stop that with the api of that
javax.swing.Timer timer = new Timer(1000,new ActionListener() {
public void actionPerformed(ActionEvent e) {
colorPanel.repaint();
}
});
timer.setRepeats(true);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
Try this:
public class TimerThread extends Thread {
private volatile boolean stop = false;
private JPanel colorPanel;
public TimerThread(JPanel colorPanel) {
this.colorPanel = colorPanel;
}
public void stopTimer() {
stop = true;
}
public void run() {
while (stop == false) {
try {
Thread.sleep(1000);
colorPanel.repaint();
} catch (Exception ex) {
//do Nothing
}
}
}
}
// Why new Thread(new TimerThread(...))?
// timer = new Thread(new TimerThread(colorPanel));
timer = new TimerThread(colorPanel)
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.stopTimer();
}
});
Also have a look at here to see how you can replicate stop now that it's deprecated.
You make them co-operate, basically. You have some shared flags to let them see what they should be doing, and whenever you would sleep, instead you wait on some shared monitor. Then when you want to control the thread, you set the appropriate flag and notify the monitor so that if the thread was waiting, it will wake up and notice that it should suspend/stop/whatever. Obviously you need to take the normal sort of care around shared state, using volatile variables, Atomic* objects or locking to make sure that every thread sees the updates made by every other thread.
Anything non-cooperative is risky due to the chance of corrupting state half way through an operation.
It is dangerous to stop threads pre-emptively. Doing so leads to deadlocks, resource leaks and so on. Instead you should use a cooperative signaling mechanism.
Signal to the thread that you want it to stop, and then wait for it to do so. The thread should regularly check whether it needs to stop and react accordingly.
Instead of looping while (true), you should loop while the thread is not interrupted:
#Override public void void() {
// some kind of initialization...
while (!Thread.currentThread().isInterrupted()) {
try { ...
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // ensure interrupt flag is set
}
}
// some kind of cleanup
}
If InterruptedException is not thrown by anything inside your while block, either you don't use blocking operations (and simply calling Thread.interrupt() on this thread would stop it the next iteration) or you use some blocking calls that are not well behaved (there are many such examples in the JCL itself!).
The correct way to do this is indeed to have a variable that determines when the Thread should be stopped, exiting from its run method. You can find more information about how to do this properly here
With this solution you won't get "instantaneous" updates that you could get with wait/notify or interrupt, but if you don't mind the fraction of a second delay, it should do the job.
volatile boolean stopped = false;
volatile boolean paused = false;
pauseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
paused = true;
}
});
resumeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
paused = false;
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stopped = true;
}
});
... TimerThread
public void run() {
while (stopped == false) {
try {
Thread.sleep(1000);
if (stopped)
break;
if (!paused)
colorPanel.repaint();
} catch (Exception ex) {
//do Nothing
}
}
}

Categories