跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

从屏幕返回值

有两种模式,选对模式可以避免一个常见的 bug。

⚠️ 关键点

Window.show(onAnswer) 只有当窗口是 Picker 时才会触发 onAnswer(在内部, hide() 执行 answer = this instanceof Picker ? getAnswer() : null,仅当 answer != null 时才调用回调)。对于普通屏幕(Window 的子类),show(onAnswer) 不返回 值——请使用构造函数回调模式。

完整示例(复制、粘贴并运行)

package com.exemplo;

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

/** 可执行的主界面。将 launcher 指向此类(classname)并运行: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");
      // 普通屏幕 → 回调通过构造函数传入(show(cb) 只在 Picker 中触发)。
      escolher.onAction(c ->
         new TelaSelecao(op -> resultado.setText("Escolheu: " + op)).show());
      add(LAY_AUTO, escolher);
   }
}

/** 普通屏幕,通过构造函数中接收的回调返回一个值。 */
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(); });   // 返回并关闭
      add(LAY_AUTO, a);

      Button b = new Button("Opção B");
      b.onAction(c -> { onEscolha.run("B"); hide(); });
      add(LAY_AUTO, b);
   }
}

下面的片段仅展示核心部分(放入 onShow() 内的内容)。要运行它们,请放入上面的 MainWindow 骨架中。

模式 1——构造函数回调(普通屏幕)

向屏幕的构造函数传递一个回调;它会在 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(); });   // 返回并关闭
      add(LAY_AUTO, opa);
   }
}

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

模式 2——Picker + onAnswer(现成的选择器)

选择器(DatePicker、TimePicker、ColorPicker 等)已经实现了 getAnswer()。对它们使用 show(onAnswer):

new DatePicker().show(resposta -> {
   // 只在 != null 时触发(用户已确认;取消 ⇒ getAnswer() 为 null)
   System.out.println("Data: " + resposta);
});

要创建自己的选择器,请继承 Picker 并实现 getAnswer()。

⚠️ 对话框不使用 onAnswer

Alert 和 ActionSheet 继承自 Window(而非 Picker),因此 show(callback) 不会触发。 响应通过按钮的回调(buttonAction)传入——参见对话框与模态框。

最佳实践

  • 普通屏幕 → 构造函数回调。选择器 → Picker + onAnswer。
  • 对于屏幕之间共享的状态,考虑使用 ViewModel/controller(参见 架构)。

常见错误

  • 在不是 Picker 的屏幕上使用 minhaTela.show(cb) 并期望 cb 触发(不会触发)。
  • 使用 alert.show(cb)——回调永远不会运行;请使用 buttonAction。

另见

这个页面有帮助吗?