# Navegar entre pantallas

> Avanzar y volver entre pantallas (push/pop) y pasar datos a la pantalla de destino.

Source: https://crossfly.dev/es/docs/ui/navigation/navigate-between-screens — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Navegar entre pantallas

## Qué vas a aprender
- Avanzar a una nueva pantalla (`show()`) y volver (`hide()`).
- **Pasar datos** a la pantalla de destino.
- Dónde montar la UI de cada pantalla.

## Requisitos previos
Entender que toda pantalla es una subclase de `Window` y que la UI se monta en `onShow()`.

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: 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 (avanza) — datos por el constructor
      add(LAY_AUTO, abrir);
   }
}

/** Segunda pantalla: recibe el id por el constructor y vuelve con hide(). */
class TelaDetalhe extends Window
{
   private final int id;

   public TelaDetalhe(int id) { this.id = id; }   // los datos vienen por el 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 (vuelve)
      add(LAY_AUTO, voltar);
   }
}
```
> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Avanzar (push) y volver (pop)
```java
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 (avanza)
      add(LAY_AUTO, abrir);
   }
}

public class TelaDetalhe extends Window {
   private final int id;
   public TelaDetalhe(int id) { this.id = id; }          // los datos vienen por el 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 (vuelve)
      add(LAY_AUTO, voltar);
   }
}
```

## Pasar datos a la pantalla siguiente
No existen "argumentos de ruta". **Pásalos por el constructor** de la `Window` de destino (como `id` arriba).
Para objetos, pasa la referencia: `new TelaCliente(cliente).show();`.

## Dónde montar la UI
- **`onShow()`** (con `super.onShow()`): aquí `Screen.width/height` y los bounds de la ventana ya son válidos.
- **No** montes en el constructor — los bounds podrían no estar listos.

## Buenas prácticas
- Carga datos **fuera del paint thread** y vuelve con `Component.onUI(...)` para llenar la UI.
- Libera recursos (timers, cursores) en `onRemove()`.

## Errores comunes
- Montar la UI en el constructor (bounds inválidos) u olvidar `super.onShow()`.
- Esperar un "back-stack con argumentos nombrados" — pasa los datos por el constructor.

## Ver también
- [Devolver valores de una pantalla](/docs/ui/navigation/returning-results) · [La pila de ventanas](/docs/ui/navigation/the-window-stack)
