Java - Countdown timer without GUI - java

Basically I am making a text based "game" (Not so much a game, more of a way to improve basic java skills and logic). However, as part of it I wish to have a timer. It would count down on the time I wish from the variable to 0. Now, I have seen a few ways to do this with a gui, however, is there a way to do this without a gui/jframe etc.
So, what I am wondering is. Can you make a count down from x to 0 without using a gui/jframe. If so, how would you go about this?
Thanks, once I have some ideas will edit with progress.
Edit
// Start timer
Runnable r = new TimerEg(gameLength);
new Thread(r).start();
Above is how I am calling the thread/timer
public static void main(int count) {
If I then have this in the TimerEg class, the timer complies. However, when compiling the main in the other thread I get.
Now, am I completely miss-understanding threads and how this would work? Or is there something I am missing?
Error:
constructor TimerEg in class TimerEg cannot be applied to given types;
required: no arguments; found int; reason: actual and formal arguments differ in length
Found on line Runnable r = new TimerEg(gameLength);

Same as with a GUI, you'd use a Timer, but here instead of using a Swing Timer, you'd use a java.util.Timer. Have a look at the Timer API for the details. Also have a look at the TimerTask API since you would use this in conjunction with your Timer.
For example:
import java.util.Timer;
import java.util.TimerTask;
public class TimerEg {
private static TimerTask myTask = null;
public static void main(String[] args) {
Timer timer = new Timer("My Timer", false);
int count = 10;
myTask = new MyTimerTask(count, new Runnable() {
public void run() {
System.exit(0);
}
});
long delay = 1000L;
timer.scheduleAtFixedRate(myTask, delay, delay);
}
}
class MyTimerTask extends TimerTask {
private int count;
private Runnable doWhenDone;
public MyTimerTask(int count, Runnable doWhenDone) {
this.count = count;
this.doWhenDone = doWhenDone;
}
#Override
public void run() {
count--;
System.out.println("Count is: " + count);
if (count == 0) {
cancel();
doWhenDone.run();
}
}
}

You could write your own countdown timer, as simply as:
public class CountDown {
//Counts down from x to 0 in approximately
//(little more than) s * x seconds.
static void countDown(int x, int s) {
while (x > 0 ) {
System.out.println("x = " + x);
try {
Thread.sleep(s*1000);
} catch (Exception e) {}
x--;
}
}
public static void main(String[] args) {
countDown(5, 1);
}
}
Or you could use Java Timer API

It is simple to countdown with java..
int minute=10,second=60; // 10 min countdown
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
second--;
// do something with second and minute. put them where you want.
if (second==0) {
second=59;
minute--;
if (minute<0) {
minute=9;
}
}
}
};
new Timer(delay, taskPerformer).start();

Related

(Java) How to cancel the timer immediately when some condition is met

The Program
My program asks three math questions such as 10+5?
It shows one question at a time on the console. Users answers via the command-line and have 5 seconds to answer. The next question would show only when the user answers the question correctly or when the time is up.
Once the user answers the question correctly within the given time, the next question needs to show (it shouldn't wait until the time is up). The timer should should continue and not restart when the user answers the question wrong. The timer restarts only when the next question shows.
The problems
The program does not immediately cancel the timer after the user answered the question correctly.
Also, the next question would not show up even when the time is up; users have to input something in order to continue to the next question.
Lastly, The next question would also show when users enter an incorrect answer.
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
/**
*Simple count down timer demo of java.util.Timer facility.
*/
/*
* start timer
* cancel when isLastMoveValid == true
* start timer again soon
* */
public class Countdown {
public static double i = 5;
public static int answer;
static Scanner inputs = new Scanner(System.in);
static Random rand = new Random();
static int num1;
static int num2;
static int questionNo = 3;
public static void main(String args[]) {
while (questionNo >0) {
num1 = rand.nextInt(11);
num2 = rand.nextInt(11);
callTimer();
System.out.println(num1+ "+" + num2 + "?");
answer = inputs.nextInt();
}
} // end of main method
public static void callTimer() {
final Timer timer = new Timer();
i = 6;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
i -= 0.001;
if (i< 0 || answer == num1 + num2) {
questionNo--;
timer.cancel();
}
} // end of run
}, 0, 1); // end of scheduleAtFixedRate
} // end of callTimer
}
You need to have your timer object as a field, so you can access it at any time. See the cancel method how to cancel. If you want to restart the timer, you must create a new object of the timer and the timertask, because they get discarded with the thread.
See documentation on Timer.cancel method:
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 terminatesgracefully,
and no more tasks may be scheduled on it.
For example something like this:
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest
{
private Timer timer;
public void cancelTimer()
{
this.timer.cancel();
System.out.println("Canceled timer!");
}
public void startTimer()
{
// once a timertask is canceled, you can not restart it
// because the thread is deleted. So we need to create a
// new object of a timer and a timertask.
TimerTask timerTask = new TimerTask()
{
#Override
public void run()
{
System.out.println("Hello there!");
}
};
this.timer = new Timer();
System.out.println("Starting timer ...");
int period = 1000;
this.timer.schedule(timerTask, 0, period);
}
public static void main(String[] args) throws InterruptedException
{
TimerTest tt = new TimerTest();
tt.startTimer();
Thread.sleep(5000);
tt.cancelTimer(); // you can call this method, as soon as u have a correct answer
Thread.sleep(1000);
tt.startTimer(); // you can restart your timer as demanded
Thread.sleep(5000);
tt.cancelTimer(); // and cancel it again
}
}

