【问题标题】:MVP, JavaFx and components referencesMVP、JavaFx 和组件参考
【发布时间】:2015-05-31 06:53:06
【问题描述】:

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

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

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

【问题讨论】:

  • 如何加载 MyView?你是在代码中构建它,还是从 FXML 加载?
  • @Steven Van Impe 我用代码构建它

标签: java design-patterns model-view-controller javafx


【解决方案1】:

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

模型 - 您在应用程序中使用的域数据/数据结构(例如人员、雇主、课程作业等)

View - 应用程序及其模型的 UI 定义。创建视图的首选方式是通过FXML 文件,它本质上是JavaFX MVC 中的View

Controller - ModelView 之间的桥梁。代码通常隔离在XController 类中(其中X 是FXML 视图 的名称)。 Controller 的实例由FXMLLoader 自动注入,如果您需要自定义Controller,也可以手动完成。 Controller 类将有权访问 UI (View) 元素,以便能够操作不同的属性以及 Model,以便它可以执行基于UI(视图)输入。

总而言之,在JavaFX 中你不需要有View 类,View 定义应该完全在FXML 文件中。所有 UI 元素都应使用 @FXML 注入到您的 Controller 类中。如果您绝对必须使用 MVP,那么 AWT/Swing 或 MVP4j - http://www.findbestopensource.com/product/mvp4j 可能是更好的选择。

更详细的解释请看Oracle官方JavaFX教程: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/

【讨论】:

  • ,我真的很困惑在 JavaFX 项目中使用 MVC 还是 MVP,这里的问题是控制器如何在 MVC 模型中在它们之间进行通信?
【解决方案2】:

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

这是我的解决方案:

初始步骤

  • fxml 文件中创建 UI,无需指定控制器,因为您不需要控制器。
  • 创建 Java 接口(IView、IPresenter 等..)

  • 在 Presenter class 中实现 IPresenter interface,就像您通常所做的那样(执行 http 请求,查询 DB..)

现在有趣的部分:

使您的视图适应 MVP 模式

让我们看一些代码:

  • 创建您的 GUI(例如主 GUI)并实现您的视图 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 当然是在 MainGUI 中实现的MainContract.View class

  • 现在我们必须获得对视图组件的引用

    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);

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

【讨论】:

  • 但是 IDE 为视图创建了一个控制器,为什么我们需要转向 MVP 模式?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 2013-07-08
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
相关资源
最近更新 更多