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.

2. Windows and navigation

What you’ll learn: the screen unit (Window), where to build the UI, and the stack-based navigation model. Prerequisites: The big picture.

Complete example (copy, paste, and run)

Two screens navigating by stack (push/hide), with data passed through the constructor. MainWindow is the list; TelaDetalhe is the detail. Compiles as is.

package com.exemplo;

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

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

      add(LAY_AUTO, new Label("Minhas tarefas"));

      Button abrir = new Button("Abrir tarefa 42");
      abrir.onAction(c -> new TelaDetalhe(42).show());   // push: stacks the detail
      add(LAY_AUTO, abrir);
   }
}

class TelaDetalhe extends Window
{
   private final int id;

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

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

      add(LAY_AUTO, new Label("Tarefa " + id));

      Button voltar = new Button("Voltar");
      voltar.onAction(c -> hide());                       // pop: unstacks, returns to the list
      add(LAY_AUTO, voltar);
   }
}

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

Window and onShow()

Each screen is a subclass of Window (which is a Component). Build the UI in onShow() — with super.onShow() — where the bounds are already valid (never in the constructor).

The navigation stack (LIFO)

show() pushes a window; hide() pops it. The top window receives the input.

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

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

Passing data and returning values

  • Go to a screen with data: through the constructor (new TelaDetalhe(42).show()).
  • Return a value: the pickers use show(onAnswer); ordinary screens use a constructor callback; dialogs (Alert) respond via buttonAction (see Returning values).

What you build in this step

The two-screen skeleton of the guiding-thread app: list → detail, navigating between each other.

Recap

Screen = Window; UI in onShow()+super.onShow(); show()/hide() = push/pop; data through the constructor.

Next steps

→ Thinking in components

See also

Was this page helpful?