# Devolver valores de una pantalla

> Cómo recibir un resultado de vuelta — el patrón de callback y el patrón Picker/onAnswer.

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

# Devolver valores de una pantalla

Hay **dos** patrones, y elegir el correcto evita un bug común.

## ⚠️ Punto crítico
`Window.show(onAnswer)` **solo dispara el `onAnswer` si la ventana es un `Picker`** (internamente,
`hide()` hace `answer = this instanceof Picker ? getAnswer() : null` y solo llama al callback si
`answer != null`). Para una **pantalla común** (subclase de `Window`), `show(onAnswer)` **no** devuelve
valor — usa el patrón de **callback por el constructor**.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;
import dev.crossfly.util.*;   // RunnableWith

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

      Label resultado = new Label("Nenhuma escolha ainda");
      add(LAY_AUTO, resultado);

      Button escolher = new Button("Escolher opção");
      // Pantalla común → callback POR EL CONSTRUCTOR (show(cb) solo dispara en Picker).
      escolher.onAction(c ->
         new TelaSelecao(op -> resultado.setText("Escolheu: " + op)).show());
      add(LAY_AUTO, escolher);
   }
}

/** Pantalla común que devuelve un valor por el callback recibido en el constructor. */
class TelaSelecao extends Window
{
   private final RunnableWith<String> onEscolha;

   public TelaSelecao(RunnableWith<String> onEscolha) { this.onEscolha = onEscolha; }

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

      Button a = new Button("Opção A");
      a.onAction(c -> { onEscolha.run("A"); hide(); });   // devuelve y cierra
      add(LAY_AUTO, a);

      Button b = new Button("Opção B");
      b.onAction(c -> { onEscolha.run("B"); hide(); });
      add(LAY_AUTO, b);
   }
}
```
> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Patrón 1 — callback por el constructor (pantallas comunes)
Pasa un callback al constructor de la pantalla; ella lo invoca antes de `hide()`:
```java
public class TelaSelecao extends Window {
   private final RunnableWith<String> onEscolha;
   public TelaSelecao(RunnableWith<String> onEscolha) { this.onEscolha = onEscolha; }

   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      Button opa = new Button("Opção A");
      opa.onAction(c -> { onEscolha.run("A"); hide(); });   // devuelve y cierra
      add(LAY_AUTO, opa);
   }
}

// uso:
new TelaSelecao(resultado -> System.out.println("Escolheu: " + resultado)).show();
```

## Patrón 2 — Picker + `onAnswer` (selectores listos)
Los [pickers](/docs/ui/widgets/picker) (`DatePicker`, `TimePicker`, `ColorPicker`, etc.) ya implementan
`getAnswer()`. Para ellos, usa `show(onAnswer)`:
```java
new DatePicker().show(resposta -> {
   // solo dispara si != null (usuario confirmó; cancelar ⇒ getAnswer() nulo)
   System.out.println("Data: " + resposta);
});
```
Para crear tu propio selector, **extiende `Picker`** e implementa `getAnswer()`.

## ⚠️ Los diálogos NO usan `onAnswer`
`Alert` y `ActionSheet` extienden `Window` (no `Picker`), por lo que `show(callback)` **no** se dispara. La
respuesta viene por los **callbacks de los botones** (`buttonAction`) — ver [Diálogos y modales](/docs/ui/navigation/dialogs-and-modals).

## Buenas prácticas
- Pantallas comunes → **callback en el constructor**. Selectores → **`Picker` + `onAnswer`**.
- Para estado compartido entre pantallas, considera un **ViewModel/controller** (ver
  [arquitectura](/docs/best-practices)).

## Errores comunes
- Usar `minhaTela.show(cb)` esperando que el `cb` se dispare en una pantalla que **no** es `Picker` (no se dispara).
- Usar `alert.show(cb)` — el callback nunca se ejecuta; usa `buttonAction`.

## Ver también
- [Diálogos y modales](/docs/ui/navigation/dialogs-and-modals) · [Pickers (catálogo)](/docs/ui/widgets/picker)
