How can I get the time left in a util.Timer?
What I want to do is to add a progressbar that displays time left until the timer starts over.
This is what I've got this far:
int seconds = 8;
java.util.Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run(){
// Do something
// Add a progressbar that displays time left until the timer "starts over".
},0,(long) (seconds*1000));
You would need a second timer to refresh the gui in a specific interval.
Another way to achieve this, would be to activate a single timer every second and update the counting in the ui. If the time is up, call your specific action.
A simple expample with console output only:
TimerTask task = new TimerTask()
{
int seconds = 8;
int i = 0;
#Override
public void run()
{
i++;
if(i % seconds == 0)
System.out.println("Timer action!");
else
System.out.println("Time left:" + (seconds - (i %seconds)) );
}
};
Timer timer = new Timer();
timer.schedule(task, 0, 1000);
It's output would be:
Time left:7
Time left:6
Time left:5
Time left:4
Time left:3
Time left:2
Time left:1
Timer action!
Time left:7
Time left:6
Time left:5
Time left:4
Time left:3
Time left:2
Time left:1
Timer action!
Time left:7
Time left:6
...
Then simply change the System.out's with your code to update the progress bar. Remember: java.util.Timer starts its own Thread. Swing is not thread safe, so you need to put every gui changing code into SwingUtilities.invokeLater()!
If you're not doing any long running tasks, every time your timer reachs the 8 seconds mark, you may want to use javax.swing.Timer directly. It uses the EDT and not its own Thread, so you don't need to synchronize your calls to Swing components with SwingUtilities.invokeLater().
Also see:
javax.swing.Timer vs java.util.Timer inside of a Swing application
All you need to do is declare a long variable timeleft in your MainActivity.
long timeleft;
Then, when you create a new Timer, set the "onTick" override to update the timeleft variable each "onTick" (which in the following example is 1000 milliseconds )
timer = new CountDownTimer(time, 1000) {
#Override
public void onTick(long millisecondsUntilFinished) {
timeleft = millisecondsUntilFinished;
}
}
Your app can access then the variable timeleft every time you need to check how much time is left.
Related
friends, I have this simple timer, which is suppose to tick every 10ms for the period of 2seconds.
breathTimer = new CountDownTimer(2000, 10) {
int currStep = 0;
public void onTick(long millisUntilFinished) {
Log.e(String.valueOf(currStep*10),String.valueOf(mSecPerBreath));
currStep++;
}
public void onFinish() {
Log.e("END: "+String.valueOf(currStep*10),String.valueOf(mSecPerBreath));
}
};
breathTimer.start();
Yet it always stops too early, for example
E/END: 1640: 2000
what do you think might be the problem?
or if I set the timer to 3000, it will end in E/END: 2520: 2000
As per documentation, seems like the onTick execution time is significant compared to the countdown interval (10ms). This could be the reason for the increased period (i.e. 2520).
The calls to onTick(long) are synchronized to this object so that one call to onTick(long) won't ever occur before the previous callback is complete. This is only relevant when the implementation of onTick(long) takes an amount of time to execute that is significant compared to the countdown interval.
I'm trying to make an image twinkle with RaffleImage(); while I'm executing the timer, my character is immune to any collision, I want it to be immune only for 2 seconds, so the timer get execute only for 2 seconds and then get finished.
I've tried subtracting System.currentTimeMillis() but any variable I create from this method, have always the same value, making me get a zero from that subtracting.
Do you know how I can stop or pause the timer after any elapsed time in seconds?
immuneTimer = new Timer(50, new ActionListener() {
#Override
public synchronized void actionPerformed(ActionEvent e) {
long initMillis = System.currentTimeMillis();
if (System.currentTimeMillis() - initMillis > 2000 ) { // this substract gives me 0
initImages();
setImmune(false); // so this never reached
immuneTimer.stop();
} else {
raffleImage(); //its executing like forever;
}
}
});
The Swing timer fires a an ActionEvent. From the event you can use getSource() to get the source of the event. Cast that source to the swing timer object and use that to turn it off.
To know when to turn it off you need to have a variable count the number of times the swing timer is invoked. When the variable reaches that amount, turn it off.
int elapsedTime = 0;
int timerDelay = 50;
int max = 2000;
public void actionPerformed(ActionEvent ae) {
elapsedTime += timerDelay; // you could use getDelay here but it
// is in milliseconds.
if (elapsedTime >= max) {
Timer s = (Timer)ae.getSource();
s.stop();
}
// rest of code
}
I try to add time to my game that will increment every second.
How to fix that?
I add my code below
float timer;
timer += delta;
if(timer<=delta+1000)//every one sec
{
time = time+1;
timePoint.setSentence(""+time/100);
timer = 0f;
}
as your note, delta is Gdx.graphics.getDeltaTime().
'time' is string.
but looks like the time increment slowly. means that when time already run about 1,5 sec,
'time' still increase 1.
I divide by 100 because if not it will increase more faster/sec,
i also use TimeUtils class from libgdx but it produced similar result.
Thanks before.
This should work. Note that time/100 results in 0 for 0-99 and 1 for 100-199. That's probably not the effect you wanted.
float timer;
timer += delta;
if (timer >= 1) {
time++;
timePoint.setSentence(""+time);
timer -= 1;
}
The problem was that you set the timer back to 0. If it was 1.1f for example (because the last delta was 0.1f), then you basically lose 100ms. Don't reset the timer to 0f, but decrease it by 1f instead.
I would do it like this:
float time = 0f;
In render:
time += delta;
timePoint.setSentence(Integer.toString((int)time));
delta is giving the ellapsed time in seconds, so for 30FPS it is 1/30 seconds. So you only need to add it to your time. To print the difference (i guess the setSentence is printing the text) you only need to cast it to int, so that it cuts the fraction digits.
Hope it helps.
EDIT: If you need the timer and the time variable somewhere you need to store them in 2 different variables.
For that i would do it like this:
float timer = 0f;
int time = 0;
And in render:
timer+=delta;
if (timer >= 1f) {
time++;
timePoint.setSentence(Integer.toString(time));
timer-=1f;
}
By doing this you are not loosing the few milli seconds you would loose if you reset the timer.
This means, that if timer goes from 0.99f to 1.05f in one renderloop and you reset the timer to 0f, you loose 0.05 seconds. If this happens every second you loose 1 second every 20 seconds (if i am not wrong^^)
Like in pure java:
Timer timer = new Timer();
timer.schedule(new incrementYourValue(), 0, 1000); //1000 is time in mili sec
//0 is the time waited before the beginning.
Had similar problem but for me using delta time was kinda overkill. Instead I used Libgdx Timer that "Executes tasks in the future on the main loop thread". Using Timer from java.util may cause Concurrency problems in libgdx.
import com.badlogic.gdx.utils.Timer;
public class Scheduler {
public Scheduler(Runnable runnable, float periodInSeconds) {
Timer timer = new Timer();
timer.scheduleTask(new Timer.Task() {
#Override
public void run() {
runnable.run();
}
}, 0, periodInSeconds);
}}
And usage:
new Scheduler(() -> updateSth(), 1f);
I am using a while loop with a timer.
The thing is that the timer is not used in every loop.
It is used only the first time. After the first time the statements included inside the loop are executed without the delay that i have set.
How is this even possible since the timer is included inside the while loop.
Any solutions ?
int count = 1;
while (count <= 10) {
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
// Stuff the while loop executes
}
});
}
}, 20000);
count++;
}
The TimerTask kicks off a new Thread and then the loop proceeds as normal.
The execution of the thread does not cause a delay to the execution of the code in your loop.
It's because you're queueing up 10 toasts all to execute in one hour. Each iteration of your loop takes only a fraction of a millisecond or maybe a tad bit more than that. To enqueue them properly, you could do 3600000 * count instead of 3600000 each time.
This is a terrible way to do it though. You should use AlarmManager for stuff like this.
You're scheduling 10 TimerTasks to execute after an hour, at the same time. So all 10 tasks are being executed after 1 hour, which makes it seem like 1 execute since all the Toast messages display at the same time. To schedule tasks at a fixed delay, with the first task starting in 1 hour, use this method:
Timer t = new Timer();
t.schedule(task, 3600000, 3600000);
This will execute until you call t.cancel().
I am using a while loop with a timer.
The thing is that the timer is not used in every loop.
It is used only the first time. After the first time the statements included inside the loop are executed without the delay that i have set.
How is this even possible since the timer is included inside the while loop.
Any solutions ?
int count = 1;
while (count <= 10) {
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
// Stuff the while loop executes
}
});
}
}, 20000);
count++;
}
The TimerTask kicks off a new Thread and then the loop proceeds as normal.
The execution of the thread does not cause a delay to the execution of the code in your loop.
It's because you're queueing up 10 toasts all to execute in one hour. Each iteration of your loop takes only a fraction of a millisecond or maybe a tad bit more than that. To enqueue them properly, you could do 3600000 * count instead of 3600000 each time.
This is a terrible way to do it though. You should use AlarmManager for stuff like this.
You're scheduling 10 TimerTasks to execute after an hour, at the same time. So all 10 tasks are being executed after 1 hour, which makes it seem like 1 execute since all the Toast messages display at the same time. To schedule tasks at a fixed delay, with the first task starting in 1 hour, use this method:
Timer t = new Timer();
t.schedule(task, 3600000, 3600000);
This will execute until you call t.cancel().