JavaFX 包含相同的控制器实例

JavaFX include with the same controller instance

我有一个 JavaFX 项目,它有一个用 FXML 编写并附加到控制器的视图。在这个控制器中,我有一个重物,几乎在每次用户交互中都会用到它。

我的视图有一个具有不同功能的 TabPane。我遇到的问题是 FXML 文件很大,我想分成不同的子文件(每个选项卡都会有一个)。我尝试使用 fx:include.

我遇到的问题是我必须将这些文件附加到控制器,所以我使用 fx:controller 附加它们。问题是该语句创建了一个新的控制器实例,所以我无权访问共享对象。

有什么办法我仍然可以使用相同的控制器和 fx:include

单控制器

如果您真的需要所有选项卡都使用一个控制器,您可以考虑采用编程方法。您可以手动初始化视图并将它们 link 到控制器实例。您可以创建以下辅助方法并随后为每个视图调用它(例如:loadAndLink(controller, "/com/ui/views/login.fxml").

public void loadAndLink(Object controller, String viewPath) {
    FXMLLoader loader = new FXMLLoader(getClass().getResource(viewPath));
    loader.setController(controller);
    try {
        loader.load();
    } catch (IOException e) {
        // ...
    }
}

请记住,将为每个视图调用控制器的 initialize(...) 方法(在 loader.setController(controller) 调用中),因此您希望它是幂等的。此外,在以编程方式加载 FXML 的情况下,您需要从中删除 fx:controller 标记。还要确保所有视图中所有元素的 fx:id 具有唯一值。

嵌套控制器

另一方面,如果您的 FXML 文件很大,那么控制器可能也很大。考虑为每个选项卡使用单独的嵌套控制器(此 fx:include 的用途)。如果将它们设置为 link,则可以将它们从父控制器设置为 link:

父级 FXML:

...
<fx:include fx:id="embeddedView" source="SomeOtherView.fxml"/>
...

父控制器:

...
@FXML
private Parent embeddedView;
...