The simplest office of JavaFX'south significant animation underpinning is the blitheness timer. The AnimationTimer class it gives admission to JavaFX's slightly modified version of Organization.nanoTime(), and provides an overridable handle() method, which is executed exactly in one case per frame – or animation 'pulse'.

Only how oftentimes is "once per frame"?

In this project, nosotros'll look at set upwardly, frame and pulse length, and computing frame length for an blitheness timer. The starting lawmaking for this project is here.

Creating an animation timer

The AnimationTimer is the simplest element of the JavaFX animation layer. In fact, if you're interested, I've made a comprehensive guide to every element of the JavaFX animation toolkit, then check that out also.. It has iii methods, which define its behaviour, and in the simplest employ example, we'll merely use one.

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

AnimationTimer is abstract, then to use information technology we must provide a concrete instantiation. Virtually of the time, this is done by creating an anonymous inner class, merely we can also do information technology past sub-classing. If you lot're interested in calculation functionality to pause or restart the timer, sub-classing would be more efficient.

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

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

Determining the get-go of every frame is done through a cascade of blitheness pulses, which kickoff with the MasterTimer. Then, to properly understand the speed of the animation timer, we demand to look starting time at how the animation timer internally constructs itself, and where information technology gets its settings.

How the cogs piece of work

Hither, nosotros'll take a look at the methods, classes and Toolkits that brand information technology work. Then, we'll look at customising information technology to get the process we want.

If you're non that fussed almost the inner workings, and you only desire to know how to use the blitheness timer, don't worry. You lot can jump ahead now.

Creation and Running

And so, we've just created our animation timer. Because nosotros're creating an case for an abstract grade, nosotros don't really come across the constructor. This encapsulates the blitheness 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 office of JavaFX ("Drinking glass") with the graphics engine ("Prism"). That's relevant to us considering the Glass Windowing Toolkit runs the animation pulses, and Prism handles the rending of the window.

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

With that in mind, if you're the outset bit of code that's requested the Toolkit, you've simply set into action a little concatenation of events that sets up the Windowing system for JavaFX.

Afterwards that, the blitheness timer is simply handed the toolkit in apply. The animation timer doesn't demand the whole toolkit – and then 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 almost the speed of the blitheness timer:

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

2. AbstractMasterTimer

The master timer, which more than or less runs the animation prove is a singleton that synchronises every timer in the current programme. It manages all the scheduling and running of the animation actions, every bit well equally any mail-update methods JavaFX might deem necessary. It'southward responsible for the frame rate (which we'll look at in Animation Speed), and allows JavaFX to stop and showtime the clock on animation globally.

three. TimerReciever

Finally, the animation timer creates an AnimationTimerReceiver, a private grade inside of the animation timer. Its only task is to act every bit an intermediary – a petty similar an observer – on the master timer'southward pulse switch.

The merely divergence 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 lot have to exist office of the timer system. So, the blitheness timer creates a AnimationTimerReceiver, which has the correct privileged access.

Animation Timer Speed (fps)

1. How JavaFX determines the frame charge per unit

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

To piece of work out the frame charge per unit of the application, the master timer refers itself to the Settings class. That form is an internal packet in the graphics module chosen com.sunday.scenario. And in case you're wondering, just like the privileged actions of the animation pulses, the internal parcel can't exist accessed by the states. Nosotros can't, at this betoken in time, set the frame rate.

JavaFX takes three steps to work out the frame charge per unit in the Settings class:

  1. Check the ' frame rate holding', based on the screen refresh charge per unit
  2. If that's non gear up, cheque 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 awarding to exam the frame rate of the animation timer.

Practically determining the frame rate

And then, what'southward the runtime speed of the JavaFX blitheness timer? Well, at that place's an easy way to detect out. AnimationTimer is an abstruse course, then we extend it to create a timer anyway. Nosotros unremarkably exercise that past creating an anonymous inner form, but you can create physical sub-classes too.

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

AnimationTimer animationTimer = new AnimationTimer() {     long delta;     long lastFrameTime;      @Override     public void handle(long now) {         delta = at present - lastFrameTime;         lastFrameTime = now;     } };

Finally, nosotros can add together a method to our animation timer, which gives the states admission to the frame rate, in frames per 2d, 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 course, 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 belongings provided.

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

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

And in that location it is, automatically updating:

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

Conclusions

JavaFX deter