Class Slider

java.lang.Object
limn.scene.Widget
limn.components.Slider

public class Slider extends Widget
Horizontal slider selecting a value in [min, max]. Drag the thumb or click the track to jump; keyboard arrows nudge by the step (Home/End jump to the ends, PageUp/PageDown by ten steps). A continuous slider (step == 0) nudges by 1% of the range. The filled portion, thumb and focus ring all come from the Theme; the thumb grows on hover and the focus ring fades in through the shared Transition animator.

 Slider volume = new Slider(0, 100).setStep(5).setValue(30);
 volume.onChange(v -> audio.setGain(v / 100f));
 

Sizes follow the ControlSize resolved on this widget. This control's height derives from a focus-ring constant, 2 * (knobHover + FOCUS_GAP_SLIDER + border), rather than from a font or a design height, so it must not be rounded onto the shared control-height ramp. It is also the one place Strokes.MIN_HIT_TARGET binds: at the densest step the natural height falls below the floor, because the ring needs absolute room the knob ramp does not predict.

The preferred length is free: 220 at every step, equal to ProgressBar's so the two stack in a settings panel without a ragged column. Only the thickness moves with the step.

The value axis follows the resolved layout direction: reading right to left, min is at the right end of the track, the fill grows leftwards from it, and Left/Right nudge the value the way the thumb visibly moves. Up/Down are a vertical pair and keep their meaning in both directions, and Home/End/PageUp/PageDown name a value rather than a side, so they never mirror either. The track rectangle itself does not move: the pad is reserved at both ends, so only the meaning of each end changes.

  • Constructor Details

    • Slider

      public Slider(float min, float max)
      A slider over [min, max], starting at min.
  • Method Details

    • setValue

      public Slider setValue(float newValue)
      Sets the value programmatically (clamped + snapped to the step); does not fire onChange.
    • value

      public float value()
      The current value, always within [min, max].
    • min

      public float min()
      Lower bound, inclusive.
    • max

      public float max()
      Upper bound, inclusive.
    • setStep

      public Slider setStep(float newStep)
      Sets the discrete increment (0 = continuous). Re-snaps the current value.
    • onChange

      public Slider onChange(Consumer<Float> listener)
      Called with the new value on user changes only, not on setValue(float).
    • onCommit

      public Slider onCommit(Consumer<Float> listener)
      Called with the value the user settled on: once when a drag ends, and after each change made with the keyboard. onChange fires continuously while a drag is in progress and this fires once at the end of it, which is the difference between a preview and a decision.

      For anything a value change starts that should not be started per pixel: a decode, a request, a recomputation. A control bound only to onChange does that work for every position the thumb passes through; one bound to both can show something cheap on the way and do the real work here.

      Fires on a drag that ends where it began, because the user still chose that value, and does not fire for setValue(float), which is not a user change at all.

    • onMeasure

      protected Size onMeasure(Constraints constraints)
      Description copied from class: Widget
      Reports the size this widget wants within constraints. Called once per layout pass, and the result is cached against the constraints and the resolved axes (size step, layout direction, locale), so it must be a pure function of them and of this widget's own state.

      Resolve the ControlSize and the LayoutDirection once each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, and I18n.locale() answers it wherever text is resolved.

      Specified by:
      onMeasure in class Widget
    • onPaint

      protected void onPaint(Canvas canvas)
      Description copied from class: Widget
      Widget's own background/content, in local coordinates.
      Overrides:
      onPaint in class Widget
    • onMouseEvent

      protected void onMouseEvent(MouseEvent event)
      Description copied from class: Widget
      Mouse events (bubbling); call event.consume() when handled.
      Overrides:
      onMouseEvent in class Widget
    • onKeyEvent

      protected void onKeyEvent(KeyEvent event)
      Description copied from class: Widget
      Key events (focused widget first, then ancestors).
      Overrides:
      onKeyEvent in class Widget
    • onFocusGained

      protected void onFocusGained()
      Description copied from class: Widget
      Called when this widget takes keyboard focus. Default: nothing.
      Overrides:
      onFocusGained in class Widget
    • onFocusLost

      protected void onFocusLost()
      Description copied from class: Widget
      Called when this widget loses keyboard focus. Default: nothing.
      Overrides:
      onFocusLost in class Widget