传递参数JavaFX FXML [英] Passing Parameters JavaFX FXML

查看:3149
本文介绍了传递参数JavaFX FXML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将参数传递给javafx中的辅助窗口?有没有办法与对应的控制器进行通信?

How can I pass parameters to a secondary window in javafx? Is there a way to communicate with the corresponding controller?

例如:
用户从 TableView 并打开一个新窗口,显示客户的信息。

For example: The user chooses a customer from a TableView and a new window is opened, showing the customer's info.

Stage newStage = new Stage();
try 
{
    AnchorPane page = (AnchorPane) FXMLLoader.load(HectorGestion.class.getResource(fxmlResource));
    Scene scene = new Scene(page);
    newStage.setScene(scene);
    newStage.setTitle(windowTitle);
    newStage.setResizable(isResizable);
    if(showRightAway) 
    {
        newStage.show();
    }
}

newStage 将成为新窗口。问题是,我找不到一种方法来告诉控制器在哪里查找客户的信息(通过将id作为参数)。

newStage would be the new window. The problem is, I can't find a way to tell the controller where to look for the customer's info (by passing the id as parameter).

任何想法? / p>

Any ideas?

推荐答案

推荐方法

列举了将参数传递给FXML控制器的不同机制。

This answer enumerates different mechanisms for passing parameters to FXML controllers.

对于小型应用程序,我强烈建议将参数直接从调用者传递给控制器​​ - 它简单直观,不需要额外的框架。

For small applications I highly recommend passing parameters directly from the caller to the controller - it's simple, straightforward and requires no extra frameworks.

对于更大,更复杂的应用程序,如果您想使用依赖注入事件总线机制在您的应用程序中。

For larger, more complicated applications, it would be worthwhile investigating if you want to use Dependency Injection or Event Bus mechanisms within your application.

直接从调用者传递给控制器​​

通过从FXML加载器实例中检索控制器并将控制器上的方法调用所需的数据值进行初始化,将自定义数据传递给FXML控制器。

Pass custom data to an FXML controller by retrieving the controller from the FXML loader instance and calling a method on the controller to initialize it with the required data values.

以下代码:

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

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

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

  stage.show();

  return stage;
}

...

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

新的FXMLLoader的构造如示例代码所示即新的FXMLLoader(位置)。该位置是一个URL,您可以通过以下方式从FXML资源生成此类URL:

A new FXMLLoader is constructed as shown in the sample code i.e. new FXMLLoader(location). The location is a URL and you can generate such a URL from an FXML resource by:

new FXMLLoader(getClass().getResource("sample.fxml"));

请勿在FXMLLoader上使用静态加载功能,否则您将不会您可以从装载程序实例获取控制器。

FXMLLoader实例本身从来不知道有关域对象的任何内容。您不会将应用程序特定的域对象直接传递到FXMLLoader构造函数中,而不是:

FXMLLoader instances themselves never know anything about domain objects. You do not directly pass application specific domain objects into the FXMLLoader constructor, instead you:


  1. 根据指定位置的fxml标记构建一个FXMLLoader

  2. 从FXMLLoader实例获取控制器。

  3. 在检索到的控制器上调用方法,为控制器提供对域的引用。 >
  1. Construct an FXMLLoader based upon fxml markup at a specified location
  2. Get a controller from the FXMLLoader instance.
  3. Invoke methods on the retrieved controller to provide the controller with references to the domain objects.

这个博客(由另一位作家)提供了一个替代的,但类似的示例

This blog (by another writer) provides an alternate, but similar, example.

在FXMLLoader上设置控制器

Setting a Controller on the FXMLLoader

CustomerDialogController dialogController = 
    new CustomerDialogController(param1, param2);

FXMLLoader loader = new FXMLLoader(
    getClass().getResource(
        "customerDialog.fxml"
    )
);
loader.setController(dialogController);

Pane mainPane = (Pane) loader.load();

您可以在代码中构造一个新的控制器,将您想要的任何参数传递到控制器构造函数。一旦构建了控制器,您可以在之前的FXMLLoader实例上设置它,您调用 load() 实例方法。

You can construct a new controller in code, passing any parameters you want from your caller into the controller constructor. Once you have constructed a controller, you can set it on an FXMLLoader instance before you invoke the load() instance method.

要在加载程序(在JavaFX 2.x中)设置控制器,您不能同时定义一个 fx:controller 属性在您的fxml文件。

由于 fx:controller 在FXML中定义,我个人更喜欢从FXMLLoader获取控制器,而不是将控制器设置到FXMLLoader中。

