The simplest role of JavaFX's significant blitheness 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 in one case per frame – or animation 'pulse'.

Simply how often is "once per frame"?

In this project, nosotros'll look at set up, frame and pulse length, and calculating frame length for an blitheness timer. The starting code for this project is here.

Creating an animation timer

The AnimationTimer is the simplest element of the JavaFX animation layer. In fact, if y'all're interested, I've made a comprehensive guide to every chemical element of the JavaFX blitheness toolkit, so check that out too.. It has iii methods, which define its behaviour, and in the simplest use case, we'll merely utilize one.

public void beginning(); public void stop(); public abstract void handle(long fourth dimension);

AnimationTimer is abstract, so to use it we must provide a concrete instantiation. About of the fourth dimension, this is done by creating an bearding inner class, but we tin can as well do it by sub-classing. If y'all'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 inside this method will and then be executed in one case 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. And so, to properly understand the speed of the animation timer, we need to expect beginning 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 brand information technology work. So, nosotros'll look at customising it to go the process we want.

If you're non that fussed about the inner workings, and you merely want to know how to use the blitheness timer, don't worry. You can jump alee now.

Cosmos and Running

Then, we've simply created our animation timer. Because nosotros're creating an example for an abstruse course, 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.

one. Breakthrough Toolkit

The Quantum Toolkit integrates the windowing role 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 Breakthrough Toolkit makes sure nosotros can't update our animations faster than the window is rendering.

With that in heed, if you're the beginning bit of lawmaking that's requested the Toolkit, y'all've just fix into action a piddling concatenation of events that sets up the Windowing system for JavaFX.

Subsequently that, the blitheness timer is simply handed the toolkit in utilize. The animation timer doesn't need the whole toolkit – so it asks the toolkit to just requite it the main timer.

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

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

Dominion 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 plan. Information technology manages all the scheduling and running of the blitheness actions, as well as any post-update methods JavaFX might deem necessary. Information technology's responsible for the frame rate (which we'll expect at in Animation Speed), and allows JavaFX to terminate and outset the clock on animation globally.

3. TimerReciever

Finally, the animation timer creates an AnimationTimerReceiver, a private grade inside of the animation timer. Its only job is to deed as an intermediary – a footling like an observer – on the main timer's pulse switch.

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

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

Animation Timer Speed (fps)

ane. How JavaFX determines the frame rate

Now, knowing that the master timer runs the send in terms of animation, nosotros tin can dig into it to encounter how information technology determines what it should be.

To work out the frame rate of the application, the master timer refers itself to the Settings grade. That grade is an internal package in the graphics module called com.sun.scenario. And in case y'all're wondering, but like the privileged actions of the animation pulses, the internal package can't be accessed by u.s.a.. We tin 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 charge per unit holding', based on the screen refresh rate
  2. If that'southward not set, check the pulse belongings, based on the preferred pulse frequency of JavaFX on this arrangement
  3. Finally, default to threescore 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, at that place's an easy way to detect out. AnimationTimer is an abstruse class, and so we extend it to create a timer anyway. Nosotros ordinarily do that past creating an anonymous inner form, but you can create concrete sub-classes too.

By extending the animation timer a fiddling more, nosotros can get it to remember the timestamp of the final frame (in nanoseconds). A trivial chip more that, and nosotros 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, nosotros can add together a method to our animation timer, which gives us access to the frame charge per unit, in frames per second, calculated from the duration of the last frame.

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

In this examination awarding, 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 characterization, FPSLabel, which nosotros bind to the property provided.

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

Using a simple NumberStringConverter, nosotros attached "FPS: " give the text a useful title..

And there information technology is, automatically updating:

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

Conclusions

JavaFX deter