Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

Como receber um resultado de uma tela

Propósito. Você abre uma tela para o usuário escolher/preencher algo e precisa do valor de volta. O CrossFly tem dois mecanismos distintos: show(onAnswer) para pickers, e callback no construtor para telas comuns.

APIs usadas

  • Window.show(RunnableWith<Object> onAnswer) — registra um callback de resultado. Na fonte, o callback só dispara se getAnswer() != null, e Window.getAnswer() retorna null por padrão — apenas Picker sobrescreve getAnswer(). Ou seja: para telas comuns esse callback nunca dispara.
  • Picker.getAnswer() — retorna o valor escolhido, ou null se cancelado. Só pickers implementam.
  • Callback no construtor — o padrão para telas comuns: passe um RunnableWith<T> (ou uma interface própria) ao construtor da tela e invoque-o antes de hide().

Exemplo completo (copiar, colar e rodar)

package com.exemplo;

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

/** Tela principal executável: abre a tela de seleção e recebe o resultado via callback no construtor. */
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 ->
         // TELA COMUM — resultado via callback no construtor (show(onAnswer) NÃO funciona aqui).
         new SelecionarClienteTela(cliente -> Hint.show("Escolhido: " + cliente.nome, 1500)).show()));
   }
}

/** Modelo simples de exemplo. */
class Cliente
{
   final String nome;
   Cliente(String nome) { this.nome = nome; }
}

/** Tela de seleção: entrega o resultado pelo callback do construtor antes de fechar. */
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"));  // entrega o resultado
         hide();                                              // depois fecha
      }));
   }
}

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

Trecho mínimo

// verificado na fonte: hide() só chama onAnswer.run(answer) quando (this instanceof Picker) e answer != null

// 1) PICKER — usa show(onAnswer). Dispara SOMENTE com resultado não-nulo (escolha confirmada).
DatePicker picker = new DatePicker(/* ... */);
picker.show(answer ->
{
   Date d = (Date) answer;      // nunca é null aqui; cancelar NÃO dispara o callback
   Hint.show("Data: " + d, 1500);
});

// 2) TELA COMUM — resultado via callback no construtor (show(onAnswer) NÃO funciona aqui).
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"));  // entrega o resultado
         hide();                                              // depois fecha
      }));
   }
}

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

Por que dois caminhos? hide() chama onAnswer apenas para Picker (o instanceof Picker está no código de Window.hide()). Para telas comuns, o callback do construtor é o contrato explícito — e permite tipar o resultado (RunnableWith<Cliente>) em vez de Object.

Aprofunde-se

Esta página foi útil?