Due to the limitation on the fx:controller definition in FXML, I personally prefer getting the controller from the FXMLLoader rather than setting the controller into the FXMLLoader.

控制器从外部检索参数静态方法

此方法的例子是Sergey对 Javafx 2.0 Controller.java文件中的Application.getParameters()方法

This method is exemplified by Sergey's answer to Javafx 2.0 How-to Application.getParameters() in a Controller.java file.

使用依赖注入

FXMLLoader支持依赖注入系统,如Guice,Spring或Java EE CDI,由让您在FXMLLoader上设置自定义控制器工厂。这提供了一个回调,您可以使用它来创建具有由相应依赖注入系统注入的依赖值的控制器实例。有一个示例将 FXML与Spring集成依赖注入系统(不幸的是,链接已经死了,内容消失了,如果有人知道一个类似的例子,请编辑这个问题来引用它),尽管它比使用新的自定义控制器有点笨拙工厂功能在JavaFX 2.2中可用。

FXMLLoader supports dependency injection systems like Guice, Spring or Java EE CDI by allowing you to set a custom controller factory on the FXMLLoader. This provides a callback that you can use to create the controller instance with dependent values injected by the respective dependency injection system. There is a sample of integrating FXML with the Spring dependency injection system (unfortunately the link is dead and the content is gone, if anybody knows of a similar example, please edit this question to reference it), though it's a bit clunkier than it would be using the new custom controller factory features made available in JavaFX 2.2.

一个非常好的,干净的依赖注入方法由 afterburner.fx框架与示例 air-hack应用程序使用它。 afterburner.fx依赖于JEE6 javax.inject 执行依赖注入。

A really nice, clean dependency injection approach is exemplified by the afterburner.fx framework with a sample air-hacks application that uses it. afterburner.fx relies on JEE6 javax.inject to perform the dependency injection.

使用事件总线

Greg Brown,原始的FXML规范创建者和实现者通常建议考虑使用事件总线进行FXML实例控制器与其他应用逻辑之间的通信

Greg Brown, the original FXML specification creator and implementor, often suggests considering use of an event bus for communication between FXML instantiated controllers and other application logic.


EventBus是一个简单但功能强大的发布/订阅API,其注释允许POJO在JVM的任何地方彼此通信,互相参照

The EventBus is a simple but powerful publish/subscribe API with annotations that allows POJOs to communicate with each other anywhere in a JVM without having to refer to each other.

后续问题&答案


第一种方法,你为什么要返回舞台?该方法也可以是空的,因为你已经给出了命令show();就在回归阶段之前。如何通过返回舞台来计划使用情况

on first method, why do you return Stage? The method can be void as well because you already giving the command show(); just before return stage;. How do you plan usage by returning the Stage

它是一个功能解决问题的方法。从 showCustomerDialog 函数返回一个阶段,以便可以通过外部类来存储它的引用,该类可能希望执行某些操作,例如基于按钮隐藏舞台点击主窗口,稍后再点击。另一个面向对象的解决方案可以将CustomerDialog对象中的功能和阶段引用封装,或者具有CustomerDialog扩展阶段。封装FXML,控制器和模型数据的自定义对话框的面向对象界面的完整示例超出了此答案的范围,但可能会为任何倾向创建一个的人提供一个有价值的博文。

It is a functional solution to a problem. A stage is returned from the showCustomerDialog function so that a reference to it can be stored by an external class which may wish to do something, such as hide the stage based on a button click in the main window, at a later time. An alternate, object-oriented solution could encapsulate the functionality and stage reference inside a CustomerDialog object or have a CustomerDialog extend Stage. A full example for an object-oriented interface to a custom dialog encapsulating FXML, controller and model data is beyond the scope of this answer, but may make a worthwhile blog post for anybody inclined to create one.

StackOverflow用户提供的其他信息,名为 @dzim

Additional information supplied by StackOverflow user named @dzim

弹簧引导依赖注入示例

如何做到这一点的问题春天的启动方式,有关于JavaFX 2的讨论,我在附件的固定链接。
该方法在2016年3月的Spring Boot v1.3.3中仍然有效并经过测试.RELEASE:
http: //stackoverflow.com/a/36310391/1281217

The question of how to do it "The Spring Boot Way", there was a discussion about JavaFX 2, which I anserwered in the attached permalink. The approach is still valid and tested in March 2016, on Spring Boot v1.3.3.RELEASE: http://stackoverflow.com/a/36310391/1281217

这篇关于传递参数JavaFX FXML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