gpt4 book ai didi

java - 使用 fx :include 时自定义 Controller 工厂

转载 作者:行者123 更新时间:2023-12-04 00:51:44 24 4
gpt4 key购买 nike

我使用的是 JavaFX 版本 15.0.1。我想通过向其中注入(inject)多个 FXML 文件来制作更复杂的场景,如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>

<AnchorPane fx:controller="MainFxmlController">
<children>
<VBox>
<children>
<fx:include fx:id="topMenu" source="top_menu.fxml" />
<fx:include fx:id="navigation" source="navigation.fxml" />
<fx:include fx:id="statusBar" source="status_bar.fxml" />
</children>
</VBox>
</children>
</AnchorPane>

Here我发现包含的 FXML 的 Controller 会自动加载并注入(inject)到主 Controller 中名为 Controller 的 @FXML 注释字段中(在本例中为 MainFxmlController)。

我的问题是:在这种情况下,我如何使用自己的 Controller 工厂来实例化相应的 Controller 类?我需要在构造函数中为 Controller 提供一些依赖项。

最佳答案

相同的 Controller 工厂将用于包含的 FXML 和封闭的 FXML;因此您的 Controller 工厂可以测试将哪个 Controller 类传递给回调方法,创建适当的对象,并将依赖项传递给它。

像这样:

// application model class:
DataModel model = new DataModel();

FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
loader.setControllerFactory(controllerType -> {

if (controllerType == MainController.class) {
return new MainController(model);
}

if (controllerType == TopMenuController.class) {
return new TopMenuController(model);
}

if (controllerType == NavigationController.class) {
return new NavigationController(model);
}

if (controllerType == StatusBarController.class) {
return new StatusBarController(model);
}

return null ; // or throw an unchecked exception
});

Parent mainRoot = loader.load();

如果您愿意(或需要更通用),您可以使用反射:

loader.setControllerFactory(controllerType -> {

try {
for (Constructor<?> c : controllerType.getConstructors()) {
if (c.getParameterCount() == 1
&& c.getParameterTypes()[0] == DataModel.class) {

return c.newInstance(model);
}
}
// If we got here, there's no constructor taking a model,
// so try to use the default constructor:
return controllerType.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
});

关于java - 使用 fx :include 时自定义 Controller 工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65814539/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com