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)
Related
I have a game method that has Timer inside this method, only for some specific case(if condition below) i wanna stop timer...But for some reason it is causing me a crash.
public model() {
public game() {
Timer timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
....
//draw shapes on JFrame
if (model.Life == 0) { //specific condition
model.timer.stop(); //timer is making a crash here
}
repaint();
}
});
timer.start();
}
The Timer is the source of the ActionEvent so you can just do:
if (your condition)
{
Timer timer = (Timer)e.getSource();
timer.stop();
}
This way you don't have to worry about keeping an instance variable for the Timer.
This application has 2 threads the one shown here calls a method that pauses an auto clicker method every 4 seconds(just for ease) to do some mouse movement. I want it to stop the timer when you click the gui stop button.
Right now when you hit stop and then start again it then has two timers that will execute the code; and so on.
Action Listener Stuff.
class MyButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(view.getBtnStart()))
{
autoClick.unTerminate();
bool = true;
getInfo();
}
if (e.getSource().equals(view.getBtnExit()))
{
System.exit(0);
}
if (e.getSource().equals(view.getBtnStop()))
{
bool = false;
autoClick.terminate();
}
}//end of actionPerformed
}//end of inner class
Thread
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
Timer timer = new Timer(4000, new ActionListener() {//301000 5minutes and 1second
#Override
public void actionPerformed(ActionEvent evt) {
autoClick.timeOverload();
}
});
//if (!bool){timer.stop();}
timer.setRepeats(true); //false only repeates once
timer.start();
}
});//end of t2
It calls the timeOverload method repeatedly.
Thanks for your time and helping a newbie out :).
Here is a quick sample of how to declare a instance outside of your thread and be able to control it outside of it.
public static void main(String[] args){
final Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("tick");
}
});
timer.setRepeats(true);
Thread t = new Thread(new Runnable() {
public void run() {
timer.start();
}
});
t.start();
try {
Thread.sleep(2600);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
timer.stop();
}
Basicly, you need to set the instance final to be used in a anonymous class (the ActionListener implementation).
Here, I just start the thread then pause the process for a few seconds and stop the timer.
Note that here, the Thread don't do anything else so it ends directly. You will need to tweek this a bit to match your needs but you have a working example.
EDIT : (DevilsHnd, if you post your answer, notify me, I will remove this part)
Using a flag (here in a Class)
public class Main {
public static void main(String[] args){
new Main();
}
boolean running = true;
public Main(){
final Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!running){
((Timer)e.getSource()).stop();
} else {
System.out.println("tick");
}
}
});
timer.setRepeats(true);
timer.start();
try {
Thread.sleep(2600);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
stop();
}
public void stop(){
running = false;
}
}
Calling the Main.stop() will set the flag to false, on each action performed, you check this flag, if it is false, you get the timer from the event (in the source) and stop it.
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.
String move=jTextField1.getText();
i=Integer.parseInt(move);
timer = new Timer(1000,new ActionListener(){
public void actionPerformed(ActionEvent e)
{
i--;
if(i<=0)
{
if(move.equals("0"))
{
Thread th=new Thread(new DetectImage());
th.start();
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new TrafficMainGUI(storeValue);
}
});
}
timer.stop();
}
}
jTextField1.setText(""+i);
}
});
timer.start();
move=""+i;
//Thread th in DetectImage class
public void run()
{
while(stay<20)
{
try {
stay++;
//few contions
Thread.sleep(1000);
}
}
}
//EveryThing is working fine with thread but when i use SwingUtiities.invokeLater()
to call the same class in which this code is there for getting infinite condition.
This doesnot redirect it to the class TrafficMainGUI.Is there some other method to achieve this kind of model.
jTextField1.setText(""+i); must be wrapped in invokeLater for this job by invoked from util.Timer
use Swing Timer instead
if(move.equals("0")) { is about animations, then to use Swing Timer exclusivelly
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
}
}
}