Animations & Transitions
Animations & Transitions
JavaFX ships a fully integrated animation engine that runs on the same pulse timer as layout and rendering. You do not reach for an external library or a background thread — the framework handles scheduling, interpolation, and thread safety automatically. This lesson covers every major tool in that engine: value-animating Timeline, property-targeting Transition subclasses, chained SequentialTransition / ParallelTransition, and the low-level AnimationTimer for frame-by-frame logic.
Thread.sleep loop or a javax.swing.Timer.
Timeline — The General-Purpose Animator
A Timeline animates any WritableValue (which includes every JavaFX property) along a series of KeyFrame checkpoints. You specify what value a property should hold at what time; the engine interpolates smoothly between them.
KeyValue wraps a property reference and a target value. KeyFrame wraps one or more KeyValue objects and a point in time. A single Timeline can carry as many keyframes — with as many properties — as you need.
You can also attach a plain EventHandler<ActionEvent> to a keyframe to fire a callback at a specific moment, which is useful for triggering sound effects, updating state, or coordinating non-property changes:
Built-in Transition Classes
For the most common animation tasks JavaFX provides ready-made Transition subclasses. Each one targets a specific property or effect, so you avoid writing manual KeyValue boilerplate.
TranslateTransition— moves a node along X / Y / Z.ScaleTransition— scales a node around its pivot point.RotateTransition— rotates a node around its Z-axis (or a custom axis).FadeTransition— animates theopacityproperty between two values.FillTransition— interpolates the fill color of aShape.StrokeTransition— interpolates the stroke color of aShape.PathTransition— moves a node along an arbitraryShapepath.
Every subclass shares the same base API: setDuration(), setCycleCount(), setAutoReverse(), play(), pause(), stop(). Here is a complete example combining three transitions:
Composing Animations: Sequential and Parallel
Real UIs rarely run a single animation in isolation. SequentialTransition plays a list of animations one after the other; ParallelTransition plays them all at the same time. Both implement Animation, so you can nest them arbitrarily.
Transition instance remembers its target node. If you call play() on a transition that is already running it restarts from the beginning. Clone or create fresh instances when you need to fire the same animation on multiple nodes.
Interpolators — Controlling the Feel
By default, properties interpolate linearly — constant speed from start to end, which looks mechanical. JavaFX's Interpolator class provides several built-in easing curves:
Interpolator.LINEAR— constant rate (default).Interpolator.EASE_IN— starts slowly, accelerates.Interpolator.EASE_OUT— starts fast, decelerates into the end value.Interpolator.EASE_BOTH— slow start and slow end; the most natural-feeling curve for UI animations.Interpolator.SPLINE(x1, y1, x2, y2)— a cubic Bézier for fully custom easing.Interpolator.DISCRETE— jumps to the target value instantly at the keyframe boundary; useful for frame-by-frame sprite sheets.
Pass an Interpolator as the third argument to KeyValue, or call setInterpolator() on a Transition:
AnimationTimer — Frame-by-Frame Control
When you need to update a scene property on every single frame — for a game loop, a physics simulation, or a real-time data chart — AnimationTimer is the right tool. Override its handle(long now) method: now is the current timestamp in nanoseconds, which you use to compute delta-time between frames.
handle() blocks the rendering thread. Keep it lightweight: update positions, consume a pre-computed queue, swap a pre-rendered image buffer. Never do I/O, database calls, or blocking computations there.
Lifecycle Methods
All Animation subclasses share the same lifecycle:
play()— start or resume from the current position.playFromStart()— rewind to time 0 and play.pause()— freeze at the current position;play()resumes from there.stop()— halt and reset to time 0.jumpTo(Duration)— seek to a specific position without changing play state.setRate(double)— 2.0 plays at double speed; -1.0 plays in reverse.setOnFinished(EventHandler)— callback fired when the final cycle completes.
Practical Pattern: Button Press Feedback
A short scale-and-return animation on button click is a classic example that ties together what you have learned. It uses a SequentialTransition of two ScaleTransition instances and reads cleanly in controller code:
Summary
JavaFX gives you a layered animation toolkit: Timeline for full control over arbitrary properties, ready-made Transition subclasses for common effects, SequentialTransition and ParallelTransition for composition, and AnimationTimer for frame-level game loops. Interpolator curves decide how the motion feels. In the final lesson of this tutorial you will pull all of these techniques — binding, events, CSS, and animation — together into a complete reactive JavaFX application.