Button
Button é o componente interativo mais básico: exibe texto e/ou ícone e dispara uma ação ao ser tocado, com estado visual de pressionado (via ButtonStyle). Quando há texto e ícone, a posição relativa entre eles é controlada pelo enum TextPos. É também a base de outros widgets (por exemplo, Dropdown extends Button).
A ação é registrada com onAction(Action) (herdado de Component); o disparo ocorre no fluxo padrão de clique (runActions() em onTouchUp), não em onTouchDown.
🟢 · Pacote:
dev.crossfly.ui· Estende:Component· Estilo:ButtonStyle
Quando usar
- Qualquer ação tocável: salvar, confirmar, navegar, abrir um diálogo.
- Botão só-ícone (barra de ferramentas) ou só-texto (link/ação secundária).
Quando NÃO usar
Aparência
Texto e/ou ícone centralizados dentro do botão. Com ambos presentes, o bloco [ícone + gap + texto] é centralizado em ambos os eixos; o icongap define o espaçamento. O posicionamento segue TextPos:
TextPos |
Layout | isHorizontal() |
|---|---|---|
NONE |
texto e ícone sobrepostos (centrados) | false |
TEXT_AT_LEFT |
texto à esquerda do ícone | true |
TEXT_AT_RIGHT |
texto à direita do ícone | true |
TEXT_AT_TOP |
texto acima do ícone | false |
TEXT_AT_BOTTOM |
texto abaixo do ícone | false |
Se textPos == null, o padrão é sobreposição centralizada (equivalente a NONE).
``
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());
// Label que exibe quantas vezes o botão foi tocado
Label saida = new Label("Cliques: 0");
add(LAY_AUTO, saida);
// Contador mutável usado dentro do callback (array de 1 posição)
final int[] cliques = {0};
// Botão que incrementa o contador e atualiza o Label a cada toque
Button botao = new Button("Clique aqui")
.onAction(c -> saida.setText("Cliques: " + (++cliques[0])));
add(LAY_AUTO, botao);
}
}
Os trechos abaixo mostram só o miolo (o que vai dentro de
onShow()). Para rodar, coloque-os no esqueletoMainWindowacima.
Uso básico
Button b = new Button("Salvar").onAction(c -> salvar());
container.add(LAY_AUTO, b);
Construtores
| Construtor | Descrição |
|---|---|
Button(String text) |
botão só com texto |
Button(Icon icon) |
botão só com ícone |
Button(String text, Icon icon, TextPos textPos) |
texto + ícone com posição relativa |
Propriedades e personalização
| Propriedade / método | Tipo | Padrão | O que faz |
|---|---|---|---|
setText(String) |
void |
— | troca o texto, invalida layout e chama repaint() |
icon(Icon, TextPos) |
Button (fluente) |
— | define ícone e sua posição relativa ao texto |
text / icon / textPos |
campos públicos | — | conteúdo atual (podem ser lidos/atribuídos) |
estilo .pressable() |
— | — | habilita o realce de pressionado |
estilo .textAlign(Position, Position) |
Position |
tema | alinhamento do conteúdo |
estilo .autoWidth(Relative) / .autoHeight(Relative) |
Relative |
— | fixa o tamanho preferido |
getAutoWidth() / getAutoHeight(int) |
int |
— | tamanhos preferidos por conteúdo |
Callbacks e eventos
| Callback | Quando dispara |
|---|---|
onAction(Action) |
ao concluir o clique (touch-up), via runActions(). Retorna this, permitindo encadear (new Button(...).onAction(...).style(...)). |
O Action é c -> { ... }, onde c é o Component de origem; pode lançar Exception.
Estados
- pressed: enquanto pressionado, o
ButtonStyleaplica o estilo de pressão (com fade). Requerpressable()no estilo. - disabled:
setEnabled(false)aplica a aparência desabilitada e ignora toques.
Botão com ícone à direita do texto
Button proximo = new Button(
"Próximo", new MaterialIcon(""), TextPos.TEXT_AT_RIGHT);
container.add(LAY_AUTO, proximo);
Botão estilo “link” que limpa campos
Button clear = new Button("Clear").style(
Styles.theme().button(ButtonRole.LINK, State.NORMAL)
.pressable()
.textAlign(Position.CENTER, Position.CENTER));
clear.onAction(c -> {
nome.clearText();
email.clearText();
});
container.add(LAY_AUTO, clear);
Boas práticas
- Sempre passe
textPosquando o botão tem texto e ícone (senão ficam sobrepostos). - Use papéis do tema (
ButtonRole.PRIMARY/SECONDARY/LINK) para consistência visual. - Para espaçar botões, use
Gapouingap/outgap/frações do layout — oSpacerfoi removido (verspacing.md).
Erros comuns
text+iconsemtextPos: o resultado fica sobreposto (comportamento denull=NONE).- Esperar disparo em
onTouchDown: a ação dispara no fluxo padrão de clique (touch-up).