# Como abrir e fechar uma tela

> Empilhar (push) e desempilhar (pop) telas com show() e hide(), montando a UI em onShow().

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

# Como abrir e fechar uma tela

**Propósito.** No CrossFly não há "rotas": toda tela é uma `Window` e a navegação é uma **pilha**. Abrir uma tela é `show()` (push); voltar é `hide()` (pop). A UI da tela deve ser montada em `onShow()`.

## APIs usadas
- `Window.show()` — empilha a janela no `EventsProcessor` e chama `onShow()` (push). Se chamado fora da paint thread, agenda e aguarda.
- `Window.hide()` — desempilha a janela e chama `onRemove()` (pop). Dispara a transição reversa, se houver.
- `Window.onShow()` — gancho de ciclo de vida chamado pelo framework ao empilhar; monte a UI aqui. **Sempre chame `super.onShow()` primeiro** (ele recalcula bounds e chama `onAdd(true)`).
- `EventsProcessor.topWindow()` — retorna a janela no topo da pilha (a que recebe eventos).

## Exemplo completo (copiar, colar e rodar)
```java
package com.exemplo;

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

/** Tela principal executável. Aponte o launcher (classname) e rode: 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
   }
}

/** Tela empilhada; o botão "Voltar" faz pop (hide) e retorna à MainWindow. */
class OutraTela extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();            // OBRIGATÓRIO: recalcula bounds e dispara onAdd()
      setLayout(new VerticalLayout());

      add(new Label("Detalhe do pedido"));
      add(new Button("Voltar").onAction(e -> hide()));  // pop: volta à tela anterior
   }
}
```

> O trecho abaixo mostra **só o miolo**. Para rodar, coloque-o no esqueleto `MainWindow` acima.

## Trecho mínimo
```java
// verificado na fonte: Window.show()/hide()/onShow(); super.onShow() faz updateBounds()+onAdd(true)
public class MinhaTela extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();            // OBRIGATÓRIO: recalcula bounds e dispara onAdd()
      setLayout(new GridLayout());

      add(new Label("Detalhe do pedido"));
      add(new Button("Voltar").onAction(e -> hide()));  // pop: volta à tela anterior
   }
}

// Em qualquer lugar (ex.: no onAction de um botão da tela anterior):
new MinhaTela().show();          // push: empilha e exibe
```

Regras que evitam bugs:

- **Nunca monte a UI no construtor** que dependa do tamanho de tela — `Screen.width/height` só está estabilizado quando `onShow()` roda. Use `onShow()`.
- `hide()` fecha **a própria** janela. Para fechar a janela do topo a partir de fora, use `EventsProcessor.topWindow().hide()`.
- `show()` é seguro fora da paint thread: ele reencaminha para a thread de pintura e aguarda.

## Aprofunde-se
- [Navegar entre telas](/docs/ui/navigation/navigate-between-screens) · [A pilha de janelas](/docs/ui/navigation/the-window-stack)
- Receita irmã: [Receber resultado de uma tela](/docs/cookbook/nav/receber-resultado)
