This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
TextArea
TextArea is the multiline text input. On top of the TextInput base, it adds: word-wrap, line structure, vertical scrolling, 2D coordinate mapping and multiline layout. It supports icons on the right (one per visible line) and a scrollable read-only mode (to display long text that the user only scrolls through).
Unlike TextField, TextArea has no mask or password mode; ENTER inserts a line break and getText() preserves the \n.
🟡 · Package:
dev.crossfly.ui· Extends:TextInput· Style:TextAreaStyle
When to use
- Notes, comments, descriptions, addresses — any multi-line text.
- Displaying a long scrollable block (with
editable=false).
When NOT to use
- Single-line input (name, email, value) → use
TextField. - Mask / password mode → use
TextField(TextAreadoes not support them).
Appearance
Rectangle with background/border from the TextAreaStyle, text wrapped into lines (word-wrap at the inner width), with vertical scrolling when the content exceeds the height. The preferred height comes from rowCount (number of visible lines) × line height + ingap. Right-side icons, when defined, occupy their own column, one per visible line.
``
Complete example (copy, paste and run)
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());
// Multiline field; LAY_FILL gives height to the scrollable area
TextArea obs = new TextArea().caption("Observações");
add(LAY_FILL, obs);
// Output label
Label saida = new Label("Escreva algo e toque em Enviar");
add(LAY_AUTO, saida);
// There is no onChange per key: read getText() on submit (preserves the \n)
Button enviar = new Button("Enviar")
.onAction(c -> saida.setText("Você escreveu " + obs.getText().length() + " caracteres"));
add(LAY_AUTO, enviar);
}
}
The snippets below show only the core (what goes inside
onShow()). To run them, place them in theMainWindowskeleton above.
Basic usage
TextArea obs = new TextArea().caption("Observações");
container.add(0.4f, obs);
// ...
String texto = obs.getText(); // preserves the \n
Constructors
| Constructor | Description |
|---|---|
TextArea() |
empty |
TextArea(String text) |
with initial text (\r\n/\r normalized to \n) |
Properties and customization
| Property / method | Type | Default | What it does |
|---|---|---|---|
text(String) / setText(String) |
TextArea / void |
— | sets the text (normalizes line breaks; cursor at start) |
getText() |
String |
— | raw text, preserving \n |
caption(String) |
TextArea (fluent) |
null |
placeholder |
rightIcons(Icon...) |
TextArea (fluent) |
— | right-side icons, one per visible line |
rightIconAction(int row, Action) |
TextArea (fluent) |
— | action of the icon on line row (0-based) |
clearText() |
void |
— | clears all text |
getNumberOfTextLines() |
int |
— | total logical lines (word-wrapped) |
scrollToTop() / scrollToBottom() / scrollToLine(int) |
void |
— | programmatic scrolling |
style .rowCount(int) |
int |
— | no. of visible lines (sets the preferred height) |
style .maxLength(int) |
int |
0 (unlimited) |
character limit |
style .validChars(String) |
String |
null |
allowed characters (\n always accepted) |
style .editable(false) |
boolean |
true |
scrollable read-only |
style .spaceBetweenLines(int) |
int |
— | extra space between lines |
Callbacks and events
| Callback | When it fires |
|---|---|
onAction(Action) (inherited) |
on onTouchUp, after opening the keyboard |
onFocus() / onBlur() (inherited) |
focus gained / lost |
rightIconAction(row, Action) |
on tapping (and releasing over) that line’s icon |
States
- focused: blinking cursor, keyboard opens on tap; ↑/↓ arrows navigate between lines.
- selection: 2D selection by dragging; long-touch selects all and opens the
ActionSheet. - read-only (
editable=false): no cursor/editing; dragging scrolls the content; the mouse wheel also scrolls.
Notes field with a limit
TextArea obs = new TextArea().caption("Observações");
obs.style(Styles.theme()
.textArea(State.NORMAL)
.rowCount(4)
.maxLength(500));
container.add(LAY_AUTO, obs);
Read-only, scrollable text block
TextArea termos = new TextArea(textoDosTermos);
termos.style(Styles.theme()
.textArea(State.NORMAL)
.editable(false) // scroll only, no editing
.rowCount(8));
container.add(LAY_FILL, termos);
termos.scrollToTop();
Lines with an action icon on the right
TextArea lista = new TextArea("Item A\nItem B\nItem C");
lista.rightIcons(
new MaterialIcon(""), // "delete" on line 0
new MaterialIcon(""),
new MaterialIcon(""));
lista.rightIconAction(0, c -> removerLinha(0));
container.add(0.3f, lista);
Best practices
- Set
rowCountin the style to control the visible height; combine it withLAY_AUTOin the layout. - To display long text without editing, use
editable(false)— dragging then scrolls instead of selecting. - Use
getText()to persist (preserves\n);\r\nnormalization is already done on input.
Common mistakes
- Expecting a mask or password mode:
TextAreadoes not support them — useTextField. - Defining too many
rightIcons: only those up tovisibleRows(no. of visible lines) are drawn; icons beyond that are ignored.