TextArea
TextArea é a entrada de texto de múltiplas linhas. Sobre a base TextInput, adiciona: word-wrap, estrutura de linhas, rolagem vertical, mapeamento de coordenadas 2D e layout multilinha. Suporta ícones à direita (um por linha visível) e um modo read-only rolável (para exibir texto longo que o usuário só percorre).
Diferente do TextField, o TextArea não tem máscara nem modo senha; ENTER insere quebra de linha e getText() preserva os \n.
🟡 · Pacote:
dev.crossfly.ui· Estende:TextInput· Estilo:TextAreaStyle
Quando usar
- Observações, comentários, descrições, endereços — qualquer texto de várias linhas.
- Exibir um bloco longo rolável (com
editable=false).
Quando NÃO usar
- Entrada de uma linha (nome, e-mail, valor) → use
TextField. - Máscara / modo senha → use
TextField(oTextAreanão os suporta).
Aparência
Retângulo com fundo/borda do TextAreaStyle, texto quebrado em linhas (word-wrap na largura interna), com rolagem vertical quando o conteúdo excede a altura. A altura preferida vem de rowCount (número de linhas visíveis) × altura de linha + ingap. Ícones à direita, quando definidos, ocupam uma coluna própria, um por linha visível.
``
Exemplo completo (copiar, colar e rodar)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
// Campo multilinha; LAY_FILL dá altura à área rolável
TextArea obs = new TextArea().caption("Observações");
add(LAY_FILL, obs);
// Label de saída
Label saida = new Label("Escreva algo e toque em Enviar");
add(LAY_AUTO, saida);
// Não há onChange por tecla: leia getText() no envio (preserva os \n)
Button enviar = new Button("Enviar")
.onAction(c -> saida.setText("Você escreveu " + obs.getText().length() + " caracteres"));
add(LAY_AUTO, enviar);
}
}
Os trechos abaixo mostram só o miolo (o que vai dentro de
onShow()). Para rodar, coloque-os no esqueletoMainWindowacima.
Uso básico
TextArea obs = new TextArea().caption("Observações");
container.add(0.4f, obs);
// ...
String texto = obs.getText(); // preserva os \n
Construtores
| Construtor | Descrição |
|---|---|
TextArea() |
vazio |
TextArea(String text) |
com texto inicial (\r\n/\r normalizados para \n) |
Propriedades e personalização
| Propriedade / método | Tipo | Padrão | O que faz |
|---|---|---|---|
text(String) / setText(String) |
TextArea / void |
— | define o texto (normaliza quebras; cursor ao início) |
getText() |
String |
— | texto bruto, preservando \n |
caption(String) |
TextArea (fluente) |
null |
placeholder |
rightIcons(Icon...) |
TextArea (fluente) |
— | ícones à direita, um por linha visível |
rightIconAction(int row, Action) |
TextArea (fluente) |
— | ação do ícone da linha row (0-based) |
clearText() |
void |
— | limpa todo o texto |
getNumberOfTextLines() |
int |
— | total de linhas lógicas (word-wrapped) |
scrollToTop() / scrollToBottom() / scrollToLine(int) |
void |
— | rolagem programática |
estilo .rowCount(int) |
int |
— | nº de linhas visíveis (define a altura preferida) |
estilo .maxLength(int) |
int |
0 (ilimitado) |
limite de caracteres |
estilo .validChars(String) |
String |
null |
caracteres permitidos (\n sempre aceito) |
estilo .editable(false) |
boolean |
true |
read-only rolável |
estilo .spaceBetweenLines(int) |
int |
— | espaço extra entre linhas |
Callbacks e eventos
| Callback | Quando dispara |
|---|---|
onAction(Action) (herdado) |
em onTouchUp, após abrir o teclado |
onFocus() / onBlur() (herdados) |
ganho / perda de foco |
rightIconAction(row, Action) |
ao tocar (e soltar sobre) o ícone daquela linha |
Estados
- focused: cursor piscando, teclado abre no toque; setas ↑/↓ navegam entre linhas.
- selection: seleção 2D por arrasto; long-touch seleciona tudo e abre o
ActionSheet. - read-only (
editable=false): sem cursor/edição; o arrasto rola o conteúdo; roda do mouse também rola.
Campo de observações com limite
TextArea obs = new TextArea().caption("Observações");
obs.style(Styles.theme()
.textArea(State.NORMAL)
.rowCount(4)
.maxLength(500));
container.add(LAY_AUTO, obs);
Bloco de texto somente-leitura, rolável
TextArea termos = new TextArea(textoDosTermos);
termos.style(Styles.theme()
.textArea(State.NORMAL)
.editable(false) // apenas rolar, sem editar
.rowCount(8));
container.add(LAY_FILL, termos);
termos.scrollToTop();
Linhas com ícone de ação à direita
TextArea lista = new TextArea("Item A\nItem B\nItem C");
lista.rightIcons(
new MaterialIcon(""), // "delete" na linha 0
new MaterialIcon(""),
new MaterialIcon(""));
lista.rightIconAction(0, c -> removerLinha(0));
container.add(0.3f, lista);
Boas práticas
- Defina
rowCountno estilo para controlar a altura visível; combine comLAY_AUTOno layout. - Para exibir texto longo sem edição, use
editable(false)— o arrasto passa a rolar em vez de selecionar. - Use
getText()para persistir (preserva\n); normalização de\r\njá é feita na entrada.
Erros comuns
- Esperar máscara ou modo senha: o
TextAreanão os suporta — useTextField. - Definir muitos
rightIcons: só são desenhados atévisibleRows(nº de linhas visíveis); ícones além disso são ignorados.