Making thread.sleep accurate

I am attempting to make a game loop that has an accurate timer. I know that TimeUnit uses thread.sleep(); which can vary by milliseconds. My question is simple:
Does this code make thread.sleep(); more accurate?
and further
Is there anything I can do to fix/make it better, or should I abandon it?
import java.util.concurrent.TimeUnit;
public class Timer implements Runnable {
public static void main(String[]args){
new Timer().start();
}
public int ups = 1;
#Override
public void run() {
int uc = 0;
long startTime = 0;
long result = 0;
long offset = 0;
while(true){
startTime = System.nanoTime();
uc++;
if(uc==1000/ups){
update();
uc=0;
}
result = System.nanoTime()-startTime;
if(1000000-result>0)
try {
int prefered = 1000000;
startTime = System.nanoTime();
TimeUnit.NANOSECONDS.sleep(prefered-result-offset);
offset = System.nanoTime()-startTime-prefered+result+offset;
} catch (InterruptedException e) {
System.out.println("an error has occured");
}
}
}
public void update(){
System.out.println("Hello World");
}
public void start(){
new Thread(this).start();
}
}
I have already seen this by the way. I might as well add
How does this compare to the other loop?
Edit: This is for a desktop game, not mobile
In case of games, I doubt you really want nanosecond precision in waking up. What you do want though is avoiding accumulating error, which is what your code is trying to do. It's a reasonable approach, although it probably would make more sense to use a Timer instead:
Timer timer = new Timer()
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Your periodic code here
}
}, 0, 1);

Count up timer on Android?

I've been looking for a way to create a timer that counts up in the format of mm:ss:SS and cannot for the life of me find a way of doing it. I had a timer running through a Handler and a Runnable but the timing was off and it took around 2.5 seconds to do a "second". I'll also need this timer be able to countdown too!
Can anyone give me any resources or code snippets to research on this as it is a big part of the app I'm coding.
Here's a bit of the code that I was using
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
#Override
public void run() {
/* do what you need to do */
testMethod();
/* and here comes the "trick" */
handler.postDelayed(this, 10);
}
};
public void testMethod()
{
// Log.d("Testing", "Test");
final TextView timeLabel = (TextView)findViewById(R.id.timeString);
count++;
seconds = (int)(count / 100);
final String str = ""+count;
runOnUiThread(new Runnable() {
public void run() {
timeLabel.setText("" + seconds);
// Log.d("Time", "" + count);
}
});
}
Ta!
Make small custom class by extending CountDownTimer class and then add integer or long type and then increment it, since each tick is 1 second (integer) in this case
public class TimeCounter extends CountDownTimer {
// this is my seconds up counter
int countUpTimer;
public TimeCounter(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
countUpTimer=0;
}
#Override
public void onTick(long l) {
//since each tick interval is one second
// just add 1 to this each time
myTextView.setText("Seconds:"+countUpTimer);
countUpTimer = countUpTimer+1;
}
#Override
public void onFinish() {
//reset counter to 0 if you want
countUpTimer=0;
}
}
TimeCounter timer = new TimeCounter(whenToStopInSeconds*1000, 1000);
This should get you started, in your case use long instead integer
countUpTimer = countUpTimer+1000 countUpTimer type and do time parsing as suits you
Rather than using the Handler, I'd recommend using the java.util.Timer and the java.util.TimerTask APIs. Use the Timer's void scheduleAtFixedRate() method which basically executes tasks after a fixed interval of time. The Handler's method most likely uses a fixed-delay execution.
Timer's Documentation
TimerTask's Documentation

Making a program run for 5 minutes

