Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

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 (TextArea does 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 the MainWindow skeleton 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 rowCount in the style to control the visible height; combine it with LAY_AUTO in the layout.
  • To display long text without editing, use editable(false) — dragging then scrolls instead of selecting.
  • Use getText() to persist (preserves \n); \r\n normalization is already done on input.

Common mistakes

  • Expecting a mask or password mode: TextArea does not support them — use TextField.
  • Defining too many rightIcons: only those up to visibleRows (no. of visible lines) are drawn; icons beyond that are ignored.

See also

Was this page helpful?