Model view controller JavaFX在没有控制器的fxml中包含fxml
我正在用javafx编写一个应用程序。 这是一个带有主菜单的“多屏幕”应用程序,我可以从主菜单切换场景 我的场景在不同的fxml文件中定义 因为我尝试使用mvc模式,所以我没有在fxml文件中设置控制器,而是在FXMLloader上使用setController 一切都很好,但我有主菜单和它的所有功能,在单独的控制器和单独的fxml文件的操作 我已经试过了Model view controller JavaFX在没有控制器的fxml中包含fxml,model-view-controller,javafx,controller,fxml,Model View Controller,Javafx,Controller,Fxml,我正在用javafx编写一个应用程序。 这是一个带有主菜单的“多屏幕”应用程序,我可以从主菜单切换场景 我的场景在不同的fxml文件中定义 因为我尝试使用mvc模式,所以我没有在fxml文件中设置控制器,而是在FXMLloader上使用setController 一切都很好,但我有主菜单和它的所有功能,在单独的控制器和单独的fxml文件的操作 我已经试过了 <fx:include source="Menubar.fxml"/> startpage.fxml包括menubar.fxm
<fx:include source="Menubar.fxml"/>
startpage.fxml
包括menubar.fxml
,现在如何为menubar控件设置控制器?或者如何在每个其他控制器中轻松包含menubarController?我认为您需要在加载器中使用controllerFactory
来实现所需的功能。使用controllerFactory
时,可以在FXML文件中指定控制器的类名,但控制器工厂允许您控制如何将其映射到对象(因此您仍然可以通过模型等来构造它)。当为FXMLLoader
指定controllerFactory
时,该工厂还用于为FXML文件中的任何
创建控制器
最后,请注意,可以将包含的fxml文件的控制器插入到“main”fxml文件中,如中所述
因此,如果startpage.fxml如下所示:
<!-- imports etc -->
<BorderPane fx:controller="com.example.Startpage" ... >
<top>
<fx:include source="Menubar.fxml" fx:id="menubar" />
</top>
<!-- etc ... -->
</BorderPane>
Menubar.fxml看起来像
<!-- imports etc -->
<MenuBar fx:controller="com.example.MenubarController" ... >
<!-- etc... -->
</MenuBar>
然后,您可以通过以下方式控制控制器类的实例化:
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();
fxmloader=newfxmloader(getClass().getResource(“../fxml/startpage.fxml”);
模型m=;
起始页起始页控制器=新起始页(m);
MenubarController MenubarController=新的MenubarController(m);
好吧,我需要更多的知识,我现在不明白你的答案。编辑我希望它能像“startpagecontroller扩展menucontroller”之类的简单。我想我仍然会在每个控制器中保留菜单栏的所有方法以及fxml代码..:/我真的帮不了你,除非我知道你不懂的地方。每个fxml文件都有一个与之关联的控制器实例。fxml文件可以为控制器指定一个类。因此,控制器工厂只是一个告诉fxmloader
如何从指定类获取控制器实例的函数。复制方法或使一个控制器成为另一个控制器的子类都不会有帮助,因为您仍然有两个不同的控制器实例(因此它们不会引用相同的数据)。对我来说,最大的问题是理解您的解决方案(只是java初学者)和/或使您的示例适应我的代码。我会试着解释一下为什么我需要这些。首先,当我开始这个项目时,每个fxml文件都有自己的控制器,这很好,我可以在不丢失任何函数的情况下将每个fxml包含在彼此中。例如,我在应用程序“createproject”中有一个页面,该页面包含一些文本字段并包含菜单栏。当我使用menuitems将页面(场景)切换到“settingsforcreateproject”时,我再次将menubar包含在新的fxml中。看看这里,使用swing或awt时,一切都很好,也更愉快,但是我需要场景b中场景a中的数据,就像projectcreate场景中设置场景中的设置一样。我在我的主课上创建了一个模型,然后。。问题开始了,如何在控制器之间共享模型。我环顾四周,发现了一些听起来不错的解决方案,一个是设置控制器,但这个解决方案不适用于fxml,包括fxml。。现在我站在这里……好吧,我的解决方案确实做到了:在“主”控制器和包含的fxml的控制器之间共享一个模型。你不明白代码的哪些部分?
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();
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 ;
}
// ...
}