This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
Value animations
The three animators interpolate a number over time. They do not draw anything: in the
onUpdate you read getValue() and apply it wherever you want (alpha, position, color…). Since rendering is on
demand, call Component.repaint() in the callback.
Comparison
| Class | Range | Curve | Repeats? | Use for |
|---|---|---|---|---|
AlphaAnimation |
[0,1] | cubic ease-in-out | no (has onComplete) |
fade, opacity, highlight |
PositionAnimation |
free | linear | no (has onComplete) |
move in pixels, slide |
LoopAnimation |
[0,1] | linear or eased | yes, infinite | pulse, glow, loading |
Complete example (copy, paste and run)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.animation.*; // AlphaAnimation, PositionAnimation, LoopAnimation
import dev.crossfly.util.*; // Debug
/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
// AlphaAnimation — fade-in of a label (0→1 in 0.3s)
Label card = new Label("Olá");
add(LAY_AUTO, card);
AlphaAnimation fade = new AlphaAnimation(0f, 1f, 0.3f);
fade.onUpdate(() -> { card.alpha(fade.getValue()); Component.repaint(); })
.onComplete(() -> Debug.log("fade concluído"))
.start();
// PositionAnimation — slides a panel in from the right (in pixels, free)
Label painel = new Label("Painel");
add(LAY_AUTO, painel);
int y0 = painel.y, w = painel.width, h = painel.height;
PositionAnimation slide = new PositionAnimation(Screen.width, 0, 0.4f);
slide.onUpdate(() -> { painel.setBounds((int) slide.getValue(), y0, w, h); Component.repaint(); })
.start();
// LoopAnimation — continuous opacity pulse (1s cycle, smoothed, infinite)
Label ponto = new Label("●");
add(LAY_AUTO, ponto);
LoopAnimation pulse = new LoopAnimation(1.0f, 60f, true);
pulse.onUpdate(() -> { ponto.alpha(0.4f + 0.6f * pulse.getValue()); Component.repaint(); })
.start();
}
}
The snippets below show only the core (what goes inside
onShow()). To run them, place them in theMainWindowskeleton above.
AlphaAnimation — fade-in
Label card = new Label("Olá");
AlphaAnimation fade = new AlphaAnimation(0f, 1f, 0.3f); // 0→1 in 0.3s
fade.onUpdate(() -> { card.alpha(fade.getValue()); Component.repaint(); })
.onComplete(() -> Debug.log("fade concluído"))
.start();
Constructors: AlphaAnimation(start, end, duration) (60 FPS) or (start, end, duration, fps).
PositionAnimation — slide a panel (in pixels)
int y0 = painel.y, w = painel.width, h = painel.height;
PositionAnimation slide = new PositionAnimation(Screen.width, 0, 0.4f); // enters from the right
slide.onUpdate(() -> { painel.setBounds((int) slide.getValue(), y0, w, h); Component.repaint(); })
.start();
It is not limited to [0,1] and is linear — ideal for coordinates.
LoopAnimation — continuous pulse
LoopAnimation pulse = new LoopAnimation(1.0f, 60f, true); // 1s cycle, 60 FPS, smoothed
pulse.onUpdate(() -> { float v = 0.4f + 0.6f * pulse.getValue(); ponto.alpha(v); Component.repaint(); })
.start();
// pulse.stop(); // stop when leaving the screen
Constructors: LoopAnimation(duration) (linear, 60 FPS) or (duration, fps, easeInOut). It does not have
onComplete (runs forever until stop()).
Common control
start() · stop() (fires onComplete on Alpha/Position) · cancel() (does not fire) ·
isRunning() · getValue().
Best practices
- Always
Component.repaint()inonUpdate— rendering is on demand. - Stop loops (
stop()) when leaving the screen (inonRemove()), otherwise theTimerkeeps running. - Store the animation in a variable/field so you can
stop()/cancel()it later.
Common mistakes
- Using
PositionAnimationexpecting a [0,1] range — it is free; the one that clamps isAlphaAnimation. - Forgetting the
repaint()and “the animation doesn’t show up”. - Calling
setAlpha(...)(from the old Javadoc) — the real method isalpha(float).