Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar

Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.

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)

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():

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 (DatePicker, TimePicker, ColorPicker, etc.) ya implementan getAnswer(). Para ellos, usa show(onAnswer):

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.

Buenas prácticas

  • Pantallas comunes → callback en el constructor. Selectores → Picker + onAnswer.
  • Para estado compartido entre pantallas, considera un ViewModel/controller (ver arquitectura).

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

¿Te resultó útil esta página?