So I wanted to try out something for a bit with the Timer and TimerTask classes.
I was able to get a line of code to execute after 30 seconds elapsed.
What I've been trying to do now is to get this line of code to execute for 5 minuets.
This is what I originally tried
public static void main(String[] args)
{
for ( int i = 0; i <= 10; i ++ )
{
Timer timer = new Timer();
timer.schedule( new TimerTask()
{
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000
);
}
}
I used the number 10 in the for loop to see if the timer.schedule would wait for another 30 seconds during the next iteration of the loop.
Any idea how I should go about this? I tried using the schedule method with a parameter passed in for period, but that only made it re-execute and it never stopped.
Java has provided a rich set of APIs in java.util.concurrent package to achieve such tasks. One of these APIs is ScheduledExecutorService. For example consider the code given below: This code will execute the Runnable task after every 30 seconds for upto 5 minutes:
import java.util.concurrent.*;
class Scheduler
{
private final ScheduledExecutorService service;
private final long period = 30;//Repeat interval
public Scheduler()
{
service = Executors.newScheduledThreadPool(1);
}
public void startScheduler(Runnable runnable)
{
final ScheduledFuture<?> handler = service.scheduleAtFixedRate(runnable,0,period,TimeUnit.SECONDS);//Will cause the task to execute after every 30 seconds
Runnable cancel = new Runnable()
{
#Override
public void run()
{
handler.cancel(true);
System.out.println("5 minutes over...Task is cancelled : "+handler.isCancelled());
}
};
service.schedule(cancel,5,TimeUnit.MINUTES);//Cancels the task after 5 minutes
}
public static void main(String st[])
{
Runnable task = new Runnable()//The task that you want to run
{
#Override
public void run()
{
System.out.println("I am a task");
}
};
Scheduler sc = new Scheduler();
sc.startScheduler(task);
}
}
The issue you're running into is that the scheduled Timer runs on a different thread - that is, the next iteration of your for loop starts running immediately after scheduling, not 30 seconds later. It looks like your code starts ten timers all at once, which means they should all print (roughly) 30 seconds later, all at once.
You were on the right track when you tried using the recurring version of schedule (with the third parameter). As you noted, this isn't quite what you want because it runs indefinitely. However, Timer does have a cancel method to prevent subsequent executions.
So, you should try something like:
final Timer timer = new Timer();
// Note that timer has been declared final, to allow use in anon. class below
timer.schedule( new TimerTask()
{
private int i = 10;
public void run()
{
System.out.println("30 Seconds Later");
if (--i < 1) timer.cancel(); // Count down ten times, then cancel
}
}, 30000, 30000 //Note the second argument for repetition
);
here's a workaround I'm ashamed of presenting:
package test;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class FiveMinutes {
private static int count = 0;
// main method just to add example
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("Count is: " + count);
if (count == 1) {
System.err.println("... quitting");
System.exit(0);
}
count++;
}
},
// starting now
new Date(),
// 5 minutes
300000l
);
}
}
Also please note that the application might not run exactly 5 minutes - see documentation for TimerTask.
Your solution is pretty close to working, you just have to multiply the delay by the counter (in your case, i):
public static void main(String[] args)
{
for (int i = 1; i <= 10; i++) // start i at 1 for initial delay
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000 * i); // 5 second intervals
}
}
I don't know if this solution has problems with the garbage collector or not, but I throw it in here anyways. Maybe someone clears that out, and I learn something as well. Basically a timer sets a new timer if there is time left, and it should stop after 5 minutes.
Main.java:
public class Main {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer(300000,30000);
myTimer.startTimer();
}
}
MyTimer.java:
import java.util.Timer;
import java.util.TimerTask;
public class MyTimer {
private int totalRunningTime;
private int currentTime = 0;
private int intervalTime;
private Timer timer = new Timer();
public MyTimer(int totalRunningTime, int intervalTime) {
this.totalRunningTime = totalRunningTime;
this.intervalTime = intervalTime;
}
public void startTimer() {
startTimer(intervalTime);
}
private void startTimer(int time) {
timer.schedule(new TimerTask() {
public void run() {
if (currentTime <= totalRunningTime - intervalTime) {
printTimeSinceLast(intervalTime / 1000);
currentTime += intervalTime;
startTimer(intervalTime);
} else if (currentTime < totalRunningTime) {
int newRestIntervalTime = totalRunningTime - currentTime;
printTimeSinceLast(newRestIntervalTime / 1000);
currentTime += newRestIntervalTime;
startTimer(newRestIntervalTime);
}
}
}, time);
}
private void printTimeSinceLast(int timeSinceLast) {
System.out.println(timeSinceLast + " seconds later.");
}
}

java TimerTask increase time?

Hi m using the following timer task,and i want to increase the time of this task when a certain condition occurs
Timer timer2=new Timer();
timer2.schedule(new TimerTask(){
public void run(){
//whatevr
}
}, 4000);
examlpe
if(mycondition)
{
increase time????
}
how can i do that
Extract the TimerTask in an inner or standalone class. Cancel currently running timer task and schedule a new instance with increased time period.
You can't. You'll have to schedule a new task with the incremented period. And if the previous task has become obsolete, make sure that you cancel() it.
For future reference, I recommend you utilize the Executors framework.
Submit another one task from run() if necessary:
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTaskTest {
private static class MyTimerTask extends TimerTask {
private final Timer timer;
private boolean fire;
private MyTimerTask(Timer timer) {
this(timer, false);
}
private MyTimerTask(Timer timer, boolean fire) {
this.timer = timer;
this.fire = fire;
}
#Override
public void run() {
if (!fire) {
System.out.println(new Date() + " - steady...");
timer.schedule(new MyTimerTask(timer, true), 2000);
} else {
System.out.println(new Date() + " - go!");
}
}
}
public static void main(String args[]) {
Timer timer = new Timer(true);
MyTimerTask timerTask = new MyTimerTask(timer);
System.out.println(new Date() + " - ready...");
timer.schedule(timerTask, 4000);
try {
Thread.sleep(7000);
} catch (Exception ignore) {
}
}
}

Categories

Resources