How to do an array of timers in java - java

I know I am probably way off here, but I am trying to create a timer array so that mytimer[0] mytimer[1], mytimer[2], etc... all fire off at a different interval, with diffrerent events sent to a server. Any ideas? The for loop value of 6 is an organic number for testing purposes only. This number would later be decided base on a setting from the program's xml file.
Timer mytimers[] = new Timer[6];
for(int i = 0;i < 6;i++){
final int mytime = i;
mytimers[i].scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//do action
sendData("Timer " + mytime + " fired");
}
}, 10000, i*1000);
}

Timer mytimers[] = new Timer();
I'm assuming this is the line that doesn't work? You can't initialize an array with an object; initialize it with an array:
Timer mytimers[] = new Timer[6];
Making another guess, you're also not initializing the individual timers:
mytimers[i].scheduleAtFixedRate(new TimerTask() {
At this point mytimers[i] isn't set to anything, so how can you call scheduleAtFixedRate on it? Initialize it first:
mytimers[i] = new Timer();
mytimers[i].scheduleAtFixedRate(new TimerTask() {
EDIT:
Your "IllegalArgumentException: Non-positive period." is because on the first time through the loop, i = 0, so i * 1000 = 0, and the period can't be 0 ("run this event every 0 zero seconds").
Start with i = 1 and it should be fine.

Have you thought about just doing one timer, and the putting all the different events in some sort of (if timeElapsed % timerinterval[1] == 0) and then that way you can simulate the different times by using just one timer. Then you only need an array of integers with the timer interval.

Use this:
Timer mytimers[] = new Timer[6];
for(int i = 0;i < 6;i++){
mytimers[i] = new Timer();
final int mytime = i;
mytimers[i].scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//do action
sendData("Timer " + mytime + " fired");
}
}, 10000, i*1000);
}
The problem is, you are calling the Timer() constructor on an array and never initializing your individual timers. Rather, you should initialize the array as an array and the individual timers as timers.

Related

How can I stop a Swing Timer after n seconds?

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
}

Java - how to make a timer which displays elapsing time in JLabel

I'm writing the code of my first Java Game right now, so far I have built GUI and I want to add some logic. In my game, user should see elapsing time for his move (begin with 10s), like 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. I created JLabel and would like to display that elapsing time on it. My program has 3 levels of difficulty, firstly user chooses one by clicking on appropriate JButton and then user should see the timer and some options to choice and play. How can i cope with this problem? I read about Timer class in Java but still don't know how can i display counting-down time on JLabel. Maybe should I implement a game loop, but to be honest I don't have any idea how to make it.
You can simply use a count down timer method and pass your JLabel to it along with the number of seconds to count down and a optional 'End Of Time' message.
There are lots of examples of this sort of thing on the internet but here is my quick rendition of one:
public static Timer CountdownTimer(JLabel comp, int secondsDuration, String... endOfTimeMessage) {
if (secondsDuration == 0) { return null; }
String endMsg = "~nothing~";
if (endOfTimeMessage.length>0) { endMsg = endOfTimeMessage[0]; }
final String eMsg = endMsg;
int seconds = secondsDuration;
final long duration = seconds * 1000;
JLabel label = (JLabel)comp;
final Timer timer = new Timer(10, new ActionListener() {
long startTime = -1;
#Override
public void actionPerformed(ActionEvent event) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long now = System.currentTimeMillis();
long clockTime = now - startTime;
if (clockTime >= duration) {
((Timer)event.getSource()).stop();
if (!eMsg.equals("~nothing~")) { label.setText(eMsg); }
return;
}
SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
label.setText(df.format(duration - clockTime));
}
});
timer.start();
return timer;
}
If you want to change the way the count-down is displayed within the JLabel then you can change the SimpleDateFormat string. This method returns the Timer object so...you figure out how to stop it whenever you want (before the duration has expired).

Progressively increase integer / increase int on regular interval

