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
}
Related
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.
I'm making fast forward button in my Mp3 player. I wrote already code for this, but have problem how to implement timer to jump 5% forward? I mean when I press button timer should jump 5% forward of total long song. This is my fastForward method.
public void FastForward(){
try {
//songTotalLength = fis.available();
fis.skip((long) ((songTotalLength * 0.05)));
} catch (IOException e) {
e.printStackTrace();
}
}
And here is the button method:
private void jButton3ActionPerformed(ActionEvent e) {
mp3.FastForward();
if(mp3.player.isComplete()){
bar = 100;
}
jProgressBar1.setValue((int)bar);
bar+=5;
}
And this one is for timer:
private void setTime(float t) {
int mili = (int) (t / 1000);
int sec = (mili / 1000) % 60;
int min = (mili / 1000) / 60;
start.set(Calendar.MINUTE, 0);
start.set(Calendar.SECOND, 0);
end.set(Calendar.MINUTE, 0 + min);
end.set(Calendar.SECOND, 0 + sec);
timer = new javax.swing.Timer(1000, new TimerListener());
percent = (float)100/(min*60+sec);
}
You're already redundantly tracking progress in two variables fis and bar. For the sake of good design, use one of those to determine elapsed time rather than using yet another variable for the same purpose.
but have problem how to implement timer to jump 5% forward?
You seem to have mistaken the purpose of a Timer. According to the Timer class documentation, it:
Fires one or more ActionEvents at specified intervals.
So the timer is not meant to keep track of how much time has elapsed. It will simply invoke the actionPerformed(ActionEvent) method of your TimerListener once per second (every 1000 milliseconds) as you have it configured.
For a more complete answer, please post the code for your TimerListener class.
Notes
It seems that your setTime(float) method is meant to be called repeatedly, so this method should not be initializing the timer variable. Rather initialize the timer once and leave it alone to do its job.
I'm assuming you intended the supplied float parameter t to represent microseconds.
The float data type has only 7 digits of precision. This could be fine since you're interested only in minutes and seconds, otherwise float is only good for up to about four months of seconds before losing accuracy.
It seems like you wanted your button click handler to do this (increment bar sooner):
private void jButton3ActionPerformed(ActionEvent e) {
mp3.FastForward();
bar+=5; // increment bar before checking complete, and before setting progress
if(mp3.player.isComplete()){
bar = 100;
}
jProgressBar1.setValue((int)bar);
}
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.
I'm trying to make a stopwatch in Java and don't know how to pause and continue my timer. Here is what I have done so far.
startButton.addActionListener(this);
stopButton.addActionListener(this);
pauseButton.addActionListener(this);
public void actionPerformed(ActionEvent e) {
Calendar aCalendar = Calendar.getInstance();
if (e.getSource() == startButton){
start = aCalendar.getTimeInMillis();
startButton.setBackground(Color.GREEN);
stopButton.setBackground(null);
pauseButton.setBackground(null);
} else if (e.getSource() == stopButton) {
stopButton.setBackground(Color.RED);
startButton.setBackground(null);
pauseButton.setBackground(null);
aJLabel.setText("Elapsed time is: " +
(double) (aCalendar.getTimeInMillis() - start) / 1000 );
} else if (e.getSource() == pauseButton) {
pauseButton.setBackground(Color.YELLOW);
stopButton.setBackground(null);
startButton.setBackground(null);
}
}
As you can see, I've only changed the colors for my pause button. I don't really know how to pause the thread by having the user click on the button. All examples I've found of thread.sleep() were with a specific time.
You can use the swing.Timer (not util.Timer) like this:
int interval = 100; // set milliseconds for each loop
Timer timer = new Timer(interval, (evt) -> repeatingProccess());
// create the method repeatingProccess() with your
// code that makes the clock tick
startButton.addActionListener(e -> timer.start());
stopButton.addActionListener( e -> {
timer.stop();
// here refresh your clock with some code...
};
pauseButton.addActionListener(e -> timer.stop());
You write a method called repeatingProccess() and it works in its own thread again and again every interval milliseconds. For a clock that counts seconds you can do this:
int interval = 1000;
int seconds = 0;
public void repeatingProccess() {
seconds++ ;
}
note:
The second will not be exactly 1000 milliseconds but around 1001 because of the time needed to run seconds++ but you can fix that as well by getting System time before and after and substracting the difference from your clock. You should use the Calendar API for this.
Why is this Code not working ?
This code should extend the Countdowntimer to 10 sec (everytime when point is 20 , 40 , 60) etc.But when I start it and my score is by 20 it shows in a TextView a right value of time.But then it is gone in 1 sec and the Countdowntimer got the old value and continue.Someone a idea ?
int bonus_time = 1 , sec = 10000 , point == 0;
points_timer =new CountDownTimer(sec,1000) {
#Override
public void onTick(long millisUntilFinished)
{
if ( point == (bonus_time * 20))
{
++bonus_time;
millisUntilFinished += 10000;
sec += 10000;
}
++point;
}
#Override
public void onFinish()
{
bonus_time = 1;
}
};
When you create a timer with the sec variable for its time, it does not magically connect the two so when the value of sec changes the timer's time changes, it just uses the value of sec once when you make the timer.
Same goes for changing millisUntilFinished, it's a parameter you got from a callback, by changing its value you are not doing anything.
The only way to change a timer's time is to create a new one. This is my suggestion:
// GLOBAL VARIABLES
CountDownTimer points_timer;
int bonus_time = 1 , sec = 10000 , point == 0;
public void createTimer()
{
points_timer =new CountDownTimer(sec,1000) {
#Override
public void onTick(long millisUntilFinished)
{
sec = millisUntilFinished;
if ( point == (bonus_time * 20))
{
++bonus_time;
//millisUntilFinished += 10000;
sec += 10000;
createTimer();
}
++point;
}
#Override
public void onFinish()
{
bonus_time = 1;
}
};
}
The creation of the timer is surrounded by a function, and that function is called each time the bonus is gained to recreate the timer with the new value of sec.
You should also call that method once in place of your previous code, to initially create the timer.
Hope this works..
There is no way to extend a CountDownTimer, no method in the class provides this.
Your attempt to add time to sec is useless, I even wonder how it can compile. Anyway, in Java integers are passed by value, so once you passed 1000, you passed it and can't change that value.
The only alernative is to re-create a new timer and use it instead of the old one. Or recode everything, a timer of your own that you can extend.
in
public void onTick(long millisUntilFinished)
you do
millisUntilFinished += 10000;
you can not assign to primitive parameter and expect that it changes anything outside of that method (eg. scope of millisUntilFinished is onTick method and nothing more)