首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX在没有控制器的fxml中包含fxml

JavaFX在没有控制器的fxml中包含fxml
EN

Stack Overflow用户
提问于 2015-03-25 21:19:41
回答 1查看 22.8K关注 0票数 8

我正在用javafx编写一个应用程序。

我的场景在不同的fxml文件中定义。

因为我尝试使用mvc模式,所以没有在fxml文件中设置控制器,所以我在FXMLloader上使用setController。

一切正常,但我有主菜单和它的所有功能的onActions在单独的控制器和单独的fxml文件。

我已经尝试过了

代码语言:javascript
复制
<fx:include source="Menubar.fxml"/>

并为fxml文件创建了一个控制器,当我在fxml文件中设置控制器时,我无法编译源代码。如何为包含的fxml文件设置控制器?

startpage.fxml通过以下命令获取其控制器"Startpage“

代码语言:javascript
复制
FXMLLoader loader = new FXMLLoader(getClass().getResource("../fxml/startpage.fxml"));
        loader.setController(new Startpage(m));
        Pane mainPane = loader.load();

startpage.fxml包含menubar.fxml,现在如何为菜单栏控件设置控制器?或者如何轻松地将menubarController包含在每个其他控制器中?

EN

回答 1

Stack Overflow用户

发布于 2015-03-25 22:22:24

我认为你需要在加载器中使用controllerFactory来达到你想要的效果。当您使用controllerFactory时,您可以在FXML文件中指定控制器的类名,但是控制器工厂允许您控制如何将其映射到对象(因此,您仍然可以通过传入模型来构造它,等等)。当您为FXMLLoader指定controllerFactory时,该工厂还用于为您在FXML文件中拥有的任何<fx:include>创建控制器。

最后,请注意,您可以将包含的fxml文件的控制器注入到“主”fxml文件中,如"Nested controllers" section of the FXML documentation中所述。

因此,如果startpage.fxml看起来像这样:

代码语言:javascript
复制
<!-- imports etc -->
<BorderPane fx:controller="com.example.Startpage" ... >
  <top>
    <fx:include source="Menubar.fxml" fx:id="menubar" />
  </top>
  <!-- etc ... -->
</BorderPane>

Menubar.fxml看起来像是

代码语言:javascript
复制
<!-- imports etc -->
<MenuBar fx:controller="com.example.MenubarController" ... >
  <!-- etc... -->
</MenuBar>

然后,您可以使用以下命令控制控制器类的实例化:

代码语言:javascript
复制
FXMLLoader loader = new FXMLLoader(getClass().getResource("../fxml/startpage.fxml"));

Model m = ... ;

Startpage startpageController = new Startpage(m);
MenubarController menubarController = new MenubarController(m);

Callback<Class<?>, Object> controllerFactory = type -> {
    if (type == Startpage.class) {
        return startpageController ;
    } else if (type == MenubarController.class) {
        return menubarController ;
    } else { 
        // default behavior for controllerFactory:
        try {
            return type.newInstance();
        } catch (Exception exc) {
            exc.printStackTrace();
            throw new RuntimeException(exc); // fatal, just bail...
        }
    }
};

loader.setControllerFactory(controllerFactory);

Pane mainPane = loader.load();

现在,如果需要,您的应用程序代码中实际上有对这两个控制器的引用,但您也可以这样做

代码语言:javascript
复制
public class Startpage {

    public final Model m ;

    // note the name of this field must be xController,
    // where x is the fx:id set on the <fx:include>:

    @FXML
    private final MenubarController menubarController ;

    public Startpage(Model m) {
        this.m = m ;
    }

    // ...
}
票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29256848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档