MVP、JavaFx和组件参考

ahy6op9u  于 2023-09-29  发布在  Java
关注(0)|答案(3)|浏览(153)

我研究了所有流行的GUI模式- MVP,MVC,MVVM,最后我决定实现MVP(监督控制器)。所以我有以下对象(!). Stage<-View<->Model .舞台很重要!=视图,它是另一个对象。视图和模型数据绑定之间。此外,我有一个presenter(控制器),它处理所有事件,并与视图和模型一起工作,所以View<-ViewInterface<-Controller->Model。现在的问题是如何在视图中获取对标签、文本区域等的引用。Javafx允许使用@FXML注解将这些组件注入控制器。然而,使用MVP时,我需要在View中使用这些组件,因为View的所有逻辑都在View中,而控制器中不需要它们。我知道的唯一解决办法是:

public class MyView{
 private Button button;
 public MyView(){
  ...
  button=(Button) root.lookup("#myButton");
 }
}

也就是通过ID获取引用。但是我不喜欢。或者我做错了什么,或者我理解错了什么,但我认为存在更好的解决方案。请帮我找到它。

rkue9o1l

rkue9o1l1#

JavaFX被设计为使用MVC模式。因此,使用MVC比使用MVP容易得多。在MVP中,Presenter负责格式化要显示的数据。在JavaFX中,它是由View自动完成的。以下是JavaFX MVC的快速概述:

模型-您在应用程序中使用的域数据/数据结构(例如人员、雇主、课程作业等)
View-应用及其Model的UI定义。创建视图的首选方法是通过FXML文件,它本质上是JavaFX MVC中的View
Controller-连接Model和View的桥梁。代码通常隔离在XController类中(其中X是FXMLView的名称)。Controller的示例由FXMLLoader自动注入,如果您需要自定义Controller,也可以手动注入。Controller类可以访问UI(View)元素,以便能够操作不同的属性以及Model,从而可以根据UI(View)输入执行操作。

总而言之,在JavaFX中,您不需要拥有类ViewView定义应该完全在FXML文件中。所有UI元素都应该使用@FXML注入到Controller类中。如果你一定要使用MVP,那么AWT/Swing或MVP 4j-http://www.findbestopensource.com/product/mvp4j可能是一个更好的选择。
有关详细说明,请查看JavaFX的Oracle官方教程:http://docs.oracle.com/javase/8/javafx/get-started-tutorial/jfx-overview.htm
如果您需要使用FXML构建UI的帮助:http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html
本教程涵盖了JavaFX中MVC的基础知识以及每个组件如何与其他组件进行通信:http://code.makery.ch/library/javafx-8-tutorial/part1/

bttbmeg0

bttbmeg02#

作为一个Android开发者,我总是在我的应用程序中使用MVP模式。与MVP相比,MVC对我来说似乎太老了,所以当我开始开发一个新的Java应用程序时,我感到有点失落。

我的解决方案如下:

初始步骤

  • fxml文件中创建UI,指定控制器,因为您不需要控制器。
  • 创建Java接口(IView、IPresenter等)
  • 在Presenter class中实现IPresenter interface,就像您通常所做的那样(执行http请求、查询DB..)

现在有趣的部分:

根据MVP模式调整视图

让我们看一些代码:

  • 创建GUI(例如主GUI)并实现View interface
public class MainGUI extends Application implements MainContract.View {

  public static void main(String... args) {
      launch(args);
  }

  @Override
  public void start(Stage primaryStage) throws IOException {
      //here we will load fxml or create the ui programmatically
  }

  //method from view interface
  @Override
  public void onServerResponse(String message) throws IOException {
      //update the view
  }

最后一步:

与主讲人沟通

  • 为此,我们首先创建演示者的一个列表:
private MainContract.Presenter presenter;

public MainGUI() {
    presenter = new MainPresenter(this);
}

当然,this是在MainGUIclass中实现的MainContract.View

  • 现在我们必须获得对视图组件的引用
private ComboBox<Double> mySimpleList;

@Override
public void start(Stage primaryStage) throws IOException {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("layout_main.fxml"));
    Parent root = loader.load();
    mySimpleList= (ComboBox<Double>) loader.getNamespace().get("mysimplelist_id");

...

    primaryStage.setScene(new Scene(root, -1, -1));
    primaryStage.show();

我更喜欢使用fxml文件,而不是通过代码创建ui,但背后的逻辑是相同的。

