# How to open and close a screen

> Push and pop screens with show() and hide(), building the UI in onShow().

Source: https://crossfly.dev/docs/cookbook/nav/abrir-tela — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 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)
```java
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
```java
// 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
- [Navigate between screens](/docs/ui/navigation/navigate-between-screens) · [The window stack](/docs/ui/navigation/the-window-stack)
- Sibling recipe: [Receive a result from a screen](/docs/cookbook/nav/receber-resultado)
