使用JavaFX和FXML实现MVC模式

3
如果我有一个使用FXML的JavaFX项目,如何将其结构化以符合模型-视图-控制器模式?以下是我假设的一般结构:
模型 - 底层程序(GUI所代表的内容)。 视图 - FXML文件。 控制器 - FXML控制器。
这种表示方法的问题在于,视图无法被通知模型的更改,因为它只是一个FXML文件。视图应该是FXML控制器类吗?然后,我是否应该有一个主控制器类,使FXML控制器从模型获取信息,而主控制器处理操作事件?在这种情况下,主控制器如何访问JavaFX节点?
此外,在MVC模式中,主方法应该放在哪里?现在,我的JavaFX应用程序类中有主方法,但在程序的其余部分中没有任何作用。JavaFX应用程序类应该是MVC模式的一部分吗?还是仅需要初始化GUI?
问题总结(请阅读完整帖子): 1. 如何结构化使用FXML的JavaFX项目以符合MVC模式?视图是否应该是FXML控制器类,然后是否应该有一个主控制器类,使FXML控制器从模型获取信息,而主控制器处理操作事件? 2. 在MVC模式中,主方法应该放在哪里? 3. JavaFX应用程序类应该是MVC模式的一部分吗?还是仅需要初始化GUI?

如果您尽最大努力将GUI代码与状态和逻辑代码解耦,您会发现您的应用程序非常类似于MVC,因为关注点分离是MVC所追求的。这可能是达到目标的最实用方法,因为实际上并不存在一条真正的MVC路径可供选择。 - NESPowerGlove
还可以参考以下网址:https://dev59.com/MFwY5IYBdhLWcg3wq5bk 和https://dev59.com/KmAg5IYBdhLWcg3wx9fG?rq=1 - James_D
2个回答

4
如何结构化我的JavaFX项目以便使用FXML遵循MVC模式?视图应该是FXML控制器类吗?然后,我是否应该有一个主控制器类,使FXML控制器从模型获取信息,而主控制器处理动作事件?
JavaFX和Swing都倾向于将视图和控制器之间的耦合度紧密结合,理由是制作通用控制器很困难。但是,MVC本身有一些不同的解释,所以有点模糊。
鉴于这种紧密耦合的理由,您有一些选择。我建议两个选项,也许其他人可以添加甚至不同意。
1)接受View类只是用于加载FXML文件、设置场景和舞台,从而使FXMLController类观察模型并更新视图的占位符。
这将控制器限制为JavaFXML应用程序,这意味着它不能轻松地与Swing等交换。虽然只要引用正确的控制器,并且所有onAction或等效节点属性使用相同的引用,更改视图就很快而简单。

2) 不要使用提供的骨架代码。相反,使视图加载FXML文件并手动访问节点,此外,从您的FXML文件中删除fx:controller属性以及从FXML文件中相关节点的onAction属性。

然后,您可以根据需要从视图中访问任何Node,例如:

Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Button example = (Button) root.lookup("#button"); // #button exists in FXMLDocument.fxml
example.setOnAction(e -> { myController.doSomething(); });

这样做可以让你指定自己的通用控制器,并允许View类观察模型本身。
归根结底,最重要的是将Model与View和Controller分离,因为Model是程序的核心。 智能模型,薄控制器,愚笨视图

主方法应该放在哪里?

不重要。然而,如果使用JavaFX打包工具创建的JAR文件,则JavaFX应用程序不需要严格的main方法,而是使用launch作为入口点。但是,您可以在单独的类中使用main方法作为入口点,并调用Application.launch(MyJavaFXApplicationClass.class);

JavaFX应用程序类是否应该成为MVC模式的一部分,还是仅需要初始化GUI?

是的,因为它是视图的一部分。请参见我上面提到的两种方法。


那么Application类将拥有对模型的引用,观察其变化,并在必要时修改视图? - null
我同意JavaFX和Swing都倾向于在视图和控制器之间实现紧密耦合,控制器几乎感觉像是FXML文件的“支持”类。 - Chris Vilches

1
在我看来,如果每个刚开始使用JavaFX的人都试图发明自己的MVC变体实现方案,那并没有多大帮助。相反,应该选择已经存在的JavaFX应用程序框架之一,尝试理解它,然后严格遵循该框架的指南构建应用程序。我的个人最爱是mvvmFX,但当然也可以使用其他框架,例如AfterburnerFX。学习和使用这样的框架将回答许多在SO上不断提出的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接