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

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

如何从一个界面接收结果

目的。 你打开一个界面让用户选择/填写某些内容,并需要拿回该值。CrossFly 有 两种不同的机制:show(onAnswer) 用于 picker,而 构造函数中的回调 用于普通界面。

使用的 API

  • Window.show(RunnableWith<Object> onAnswer) — 注册一个结果回调。在源码中,该回调 只在 getAnswer() != null 时才触发,而 Window.getAnswer() 默认返回 null —— 只有 Picker 重写了 getAnswer()。也就是说:对于普通界面,这个回调 永远不会触发。
  • Picker.getAnswer() — 返回所选的值,若取消则返回 null。只有 picker 实现了它。
  • 构造函数中的回调 —— 普通界面的标准做法:将一个 RunnableWith<T>(或你自己的接口)传给界面的构造函数,并在 hide() 之前调用它。

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

package com.exemplo;

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

/** 可执行主屏:打开选择屏并通过构造函数中的回调接收结果。 */
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 ->
         // 普通屏 — 结果通过构造函数中的回调返回(此处 show(onAnswer) 不生效)。
         new SelecionarClienteTela(cliente -> Hint.show("Escolhido: " + cliente.nome, 1500)).show()));
   }
}

/** 简单的示例模型。 */
class Cliente
{
   final String nome;
   Cliente(String nome) { this.nome = nome; }
}

/** 选择屏:在关闭前通过构造函数回调交付结果。 */
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"));  // 交付结果
         hide();                                              // 然后关闭
      }));
   }
}

下面的片段只展示 核心部分。要运行它,请把它放进上面的 MainWindow 骨架里。

最小片段

// 已在源码核对:仅当 (this instanceof Picker) 且 answer != null 时 hide() 才调用 onAnswer.run(answer)

// 1) PICKER — 使用 show(onAnswer)。仅在结果非空(已确认选择)时触发。
DatePicker picker = new DatePicker(/* ... */);
picker.show(answer ->
{
   Date d = (Date) answer;      // 此处绝不为 null;取消不会触发回调
   Hint.show("Data: " + d, 1500);
});

// 2) 普通屏 — 结果通过构造函数中的回调返回(此处 show(onAnswer) 不生效)。
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"));  // 交付结果
         hide();                                              // 然后关闭
      }));
   }
}

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

为什么有两条路径?hide() 只为 Picker 调用 onAnswer(instanceof Picker 就写在 Window.hide() 的代码里)。对于普通界面,构造函数中的回调是明确的约定 —— 而且它允许为结果指定类型(RunnableWith<Cliente>),而不是 Object。

深入了解

这个页面有帮助吗?