How do I change the speed of the AnimationTimer?
I use it AnimationTimer
for several tasks like animation with changing images and animation ProgressIndicator
. I put the thread to sleep to achieve the speed I want, but when several animations run at the same time, they affect the speed of each other. Is there any other way to change the speed AnimationTimer
? Sample code:
private void initialize() {
programButtonAnimation=new AnimationTimer(){
@Override
public void handle(long now) {
showClockAnimation();
}
};
programButtonAnimation.start();
}
private void showClockAnimation(){
String imageName = "%s_"+"%05d"+".%s";
String picturePath="t093760/diploma/view/styles/images/pink_frames/"+String.format( imageName,"pink" ,frameCount,"png");
programButton.setStyle("-fx-background-image:url('"+picturePath+"')");
frameCount++;
try {
Thread.sleep(28);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(frameCount>=120){
programButtonAnimation.stop();
frameCount=0;
}
}
source to share
The method AnimationTimer
handle
is called once for each frame that is displayed on the FX application thread. You should never block this thread, so don't call Thread.sleep(...)
here.
The parameter passed to the method handle(...)
is a timestamp in nanoseconds. So if you want to throttle updates so that they don't repeat more than once, say 28 milliseconds, you can use this to do this:
private void initialize() {
programButtonAnimation=new AnimationTimer(){
private long lastUpdate = 0 ;
@Override
public void handle(long now) {
if (now - lastUpdate >= 28_000_000) {
showClockAnimation();
lastUpdate = now ;
}
}
};
programButtonAnimation.start();
}
private void showClockAnimation(){
String imageName = "%s_"+"%05d"+".%s";
String picturePath="t093760/diploma/view/styles/images/pink_frames/"+String.format( imageName,"pink" ,frameCount,"png");
programButton.setStyle("-fx-background-image:url('"+picturePath+"')");
frameCount++;
if(frameCount>=120){
programButtonAnimation.stop();
frameCount=0;
}
}
source to share
Since I already wrote the code, and James_D informed you faster about blocking the UI, I would still like to add that if you have multiple AnimationTimers with different timings, you should create a dedicated class for this. If each one runs at a different speed, you can implement it like this:
import javafx.animation.AnimationTimer;
public abstract class AnimationTimerExt extends AnimationTimer {
private long sleepNs = 0;
long prevTime = 0;
public AnimationTimerExt( long sleepMs) {
this.sleepNs = sleepMs * 1_000_000;
}
@Override
public void handle(long now) {
// some delay
if ((now - prevTime) < sleepNs) {
return;
}
prevTime = now;
handle();
}
public abstract void handle();
}
This means that the handle () method is called at least after the sleepMs milliseconds have passed.
Or you change the parameter and specify the fps whatever you want.
You can use the above code like this:
AnimationTimerExt timer = new AnimationTimerExt(100) {
@Override
public void handle() {
System.out.println( System.currentTimeMillis());
}
};
timer.start();
Also, uploading an image over and over again is not the best choice. If you want to do animation, I suggest you take a look at Mike's blog about Creating Sprite Animations with JavaFX .
source to share