Search code examples
javaanimationtimerjavafx

How to change AnimationTimer speed?


I use AnimationTimer for several tasks like animation with changing pictures and ProgressIndicator animation. To achieve needed speed I put thread to sleep, but when several animations are running simultaneously they affect each others speed. Is there any other way to change speed of AnimationTimer? Code sample:

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;
    }
}

Solution

  • The AnimationTimer's handle method is invoked once for each frame that is rendered, on the FX Application Thread. You should never block that thread, so do not call Thread.sleep(...) here.

    The parameter passed to the handle(...) method is a timestamp, in nanoseconds. So if you want to throttle updates so they don't happen more than once every, say 28 milliseconds, you can use this to do so:

    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;
        }
    }