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.

Navigate between screens

What you will learn

  • Move forward to a new screen (show()) and back (hide()).
  • Pass data to the destination screen.
  • Where to build each screen’s UI.

Prerequisites

Understand that every screen is a subclass of Window and that the UI is built in onShow().

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

      add(LAY_AUTO, new Label("Lista"));

      Button abrir = new Button("Abrir detalhe do item 42");
      abrir.onAction(c -> new TelaDetalhe(42).show());   // push (advance) — data via the constructor
      add(LAY_AUTO, abrir);
   }
}

/** Second screen: receives the id via the constructor and returns with hide(). */
class TelaDetalhe extends Window
{
   private final int id;

   public TelaDetalhe(int id) { this.id = id; }   // data comes via the constructor

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      add(LAY_AUTO, new Label("Detalhe do item " + id));

      Button voltar = new Button("Voltar");
      voltar.onAction(c -> hide());   // pop (back)
      add(LAY_AUTO, voltar);
   }
}

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

Move forward (push) and back (pop)

public class TelaLista extends Window {
   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      Button abrir = new Button("Abrir detalhe");
      abrir.onAction(c -> new TelaDetalhe(42).show());   // push (advance)
      add(LAY_AUTO, abrir);
   }
}

public class TelaDetalhe extends Window {
   private final int id;
   public TelaDetalhe(int id) { this.id = id; }          // data comes via the constructor
   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      add(LAY_AUTO, new Label("Detalhe do item " + id));
      Button voltar = new Button("Voltar");
      voltar.onAction(c -> hide());                       // pop (back)
      add(LAY_AUTO, voltar);
   }
}

Pass data to the next screen

There are no “route arguments”. Pass them through the constructor of the destination Window (like id above). For objects, pass the reference: new TelaCliente(cliente).show();.

Where to build the UI

  • onShow() (with super.onShow()): here Screen.width/height and the window bounds are already valid.
  • Do not build in the constructor — the bounds may not be ready.

Best practices

  • Load data off the paint thread and return with Component.onUI(...) to populate the UI.
  • Release resources (timers, cursors) in onRemove().

Common mistakes

  • Building the UI in the constructor (invalid bounds) or forgetting super.onShow().
  • Expecting a “back-stack with named arguments” — pass data through the constructor.

See also

Was this page helpful?