Class Label
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.
Between the two, setMaxLines(int) breaks the text the same way across a set number of
lines and puts the ellipsis at the end of the last.
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.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumWhere a line sits in the text region, on two vocabularies that coexist on purpose.static enumWhat happens to text that does not fit: cut at the box's edge, or ended with an ellipsis.static enumWhich typographic token the text is drawn with, orthogonal to the size step, which decides how big that token is.static enumWhere the lines sit vertically in the text region. -
Constructor Summary
ConstructorsConstructorDescriptionA label showing a fixed string; see theI18nStringconstructor for localized text.Label(I18nString text) A label whose text follows the UI language; seeI18nString. -
Method Summary
Modifier and TypeMethodDescriptionprotected @Nullable StringThe chord of the access letter this label gives the control it names, only while the letter would reach it: a caption kept hidden as a field's name, or one in a collapsed or disabled section, is skipped by the scene, and a reader told "Alt+N" would press a key that does nothing.protected I18nStringThe text this widget offers when it is named as another's label, ornullwhen it is not the kind of widget that captions anything.protected floatDistance from this widget's top edge to its first text baseline, in logical points: the alignment reference forFlex.CrossAlignment.BASELINE.@Nullable Widget<?> The widget this label describes, ornull; seesetDescriptionFor(Widget).@Nullable Widget<?> labelFor()The widget this label names, ornull; seesetLabelFor(Widget).intmaxLines()protected voidWhat a label is to an assistive technology: static text, or a heading when its typographic role isLabel.Role.TITLE, named by the whole paragraph it holds.protected voidonLayout()Containers position children here (measure +Widget.layoutBox(float, float, float, float)per child).protected SizeonMeasure(Constraints constraints) Reports the size this widget wants withinconstraints.protected voidWidget's own background/content, in local coordinates.protected floatThe icon's optical bump, the only ink a Label puts outside its bounds.role()The typographic role this label draws with.setAlign(Label.HAlign horizontal, Label.VAlign vertical) Alignment of the text block inside the laid-out box.Pins the text colour;nullrestores the theme's, resolved at paint time.setDescriptionFor(@Nullable Widget<?> target) Makes this label the accessible description of another widget, the way the message beneath a field says why the field is invalid.Pins an explicit font, overriding both theLabel.Roleand the size step: the escape hatch, and the only thing that beats them.Sets a leading icon, tinted to the text color, drawn as authored whichever way this label reads.setIcon(@Nullable Icon newIcon, Icon.Mirroring mirroring) Sets a leading icon and says whether its glyph turns around when the interface does.setItalic(boolean newItalic) Italic style on top of the effective font; follows runtime theme switches.setLabelFor(@Nullable Widget<?> target) Makes this label the accessible name of another widget, the way a form's caption names the field it sits beside.setMaxLines(int lines) Lets the text break across up tolineslines, at the same opportunities and by the same walk aswrap, and ends the last of them with a measured ellipsis when more text remains (or lets it run on to the box's edge, underLabel.Overflow.CLIP).setMuted(boolean newMuted) Uses the theme's muted text color, resolved at paint time; unlike an explicitsetColor(limn.graphics.Color), it follows runtime theme switches.setOverflow(Label.Overflow newOverflow) What happens to text that does not fit: on the one line of a label that does not wrap, and on the last line of one given more lines, whereLabel.Overflow.ELLIPSISends that line with an ellipsis when more text remains andLabel.Overflow.CLIPlets the rest run on and cuts it at the box's edge.setRole(Label.Role newRole) Selects the typographic token; the resolved step decides its size.setStrong(boolean newStrong) Bold weight on top of the effective font; follows runtime theme switches.Replaces the text with a fixed string.setText(I18nString newText) Replaces the text with a value that follows the UI language.Draws the text in one of the palette's colours, said by what it means:Tone.DANGERfor a line that reports a failure,Tone.SUCCESSfor one that confirms.setWrap(boolean newWrap) Breaks text across lines at the opportunitiesBreakIteratorreports 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.text()The text as it currently reads; seetextSource()for the key behind it.The localizable value this label holds, which a language change re-resolves.@Nullable Tonetone()The tone this label draws its text in, ornull; seesetTone(limn.components.Tone).Methods inherited from class limn.scene.Widget
acceptsTextInput, accessibleLabelTarget, add, add, announceChange, backdropReach, baselineOffsetOf, caretRect, children, clipboard, clipHeight, clipsChildren, clipWidth, clipX, clipY, controlSize, cursor, declaredControlSize, declaredLayoutDirection, declaredLocale, focusArrivedBackward, focusArrivedByTraversal, handleUserChange, height, hitTest, hitTestChild, id, imageCursor, inheritanceHost, invalidate, invalidate, invalidateAccessible, isEnabled, isFocusable, isFocused, isRightToLeft, isSelfEnabled, isShowing, isVisible, isVisibleByItsOwnFlag, layoutBox, layoutDirection, locale, localToScene, localToSceneBounds, markNeedsContainedLayout, markNeedsLayout, markNeedsLayoutInPlace, maxHeight, maxWidth, measure, minHeight, minWidth, moveChild, moveChild, moveChild, neutralBase, notifyChange, notifyTextEdit, observeChanges, onAccessibilityAction, onAccessibilityChild, onAccessibilityChildAction, onAccessibilityChildIdentity, onAttached, onCanEdit, onCharTyped, onDetached, onDragExit, onDragOver, onDragStart, onDrop, onEdit, onFocusGained, onFocusLost, onHitTest, onKeyEvent, onMouseEvent, onPaintOverlay, onPreedit, onSyntheticAction, overlayPassesPointer, paintChildren, paintsDecoration, paintsFromBackdrop, paintWidget, parent, remove, remove, requestFocus, requestFocus, revealInView, revealInView, runHandler, scene, sceneNanos, sceneToLocal, self, setAccessibleDescribedBy, setAccessibleDescription, setAccessibleDescription, setAccessibleIgnored, setAccessibleLabelledBy, setAccessibleName, setAccessibleName, setAccessibleRole, setControlSize, setCursor, setEnabled, setFocusable, setId, setImageCursor, setInheritanceHost, setLayoutDirection, setLocale, setMaxHeight, setMaxWidth, setMinHeight, setMinWidth, setPresentedElsewhere, setTooltip, setTooltip, setVisible, shapeText, textRuler, tooltip, tooltipSource, width, x, y
-
Constructor Details
-
Label
A label showing a fixed string; see theI18nStringconstructor for localized text. -
Label
A label whose text follows the UI language; seeI18nString.
-
-
Method Details
-
text
The text as it currently reads; seetextSource()for the key behind it. A label that names a control (setLabelFor(limn.scene.Widget<?>)) reads its access letter's&mark out of it: "&Name" reads "Name". Any other label shows its text as written, an ampersand included. -
textSource
The localizable value this label holds, which a language change re-resolves. -
setLabelFor
Makes this label the accessible name of another widget, the way a form's caption names the field it sits beside. UI thread only.Nothing is inferred from where the two sit: a caption beside a field names it only when this is called, because proximity is a layout accident and a tree built from it says confident wrong things. One widget at a time; calling it again moves the link, and passing
nullremoves it.The named widget takes this label's text as its name and carries a
LABELLED_BYrelation back to it, so a client may read either. Changing this label's text renames what it labels, because the text is read at publish rather than copied here.- Parameters:
target- the widget this label names, ornullto remove the link- Returns:
- this label, for chaining
-
labelFor
The widget this label names, ornull; seesetLabelFor(Widget). -
setDescriptionFor
Makes this label the accessible description of another widget, the way the message beneath a field says why the field is invalid. UI thread only.The same rule as
setLabelFor(limn.scene.Widget<?>): a message that merely sits under a field describes nothing until this is called, one widget at a time, andnullremoves the link. The described widget takes this label's text as its description, read at publish so a message that changes follows, and carries aDESCRIBED_BYrelation back to this label; a reader then speaks the message after the field's name and state rather than finding it as a sentence somewhere else on the screen.A label may name one widget and describe another at once; a caption and a message are two different labels in a form, and this is what keeps them from having to be the same one.
- Parameters:
target- the widget this label describes, ornullto remove the link- Returns:
- this label, for chaining
-
descriptionFor
The widget this label describes, ornull; seesetDescriptionFor(Widget). -
accessibleLabelText
Description copied from class:WidgetThe text this widget offers when it is named as another's label, ornullwhen it is not the kind of widget that captions anything.Overridden by the widgets that are captions in their own right; everything else declines, which is why a link to one names nothing rather than inventing a string from its children.
- Overrides:
accessibleLabelTextin classWidget<Label>- Returns:
- the caption text, or
null
-
accessibleLabelAccessKey
The chord of the access letter this label gives the control it names, only while the letter would reach it: a caption kept hidden as a field's name, or one in a collapsed or disabled section, is skipped by the scene, and a reader told "Alt+N" would press a key that does nothing.- Overrides:
accessibleLabelAccessKeyin classWidget<Label>- Returns:
- the access key's display form, or
null
-
onAccessibility
What a label is to an assistive technology: static text, or a heading when its typographic role isLabel.Role.TITLE, named by the whole paragraph it holds.The role is decided on
role()alone and never on the font actually drawn with:setFont(limn.graphics.Font)pins a face as a size escape hatch and says nothing about what the text means, so a title drawn at fourteen points is still the title. The name istexthanded over by reference, which is what keeps a damaged frame that changed nothing free; it is never the painted lines, because an ellipsis and a wrap are how the text fits a box and a reader must hear what the box cut off. An empty text still publishes, so a status label that empties between messages keeps its identity and an icon-only label keeps the tooltip the walk then names it by. The one relation declared is the half nothing else can supply: the walk writesLABELLED_BYonto the widget this label names, and only this label knows to point back.- Overrides:
onAccessibilityin classWidget<Label>- Parameters:
a- the node being described; write into it, and never keep it
-
setText
Replaces the text with a fixed string. Repaints without a layout pass when the box is unchanged. -
setText
Replaces the text with a value that follows the UI language. UI thread only. -
setFont
Pins an explicit font, overriding both theLabel.Roleand 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.nullrestores the role. -
role
The typographic role this label draws with. -
setRole
Selects the typographic token; the resolved step decides its size. Ignored while an explicitsetFont(limn.graphics.Font)is in force. -
setColor
Pins the text colour;nullrestores the theme's, resolved at paint time. A pinned colour is the palette of the moment it was read and stays when the palette changes; a text that should follow it says what it means withsetTone(limn.components.Tone)instead. -
setTone
Draws the text in one of the palette's colours, said by what it means:Tone.DANGERfor a line that reports a failure,Tone.SUCCESSfor one that confirms. The colour is asked of the theme on every paint, so a change of palette re-colours the text with no code of the application's, which a colour read once and passed tosetColor(limn.graphics.Color)does not do. An explicitsetColor(limn.graphics.Color)still wins over the tone, and a disabled label is drawn disabled whatever its tone. UI thread only.- Parameters:
newTone- the tone, ornullfor none: the theme's text colour, or its muted one whilesetMuted(boolean)says so- Returns:
- this label
-
tone
The tone this label draws its text in, ornull; seesetTone(limn.components.Tone). -
setMuted
Uses the theme's muted text color, resolved at paint time; unlike an explicitsetColor(limn.graphics.Color), it follows runtime theme switches. Atonewins over it. -
setStrong
Bold weight on top of the effective font; follows runtime theme switches. -
setItalic
Italic style on top of the effective font; follows runtime theme switches. -
setOverflow
What happens to text that does not fit: on the one line of a label that does not wrap, and on the last line of one given more lines, whereLabel.Overflow.ELLIPSISends that line with an ellipsis when more text remains andLabel.Overflow.CLIPlets the rest run on and cuts it at the box's edge. -
setAlign
Alignment of the text block inside the laid-out box. -
setWrap
Breaks text across lines at the opportunitiesBreakIteratorreports 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. As many lines as the text needs, unlesssetMaxLines(int)sets a limit above one. UI thread only. -
setMaxLines
Lets the text break across up tolineslines, at the same opportunities and by the same walk aswrap, and ends the last of them with a measured ellipsis when more text remains (or lets it run on to the box's edge, underLabel.Overflow.CLIP). 1, the default, leaves the label assetWraphas it: one line without wrap, as many as the text needs with it. Above 1 the limit holds whether or not wrap is on, so a title of two lines sayssetMaxLines(2)and nothing else. UI thread only.The lines are counted, not fitted: a label given less height than its lines take is clipped, as a wrapped one is. A reader still hears the whole text, which is the label's name however it is cut.
- Parameters:
lines- the most lines, 1 or more- Returns:
- this label
- Throws:
IllegalArgumentException- whenlinesis below 1
-
maxLines
public int maxLines()- Returns:
- the most lines the text breaks across; see
setMaxLines(int)
-
setIcon
Sets a leading icon, tinted to the text color, drawn as authored whichever way this label reads.nullclears it. Leading is the side reading starts on: the left edge left to right, the right edge right to left. -
setIcon
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, ornullto clear itmirroring-Icon.Mirroring.NEVERunless this glyph is directional; a wrongNEVERis one arrow pointing the wrong way, and a wrongIN_RTLis a flipped brand mark
-
baselineOffset
protected float baselineOffset()Description copied from class:WidgetDistance from this widget's top edge to its first text baseline, in logical points: the alignment reference forFlex.CrossAlignment.BASELINE. Defaultheight(): 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; a single-line control's istextRuler().centredBaseline(font, height()), which stands the line's capitals in the middle of the box.Valid only once this widget has been given a box.
Flexguarantees that: it lays every child of a BASELINE line out at cross position 0 first, reads the baselines, then repositions withWidget.moveChild(limn.scene.Widget<?>, int), which moves without re-running layout.- Overrides:
baselineOffsetin classWidget<Label>
-
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 onWidget.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:
paintOutsetin classWidget<Label>
-
onMeasure
Description copied from class:WidgetReports the size this widget wants withinconstraints. 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
ControlSizeand theLayoutDirectiononce each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, andI18n.locale()answers it wherever text is resolved. -
onLayout
protected void onLayout()Description copied from class:WidgetContainers position children here (measure +Widget.layoutBox(float, float, float, float)per child). -
onPaint
Description copied from class:WidgetWidget's own background/content, in local coordinates.
-