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.

ActionSheet

ActionSheet is the iOS-style action sheet: a rounded card anchored to the bottom of the screen with a list of option buttons and a separate Cancel button below it. When there are too many options to fit, they spread across multiple columns (up to maxColumns). Behind the sheet there is a gray “scrim” (fullscreenColor = 0xD0DDDDDD) that produces the modal effect.

🟢 · Package: dev.crossfly.ui · Extends: Window · Style: ComponentStyle/WindowStyle

When to use

  • Contextual action menu over an item (share, rename, delete…).
  • When you want to visually highlight a destructive action (red), as in the iOS pattern.

When NOT to use

  • Simple yes/no choice or confirmation with a message → use Alert.
  • Passive/ephemeral feedback → use Hint.

Appearance

A bottom card about 92% of the screen width with the options stacked, separated by thin lines, and the fully rounded Cancel button right below it. The screen background is covered by a gray scrim.

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

      Button abrir = new Button("Abrir folha de ações");
      abrir.onAction(c ->
      {
         ActionSheet sheet = new ActionSheet("Cancelar", "Compartilhar", "Renomear", "Excluir");
         sheet.buttonAction(0, origin -> { sheet.hide(); Hint.show("Compartilhar", 2000); });
         sheet.buttonAction(1, origin -> { sheet.hide(); Hint.show("Renomear", 2000); });
         sheet.buttonAction(2, origin -> { sheet.hide(); Hint.show("Excluído", 2000); });
         // Destructive action in red
         sheet.buttonStyle(2, ActionSheet.createDefaultButtonStyle().textColor(0xFFFF0000));
         sheet.show();
      });
      add(LAY_AUTO, abrir);
   }
}

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

Basic usage

ActionSheet sheet = new ActionSheet("Cancelar", "Compartilhar", "Renomear", "Excluir");
sheet.buttonAction(0, origin -> { compartilhar(); sheet.hide(); });
sheet.buttonAction(1, origin -> { renomear();     sheet.hide(); });
sheet.buttonAction(2, origin -> { excluir();      sheet.hide(); });
sheet.show();

Constructors

Constructor Description
ActionSheet(String cancelText, String... buttonTexts) cancelText (default "Cancel") and the option texts (empty/null → {"OK"}).

Properties and customization

Property / method Type Default What it does
buttonStyle(ComponentStyle) fluent skin Default style for all options.
buttonStyle(int index, ComponentStyle) fluent — Style override for a specific option.
buttonStyle(int index) ComponentStyle — Resolved style of the option.
cancelStyle(ComponentStyle) fluent skin Style of the Cancel button.
containerStyle(ComponentStyle) fluent skin Style of the card (corner radius).
maxColumns(int) fluent 1 Maximum columns on overflow (>=1).
getButton(int) / getCancelButton() Button — Buttons after show()/onAdd.
createDefaultButtonStyle() / createDefaultCancelStyle() / createDefaultContainerStyle() ComponentStyle (static) — Factories for the default styles.

Callbacks and events

Callback When it fires
buttonAction(int index, Component.Action action) on tapping option index (0-based).
cancelAction(Component.Action action) on tapping the Cancel button.

Since ActionSheet extends Window (not Picker), the response comes through these callbacks, not through show(onAnswer). There is no getAnswer(). The Component.Action lambda is void run(Component origin) — do not return a value.

States

  • Option without a callback → receives the default action hide() (closes the sheet).
  • Option with a callback → runs the callback; if it does not call hide(), the sheet stays open.
  • Tap on the scrim (outside the sheet) or back → closes when canHide is active (default).

Highlight the destructive action and allow 2 columns

ActionSheet sheet = new ActionSheet("Cancelar", "Compartilhar", "Renomear", "Excluir");

sheet.buttonAction(0, origin -> { compartilhar(); sheet.hide(); });
sheet.buttonAction(1, origin -> { renomear();     sheet.hide(); });
sheet.buttonAction(2, origin -> { excluir();      sheet.hide(); });

// Destructive option in red
sheet.buttonStyle(2, ActionSheet.createDefaultButtonStyle().textColor(0xFFFF0000));

// Allow up to 2 columns if there are many options
sheet.maxColumns(2);

sheet.show();

Best practices

  • Use it for a set of contextual actions; for a simple yes/no, prefer Alert.
  • Highlight destructive actions with buttonStyle(index, ...) in red.
  • On long lists, set maxColumns so the sheet does not exceed the screen.

Common mistakes

  • Callback without hide() — the sheet stays open; the automatic hide() only happens when there is no registered callback.
  • Making the lambda return a value — Component.Action.run(...) is void.
  • Accessing getButton(i) before show() — the buttons are created in onAdd.

See also

Was this page helpful?