MVP, JavaFx和组件参考



我研究了所有流行的GUI模式- MVP,MVC,MVVM,最后我决定实现MVP(监督控制器)。所以我有以下对象(!)。Stage<-View<->Model。这是重要的舞台!=视图,它是另一个对象。在视图和模型数据绑定之间。此外,我有一个演示者(控制器),它处理所有事件,并与视图和模型一起工作,所以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的快速概述:

Model -你在应用程序中使用的域数据/数据结构(例如Person, Employer, Coursework等)

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

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

总而言之,在JavaFX中不需要有View类,View定义应该完全在FXML文件中。所有的UI元素都应该用@FXML注入到Controller类中。如果你一定要使用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模式。MVC与MVP相比对我来说太老了,所以当我开始开发一个新的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当然是在 mainui中实现的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);

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

最新更新