This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
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 ifgetAnswer() != null, andWindow.getAnswer()returnsnullby default — onlyPickeroverridesgetAnswer(). In other words: for regular screens this callback never fires.Picker.getAnswer()— returns the chosen value, ornullif 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 beforehide().
Complete example (copy, paste, and run)
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
MainWindowskeleton above.
Minimal snippet
// 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 · Navigate between screens
- Sibling recipe: Open and close a screen
Was this page helpful?Thanks for the feedback!