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
}
}
Related
I'm trying to implement a program that receives user input, if no input within 1 minutes, the program ends, otherwise the timer resets and waits for user input again.
I'm only able to do a timer until now and can't find a way to implement it with user input.
import java.util.Timer;
import java.util.TimerTask;
import java.io.*;
public class test {
public static void main(String[] args){
Timer timer = new Timer();
TimerTask task = new TimerTask() {
int sec = 10;
public void run() {
if (sec > 0){
System.out.println(sec + "seconds");
sec--;
}else {
System.out.println("Time's up");
timer.cancel();
}
}
};
timer.scheduleAtFixedRate( task, 0,1000 );
}
}
Thanks for any help!
Heavily inspired by this answer, I've adopted the given solution to your problem.
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public class Test {
private static final int DURATION = 10;
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
System.out.println("Failed to receive input.");
//Maybe: System.exit(0);
}
};
timer.schedule(task, DURATION * 1000);
System.out.println("Provide input within " + DURATION + " seconds.");
Scanner s = new Scanner(System.in);
String input = s.nextLine();
timer.cancel();
System.out.println("Success! Your input was: \"" + input + "\".");
}
}
Start the timer first, before asking the user for input to assure it is running. When java executes s.nextLine, it will wait for the user to insert something followed by a newline (Enter). While the program waits, the timer is running in the background. If an input is received in time, you can cancel the timer, else the TimerTask is executed, and you can either let the user know or exit the program (optional).
Side note: Following the Java naming convention, I've renamed the class ;)
This question already has answers here:
How to set a Timer in Java?
(5 answers)
Closed 8 years ago.
I want to create a timer, given a set amount of time the user has to answer the question within the allotted time, if he/she fails to do so, the user no longer has the option to enter the answer
I've tried timer. I need a separate thread to check in if the allotted time is up and then exit the loop.
By Using java.util.Timer
Timer timer = new Timer();
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public class Stopwatch {
static int interval;
static Timer timer;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Input seconds => : ");
String secs = sc.nextLine();
int delay = 1000;
int period = 1000;
timer = new Timer();
interval = Integer.parseInt(secs);
System.out.println(secs);
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println(setInterval());
}
}, delay, period);
}
private static final int setInterval() {
if (interval == 1)
timer.cancel();
return --interval;
}
}
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.");
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Updating TextView every N seconds?
Here, I want to update the Hr value in the textview once it is calculated for every iteration, but with a delay of 2 seconds each time. I dont know how to do it. What i get now in the textview is the last value of the iteration. I want all the values to be displayed at a constant delay. anyone help pls.
for(int y=1;y<p.length;y++)
{
if(p[y]!=0)
{
r=p[y]-p[y-1];
double x= r/500;
Hr=(int) (60/x);
Thread.sleep(2000);
settext(string.valueof(Hr));
}
}
public class MainActivity extends Activity{
protected static final long TIME_DELAY = 5000;
//the default update interval for your text, this is in your hand , just run this sample
TextView mTextView;
Handler handler=new Handler();
int count =0;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView=(TextView)findViewById(R.id.textview);
handler.post(updateTextRunnable);
}
Runnable updateTextRunnable=new Runnable(){
public void run() {
count++;
mTextView.setText("getting called " +count);
handler.postDelayed(this, TIME_DELAY);
}
};
}
I hoped this time you will get into the code and run it .
use Handler or TimerTask(with runOnUiThread()) instead of for loop for updating text after every 5 seconds as :
Handler handler=new Handler();
handler.post(runnable);
Runnable runnable=new Runnable(){
#Override
public void run() {
settext(string.valueof(Hr)); //<<< update textveiw here
handler.postDelayed(runnable, 5000);
}
};
you should use timer class....
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
}, 900 * 1000, 900 * 1000);
Above code is for every 15 minutes.change this value and use in your case.....
TimerTask is just what you need.
lets us just hope it helps you sufficiently
import java.awt.Toolkit;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class demo
{
Toolkit toolkit;
Timer timer;
public demo()
{
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new scheduleDailyTask(), 0, //initial delay
2 * 1000); //subsequent rate
}
class scheduleDailyTask extends TimerTask
{
public void run()
{
System.out.println("this thread runs for every two second");
System.out.println("you can call this thread to start in your activity");
System.out.println("I have used a main method to show demo");
System.out.println("but you should set the text field values here to be updated simultaneouly");
}
}
public static void main(String args[]) {
new demo();
}
}
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();