# Label

> Non-interactive component for displaying text (with word-wrap) and/or read-only icons.

Source: https://crossfly.dev/docs/ui/widgets/label — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Label

`Label` is the most widely used **display** widget: it shows read-only text, with automatic line wrapping (word-wrap), multiple lines (explicit via `\n` or automatic) and optional icons on the left and/or right. It does not respond to touch — for actions use [`Button`](/docs/ui/widgets/button); for editable text use [`TextField`](/docs/ui/widgets/textfield)/[`TextArea`](/docs/ui/widgets/textarea).

Rendering is delegated to the active `Design`: the `Label` only computes coordinates in `onLayout()` and exposes public fields that the `Design` consumes (font, colors and borders come from the `LabelStyle`).

> 🟢 · **Package:** `dev.crossfly.ui` · **Extends:** `Component` · **Style:** `LabelStyle`

## When to use
- Titles, subtitles, captions and read-only values.
- Text with an informative icon on the left or right.
- Blocks of text that need to wrap across multiple lines.

## When NOT to use
- Editable text → use [`TextField`](/docs/ui/widgets/textfield) / [`TextArea`](/docs/ui/widgets/textarea).
- Touchable / clickable element → use [`Button`](/docs/ui/widgets/button) (the `Label` does not respond to touch).

## Appearance
The text is rendered within the internal area (after `ingap`), aligned horizontally and vertically according to `LabelStyle.textAlignH`/`textAlignV`. The left icon sits flush against the internal left edge; the right icon against the internal right edge; the text occupies the space between them.

``

## Complete example (copy, paste and run)
```java
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());

      // Read-only Label that will be updated by the button
      Label saida = new Label("Toque no botão abaixo");
      add(LAY_AUTO, saida);

      // Button that mutates the Label's text (Label.setText is fluent and returns Label)
      Button ola = new Button("Dizer olá").onAction(c -> saida.setText("Olá, mundo!"));
      add(LAY_AUTO, ola);
   }
}
```

> The snippets below show **only the core** (what goes inside `onShow()`). To run them, place them in the `MainWindow` skeleton above.

## Basic usage
```java
Label hello = new Label("Olá, mundo!");
container.add(LAY_AUTO, hello);
```

## Constructors
| Constructor | Description |
|---|---|
| `Label()` | empty label (`text = ""`) |
| `Label(String text)` | text label |
| `Label(Icon onlIcon)` | icon-only label (icon on the left) |

## Properties and customization
| Property / method | Type | Default | What it does |
|---|---|---|---|
| `setText(String)` | `Label` (fluent) | — | swaps the text; invalidates the layout **only if** the value changed |
| `leftIcon(Icon)` | `Label` (fluent) | `null` | sets the icon to the left of the text |
| `rightIcon(Icon)` | `Label` (fluent) | `null` | sets the icon to the right of the text |
| `text` | `String` (public field) | `""` | current content (may contain `\n`) |
| style `.textAlign(Position, Position)` | `Position` | theme | horizontal/vertical text alignment |
| style `.backColor(int)` / `.borderColor(int)` | ARGB | theme | background/border (use `0` for transparent) |
| `getAutoWidth()` / `getAutoHeight(int)` | `int` | — | preferred sizes (used by the layout) |
| `Label.wordWrap(String, Font, int)` *(static)* | `String[]` | — | line-wrapping utility by width |

> `setText(String)` returns `Label` (for fluency), **not** `void` — that is why `Label` does not declare `implements TextComponent`, despite exposing `setText`/`text`.

## Callbacks and events
None. `Label` is non-interactive — it fires neither `onAction` nor touch events.

## States
No interaction states (there is no `pressed`/`focused`). The visual changes only with the applied style or via `setEnabled(false)` (disabled appearance, according to the `Design`).

### Left icon and subtitle without background
```java
// Label with an icon on the left (Material "info")
Label info = new Label("Informação")
   .leftIcon(new MaterialIcon(""));
container.add(LAY_AUTO, info);

// Left-aligned subtitle, no background/border
Label sub = new Label("Lista:").style(
   Styles.theme().label(LabelRole.SUBTITLE)
      .backColor(0)
      .borderColor(0)
      .textAlign(Position.START, Position.CENTER));
container.add(LAY_AUTO, sub);
```

### Multiline (word-wrap + explicit `\n`)
```java
// Explicit breaks
Label endereco = new Label("Rua das Flores, 123\nCentro\n01000-000");

// Automatic word-wrap: give the Label a width (LAY_FILL) for the break to occur
Label paragrafo = new Label(
   "Este texto longo quebra automaticamente em várias linhas quando "
 + "a largura disponível é menor que a largura do texto.");
container.add(LAY_FILL, paragrafo);
```

## Best practices
- For word-wrap, make sure the layout gives the `Label` a **width** (e.g. `add(LAY_FILL, label)` in a `VerticalLayout`). Without a known width, only the explicit `\n` are counted toward the height.
- Use theme roles (`LabelRole.TITLE`/`SUBTITLE`/…) instead of hard-coding font/color.

## Common mistakes
- **Expecting word-wrap without a defined width:** if the width is `0`/unknown during the height calculation, only the explicit `\n` breaks count. Give the `Label` a width.
- **Confusing `setText` with the `TextComponent.setText` contract:** here `setText` returns `Label`, not `void`; the `Label` does not implement `TextComponent`.

## See also
- Area guide: [`ui/`](/docs/ui) · Recipes: [`cookbook/`](/docs/cookbook)
- Concept ("everything is a `Component`"): [`concepts/`](/docs/concepts)
- Related components: [`Button`](/docs/ui/widgets/button) · [`TextField`](/docs/ui/widgets/textfield) · [`ImageView`](/docs/ui/widgets/imageview)
