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.

How to create a clickable card

Purpose. Create a “card” (a Component with a background, rounded border and internal content) that reacts to touch, applying a visual highlight when pressed and triggering an action. Use it for list items, dashboard tiles, shortcuts, etc.

APIs used

  • new Component() — everything in CrossFly is a Component; a card is just a Component with a style and layout.
  • component.style(ComponentStyle s) — applies the style (background, border, radius). Returns <T extends Component> for chaining.
  • ComponentStyle.pressable() — marks the style as Pressable.YES: the component gets highlighted when pressed and starts receiving touch events.
  • component.setLayout(Layout l) — sets the layout manager for the internal content (e.g., new GridLayout(...)).
  • component.add(Object... params) — adds children according to the active layout.
  • component.onAction(Component.Action action) — registers the callback triggered on touch (only works if the style is pressable).
  • Styles.component() — returns a base ComponentStyle from the active Skin for you to customize.

Complete example (copy, paste and run)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

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

      // Card style: white background, rounded corners, clickable
      ComponentStyle cardStyle = Styles.component()
         .backColor(0xFFFFFFFF)
         .borderColor(0xFFE0E0E0)
         .borderRadius(0.5f)   // radius in font units
         .ingap(Gap.ofFont(0.8f))
         .pressable();         // ← makes the card touch-sensitive

      Component card = new Component()
         .style(cardStyle);

      // Inner content in a column (title + subtitle)
      card.setLayout(new GridLayout(Position.START, Position.CENTER));
      card.add(new Label("Pedido #1234"));
      card.add(new Label("Entregue hoje"));

      // Action on tap
      card.onAction(origin -> abrirDetalhe(1234));

      // Adds the card to the current screen/container
      add(card);
   }

   private void abrirDetalhe(int pedido)
   {
      // ... open the order detail screen ...
   }
}

The snippet below shows just the core. To run it, place it in the MainWindow skeleton above.

Minimal snippet

// Card style: white background, rounded corners, clickable
ComponentStyle cardStyle = Styles.component()
   .backColor(0xFFFFFFFF)
   .borderColor(0xFFE0E0E0)
   .borderRadius(0.5f)   // radius in font units
   .ingap(Gap.ofFont(0.8f))
   .pressable();         // ← makes the card touch-sensitive

Component card = new Component()
   .style(cardStyle);

// Inner content in a column (title + subtitle)
card.setLayout(new GridLayout(Position.START, Position.CENTER));
card.add(new Label("Pedido #1234"));
card.add(new Label("Entregue hoje"));

// Action on tap
card.onAction(origin -> abrirDetalhe(1234));

// Adds the card to the current screen/container
add(card);

Verification note (2026 code). Confirmed in source: Component.style(ComponentStyle) returns <T extends Component> T (fluent), ComponentStyle.pressable() sets Pressable.YES, and Component.onAction(Action) sets hasAction(true). The pressed highlight uses the per-state styles (default/pressed) resolved by the Skin — see Chapter 10 only if you need to customize the pressed state. Without pressable(), onAction does not fire because the component is not a touch target.

Dig deeper

Was this page helpful?