Page 1 of 1

Swing, Passive Model-View-Presenter in 5 minutes. Rate Topic: -----

#1 farrell2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 840
  • View blog
  • Posts: 2,576
  • Joined: 29-July 11

Posted 05 September 2014 - 09:02 PM

Model-View-Presener(MVP) is a variation of the Model-View-Controller (MVC) architectural pattern for building user interfaces. The main goal of MVP and its variants is separation of concerns between the user interface (UI), the model (application data), and the presenter (controller that handles business/presentation logic). This version of MVP is called passive because the View does not actively update itself, instead choosing to allow the presenter to handle that task.

In MVP, the view and the presenter are tightly coupled with the view holding a reference to the presenter and calling methods from it in response to UI events. The view knows nothing of the existence of the model.

View -> Presenter.

The presenter is fully aware of and holds references to both the Model and the View.

View <- Presenter -> Model.

The model knows nothing about either the view or the presenter. The model has one purpose: to store and retrieve data.

In this example, we'll create a simple form that checks password input. Being that the model is the simplest in this example, let's start there.

public class Model {
    private String password;
    
    public Model() {
        password = "password"; //just set a default password.
    }
    
    public void setPassword(String pass) {
        password = pass;
    }
    
    public String getPassword() {
        return password;
    }
}



That's it. For this example, our model stores a password and contains methods that set and return it. We never have to look at this class again.

Next up is the Presenter.

public class Presenter {

    private View view;
    private Model model;

    public Presenter(View view, Model model) {
        this.view = view;
        this.model = model;
    }

    public void login(String pass) {
        String result = "Incorrect password";
        
        if (model.getPassword().equals(pass)) {
            result = "Correct password";
        }
        view.updateStatusLabel(result);
    }
}



Also pretty simple. Our presenter holds a reference to the view and model. It has a login method that is called by and passed an argument from the view in response to login button event. The presenter takes the argument passed in, verifies it with the model, and if the inputted password is the same as the password set in the model, it update the view accordingly.

Our View is the most complicated, but only because of widget creation and layout.

public class View {
    private Presenter presenter; 
    private JLabel statusLabel;
    private JTextField inputField;
    
    public View() {
        createUI();
    }
    
    private void createUI() {
        statusLabel = new JLabel("This updates in reponse to input: ");
        inputField = new JTextField(20);
        JButton loginButton = new JButton("Login");
        loginButton.addActionListener((ActionEvent e) -> {
            presenter.login(inputField.getText());
        });
        
        Box topBox = Box.createHorizontalBox();
        topBox.add(statusLabel);
        topBox.add(Box.createHorizontalStrut(5));
        topBox.add(inputField);
        topBox.add(Box.createHorizontalStrut(5));
        topBox.add(loginButton);
        
        JFrame frame = new JFrame("Passive MVP Swing");
        ((JPanel)frame.getContentPane()).setBackground(Color.white);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(topBox, BorderLayout.NORTH);
        frame.pack();
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }
    
    public void setPresenter(Presenter pres) {
        presenter = pres;
    }
    
    //called by the presenter to update the status label.
    public void updateStatusLabel(String text) {
        statusLabel.setText(text);
    }
}



The view holds a reference to the presenter so it can call methods in it. The loginButton calls presenter.login() to start the password verification process. The presenter calls updateStatusLabel() to update the view.

Next we just need a main class to tie it all together.

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            View view = new View();
            view.setPresenter(new Presenter(view, new Model()));
        });
    }
}



We instantiate the view on the EDT, and to save time, we just set the presenter and instantiate the model there as well. You may not always want to set the presenter and instantiate the model on the edt so as to not cause usability problems with the UI. e.g. a model created from a remote database.

That's it. Simple MVP in Swing in about 5 minutes.

This post has been edited by farrell2k: 06 September 2014 - 01:04 AM


Is This A Good Question/Topic? 3
  • +

Page 1 of 1