Class ProgressBar

java.lang.Object
limn.scene.Widget<ProgressBar>
limn.components.ProgressBar

public final class ProgressBar extends Widget<ProgressBar>
Simple horizontal progress bar. Determinate by default (setProgress(float) in [0..1]); setIndeterminate(boolean) switches to an animated sweeping pill (frame-clock ticker) for unknown-duration work. The determinate fill eases from the previous value to the new one through a shared Transition. A rounded track and fill, both from the Theme.

The bar follows the ControlSize resolved on it through exactly one token, progressThickness (4 / 6 / 8 / 10 / 12): every other quantity it paints already derives from Widget.height(): the pill radius, the minimum determinate fill, the indeterminate pill length and its travel. The long axis is free: 220 pt at every step, deliberately equal to Slider's so a bar and a slider stacked in a form line up, and a parent normally overrides it anyway.

setThickness(float) and setPreferredWidth(float) latch: an explicit value beats the step and survives every later step change, and a negative value (UNSET) hands the dimension back to the step.

  • Field Details

    • UNSET

      public static final float UNSET
      Marks a dimension as "follow the step", the SizedBox.UNSET idiom. Both dimensions start here, so a bar that was never explicitly sized tracks its ControlSize; anything >= 0 is an author's pin and wins.
      See Also:
  • Constructor Details

    • ProgressBar

      public ProgressBar()
  • Method Details

    • setProgress

      public ProgressBar setProgress(float value)
      Sets the determinate progress, clamped to [0..1]; the fill eases to it. A bar that was indeterminate becomes determinate, and says so: the sweep's ticker stops itself without damaging anything, and the fill's transition is silent when its target has not moved, so a value that arrives after a sweep and equals the one the fill was already at — the fresh bar that connects and then reports nothing done yet — would otherwise leave the last sweep pill on screen and the busy state in the accessible tree until unrelated damage.
    • progress

      public float progress()
      Completion in [0,1]; meaningless while isIndeterminate().
    • isIndeterminate

      public boolean isIndeterminate()
      Whether the bar animates instead of showing a fraction.
    • setIndeterminate

      public ProgressBar setIndeterminate(boolean value)
      Switches to (or from) the animated indeterminate sweep. While the user has asked the system for less motion (Motion.reduced()), the sweep steps: it moves four times a second instead of every frame, and never stops, since it says the work goes on.
    • setPreferredWidth

      public ProgressBar setPreferredWidth(float width)
      Overrides the 220 pt free axis; UNSET (any negative value) restores it.
    • setThickness

      public ProgressBar setThickness(float value)
      Pins the bar's thickness, overriding the step's progressThickness; UNSET (any negative value) hands it back to the step. A pinned value latches: a later setControlSize does not disturb it.
    • onAttached

      protected void onAttached()
      Description copied from class: Widget
      Called when this widget enters a scene (attached to the tree). Widget.scene() is the scene it just joined. Fires top-down, so a parent runs before its children. Default no-op.
      Overrides:
      onAttached in class Widget<ProgressBar>
    • onDetached

      protected void onDetached()
      Description copied from class: Widget
      Called when this widget leaves the scene: detached from the tree, moved into another scene (told this before the Widget.onAttached() of the scene it joins), or still in it when the scene's window closes, which detaches every widget the scene has. What was taken in Widget.onAttached() from something that outlives the window (a listener's place in a list of the process's, a resource of the system's) is given back here.

      Widget.scene() still answers the scene being left, and becomes null once this returns, so releasing something the scene owns needs no field of your own to remember it by. Fires bottom-up, so children run before their parent, and every one of them can still reach the scene.

      Release resources here, but GPU resources must be handed to Scene.disposeLater(limn.graphics.GpuSurface) (disposal needs the owning GL context, which is only current inside a frame). Not called on Widget.setVisible(boolean). Default no-op.

      Overrides:
      onDetached in class Widget<ProgressBar>
    • onAccessibility

      protected void onAccessibility(Accessibility a)
      Describes the bar as one PROGRESS_BAR node whose value is the model and never the picture.

      The role is unconditional, and it is the reason the widget describes itself at all: the bar paints, holds no string and takes no input, which is the shape the walk deletes and then warns about once per class, and what it draws is information rather than decoration, so the decoration seam is not the answer. No name is declared, on purpose. The widget holds nothing to hand over: a tooltip names it through the walk's free default, an application's setAccessibleName wins over that and turns the tooltip into the description, and a caption beside the bar is a relation the application declares rather than one guessed here.

      Determinate, the node carries a value facet in whole percent, 0..100, with no step and no text: nothing increments it, the number is the whole of it, and there is no formatted string anywhere in this class to hand over, so no cache and no witness exist. The rounding is what keeps an application that drives setProgress(float) every frame with sub-percent deltas from copying the tree every frame; the comparison sees what it is given, and one percent is the resolution a reader speaks. Indeterminate, the facet is absent and BUSY stands in its place, because the number means nothing then and no platform carries a range on a bar that has none.

      Neither the eased fill nor the sweep phase is read here. The fill eases toward the model for the length of a fade after every set and the sweep moves on every frame; publishing either would make the difference find a change on each of those frames. Publishing the model means those frames walk, bounded and without allocating, and publish nothing. READ_ONLY is not written because the builder derives that bit from a text facet and drops it here; that the value cannot be set is said by the role together with the inherited refusal of SET_VALUE. HORIZONTAL is fixed by the class, since the long axis has no seam. An enum, four doubles and two bits, and no string, so a damaged frame that changed nothing costs no memory.

      Overrides:
      onAccessibility in class Widget<ProgressBar>
      Parameters:
      a - the node being described; write into it, and never keep it
    • 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<ProgressBar>
    • onPaint

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