将数据传递给 Javafx 中的另一个控制器

如何解决将数据传递给 Javafx 中的另一个控制器

我仍然是用 Java 开发我的项目的新手,你能指出我在将 String 传递给另一个控制器时做错了什么吗?下面是我的解决方案。我试图将字符串 purchaseCode 的值从我的第一个控制器 (DashboardController.java) 传递给另一个控制器,以便在查询中使用它或只是将其设置为文本。但是当我将它调用到我的另一个控制器 (InfoSalesController.java) 时,结果是 null。

DashboardController.java

...
SalesController sales = getTableView().getItems().get(getIndex());
String purchaseCode = sales.getPurchaseCol();
Hyperlink link = new Hyperlink(purchaseCode);
                             
link.setOnAction(event->{
  try{
    Stage stage = new Stage();
    FXMLLoader loader = new 
    FXMLLoader(getClass().getResource("/store/sales/infoSales.fxml"));
    Parent pane = (Parent) loader.load();
    InfoSalesController is = loader.getController();
    is.setPurchaseSales(purchaseCode);
    stage.setScene(new Scene(pane));
    stage.setResizable(false);
    stage.initModality(Modality.APPLICATION_MODAL);
    stage.show();
    }catch(IOException e){
      e.printStackTrace();
    }
});
setGraphic(link);
...

InfoSalesController.java

public String getPurchaseSales() {
    return purchaseSales;
}

public void setPurchaseSales(String purchaseSales) {
    this.purchaseSales = purchaseSales;
}

@Override
public void initialize(URL url,ResourceBundle rb) {
    purchaseTxt.setText(purchaseSales);
}

解决方法

这个问题实际上是重复的:

但是这个问题提出了一个有趣的附带问题:“Platform.runLater() 如何帮助程序工作?”,我将在此处发布答案作为解释。

首先,让我们看一下传递参数答案中的代码并解释其工作原理:

public Stage showCustomerDialog(Customer customer) {
  FXMLLoader loader = new FXMLLoader(
    getClass().getResource(
      "customerDialog.fxml"
    )
  );

  Stage stage = new Stage(StageStyle.DECORATED);
  stage.setScene(
    new Scene(loader.load())
  );

  CustomerDialogController controller = loader.getController();
  controller.initData(customer);

  stage.show();

  return stage;
}

...

class CustomerDialogController {
  @FXML private Label customerName;
  void initialize() {}
  void initData(Customer customer) {
    customerName.setText(customer.getName());
  }
}

这里的主要区别在于 CustomerDialogController 中的 initialize() 语句为空,并且添加了单独的 initData() 函数。 initialize() 语句在加载 FXML 时由 FXMLLoader 隐式调用。那时,初始化视图实际所需的其余数据(客户数据)不可用,因为它尚未传递给新控制器。 initData(Customer customer) 调用是在加载后显式进行的,并包含客户数据作为参数,因此可用于初始化视图。

现在让我们看看您问题中的代码以及 Platform.runLater 对它做了什么。

您的调用控制器中有此代码:

FXMLLoader loader = new 
FXMLLoader(getClass().getResource("/store/sales/infoSales.fxml"));
Parent pane = (Parent) loader.load();
InfoSalesController is = loader.getController();
is.setPurchaseSales(purchaseCode);

这在您的接收控制器中:

public void setPurchaseSales(String purchaseSales) {
    this.purchaseSales = purchaseSales;
}

@Override
public void initialize(URL url,ResourceBundle rb) {
    purchaseTxt.setText(purchaseSales);
}

这不起作用,因为调用 initialize 语句时 purchaseTxt 为空。

但如果您执行以下操作,则purchaseTxt 不为空:

@Override
public void initialize(URL url,ResourceBundle rb) {
    Platform.runLater(() -> {
        purchaseTxt.setText(purchaseSales);
    });  
}

initialize() 的内容包装在 Platform.runLater() 中的作用是将初始化函数的处理延迟到未来某个未定义的点。

可能会在下一个场景脉冲处执行。 pulse 基于 JavaFX 用于处理动画和布局更改以及向应用程序代码发送事件和回调的内部计时器。

例如,Platform.runLater() 代码可以在 1/60 秒后执行,之后:

  1. 应用程序中针对当前脉冲的所有后续语句均已执行并且
  2. 控制权已移交给 JavaFX 应用程序框架,该框架执行动画、渲染和布局过程 AND
  3. 控制权已返回给您的应用程序代码,以便为下一个脉冲执行应用程序处理。

因此,Platform.runLater() 有效地​​使初始化过程成为异步调用。在执行完所有后续代码后,将执行异步逻辑。这意味着您在新控制器中设置应用程序数据的代码将在执行 initialize() Platform.runLater() 块中的异步代码以初始化由新控制器管理的视图元素之前执行。

这两种方法都是有效的。我想您可以选择您和其他读者最清楚的一种。就我个人而言,在这种情况下我不会使用 Platform.runLater()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res