  • 设置项目
...
mySimpleList.setItems(ValuesFactory.getMyValues());
  • 和收听器
...
mySimpleList.valueProperty().addListener(simpleListListener);

什么是simpleListListener
一个简单的ChangeListener在这里我们最终调用了一个presenter方法

simpleListListener = (ChangeListener<Double>) 
    (observable, oldValue, newValue) -> presenter.doTheLogic(newValue);

这是一个简单的场景,但原则上这就是我们如何在JavaFX中使用MVP模式。我也明白这不是最终的解决方案,所以我希望有一天会有更多的文档,在那里我可以了解更多关于这个论点!
如果我在代码中的某些部分不清楚请告诉我

eagi6jfj

eagi6jfj3#

我知道这个问题很老了,但我还是决定把答案写在这里。
我首先要说的是,尽管被宣传为遵循MVC模式,但JavaFX/FXML实际上默认遵循MVP模式
有几篇关于MVC与MVP(Baeldung - MVC vs MVPGeeksForGeeks - MVC, MVP, MVVM)的好文章。在这里,我将指出关键的主要区别。

MVC模式

  • 在MVC模式中,Controller是应用程序的入口点。用户事件由控制器捕获和处理。以Spring MVC Web应用程序为例。应用程序的入口点是由控制器执行的HTTP请求处理。当然,用户需要单击视图中的按钮来发送HTTP请求,但按钮单击并不是触发后端服务器采取行动的原因。它是由您的浏览器发送的HTTP请求,作为触发Web服务器采取行动的按钮单击的结果。事实上,用户可以通过curl命令发送相同的请求。视图不是驱动交互的必要条件,它不是入口点。
  • 控制器和视图之间存在多对多关系。触发一个控制器动作可以导致取决于系统的状态而向用户示出不同的视图。控制器有权决定向用户显示什么视图。回到Web应用程序的例子,控制器可能决定对具有不同访问权限的用户发送的相同请求做出不同的响应,并显示不同的视图。此外,相同的视图可以被示出为对不同请求(例如,请求)的响应。redirect)。
  • 在传统的MVC模式中,模型和视图是耦合的,可以直接相互对话。视图使用模型的属性进行显示。我们现在在现代Web应用程序中很少看到这种情况,特别是当我们将模型称为应用程序的业务逻辑方面时。我们可以看到Spring MVC使用“Model”的概念(实际上只是一个键值对的Map)在Controller和View之间传递数据。我们可以注入一个Model的示例(这里我的意思是org.springframework.ui.Model,请不要将其与MVC Model一起使用)到控制器中,并使用它将服务/应用程序层(MVC Model)返回的数据传递到视图中。我们还可以通过方法参数或ThreadLocals或其他方式将Model(org.springframework.ui.Model)对象的示例直接传递到服务层,并实现“True MVC”。但是人们通常不会这样做,因为它耦合了应用程序逻辑(MVC模型)和视图(这是MVC的缺点,MVP试图解决)。
    MVP模式
  • 在MVP模式中,视图是应用程序的入口点。用户输入由视图处理,然后视图通过调用其方法将这些用户事件转发给演示者。这就是我们在JavaFX中看到的。当用户单击视图中的按钮时,单击事件直接由视图(场景图)中的按钮处理。我们可以连接一个回调函数,让按钮节点调用与视图关联的Presenter(FxController)的某个方法。
  • 视图和演示者之间存在一对一Map。在JavaFX中,我们只能为特定的父节点设置一个控制器。
  • 在MVP中,视图和模型是解耦的,数据只能通过中介器/表示器在它们之间传递。这就是JavaFX/FXML中发生的事情。FxController可以访问视图和更新场景图,我们可以将解析fxml生成的场景图中的节点注入到FxController中。我们通常不直接将JavaFX场景图暴露给我们的核心应用程序,我们通过FxController来实现。

总的来说,JavaFX/FXML非常灵活。它的事件处理和数据绑定功能很差,所以你可以完全使用事件驱动,最终使用MVVM(有人可能会说JavaFX/FXML默认遵循MVVM)。或者你可以更传统,最终使用MVP,你也可以开始将你的JavaFX数据绑定暴露到核心应用程序中,最终使用MVC和MVP的混合,但传统的JavaFX/FXML遵循MVP。仅仅因为JavaFX使用了“控制器”这个词并不意味着它遵循MVC。例如,Angular框架也是如此。Angular遵循MVVM,但它使用术语“控制器”来指代ViewModel。
最后一件事,在你的应用程序中并不强制要求它遵循MVP;)

相关问题