JavaFX FXML参数从控制器A传递到B并返回

时间:2018-01-09 17:07:22

标签: parameter-passing javafx-2 fxml

我想创建一个基于控制器的JavaFX GUI,由多个控制器组成。

我无法完成的任务是将参数从一个场景传递到另一个场景并返回。

或换句话说: MainController加载SubController的fxml,将对象传递给SubController,切换场景。不应该有两扇敞开的窗户。 完成工作后,SubController将把场景切换回MainController并传回一些对象。 这是我失败的地方。

这个问题与此问题非常相似,但仍然没有答案。 Passing Parameters JavaFX FXML 评论中也提到了这一点:

"当您将参数从第一个控制器传递到第二个但是如何将参数从第二个控制器传递到第一个控制器时,这是有效的,我的意思是在加载first.fxml之后。

- Xlint Xms Sep 18 17 at 23:15"

我在该主题的最佳答案中使用了第一种方法。

有没有人知道如何在没有外部库的情况下实现这一目标?

3 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点。

这是一个解决方案,它将Consumer传递给另一个控制器。另一个控制器可以在完成其工作后调用使用者接受结果。该示例基于您链接的问题答案中的示例代码。

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

  Consumer<CustomerInteractionResult> onComplete = result -> {
    // update main screen based upon result.
  };
  CustomerDialogController controller = 
    loader.<CustomerDialogController>getController();
  controller.initData(customer, onComplete);

  stage.show();

  return stage;
}

...

class CustomerDialogController() {
  @FXML private Label customerName;
  private Consumer<CustomerInteractionResult> onComplete
  void initialize() {}
  void initData(Customer customer, Consumer<CustomerInteractionResult> onComplete) {
    customerName.setText(customer.getName());
    this.onComplete = onComplete;
  }

  @FXML
  void onSomeInteractionLikeCloseDialog(ActionEvent event) {
    onComplete.accept(new CustomerInteractionResult(someDataGatheredByDialog));
  }
}

另一种方法是将结果属性添加到对话框屏幕的控制器中,并且感兴趣的调用者可以侦听或检索结果属性。 result property是内置的JavaFX对话框的工作方式,因此您基本上可以模仿其中的一些功能。

如果你有很多这种来回传递的东西,基于类似Gluon Ignite的共享依赖注入模型可能会对你有所帮助。

答案 1 :(得分:1)

我已经使用AfterBurner.fx进行依赖注入,只要遵循约定,它就非常灵活且功能强大。如果您只是将3个类复制到您的结构中,它不一定是外部库。虽然你确实需要javax Inject jar,所以我猜它是一个永恒的参考。

或者,如果你有一个中央屏幕&#34;从大多数应用程序分支出来,您可以在单例模式中使用property binding。在JavaFX中有一些关于使用单例的好文章,比如this one。我为一个非常好的小应用程序做了这个,但如果有很多属性,定义所有这些绑定可能会失控。

答案 2 :(得分:0)

要传回数据,最好的方法可能是触发自定义事件,父控制器使用Node :: addEventHandler订阅它们。有关上下文,请参阅How to emit and handle custom events?

在两个控制器彼此没有引用的复杂情况下,提到@jewelsea的事件总线是更好的选择。

对于整体架构,此Reddit评论提供了一些很好的细节:https://www.reddit.com/r/java/comments/7c4vhv/are_there_any_canonical_javafx_design_patterns/dpnsedh/