I'm tyring to make a button that starts method with simple timer that count from 5 to 0 and that's it.
But my problem is when i click the button multiple times the method speeds up the timer and break it.
In the final form this button must every time when it is clicked should reset the countdown.
public class Buttons extends TimerTask {
int delay = 1000;
int period = 1000;
static Timer timer;
static int interval =10;
public static void setTimer(Label label) {
System.out.println("timer start");
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if(interval > 0)
{
Platform.runLater(() -> label.setText("TIME TO OVERHEAT: "+interval));
System.out.println(interval);
interval--;
}
else
timer.cancel();
}
}, 1000,1000);
}
Related
I want to repeat a for loop inside below code inside a service every some time ,but it print only one line and runs one time only
public void startTimer() {
timer = new Timer();
initializeTimerTask();
timer.schedule(timerTask, 10000);
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
for (int i=0; i<10; i++){
Log.i("TAG", " inside method ");}
}
};
}
You are calling the following method.
public void schedule(TimerTask task, long delay)
So the task executes only once after delay.
If you want to execute it periodically you need to call the bellow method.(you may pass same value for delay and period)
public void schedule(TimerTask task, long delay, long period)
Your another query is it prints first line only. Most probably this is an issue with the Log. try System.out.print() instead of Log.i() to debug.
class MyTimerTask extends TimerTask {
private int counter = 1;
public void run() {
timerHandler.post(new Runnable() {
public void run() {
Toast.makeText(this, "" + counter, Toast.LENGTH_SHORT).show();
counter++;
}
});
if (counter == 10) {
myTimer.cancel();
myTimer.purge();
}
}
}
//Thats the usage like on ButtonClick
MyTimerTask myTimerTask = new MyTimerTask();
Timer myTimer = new Timer();
myTimer.schedule(myTimerTask, 500, 1000);
Do you really need to run Loop ?
I have one button include timer, but when I clicked the button again, same timer start counting twice. I want to stop the counter every time and restart it. how can I do it?
#FXML
private void handleButtonAction(ActionEvent event) {
int cnt=0;
Timer timer=new Timer();
TimerTask task=new TimerTask() {
#Override
public void run() {
cnt++;
System.out.println("task: "+cnt);
}
};
timer.schedule(task, 0, 3000);
}
when I clicked the button again, it calls system out twice.
By calling Timer timer = new Timer(); inside handleButtonAction you create a new Timer with every click.
You have to declare the Timer outside the method, then you can restart it by clicking the button like:
Timer timer;
private void handleButtonAction(ActionEvent event) {
int cnt=0;
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
cnt++;
System.out.println("task: "+cnt);
}
};
timer.schedule(task, 0, 3000);
}
This way you always restart the same timer.
Recently, I have been developing some android apps and I found that android.os.Handler class is very suitable for implementing a .NET Timer (By that I mean System.Windows.Forms.Timer and System.Timers.Timer).
If you don't know what a .NET timer is, it's a timer that can be stopped, started at any time and its interval can be changed any time.
So I did the following:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable () {
#Override
public void run() {
if (!paused) {
runnable.run ();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer () {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer () {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler ();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer ();
}
}
And it came out ok. Also, this one runs on the UI thread which means that I can use this to change graphical stuff. (I mainly use timers for those stuff)
However, this only works for android though. If I want to make a "traditional" java program, I have to use the stuff in the JDK. So I tried the following:
import java.util.Timer;
import java.util.TimerTask;
public class DotNetTimer {
private Timer timer;
private boolean paused;
private int interval;
private TimerTask task = new TimerTask () {
#Override
public void run() {
if (!paused)
runnable.run();
}
};
public Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
if (!paused) {
timer.cancel();
timer.scheduleAtFixedRate(task, interval, interval);
}
}
public void startTimer () {
timer.cancel();
timer.scheduleAtFixedRate(task, 0, interval);
}
public void stopTimer () {
paused = true;
}
public DotNetTimer (Runnable runnable, int interval, boolean started) {
timer = new Timer ();
this.runnable = runnable;
this.interval = interval;
if (started) {
paused = false;
startTimer ();
}
}
}
And I use this code to test it:
import static java.lang.System.out;
public class MyTestingClass {
static DotNetTimer timer;
public static void main(String[] args) {
Runnable r = new Runnable () {
int count = 0;
#Override
public void run() {
if (count < 5) {
count++;
out.println("Hello" + count);
} else {
timer.stopTimer();
}
}
};
timer = new DotNetTimer (r, 2000, true);
}
}
However, an IllegalStateException was thrown in the start timer method. I did some research on that and I found that java.util.Timer cannot be restarted after cancel(). And I know what you're saying, "why do you call cancel() in the startTimer() method?" If I don't call cancel(), the timer would have 2 tasks running when I call startTimer() when the timer is already started.
Any help will be appreciated.
From cancel() method in Timer class
Terminates this timer, discarding any currently scheduled tasks. Does
not interfere with a currently executing task (if it exists). Once a
timer has been terminated, its execution thread terminates gracefully,
and no more tasks may be scheduled on it.
Note that calling this method from within the run method of a timer
task that was invoked by this timer absolutely guarantees that the
ongoing task execution is the last task execution that will ever be
performed by this timer.
This method may be called repeatedly; the second and subsequent calls
have no effect.
so, internal thread of Timer is one-shot, you need to instantiate a new Timer object
You can check original source code of Timer class to understand (or replicate as you wish) how it really works
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java
I found out that there is a class in Android called Handler which can execute code with a delay. So I made use of this class to create a timer!
import android.os.Handler;
import android.support.annotation.NonNull;
import android.widget.TextView;
public class Timer implements Comparable<Timer> {
private Handler handler;
private boolean paused;
private TextView text;
private int minutes;
private int seconds;
private final Runnable timerTask = new Runnable () {
#Override
public void run() {
if (!paused) {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
}
text.setText (Timer.this.toString ());
Timer.this.handler.postDelayed (this, 1000);
}
}
};
#Override
public String toString () {
if (Integer.toString (seconds).length () == 1) {
return minutes + ":0" + seconds;
} else {
return minutes + ":" + seconds;
}
}
public void startTimer () {
paused = false;
handler.postDelayed (timerTask, 1000);
}
public void stopTimer () {
paused = true;
}
public void resetTimer () {
stopTimer ();
minutes = 0;
seconds = 0;
text.setText (toString ());
}
public Timer (TextView text) {
this.text = text;
handler = new Handler ();
}
public Timer (TextView text, String parseString) {
this (text);
String[] splitString = parseString.split (":");
minutes = Integer.parseInt (splitString[0]);
seconds = Integer.parseInt (splitString[1]);
}
#Override
public int compareTo(#NonNull Timer another) {
int numberOfSeconds = seconds + minutes * 60;
int anotherNumberOfSeconds = another.seconds + another.minutes * 60;
return ((Integer)numberOfSeconds).compareTo (anotherNumberOfSeconds);
}
}
And it has a really simple interface. Very easy to use.
I want to change the length of my Countdowntimer when it finishs. So I got a Random Number which changes everytime.
standby_time = 15000
standby_counter = new CountDownTimer(standby_time,1000) {
#Override
public void onTick(long millisUntilFinished) {
++standby_zaehler;
}
#Override
public void onFinish() {
...
standby_zaehler = 0;
rndm_groesse = 60000;
random_zahl = r.nextInt(rndm_groesse);
standby_time = random_zahl;
standby_counter.start();
}
};
Where is my fault ? The time is not changing and takes the first value (15sec)
The countdown timers time isnt ment to be changed. You can recreate the timer to alter the time but because you are looking to start it again inside the onFinish() method it would be wise to use a different implementation better suited for this task. The java.util.Timer class does this well.
private Timer timer = new Timer();
private int standby_zaehler = 0;
private Random r = new Random();
public void scheduleNextTimer() {
// reset our countdown
standby_zaehler = 0;
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// 1 second passed, remove it to the countdown
--standby_zaehler;
// we are finished counting down. get a new max seconds
if(standby_zaehler < 0) {
standby_zaehler = r.nextInt(60);
}
}
}, 1000, 1000);
}
As you can see we dont even need to create a new timer, just reset the number and begin again.
At TIME = 0, a user calls a method that sets a flag after 10 seconds. (at TIME = 10)
If the user calls the method again at TIME = 2 the flag should NOT be set at TIME = 10, but instead at TIME = 12:
boolean myFlag; // initializes to false
private Timer timer;
public void setFlag() {
// remove old timer if there was one
if (timer != null) { timer.cancel(); timer = null; }
// set the new timer
timer = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() { myFlag = true; }
};
timer.schedule(tt, 10000);
}
Are there any cleaner ways to implement this "updated-schedule-time" model? Examples are appreciated.
I would have simply kept it the same but made little changes.
Declare the variables always as variables should be declared and initialized near they are first used.
public void setFlag() {
Timer timer;
timer = new Timer();
// remove old timer if there was one
if (timer != null) { timer.cancel(); }
// set the new timer
TimerTask tt = new TimerTask() {
#Override
public void run() { setFlag(); }
};
timer.schedule(tt, 10000);
}