I just recently started playing around with Java/Android.
I am trying to make a very simple Android app. I want a number to be progressively increased. Something like:
int x = 0;
then every 0.1 seconds, x++. Then I can set the text of a textview
.setText(String.valueOf(x));
So in the program it will have an integer number increasing from 0 by 1 every 0.1 seconds.
Meanwhile all other functions/code should run normally while this is happening in the background
you could use the TextView's internal handler and its postDelayed method, to increment the int . E.g.
textView.postDelayed(new Runnable() {
#Override
public void run() {
textView.setText(String.valueOf(++x));
textView.postDelayed(this, 100);
}
}, 100);
where 100 is 100 milliseconds. Don't forget to call
textView.removeCallbacks(null);
when your activity is paused
you can use:
int x = 0;
TimerTask scanTask;
Timer t = new Timer();
public void incrementValue(){
scanTask = new TimerTask() {
public void run() {
x++;
}};
t.schedule(scanTask, 100, 100);
}
and use t.cancel(); whenever you want to stop the task.

how to stop a timer with 'if'

hi guys i am new to java... :(
i just want my button(start) to start a timer but i want to stop the timer automatically with 'if' so for example... when a user enters a time and the timer get's to the timer it stops... so far my coding is like this...
private void startTimerActionPerformed(java.awt.event.ActionEvent evt) {
javax.swing.Timer tm = new javax.swing.Timer(100, new ActionListener()
{
public void actionPerformed (ActionEvent evt) {
AddOneActionPerformed(evt);
}
});
tm.start();
int getTM,getM,getTS,getS,Secs,tenSec,Mins,tenMin;
getTM = Integer.parseInt(enterTenMins.getText());
getM = Integer.parseInt(enterOneMins.getText());
getTS = Integer.parseInt(enterTenSecs.getText());
getS = Integer.parseInt(enterOneSecs.getText());
tenMin = Integer.parseInt(tenMins.getText());
Mins = Integer.parseInt(oneMins.getText());
tenSec = Integer.parseInt(tenSecs.getText());
Secs = Integer.parseInt(oneSecs.getText());
}
and AddOneActionPerformed(evt) is
private void AddOneActionPerformed(java.awt.event.ActionEvent evt) {
int dd,Secs,tenSec,Mins,tenMin;
tenMin = Integer.parseInt(tenMins.getText());
Mins = Integer.parseInt(oneMins.getText());
tenSec = Integer.parseInt(tenSecs.getText());
Secs = Integer.parseInt(oneSecs.getText());
dd= Integer.parseInt(digitValue.getText());
dd= dd+1;
if (dd==10)
dd = 0;
if (Secs == 10)
Secs = 0;
if (dd==0)
Secs=Secs +1;
if (tenSec>=6)
tenSec = 0;
if (Secs==10)
tenSec=tenSec +1;
if (Mins==10)
Mins = 0;
if (tenSec==6)
Mins=Mins+1;
if (tenMin>=6)
tenMin=0;
if (Mins==10)
tenMin=tenMin+1;
String ss = Integer.toString(dd);
digitValue.setText(ss);
String ff = Integer.toString(Secs);
oneSecs.setText(ff);
String gg = Integer.toString(tenSec);
tenSecs.setText(gg);
String hh = Integer.toString(Mins);
oneMins.setText(hh);
String jj = Integer.toString(tenMin);
tenMins.setText(jj);
showDigitActionPerformed(evt);
showOneSecsActionPerformed(evt);
showTenSecsActionPerformed(evt);
showOneMinsActionPerformed(evt);
showTenMinsActionPerformed(evt);
}
You can get the Timer instance from the ActionEvent's getSource() method, and then call stop on it. So,...
// for your Timer's ActionListener
#Override
public void actionPerformed(ActionEvent evt) {
if (someStoppingConditionIsTrue) {
Timer timer = (Timer) evt.getSource();
timer.stop();
} else {
// code to call repeatedly
}
}
Note that you've got two separate issues going on, and should solve them separately. The code above is a way to stop a Timer from within its own ActionListener using some condition. Your other question is how to get user input to allow you to change that condition, and that will involve separate code that is independent of the Timer code above.
Consider in addtion:
Use two JSpinners to for the user's to input minutes and seconds.
Give your class an int totalTime field.
Set this value in your startTimerActionPerformed method.
Have the Timer's ActionListener decrement this value based on measured elapsed time using the differences in calls to System.getSystemTime().
Calculate get the difference between the totalTime and elapsedTime (it will be in milliseconds), say called timeLeft
Calculate your minutes and seconds from timeLeft.
Then display these values in a JLabel using a formatted String, say something like String.format("%02d:%02d", minutes, seconds).
When the timeLeft == 0, that's when you stop your Timer.

read array in certain time range

How can I read an array in java in a certain time? Lets say in 1000 milliseconds.
for example:
float e[]=new float [512];
float step = 1000.0 / e.length; // I guess we need something like that?
for(int i=0; i<e.length; i++){
}
You'd need a Timer. Take a look at its methods... There's a number of them, but they can be divided into two categories: those that schedule at a fixed delay (the schedule(... methods) and those that schedule at a fixed rate (the scheduleAtFixedRate(... methods).
A fixed delay is what you want if you require "smoothness". That means, the time in between executions of the task is mostly constant. This would be the sort of thing you'd require for an animation in a game, where it's okay if one execution might lag behind a bit as long as the average delay is around your target time.
A fixed rate is what you want if you require the task's executions to amount to a total time. In other words, the average time over all executions must be constant. If some executions are delayed, multiple ones can then be run afterwards to "catch up". This is different from fixed delay where a task won't be run sooner just because one might have "missed" its cue.
I'd reckon fixed rate is what you're after. So you'd need to create a new Timer first. Then you'd need to call method scheduleAtFixedRate(TimerTask task, long delay, long period). That second argument can be 0 if you wish the timer to start immediately. The third argument should be the time in between task runs. In your case, if you want the total time to be 1000 milliseconds, it'd be 1000/array size. Not array size/1000 as you did.
That leaves us with the first argument: a TimerTask. Notice that this is an abstract class, which requires only the run() method to be implemented. So you'll need to make a subclass and implement that method. Since you're operating over an array, you'll need to supply that array to your implementation, via a constructor. You could then keep an index of which element was last processed and increment that each time run() is called. Basically, you're replacing the for loop by a run() method with a counter. Obviously, you should no longer do anything if the counter has reached the last element. In that case, you can set some (boolean) flag in your TimerTask implementation that indicates the last element was processed.
After creating your TimerTask and scheduling it on a Timer, you'll need to wait for the TimerTask's flag to be set, indicating it has done its work. Then you can call cancel() on the Timer to stop it. Otherwise it's gonna keep calling useless run() methods on the task.
Do keep the following in mind: if the work done in the run() method typically takes longer than the interval between two executions, which in your case would be around 2 milliseconds, this isn't gonna work very well. It only makes sense to do this if the for loop would normally take less than 1 second to complete. Preferably much less.
EDIT: oh, also won't work well if the array size gets too close to the time limit. If you want 1000 milliseconds and you have 2000 array elements, you'll end up passing in 0 for the period argument due to rounding. In that case you might as well run the for loop.
EDIT 2: ah why not...
import java.util.Random;
import java.util.Timer;
public class LoopTest {
private final static long desiredTime = 1000;
public static void main(String[] args) {
final float[] input = new float[512];
final Random rand = new Random();
for(int i = 0; i < input.length; ++i) {
input[i] = rand.nextFloat();
}
final Timer timer = new Timer();
final LoopTask task = new LoopTask(input);
double interval = ((double)desiredTime/((double)input.length));
long period = (long)Math.ceil(interval);
final long t1 = System.currentTimeMillis();
timer.scheduleAtFixedRate(task, 0, period);
while(!task.isDone()) {
try {
Thread.sleep(50);
} catch(final InterruptedException i) {
//Meh
}
}
final long t2 = System.currentTimeMillis();
timer.cancel();
System.out.println("Ended up taking " + (t2 - t1) + " ms");
}
}
import java.util.TimerTask;
public class LoopTask extends TimerTask {
private final float[] input;
private int index = 0;
private boolean done = false;
public LoopTask(final float[] input) {
this.input = input;
}
#Override
public void run() {
if(index == input.length) {
done = true;
} else {
//TODO: actual processing goes here
System.out.println("Element " + index + ": " + input[index]);
++index;
}
}
public boolean isDone() {
return done;
}
}
Change your step to be time per number (or total time divided by number of steps)
float step = 1000.0 / e.length;
Inside your for() loop:
try{
Thread.sleep(step);
}catch(InterruptedException e){
e.printStackTrace();
}

Categories