# How to show a spinner and a progress bar (Progress)

> Use Progress in its three modes — spinning icon, determinate bar and indeterminate.

Source: https://crossfly.dev/docs/cookbook/ui/spinner-e-progresso — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 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 (`IOS` is 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
> `Progress` is added to a parent (`onAdd`) and **stops** when it is removed (`onRemove`).
> There is no public `start()`/`stop()` — to "hide" the progress, remove the component
> from the screen. The `mode` field is final (set in the constructor, immutable).

## Complete example (copy, paste and run)
```java
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 `MainWindow` skeleton above.

## Minimal snippet
```java
// 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)` and `Progress(ProgressType)`, and the
> `enum Progress.Mode { SPINNING_ICON, DETERMINATE_BAR, INDETERMINATE }` derived from them.
> `setValue` clamps to `[min, max]` and updates `progress` (fraction 0..1). The `ProgressType`
> lives in `UIConstants` with the values `IOS, FLUTTER, MATERIAL, STRIPED`. In a test
> environment (`DeviceConfig.isTesting`) the animation does not start automatically.

## Dig deeper
- Widget page: [Progress](/docs/ui/widgets/progress) · Canonical source: Chapter 14
- Ephemeral feedback (quick messages): [mostrar-um-hint.md](/docs/cookbook/ui/mostrar-um-hint)
