MVP, JavaFx and Component References

I studied all the popular GUI patterns - MVP, MVC, MVVM and finally decided to implement MVP (Supervising Controller). Therefore, I have the following OBJECTS (!). Stage<-View<->Model

... This is an important step! = View, this is another object. Between view and model data binding. Also, I have a presenter (controller) that handles all events and works with the view and model, therefore View<-ViewInterface<-Controller->Model

. The problem is how to get links to labels, textAreas, etc. Javafx allows you to use @FXML annotation to inject these components into the controller. However, using MVP I need these components in the view, since all the logic for the view is in the view and I don't need them in the controller. The only thing I know is:

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

      

That is, to get links by their ID. However, I don't like this. Either I am doing something wrong or I understand something wrong, but I think there is a better solution. Please help me find it.

+3


source to share


2 answers


JavaFX was designed to work with the MVC pattern. Hence, it is much easier to use MVC than MVP. In MVP, Presenter is responsible for formatting the displayed data. In JavaFX, this is done automatically with View . Here's a quick overview of JavaFX MVC:

Model - Domain data / data structure that you work with in your application (e.g. Person, Employer, Coursework, etc.)

Show - defines the user interface of the application and its model. The preferred way to create a view is with a file FXML

, which is essentially a View in JavaFX MVC.

The controller is the bridge between Model and View . Usually the code is highlighted in a class XController

(where X is the name of the FXML

View ). The Controller instance is automatically entered FXMLLoader

or can be executed manually if you need a custom Controller . The class Controller

will have access to UI elements ( View ) in order to be able to manipulate various properties, as well as the Model so that it can perform operations based on the user interface ( View ).



To summarize, in JavaFX you don't need to have a class View

, the View definition must be completely in the file FXML

. All user interface elements should be injected @FXML

into the class Controller

. If you absolutely need to use MVP, then AWT / Swing or MVP4j is the best option - http://www.findbestopensource.com/product/mvp4j .

For a more detailed explanation, please check out the Oracle Official Tutorial for JavaFX: http://docs.oracle.com/javase/8/javafx/get-started-tutorial/jfx-overview.htm

If you need help building the UI using FXML

: http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html

This tutorial covers the basics of MVC in JavaFX and how each component interacts with others: http://code.makery.ch/library/javafx-8-tutorial/part1/

+4


source


As an Android developer, I always use the MVP pattern in my applications. MVC is so old compared to MVP, so when I started working on a new Java application, I felt a little lost.

There is my solution here:

Initial steps

  • In the files, fxml

    create the UI without specifying the controller, because you don't need one.
  • Create Java interfaces (IView, IPresenter, etc.)

  • Implement IPresenter interface

    in Presenter class

    as you normally would (make HTTP requests, query DB ..)

Now for the fun part:

Adapting your view to the MVP pattern

Look at the code:

  • Create your GUI (like the main GUI) and implement your 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
      }
    
          

Now the last step:



Communication with the presenter

  • To do this, we first create our host's position:

    private MainContract.Presenter presenter;
    
    public MainGUI() {
        presenter = new MainPresenter(this);
    }
    
          

    this

    - this is, of course MainContract.View

    , implemented in MainGUI class



  • Now we need to get a reference to the view components

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

I prefer to use files fxml

instead of creating ui from code, but the logic behind is identical.

  • Set items

    ...
    mySimpleList.setItems(ValuesFactory.getMyValues());
    
          

  • And the listener

    ...
    mySimpleList.valueProperty().addListener(simpleListListener);
    
          


What is it simpleListListener

?

Simple ChangeListener

, where we finally call the presenter method

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

      

This is a simple scenario, but in principle we can use the MVP pattern with JavaFX. I also understand that this is not a final solution, so I hope there will be more docs one day where I can learn more about this argument!
Let me know if I don't understand in some part of the code

+2


source







All Articles