This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
Slider
Slider lets you choose a float value within a range [min, max] by dragging a knob. It can be continuous or discrete (with steps, via npos). The orientation is detected automatically: horizontal if width ≥ height, otherwise vertical. Tapping outside the knob smoothly animates to the tapped point; dragging updates the value continuously.
🟢 · Package:
dev.crossfly.ui· Extends:Component· Style:SliderStyle(with a pressed variantsliderPressed())
When to use
- Continuous or approximate values: volume, brightness, ranges, zoom.
- Selection over a few discrete steps (e.g. 1 to 5) with
npos.
When NOT to use
- When the user needs to type an exact number → use
textfieldin numeric mode.
Appearance
A bar in two segments — filled (before the knob) and empty (after) — plus the knob. The coordinates of each segment (bx1/by1/bw1/bh1, bx2/by2/bw2/bh2) and of the knob (kx/ky/ks) are computed in layout (all float). The bar thickness is thickness * fontHeight; the knob is knobSize * fontHeight (from the SliderStyle).
Complete example (copy, paste and run)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** 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());
Label saida = new Label("Volume: 50");
add(LAY_AUTO, saida);
// Continuous slider 0..100 starting at 50; onAction fires on every value change
Slider volume = new Slider(0, 100, 50);
volume.onAction(c -> saida.setText("Volume: " + (int) volume.value));
add(LAY_AUTO, volume);
}
}
The snippets below show only the core (what goes inside
onShow()). To run them, place them in theMainWindowskeleton above.
Basic usage
Slider volume = new Slider(0, 100, 50); // continuous, starts at 50
volume.onAction(c -> System.out.println("valor: " + volume.value));
container.add(LAY_AUTO, volume);
Constructors
| Constructor | Description |
|---|---|
Slider(float min, float max, float value) |
Continuous slider. |
Slider(float min, float max, float value, int npos) |
Discrete slider: npos positions (e.g. 5 → steps at 0%, 25%, 50%, 75%, 100%). |
Properties and customization
| Property / method | Type | Default | What it does |
|---|---|---|---|
value |
float (field) |
ctor | Current value (read). |
min / max |
float (field) |
ctor | Range limits. |
npos |
int (field) |
0 |
No. of discrete positions; 0 = continuous. |
setValue(float) |
void |
— | Sets the value immediately (= setValue(v, false)); applies clamp + snap. |
setValue(float, boolean animated) |
void |
— | Sets the value with/without animation; fires runActions(). |
Callbacks and events
| Callback | When it fires |
|---|---|
onAction(Action) |
On every change of value (drag, tap animation and setValue). |
States
- dragging: while the user drags the knob (
onPan),valueis updated on every movement. - tap-to-jump: tapping outside the knob animates to the tapped point (
PositionAnimation, durationstyle.animationDuration). - pressed: uses its own pressed style (
sliderPressed()).
Discrete slider with 5 stops
Slider nivel = new Slider(0, 100, 50, 5); // steps: 0,25,50,75,100
nivel.onAction(c -> System.out.println("nível: " + nivel.value));
container.add(LAY_AUTO, nivel);
nivel.setValue(75, true); // animates to 75 (will be snapped to the nearest step)
Best practices
- Pass an initial
valuewithin[min, max]: the constructor does not clamp (onlysetValuedoes). - To force vertical orientation, give the slider more height than width in the layout.
Common mistakes
- Assuming a fixed orientation: it is decided in layout by the width/height ratio.
- Expecting continuous values with
npos > 0: in discrete mode the value is always “snapped” to the step.