0

So far, I have implemented a GUI based on Swing, and according to the MVC pattern like (here), where events are fired from both view (by using JComponents capabilities) and model (by using PropertyChangeSupport bean). The controller is in the middle, listening both of them and forwarding events, as follows:

VIEW

public class GUIview extends JFrame {
    public void propertyChange(final PropertyChangeEvent event) {
        if (event.getPropertyName().equals(GUIcontroller.A1_PROPERTY)) {
            method_a1(event.getNewValue());
        } else if (event.getPropertyName().equals(GUIcontroller.A2_PROPERTY)) {
            method_a2(event.getNewValue());
        }
    }
    public void method_a1() {...}
    public void method_a2() {...}
}

CONTROLLER

public class GUIcontroller implements PropertyChangeListener {

    public static final String A1_PROPERTY = "a1";
    public static final String A2_PROPERTY = "a2";
    public static final String B1_PROPERTY = "b1";
    public static final String B2_PROPERTY = "b2";

    public void propertyChange(PropertyChangeEvent event) {
        if (event.getPropertyName().charAt(0) == 'a') {
            GUIview.propertyChange(event);
        } else if (event.getPropertyName().charAt(0) == 'b') {
            GUImodel.propertyChange(event);
        }
    }
}

MODEL

public class GUImodel {

    public PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }
    protected void firePropertyChange(String propertyName, Object oldValue,
            Object newValue) {
        propertyChangeSupport.firePropertyChange(propertyName, oldValue,
                newValue);
    }   
    public void propertyChange(final PropertyChangeEvent event) {

        if (event.getPropertyName().equals(GUIcontroller.B1_PROPERTY)) {
            method_b1(event.getNewValue());
        } else if (event.getPropertyName().equals(GUIcontroller.B2_PROPERTY)) {
            method_b2(event.getNewValue());
        }
    }
    public void method_b1() {...}
    public void method_b2() {...}
}

Now it works, but as far as I know (or as far as I have read), the view should only contain layout functionality, and all the work must be done by the controller and the model. On the other hand, the controller should be as thinner as possible.

I can´t find a reason to implement propertyChange() methods on both view and model, and make method calls from there, instead of directly call those methods from the controller, like this:

public class GUIcontroller implements PropertyChangeListener {

    public static final String A1_PROPERTY = "a1";
    public static final String A2_PROPERTY = "a2";
    public static final String B1_PROPERTY = "b1";
    public static final String B2_PROPERTY = "b2";

    public void propertyChange(PropertyChangeEvent event) {
        if (event.getPropertyName().equals(GUIcontroller.A1_PROPERTY)) {
            GUIview.method_a1(event.getNewValue());
        } else if (event.getPropertyName().equals(GUIcontroller.A2_PROPERTY)) {
            GUIview.method_a2(event.getNewValue());
        } else if (event.getPropertyName().equals(GUIcontroller.B1_PROPERTY)) {
            GUImodel.method_b1(event.getNewValue());
        } else if (event.getPropertyName().equals(GUIcontroller.B2_PROPERTY)) {
            GUImodel.method_b2(event.getNewValue());
        }
    }
}

Considering these two approaches, which one is more tight to a real MVC pattern?

Which could be the main reason to implement propertyChange() methods on view and model?

tereško
  • 58,060
  • 25
  • 98
  • 150
capovawi
  • 377
  • 8
  • 21
  • 1
    for better help sooner post an [SSCCE](http://sscce.org/), short, runnable, compilable, otherwise could be about guessing, please [to see example](http://stackoverflow.com/q/8169964/714968) – mKorbel Jul 10 '13 at 10:23
  • 2
    See also examples [here](http://stackoverflow.com/a/2687871/230513) and [here](http://stackoverflow.com/a/3072979/230513). – trashgod Jul 10 '13 at 10:25
  • OK, I guess there is no need to implement propertyChange() on the model. Just call the model methods from the controller. And on the opposite direction (from model to view), it can be directly done, just declaring the view as a listener of the model and implementing propertyChange() whitin the view. – capovawi Jul 10 '13 at 13:57
  • I post the same question here @trashgod, let´s say I have a GUIview with 2 JTables and I have developed 2 TableModels besides the GUImodel (2 more classes in the GUImodel package, extending AbstractTableModel). Now I want to filter the information displayed on the tables, so I use a TableRowSorter, but right now the filtering methods are in the view, and I guess they should be somewhere else. Am I right? Should I move those methods (containing TableRowSorter code) to a TableModel? – capovawi Jul 10 '13 at 14:03

1 Answers1

4

In MVC, Views listen to the model and update themselves accordingly. Controllers are reponsible to handle user input to modify the model. Model is responsible to fire appropriate events when it changes.

Which could be the main reason to implement propertyChange() methods on view and model?

  • On view: fine, upon property change events, the view should update itself accordingly
  • On model: no reason to implement that method, since the model will never listen for property changes.
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • There are multiple ways to implement MVC. I mean, not MVC, but different approaches quite similar to MVC. In my case, communication between view and model is handled IN BOTH WAYS through the controller. The view has no direct access to the model, therefore the model needs to implement listeners. – capovawi Jul 10 '13 at 10:35
  • @capovawi Views should have access to the model. Not to modify the model itself, but to read its current state and update the view accordingly. Check out [this image](http://img.my.csdn.net/uploads/201112/31/0_1325315861u0Zu.gif) for a better understanding. – Guillaume Polet Jul 10 '13 at 11:02
  • regarding communication between View and Models, I have a doubt: I am working with one view that contains several tables. Each table has its own tableModel, therefore I have several models!! Sometimes I need to filter the information showed in the tables, therefore I use a TableRowSorter. But so far, I have implemented filtering methods in the view, and I guess it would be more correct to do it within the model. Am i right? – capovawi Jul 10 '13 at 12:49
  • +1 for the [image](http://img.my.csdn.net/uploads/201112/31/0_1325315861u0Zu.gif); a similar approach is outlined [here](http://stackoverflow.com/a/2687871/230513). @capovawi: No, `TableRowSorter` sorts and filters the view, `JTable`, which implements `RowSorterListener`; note that "The default sort order is natural (_the same as the model_)." – trashgod Jul 10 '13 at 18:20
  • Sequence would be: the user clicks on a JButton on the view, controller is listening and when user´s action is performed, controller modifies model through a model-method call. This method uses a TableRowSorter to filter data. Finally, the view is updated because implements RowSorterListener (model automatically notifies change to the view). Is this OK, @trashgod ? – capovawi Jul 10 '13 at 21:11