Class Label

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

public class Label extends Widget
Single- or multi-line text. Without wrap, text that does not fit is cut with a real-measured ellipsis (), never a blind character count. With wrap, lines break greedily at the opportunities BreakIterator finds under the UI language, so unspaced CJK and dictionary-segmented Thai wrap through the same walk as prose. Horizontal and vertical alignment supported. Colors come from the Theme; typography comes from the resolved ControlSize step, picked by Label.Role.

Geometry comes from one shaping of the paragraph, never from prefix widths. The width of the first N characters of a string is not the width of anything on screen once a shaper joins, ligates or reorders, so every question this class asks about where to cut is asked of a ShapedText: ShapedText.fitEnd(int, float) for the budget and ShapedText.advanceTo(int) for what a candidate costs. The paragraph shaping does not depend on the box, so a measure and the layout that follows share it; only the per-line shapings are width-dependent, and each painted line is re-shaped because advanceTo is a budget and not a promise about a substring — the forms on both sides of a cut change when the cut is made.

Content-tight at every step: the measured box is exactly the line box: no minimum height, no padding, and no contribution from the icon. A Label's job beside a Button or a TextField is to let the parent's alignment decide the row height; a floor here would double-count against the container's control height.

The icon overhangs rather than growing the row. Its square is Strokes.ICON_OPTICAL_BUMP larger than the line box, so measuring max(lineHeight, iconBox) would let it win unconditionally and leave an icon Label taller than a bare one; a form column mixing the two goes visibly ragged. The row is the line box either way and the bump hangs out of the top and bottom, which is what it is for: icon glyphs carry no ascender/descender slack and must be drawn slightly larger than the text box to read at the same weight. The overhang is declared to partial rendering by paintOutset() and drawn outside the text clip.

Reading right to left, the icon and the text swap ends and nothing else moves. Label.HAlign.START and Label.HAlign.END name where reading starts and ends, so they turn around with the paragraph; Label.HAlign.CENTER is a centre in either direction and is the one arm of that decision that is the same number. The icon square is leading, which is the left edge in one direction and the right edge in the other, and the glyph inside it turns around only when the call that placed it said it should — see Icon.Mirroring.

  • Constructor Details

    • Label

      public Label(String text)
      A label showing a fixed string; see the I18nString constructor for localized text.
    • Label

      public Label(I18nString text)
      A label whose text follows the UI language; see I18nString.
  • Method Details

    • text

      public String text()
      The text as it currently reads; see textSource() for the key behind it.
    • textSource

      public I18nString textSource()
      The localizable value this label holds, which a language change re-resolves.
    • setText

      public Label setText(String newText)
      Replaces the text with a fixed string. Repaints without a layout pass when the box is unchanged.
    • setText

      public Label setText(I18nString newText)
      Replaces the text with a value that follows the UI language. UI thread only.
    • setFont

      public Label setFont(Font newFont)
      Pins an explicit font, overriding both the Label.Role and the size step: the escape hatch, and the only thing that beats them. While it is set, the icon box falls back to the font-derived formula, so an explicitly 14 pt label inside an XLARGE subtree does not get a 24 pt icon. null restores the role.
    • role

      public Label.Role role()
      The typographic role this label draws with.
    • setRole

      public Label setRole(Label.Role newRole)
      Selects the typographic token; the resolved step decides its size. Ignored while an explicit setFont(limn.graphics.Font) is in force.
    • setColor

      public Label setColor(Color newColor)
      Pins the text colour; null restores the theme's, resolved at paint time.
    • setMuted

      public Label setMuted(boolean newMuted)
      Uses the theme's muted text color, resolved at paint time; unlike an explicit setColor(limn.graphics.Color), it follows runtime theme switches.
    • setStrong

      public Label setStrong(boolean newStrong)
      Bold weight on top of the effective font; follows runtime theme switches.
    • setItalic

      public Label setItalic(boolean newItalic)
      Italic style on top of the effective font; follows runtime theme switches.
    • setOverflow

      public Label setOverflow(Label.Overflow newOverflow)
      What happens to text wider than the box when wrap is off.
    • setAlign

      public Label setAlign(Label.HAlign horizontal, Label.VAlign vertical)
      Alignment of the text block inside the laid-out box.
    • setWrap

      public Label setWrap(boolean newWrap)
      Breaks text across lines at the opportunities BreakIterator reports for the UI language, greedily; a run that offers no opportunity at all — a word longer than the box, or a script this locale has no rule for — is cut at the last cluster that fits. The measured height then depends on the width constraint. UI thread only.
    • setIcon

      public Label setIcon(Icon newIcon)
      Sets a leading icon, tinted to the text color, drawn as authored whichever way this label reads. null clears it. Leading is the side reading starts on: the left edge left to right, the right edge right to left.
    • setIcon

      public Label setIcon(Icon newIcon, Icon.Mirroring mirroring)
      Sets a leading icon and says whether its glyph turns around when the interface does. The icon's position is leading either way and is this label's decision; whether the drawing inside that square is a back arrow (which turns around) or a logo, a download arrow or a photograph (which must not) is knowable only at the call that placed it, which is why it is a parameter here and not a table anywhere.
      Parameters:
      newIcon - the icon, or null to clear it
      mirroring - Icon.Mirroring.NEVER unless this glyph is directional; a wrong NEVER is one arrow pointing the wrong way, and a wrong IN_RTL is a flipped brand mark
    • baselineOffset

      protected float baselineOffset()
      Description copied from class: Widget
      Distance from this widget's top edge to its first text baseline, in logical points: the alignment reference for Flex.CrossAlignment.BASELINE. Default height(): align on the bottom edge, the correct fallback for a widget with no text. Text-bearing components override with the expression they already paint with, (height() - metrics.height()) / 2 + metrics.ascent().

      Valid only once this widget has been given a box. Flex guarantees that: it lays every child of a BASELINE line out at cross position 0 first, reads the baselines, then repositions with Widget.moveChild(limn.scene.Widget, float, float), which moves without re-running layout.

      Overrides:
      baselineOffset in class Widget
    • paintOutset

      protected float paintOutset()
      The icon's optical bump, the only ink a Label puts outside its bounds. Undeclared, partial rendering would both under-damage the bump on Widget.invalidate() and cull the Label out of a repaint pass that covers only the overhanging sliver, either way leaving a stale crescent of the old glyph on screen.
      Overrides:
      paintOutset in class Widget
    • 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
    • onLayout

      protected void onLayout()
      Description copied from class: Widget
      Containers position children here (measure + Widget.layoutBox(float, float, float, float) per child).
      Overrides:
      onLayout 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