MVP、JavaFx 和组件参考

MVP, JavaFx and components references

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

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

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

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

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

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

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

总而言之,在JavaFX中你不需要class ViewView定义应该完全在FXML 文件。所有 UI 元素都应与 @FXML 一起注入到您的 Controller class 中。如果您绝对必须使用 MVP,那么 AWT/Swing 或 MVP4j - 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/

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

这是我的解决方案:

初始步骤

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

  • 像往常一样在 Presenter class 中实现 IPresenter interface(做 http 请求,查询数据库..)

现在是有趣的部分:

根据 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当然是在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);

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