This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
How to show a spinner and a progress bar (Progress)
Purpose. Indicate that something is in progress. Progress has three modes,
chosen by the constructor: spinning icon (spinner), determinate bar (0–100% with a
known value) and indeterminate (infinite loop, when the time is unknown). Use
determinate when you have a known fraction (upload, download); indeterminate/spinner
for “loading…” with no fraction.
APIs used
new Progress(Icon icon)— Spinning mode: rotates the icon continuously.new Progress(float min, float max)— Determinate bar mode: creates the bar with the range[min, max]; initial value =min.progress.setValue(float v)— updates the value (clamped to[min, max]); recomputes the filled fraction. Fluent.new Progress(ProgressType type)— Indeterminate mode: infinite bar/spinner in the given style.ProgressType.MATERIAL,ProgressType.FLUTTER,ProgressType.IOS,ProgressType.STRIPED— visual variants of the indeterminate mode (IOSis a circular spinner; the others are bars).progress.pivot(int px, int py)— (spinning mode) custom rotation pivot;-1,-1= center of the icon.
Non-obvious behavior (confirmed in source): the animation starts by itself when the
Progressis added to a parent (onAdd) and stops when it is removed (onRemove). There is no publicstart()/stop()— to “hide” the progress, remove the component from the screen. Themodefield is final (set in the constructor, immutable).
Complete example (copy, paste and run)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.graphics.*;
/** 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());
// 1) Spinner (spinning icon) — generic "loading"
Progress spinner = new Progress(new MaterialIcon("autorenew", 48));
add(spinner);
// 2) Determinate bar (0 to 100) — update as real progress happens
Progress barra = new Progress(0f, 100f);
add(barra);
// ...as the download advances:
barra.setValue(75f); // 75% filled
// 3) Indeterminate (infinite loop) — with no known fraction
Progress infinito = new Progress(ProgressType.MATERIAL);
add(infinito);
// iOS-style circular spinner variant:
Progress ios = new Progress(ProgressType.IOS);
add(ios);
}
}
The snippet below shows just the core. To run it, place it in the
MainWindowskeleton above.
Minimal snippet
// 1) Spinner (spinning icon) — generic "loading"
Progress spinner = new Progress(new MaterialIcon("autorenew", 48));
add(spinner);
// 2) Determinate bar (0 to 100) — update as real progress happens
Progress barra = new Progress(0f, 100f);
add(barra);
// ...as the download advances:
barra.setValue(75f); // 75% filled
// 3) Indeterminate (infinite loop) — with no known fraction
Progress infinito = new Progress(ProgressType.MATERIAL);
add(infinito);
// iOS-style circular spinner variant:
Progress ios = new Progress(ProgressType.IOS);
add(ios);
Verification note (2026 code). Confirmed in source: the three constructors
Progress(Icon),Progress(float min, float max)andProgress(ProgressType), and theenum Progress.Mode { SPINNING_ICON, DETERMINATE_BAR, INDETERMINATE }derived from them.setValueclamps to[min, max]and updatesprogress(fraction 0..1). TheProgressTypelives inUIConstantswith the valuesIOS, FLUTTER, MATERIAL, STRIPED. In a test environment (DeviceConfig.isTesting) the animation does not start automatically.
Dig deeper
- Widget page: Progress · Canonical source: Chapter 14
- Ephemeral feedback (quick messages): mostrar-um-hint.md