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

Como usar checkbox e radio (Option e Group)

Propósito. Oferecer opções marcáveis. Um Option isolado funciona como checkbox (liga/desliga independente). Vários Option no mesmo Group funcionam como radio buttons (apenas um marcado por vez). Use checkbox para escolhas independentes; radio para escolha única entre alternativas.

APIs usadas

  • new Option() / new Option(String text) — cria a opção (com ou sem rótulo). Começa desmarcada.
  • option.checked(boolean checked) — define o estado inicial sem animação (fluente).
  • option.setChecked(boolean checked) — muda o estado com animação de crossfade.
  • option.isChecked() — retorna o estado atual (boolean).
  • option.toggle() — inverte o estado (chamado internamente no toque).
  • option.onAction(Component.Action action) — callback disparado quando o estado muda por toque do usuário.
  • new Group() — grupo de seleção mutuamente exclusiva.
  • option.group(Group g) — associa a opção ao grupo (transforma em radio).
  • group.fade(boolean) — habilita transição animada de cor ao trocar a seleção.

Comportamento não óbvio (confirmado na fonte):

  • Em um Group, tocar na opção já marcada não a desmarca (toggle() retorna cedo se checked && getGroup() != null) — igual ao rádio: só troca ao escolher outra.
  • onAction só dispara se o estado realmente mudou (if (checked != prev) runActions()).
  • Marcar via checked(true) numa opção de grupo já notifica o grupo e desmarca as demais.

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());

      // ── Checkbox (Option isolado) ──
      Option aceito = new Option("Aceito os termos");
      aceito.checked(false);                 // estado inicial, sem animação
      aceito.onAction(o -> atualizarBotao(aceito.isChecked()));
      add(aceito);

      // ── Radio (vários Option no mesmo Group) ──
      Group entrega = new Group();

      Option padrao   = new Option("Entrega padrão").group(entrega);
      Option expresso = new Option("Entrega expressa").group(entrega);

      padrao.checked(true);                  // seleção inicial do grupo

      expresso.onAction(o -> escolherFrete("EXPRESSO"));
      padrao.onAction(o -> escolherFrete("PADRAO"));

      add(padrao);
      add(expresso);
   }

   private void atualizarBotao(boolean aceito)
   {
      // ... habilitar/desabilitar o botão conforme o checkbox ...
   }

   private void escolherFrete(String tipo)
   {
      // ... reagir à escolha do frete ...
   }
}

O trecho abaixo mostra só o miolo. Para rodar, coloque-o no esqueleto MainWindow acima.

Trecho mínimo

// ── Checkbox (Option isolado) ──
Option aceito = new Option("Aceito os termos");
aceito.checked(false);                 // estado inicial, sem animação
aceito.onAction(o -> atualizarBotao(aceito.isChecked()));
add(aceito);

// ── Radio (vários Option no mesmo Group) ──
Group entrega = new Group();

Option padrao  = new Option("Entrega padrão").group(entrega);
Option expresso = new Option("Entrega expressa").group(entrega);

padrao.checked(true);                  // seleção inicial do grupo

expresso.onAction(o -> escolherFrete("EXPRESSO"));
padrao.onAction(o -> escolherFrete("PADRAO"));

add(padrao);
add(expresso);

Nota de verificação (código 2026). Confirmado: Option implementa Component.Checkable e AlphaAnimation.Animate; Group.select(sender) desmarca os demais membros (Option/Switch) automaticamente. Group.fade (default false) controla se a troca é animada. Não há “valor” no Group: para saber a seleção, verifique isChecked() em cada Option, ou guarde a referência escolhida no callback.

Aprofunde-se

Esta página foi útil?