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 open and close a screen

Purpose. In CrossFly there are no “routes”: every screen is a Window and navigation is a stack. Opening a screen is show() (push); going back is hide() (pop). The screen’s UI must be built in onShow().

APIs used

  • Window.show() — pushes the window onto the EventsProcessor and calls onShow() (push). If called off the paint thread, it schedules and waits.
  • Window.hide() — pops the window and calls onRemove() (pop). Fires the reverse transition, if any.
  • Window.onShow() — lifecycle hook called by the framework on push; build the UI here. Always call super.onShow() first (it recomputes bounds and calls onAdd(true)).
  • EventsProcessor.topWindow() — returns the window at the top of the stack (the one that receives events).

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

      add(new Label("Tela inicial"));
      add(new Button("Abrir detalhe").onAction(e -> new OutraTela().show()));  // push
   }
}

/** Stacked screen; the "Back" button does pop (hide) and returns to MainWindow. */
class OutraTela extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();            // MANDATORY: recalculates bounds and fires onAdd()
      setLayout(new VerticalLayout());

      add(new Label("Detalhe do pedido"));
      add(new Button("Voltar").onAction(e -> hide()));  // pop: returns to the previous screen
   }
}

The snippet below shows only the core. To run it, place it inside the MainWindow skeleton above.

Minimal snippet

// verified in source: Window.show()/hide()/onShow(); super.onShow() does updateBounds()+onAdd(true)
public class MinhaTela extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();            // MANDATORY: recalculates bounds and fires onAdd()
      setLayout(new GridLayout());

      add(new Label("Detalhe do pedido"));
      add(new Button("Voltar").onAction(e -> hide()));  // pop: returns to the previous screen
   }
}

// Anywhere (e.g.: in the onAction of a button on the previous screen):
new MinhaTela().show();          // push: stacks and displays

Rules that avoid bugs:

  • Never build the UI in the constructor in a way that depends on the screen size — Screen.width/height is only stabilized once onShow() runs. Use onShow().
  • hide() closes its own window. To close the top window from outside, use EventsProcessor.topWindow().hide().
  • show() is safe off the paint thread: it forwards to the paint thread and waits.

Go deeper

Was this page helpful?