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.

Button

Button is the most basic interactive component: it displays text and/or an icon and fires an action when tapped, with a visual pressed state (via ButtonStyle). When there is text and an icon, their relative position is controlled by the enum TextPos. It is also the base of other widgets (for example, Dropdown extends Button).

The action is registered with onAction(Action) (inherited from Component); the trigger occurs in the standard click flow (runActions() in onTouchUp), not in onTouchDown.

🟢 · Package: dev.crossfly.ui · Extends: Component · Style: ButtonStyle

When to use

  • Any tappable action: save, confirm, navigate, open a dialog.
  • Icon-only button (toolbar) or text-only button (link/secondary action).

When NOT to use

  • Static label → use Label.
  • Persistent on/off toggle → use Switch/Option (see ui/).

Appearance

Text and/or icon centered inside the button. With both present, the [icon + gap + text] block is centered on both axes; icongap defines the spacing. Positioning follows TextPos:

TextPos Layout isHorizontal()
NONE text and icon overlapped (centered) false
TEXT_AT_LEFT text to the left of the icon true
TEXT_AT_RIGHT text to the right of the icon true
TEXT_AT_TOP text above the icon false
TEXT_AT_BOTTOM text below the icon false

If textPos == null, the default is centered overlap (equivalent to NONE).

``

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

      // Label that shows how many times the button was tapped
      Label saida = new Label("Cliques: 0");
      add(LAY_AUTO, saida);

      // Mutable counter used inside the callback (1-element array)
      final int[] cliques = {0};

      // Button that increments the counter and updates the Label on each tap
      Button botao = new Button("Clique aqui")
         .onAction(c -> saida.setText("Cliques: " + (++cliques[0])));
      add(LAY_AUTO, botao);
   }
}

The snippets below show only the core (what goes inside onShow()). To run them, place them in the MainWindow skeleton above.

Basic usage

Button b = new Button("Salvar").onAction(c -> salvar());
container.add(LAY_AUTO, b);

Constructors

Constructor Description
Button(String text) text-only button
Button(Icon icon) icon-only button
Button(String text, Icon icon, TextPos textPos) text + icon with relative position

Properties and customization

Property / method Type Default What it does
setText(String) void — swaps the text, invalidates layout and calls repaint()
icon(Icon, TextPos) Button (fluent) — sets the icon and its position relative to the text
text / icon / textPos public fields — current content (can be read/assigned)
style .pressable() — — enables the pressed highlight
style .textAlign(Position, Position) Position theme content alignment
style .autoWidth(Relative) / .autoHeight(Relative) Relative — fixes the preferred size
getAutoWidth() / getAutoHeight(int) int — content-based preferred sizes

Callbacks and events

Callback When it fires
onAction(Action) on completing the click (touch-up), via runActions(). Returns this, allowing chaining (new Button(...).onAction(...).style(...)).

The Action is c -> { ... }, where c is the originating Component; it may throw Exception.

States

  • pressed: while pressed, the ButtonStyle applies the pressed style (with fade). Requires pressable() in the style.
  • disabled: setEnabled(false) applies the disabled appearance and ignores touches.

Button with icon to the right of the text

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

Best practices

  • Always pass textPos when the button has text and an icon (otherwise they overlap).
  • Use theme roles (ButtonRole.PRIMARY/SECONDARY/LINK) for visual consistency.
  • To space buttons, use Gap or ingap/outgap/layout fractions — Spacer was removed (see spacing.md).

Common mistakes

  • text + icon without textPos: the result overlaps (null behavior = NONE).
  • Expecting the trigger on onTouchDown: the action fires in the standard click flow (touch-up).

See also

Was this page helpful?