# How to receive a result from a screen

> Open a screen and receive a value back — pickers via show(onAnswer), regular screens via a constructor callback.

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

# How to receive a result from a screen

**Purpose.** You open a screen for the user to choose/fill in something and need the value back. CrossFly has **two distinct mechanisms**: `show(onAnswer)` for **pickers**, and a **constructor callback** for regular screens.

## APIs used
- `Window.show(RunnableWith<Object> onAnswer)` — registers a result callback. In the source, the callback **only fires if `getAnswer() != null`**, and `Window.getAnswer()` returns `null` by default — **only `Picker` overrides** `getAnswer()`. In other words: for regular screens this callback **never fires**.
- `Picker.getAnswer()` — returns the chosen value, or `null` if cancelled. Only pickers implement it.
- Constructor callback — the pattern for regular screens: pass a `RunnableWith<T>` (or your own interface) to the screen's constructor and invoke it before `hide()`.

## Complete example (copy, paste, and run)
```java
package com.exemplo;

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

/** Runnable main screen: opens the selection screen and receives the result via a callback in the constructor. */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      add(new Label("Nenhum cliente escolhido"));
      add(new Button("Escolher cliente").onAction(e ->
         // COMMON SCREEN — result via callback in the constructor (show(onAnswer) does NOT work here).
         new SelecionarClienteTela(cliente -> Hint.show("Escolhido: " + cliente.nome, 1500)).show()));
   }
}

/** Simple example model. */
class Cliente
{
   final String nome;
   Cliente(String nome) { this.nome = nome; }
}

/** Selection screen: delivers the result through the constructor callback before closing. */
class SelecionarClienteTela extends Window
{
   private final RunnableWith<Cliente> onPick;

   public SelecionarClienteTela(RunnableWith<Cliente> onPick) { this.onPick = onPick; }

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());
      add(new Button("Escolher Ana").onAction(e ->
      {
         if (onPick != null) onPick.run(new Cliente("Ana"));  // delivers the result
         hide();                                              // then closes
      }));
   }
}
```

> The snippet below shows **only the core**. To run it, place it in the `MainWindow` skeleton above.

## Minimal snippet
```java
// verified in the source: hide() only calls onAnswer.run(answer) when (this instanceof Picker) and answer != null

// 1) PICKER — uses show(onAnswer). Fires ONLY with a non-null result (confirmed choice).
DatePicker picker = new DatePicker(/* ... */);
picker.show(answer ->
{
   Date d = (Date) answer;      // never null here; cancelling does NOT fire the callback
   Hint.show("Data: " + d, 1500);
});

// 2) COMMON SCREEN — result via callback in the constructor (show(onAnswer) does NOT work here).
public class SelecionarClienteTela extends Window
{
   private final RunnableWith<Cliente> onPick;

   public SelecionarClienteTela(RunnableWith<Cliente> onPick) { this.onPick = onPick; }

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new GridLayout());
      add(new Button("Escolher Ana").onAction(e ->
      {
         if (onPick != null) onPick.run(new Cliente("Ana"));  // delivers the result
         hide();                                              // then closes
      }));
   }
}

// call:
new SelecionarClienteTela(cliente -> Hint.show("Escolhido: " + cliente.nome, 1500)).show();
```

Why two paths? `hide()` calls `onAnswer` only for `Picker` (the `instanceof Picker` check is in the `Window.hide()` code). For regular screens, the constructor callback is the explicit contract — and it lets you type the result (`RunnableWith<Cliente>`) instead of `Object`.

## Go deeper
- [Returning results](/docs/ui/navigation/returning-results) · [Navigate between screens](/docs/ui/navigation/navigate-between-screens)
- Sibling recipe: [Open and close a screen](/docs/cookbook/nav/abrir-tela)
