0

I am creating a Java Swing application. The architecture, I've chosen is a variation of MVP, MVP with Supervising Controller.

I am using JGoodies Binding Framework to bind model directly to the view.

After reading a lot of resources on MVP, I found that it is a good practice to make your view implement an interface with which a presenter can work. This will allow to swap in different views, without affecting presenter code. Also, it would help in unit testing by mocking the views.

But, I am having difficulty to think of a View interface design in the swing context.

Here is the code, for viewing a contact and launching its editor:

public class Contact extends Bean {

  private Integer id;
  private String name = "";
  private String email = "";

  public Contact() {}

  // Getters

  // Setters with fire property change methods

}

public Class ContactViewer {

  private JPanel panel;
  JLabel nameLabel;
  JLabel emailLabel;
  JButton edit;

  ContactViewer() {
    initComponents();
    build();
  }

  private void initComponents() {
    // Initializing panel, labels and button
  }

  private void build() {
    // Layouts labels & button onto panel
  }

}

public Class ContactViewerModel extends PresentationModel<Contact> {

  ContactViewerModel(Contact contact) {
    super(contact);
  }

}

public Class ContactViewerPresenter {

  private final ContactViewerModel model;
  private final ContactViewer view;

  public static ContactViewerPresenter create(Contact contact) {
    ContactViewerModel model = new ContactViewerModel(contact);
    ContactViewer view = new ContactViewer();
    ContactViewerPresenter presenter = new ContactViewerPresenter(model, view);
    return presenter;
  }

  ContactViewerPresenter(ContactViewerModel model, ContactViewer view) {
    this.model = model;
    this.view = view;
    initBindings();
    initEventHandlers();
  }

  private void initBindings() {
    PresentationModelBinder binder = Binders.binderFor(model);
    binder.bindBeanProperty(FIRST_NAME)     .to(view.nameLabel);
    binder.bindBeanProperty(EMAIL)          .to(view.emailLabel);
  }

  private void initEventHandlers() {
    view.edit.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            // Launch Contact Editor
        }

    });
  }

}

public class ContactDemo {

  public static void main(String[] args) {
    final Contact contact = new Contact("John Doe", "info@johndoe.com");
    SwingUtilities.invokeLater(
        new Runnable() {
            @Override
            public void run() {
                ComponentFactory.createAndShowDialog(
                    ContactViewerPresenter.create(contact));
            }
    });
  }

}

In this code, ContactViewer, ContactViewerModel, ContactViewerPresenter are in the same package. So that, presenter can directly refer to package-private component fields of the view, to bind them to the model and adding event handlers.

Now, when designing an interface for ContactViewer:

  • Should I define getter methods in interface for JLabel and JButton?
  • Or should I define a super interface first for all View, then sub-interfaces for each view, on which unit-testing can be performed by mocking events.
  • Also, what would be the best approach to show different views for multilanguage support?
Akshat
  • 720
  • 9
  • 24
  • 1
    *"package-private component fields of the view, to bind them to the model and adding event handlers"* Isn't that kind of breaking the intention of using interfaces? They should define the public contract so any view/controller/model can be used...? IMHO, your "view" shouldn't expose any functionality which "assumes" anything about the how the contract might be implemented (so exposing UI components, IMHO is a bad idea) – MadProgrammer Apr 18 '15 at 05:03
  • 1
    *"Also, what would be the best approach to show different views for multilanguage support?"* - This is what the i18n support is for, see [Isolating Locale-Specific Data](https://docs.oracle.com/javase/tutorial/i18n/resbundle/index.html) – MadProgrammer Apr 18 '15 at 05:04
  • @MadProgrammer I know, the code I implemented is not right. And, want to implement the design you are suggesting. But, I am unable to come up with a design for view interfaces. – Akshat Apr 18 '15 at 05:07
  • Normally I start with an interface (usually using generics), which provides a getter to get the view `JComponent` and sets the views "controller" - but that depends on who is actually managing the "creation" and "adding" of the views to the physical screen – MadProgrammer Apr 18 '15 at 05:14
  • Are you proposing to define generic type presenters for Views? As it would make sense when the entry-point is view. But, I am thinking to use [Presenter-First](https://atomicobject.com/uploadedImages/archive/files/PresenterFirstAgile2006.pdf) approach, in which presenter is the entry-point! – Akshat Apr 18 '15 at 05:26
  • So a presenter would be, maybe, a `JFrame` or `JDialog` (or even possible another `JComponent`), but in order to add a view to any of the presenters, you will need a reference to a `JComponent` – MadProgrammer Apr 18 '15 at 05:29
  • No, presenter will not be a `JFrame` or `JDialog` as it would conflict the MVP design guidelines. By "Presenter as an entry-point", I mean, that I will call `ContactViewerPresenter.create()` method to initialize MVP triad. And, I will keep top-level swing containers `JFrame`, `JDialog` out of the MVP architecture, like I did above in the code, by using a Component Factory. – Akshat Apr 18 '15 at 05:36
  • As, this discussion is extending, do you have some kind of resource or link that illustrate using interfaces for MVP design in Java Swing Context? – Akshat Apr 18 '15 at 05:38
  • Okay then, how does the "view" get on the screen? You still need some minimal contract that states that all views should have a component element? Or does some other class build the actually view from the view contract? – MadProgrammer Apr 18 '15 at 05:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75565/discussion-between-akshat-and-madprogrammer). – Akshat Apr 18 '15 at 05:39
  • Maybe http://stackoverflow.com/questions/26517856/java-swing-where-do-actionlisteners-belong-according-to-mvc-pattern/26518274#26518274 or http://stackoverflow.com/questions/29571722/java-application-with-multiple-scenes/29639672#29639672 – MadProgrammer Apr 18 '15 at 05:40

0 Answers0