Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

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

  • Rótulo estático → use Label.
  • Alternância persistente liga/desliga → use Switch/Option (ver ui/).

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 esqueleto MainWindow acima.

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 ButtonStyle aplica o estilo de pressão (com fade). Requer pressable() 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);
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 textPos quando 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 Gap ou ingap/outgap/frações do layout — o Spacer foi removido (ver spacing.md).

Erros comuns

  • text + icon sem textPos: o resultado fica sobreposto (comportamento de null = NONE).
  • Esperar disparo em onTouchDown: a ação dispara no fluxo padrão de clique (touch-up).

Veja também

Esta página foi útil?