The simplest part of JavaFX’s significant animation underpinning is the animation timer. The AnimationTimer class it gives access to JavaFX’s slightly modified version of System.nanoTime(), and provides an overridable handle() method, which is executed exactly once per frame – or animation ‘pulse’.

But how often is “once per frame”?

In this project, we’ll look at set up, frame and pulse length, and calculating frame length for an animation timer. The starting code for this project is here.

Creating an animation timer

The AnimationTimer is the simplest element of the JavaFX animation layer. It has three methods, which define its behaviour, and in the simplest use case, we’ll only use one.

public void start();
public void stop();
public abstract void handle(long time);

AnimationTimer is abstract, so to use it we must provide a concrete instantiation. Most of the time, this is done by creating an anonymous inner class, but we can also do it by sub-classing. If you’re interested in adding functionality to pause or restart the timer, sub-classing would be more efficient.

Either way, we need to overwrite the abstract method handle(). The code we provide within this method will then be executed once per JavaFX frame.

An animation timer recieves a pulse from the mater timer every frame

Determining the start of every frame is done through a cascade of animation pulses, which start with the MasterTimer. So, to properly understand the speed of the animation timer, we need to look first at how the animation timer internally constructs itself, and where it gets its settings.

How the cogs work

Here, we’ll take a look at the methods, classes and Toolkits that make it work. Then, we’ll look at customising it to get the process we want.

If you’re not that fussed about the inner workings, and you just want to know how to use the animation timer, don’t worry. You can jump ahead now.

Creation and Running

So, we’ve just created our animation timer. Because we’re creating an instance for an abstract class, we don’t actually see the constructor. This encapsulates the animation framework away from the user.

Internally, the constructor of the animation timer requests the default Toolkit. For JavaFX, this is the Quantum Toolkit.

1. Quantum Toolkit

The Quantum Toolkit integrates the windowing part of JavaFX (“Glass”) with the graphics engine (“Prism”). That’s relevant to us because the Glass Windowing Toolkit runs the animation pulses, and Prism handles the rending of the window.

In increase efficiency, the Quantum Toolkit makes sure we can’t update our animations faster than the window is rendering.

With that in mind, if you’re the first bit of code that’s requested the Toolkit, you’ve just set into action a little chain of events that sets up the Windowing system for JavaFX.

After that, the animation timer is simply handed the toolkit in use. The animation timer doesn’t need the whole toolkit – so it asks the toolkit to just give it the master timer.

AbstractMasterTimer timer = Toolkit.getToolkit().getMasterTimer();

That call to the Toolkit tells you a lot about the speed of the animation timer:

Rule 1: In JavaFX, the animation timer will never run faster than the refresh rate of the screen.

2. AbstractMasterTimer

The master timer, which more or less runs the animation show is a singleton that synchronises every timer in the current program. It manages all the scheduling and running of the animation actions, as well as any post-update methods JavaFX might deem necessary. It’s responsible for the frame rate (which we’ll look at in Animation Speed), and allows JavaFX to stop and start the clock on animation globally.

3. TimerReciever

Finally, the animation timer creates an AnimationTimerReceiver, a private class inside of the animation timer. Its only job is to act as an intermediary – a little like an observer – on the master timer’s pulse switch.

The only difference between this and a regular observer is that it interacts with the privileged network of actions underpinning animation in the Quantum Toolkit.

The toolkit won’t let just anyone access the timer pulse – you have to be part of the timer system. So, the animation timer creates a AnimationTimerReceiver, which has the right privileged access.

Animation Timer Speed (fps)

1. How JavaFX determines the frame rate

Now, knowing that the master timer runs the ship in terms of animation, we can dig into it to see how it determines what it should be.

To work out the frame rate of the application, the master timer refers itself to the Settings class. That class is an internal package in the graphics module called com.sun.scenario. And in case you’re wondering, just like the privileged actions of the animation pulses, the internal package can’t be accessed by us. We can’t, at this point in time, set the frame rate.

JavaFX takes three steps to work out the frame rate in the Settings class:

  1. Check the ‘frame rate property’, based on the screen refresh rate
  2. If that’s not set, check the pulse property, based on the preferred pulse frequency of JavaFX on this system
  3. Finally, default to 60 FPS

To test this, we’ll build a simple application to test the frame rate of the animation timer.

Practically determining the frame rate

So, what’s the runtime speed of the JavaFX animation timer? Well, there’s an easy way to find out. AnimationTimer is an abstract class, so we extend it to create a timer anyway. We usually do that by creating an anonymous inner class, but you can create concrete sub-classes too.

By extending the animation timer a little more, we can get it to remember the timestamp of the last frame (in nanoseconds). A little bit more than that, and we calculate the number of nano seconds since the last frame.

AnimationTimer animationTimer = new AnimationTimer() {
    long delta;
    long lastFrameTime;

    @Override
    public void handle(long now) {
        delta = now - lastFrameTime;
        lastFrameTime = now;
    }
};

Finally, we can add a method to our animation timer, which gives us access to the frame rate, in frames per second, calculated from the duration of the last frame.

public double getFrameRateHertz() {
    double frameRate = 1d / deltaTimeNano;
    return frameRate * 1e9;
}

In this test application, we’ve actually made a SimpleAnimationTimer class, which provides an IntegerProperty, updated each frame, providing bindable access to the frame-rate.

In our Controller, we include a label, FPSLabel, which we bind to the property provided.

FPSLabel.textProperty().bindBidirectional(timer.frameRateProperty(), new NumberStringConverter("FPS: "));

Using a simple NumberStringConverter, we attached “FPS: ” give the text a useful title..

And there it is, automatically updating:

An animation timer has been used to display the frame rate of a JavaFX application

Conclusions

JavaFX deter