I'm trying to stop a timer that ticks down from ten seconds to zero.
The problem is that the finish method only returns the first tick, rather than counting all the numbers down to one.
How can I make a boolean method return a value for every second rather than just the first?
import java.util.Timer;
import java.util.TimerTask;
public class Countdown {
static int interval;
static Timer timer;
boolean off;
public Countdown() {
int seconds = 10;
int delay = 1000;
int period = 1000;
timer = new Timer();
interval = seconds;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println(setInterval());
}
}, delay, period);
}
private int setInterval() {
off = false;
if (interval == 1){
timer.cancel();
off = true;
return --interval;
}else{
off = false;
return --interval;
}
}
public boolean finish(){
return off;
}
}
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public static void main(String[] args){
Countdown countDown = new Countdown();
countDown.finish()
System.out.println(countDown.finish);
if(countDown.finish() == true){
System.out.println("works");
}
}
If you want to write the value of finish every second, you should design your code to print it ever second, not just on startup...
ATM finish is only printed in the main-method and nowhere else. Move that line into the Runnable used by the Timer and it should print as expected.
Related
I am writing a Java program in which I have an array list of 5 strings and a countdown timer of 5 seconds. My question is this, I want the string to be changing anytime the timer is in 1 second. That is whenever the countdown timer is at 1 second, the string should change to another string then when it gets to 1 second it should change to another string till all the strings in the array list as shown.
Keep a reference to the timer somewhere, and use:
timer.cancel();
timer.purge();
I think this demo code will help you:
class Helper extends TimerTask
{
public static Timer timer;
public static int i = 0;
public static void setTimer(Timer timer) {
Helper.timer = timer;
}
public void run()
{
System.out.println("Timer ran " + ++i);
if (i==5) {
timer.cancel();
timer.purge();
}
}
}
public class Test3
{
public static void main(String[] args)
{
Timer timer = new Timer();
Helper task = new Helper();
Helper.setTimer(timer);
timer.schedule(task, 0, 1000);
}
}
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;
public class Java {
Toolkit toolkit;
Timer timer;
int t=10000,total;
public Java(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
total =seconds * t;
System.out.println(total);
timer.schedule(new RemindTask(), total);
}
class RemindTask extends TimerTask {
public void run() {
System.out.println("Time's up!");
toolkit.beep();
System.exit(0);
}
}
public static void main(String args[]) {
new Java(5);
System.out.println("Timer started");
}
}
How can I display the seconds similar to countdown timer in output screen, I want to use it in a quiz program
0:53 => 0:52 like this ...
What you can do is schedule a task at a fixed rate (Timer.scheduleAtFixedRate) using a period of 1 second. As far as possible, we should refrain from calling the System.exit(0) and wait for the threads to complete their tasks. We can make the main thread (the thread that started the timer) sleep for the duration of the timer tasks and then when it finally wakes up, it cancels the timer:
private final Timer timer;
public CountDownTimer(int seconds) {
timer = new Timer();
timer.scheduleAtFixedRate(new RemindTask(seconds), 0, 1000);
}
class RemindTask extends TimerTask {
private volatile int remainingTimeInSeconds;
public RemindTask(int remainingTimeInSeconds) {
this.remainingTimeInSeconds = remainingTimeInSeconds;
}
public void run() {
if (remainingTimeInSeconds != 0) {
System.out.println(remainingTimeInSeconds + " ...");
remainingTimeInSeconds -= 1;
}
}
}
public static void main(String args[]) throws InterruptedException {
CountDownTimer t = new CountDownTimer(5);
System.out.println("Timer started");
Thread.sleep(5000);
t.end();
}
private void end() {
this.timer.cancel();
}
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 have a fairly simple JavaFX GUI application which has an label that shows how much time is left until a certain action starts. To achieve this, I've created a DownloadTimer class as shown below:
public class DownloadTimer(){
private int minutes;
private int seconds;
private Timer innerTimer = new Timer();
private TimerTask innerTask;
private boolean isActive;
public DownloadTimer(int minutes, int seconds) {
if (seconds > 60) {
int minToAdd = seconds / 60;
this.minutes = minutes;
this.minutes += minToAdd;
this.seconds = seconds % 60;
} else {
this.minutes = minutes;
this.seconds = seconds;
}
}
public void start() {
innerTask = new TimerTask() {
#Override
public void run() {
isActive = true;
System.out.println(getTime());
if (seconds == 0 && minutes > 0){
minutes -= 1;
seconds = 59;
} else if (seconds == 0 && minutes == 0){
isActive = false;
innerTimer.cancel();
innerTimer.purge();
System.out.println("DownloadTimer DONE");
} else {
seconds -= 1;
}
}
};
innerTimer.scheduleAtFixedRate(innerTask, 0, 1000);
}
}
And then, I'm creating the DownloadTimer object and starting the countdown from my Main (JavaFX) class:
/*
code omitted for better readability
*/
downloadTimer = new DownloadTimer(0, 5);
// label gets the .getTime() value, which returns a formatted String like "00:05", "00:04", etc.
lblTimer.setText( downloadTimer.getTime() );
// start the countdown
downloadTimer.start();
// create a new timer which checks if the downloadTimer is still counting
final Timer timer = new Timer();
TimerTask timerTask = new TimerTask(){
#Override
public void run(){
if (downloadTimer.getIsActive() == false){
timer.cancel();
timer.purge();
System.out.println("GUI timer DONE");
} else {
// if it's still running, then continuously update the label's text
lblTimer.setText( downloadTimer.getTime() );
// this is where I get the error described below
}
}
};
// repeat after 1000ms
timer.scheduleAtFixedRate(timerTask, 0, 1000);
The problem I'm encountering with this is that I can't set the label text with lblTimer.setText( downloadTimer.getTime() ); from the Main class, and the error I'm getting is TimerThread.run() line: not available [local variables unavailable] as seen here.
I've read about ScheduledThreadPoolExecutor and Java Timer vs ExecutorService, but I'm curious if this can be done using two separate Timers and TimerTasks. Any help and/or tips would be greatly appreciated.
I'm surprised you're not seeing an exception. To update a label from a separate thread, one needs to schedule an update to be run in the FX thread:
Platform.runLater(new Runnable() {
public void run() {
lblTimer.setText(downloadTimer.getTime());
}
});
I am trying to make a simple timer that plays a beep after the specified number of seconds. I managed to get it to work, but the TimerTask continues to run after the beep. Now do I stop execution?
Here is my code:
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;
class Alarm {
public static void main(String[] args) {
long delay;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a delay in seconds: ");
delay = scan.nextInt()*1000;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
Toolkit.getDefaultToolkit().beep();
}
};
timer.schedule(task, delay);
}
}
You need to cancel the timer by calling the following methods
timer.cancel(); // Terminates this timer, discarding any currently scheduled tasks.
timer.purge(); // Removes all cancelled tasks from this timer's task queue.
This will cancel the task, so something like this would work:
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;
class Alarm {
private static boolean run = true;
public static void main(String[] args) {
long delay;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a delay in seconds: ");
delay = scan.nextInt()*1000;
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
#Override
public void run() {
if(run) {
Toolkit.getDefaultToolkit().beep();
} else {
timer.cancel();
timer.purge();
}
}
};
timer.schedule(task, delay);
// set run to false here to stop the timer.
run = false;
}
}
Here is what worked for me (used the purge() suggestion also):
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;
class Alarm {
public static void main(String[] args) {
long delay;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a delay in seconds: ");
delay = scan.nextInt()*1000;
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
#Override
public void run() {
Toolkit.getDefaultToolkit().beep();
timer.cancel();
timer.purge();
}
};
timer.schedule(task, delay);
}
}
cancel() should do it - cancel stops the cancels the given TimerTask / Timer
isStart = true; // if true timmer function countiue called , else time canceled
Timer timer = new Timer();
timer.schedule(new TimerClass(), 0, 5000);
class TimerClass extends TimerTask {
public void run() {
if (isStart) {
yourFunction();
}else {
cancel();
}
}
}