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
andJButton
? - 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?