aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Forwarding data changes in MVC Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Forwarding data changes in MVC" Watch "Forwarding data changes in MVC" New topic
Author

Forwarding data changes in MVC

Robert Sherman
Greenhorn

Joined: Jan 28, 2010
Posts: 3
Hello,

I'm currently trying to implement a GUI using the MVC pattern and need some advice.

Up until now I've been closely following Sun's MVC example.
I know that isn't the definite way to implement MVC, but everything is working fine so far.
The following classes show a simplified version of my program.

Model


Controller


View



As you can see, changing the values of single objects or objects located in arrays is no problem.
But now I want to add/remove elements to/from an ArrayList in the model and I'm not sure how to forward the information to the controller and view.

I thought about multiple solutions, like using PropertyChangeEvents with null values

but that looks very "hacky".

I also thought about firing ListDataEvents and let the Controller implement ListDataListener, but ListDataEvent only contains information about the range in which elements changed and not what elements were actually added.

So, I'm a little lost here, any advice is welcome.
(If you think the Sun implementation in general is a bad example I'd be happy to hear your criticism too.)
Robert Sherman
Greenhorn

Joined: Jan 28, 2010
Posts: 3
Ok, I've got a more basic question.

Should I even bother to notify the View of single add/remove operations on the list or is it better just to send send a "list changed" notification and let the View request the whole list from the model?
As in call a model method like:
Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
I'm currently trying to implement a GUI using the MVC pattern and need some advice.


The key part of any application implementing the Model-View-Controller design pattern in the Model application.

The goal of the pattern is to eliminate "technical" dependencies on the View application. You should be able to
have a single Model application and multiple Views via View/Controller pairs. Cell phone, PDA, command-line, HTML browser should all be able to easily communicate with a Model application. What this means is there is no business logic in the View or the Controller.

The View only contains logic for displaying a GUI and displaying data returned from Model. Note, the Model returns data when an action is initiated from the View. Model doesn't start this process. The "human" that is using the GUI starts the process.

In your classes, you don't have any business methods in the Model class and you don't have any GUI controls in your View class. I suggest that you start over, first defining some business method(s) and then creating a GUI, and then create the Controller to enable the View to execute a business method and display some data returned from the Model.

Good luck!
Robert Sherman
Greenhorn

Joined: Jan 28, 2010
Posts: 3
Thanks for the reply!

James Clarks wrote:
The key part of any application implementing the Model-View-Controller design pattern in the Model application.

The goal of the pattern is to eliminate "technical" dependencies on the View application. You should be able to
have a single Model application and multiple Views via View/Controller pairs. Cell phone, PDA, command-line, HTML browser should all be able to easily communicate with a Model application. What this means is there is no business logic in the View or the Controller.


That is clear to me.
On a side note: The controller in the Sun example (see link in first post) keeps a list of registered models.
When does it make sense to register multiple models with a constroller?
But back to my problem...


The View only contains logic for displaying a GUI and displaying data returned from Model. Note, the Model returns data when an action is initiated from the View. Model doesn't start this process. The "human" that is using the GUI starts the process.


That's how I implemented my classes.
View manages swing components and registers ActionListeners / MouseListeners and so on.
Model holds all data and provides methods to get/set and work with the data.


In your classes, you don't have any business methods in the Model class and you don't have any GUI controls in your View class. I suggest that you start over, first defining some business method(s) and then creating a GUI, and then create the Controller to enable the View to execute a business method and display some data returned from the Model.


The code samples I provided are extremely simplified versions of my real classes.
I tried to reduce them to the parts I am unsure about.

My actual View extends JPanel and displays a guitar fretboard.
It contains JComboBoxes to set the tuning of each string (guitar string not Java string ) and a custom component (extends JComponent) that draws the fretboard.
The user can click on the fretboard and select or deselect fret/string positions. The fretboard draws markers at all selected frets and displays the corresponding notes.

The component that actually draws the fretboard holds information about the number of strings and frets, the tuning of each string, fret selection and some other stuff.

My model among others contains information about the number of strings and frets (int variables), tuning of each string (Note array) and the selected fret/string positions (ArrayList<Point>).
[Note: I guess keeping two (or more if there's more than one view) copies of the properties in memory is unavoidable? E.g. the model saves the number of strings in an int, but the swing component also saves it's own string number int that is used in the draw method.]
It provides getter/setter methods for all properties, methods to add/remove fret selections and to find the list of notes that are defined by the fret selection.
So at least the last method that calculates the note list is pure business logic, isn't it?

Now lets say I click on the fretboard component. A MouseEvent is send to the components MouseListener which calls the controller method toggleFretSelection(<Point> fret). This controller method does nothing but call the model method toggleFretSelection(<Point> fret).
[Note: Basically all my controller methods call model methods with the exact same signature. Feels kind of wierd, is this how it's supposed to be done?]

If the provided fret position is already selected the model will remove the selection, otherwise it will add the position to the ArrayList.
Then it calls firePropertyChange("fretSelection", newValue, oldValue), where newValue is null if a list item has been removed (oldValue is the removed value) or
oldValue is null if an item (newValue) has been added.
The controller passes this PropertyChangeEvent to the view, which checks wether an add or remove occured.
The view calls the (de)selectFretPosition(Point fret) method of the component that draws the fretboard, which updates it's internal ArrayList accordingly and calls repaint().

My original question was wether or not this way of firing a PropertyChangeEvent and handling it in a view method is good practice.
I have seen MVC examples where the model only notifies the view of a change, which then directly calls one of the model's get methods to obtain the new value.
In other examples the model sends a notification AND the new value to the view, so the view can use the passed value and doesn't have to keep a reference to the model.

My view doesn't know about the model, except for the reference that is provided via PropertyChangeEvent.getSource().
So, should I use this reference? Theoretically I could even use it to directly change model data by calling getSource().setXXX() from the view and bypass the controller, but I assume that wouldn't be in the spirit of MVC?
Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
[Note: Basically all my controller methods call model methods with the exact same signature. Feels kind of wierd, is this how it's supposed to be done?]


There is no single way to implement the pattern. "Your" implementation is measured in terms of how efficient the class design is and the degrees of maintainability and extensibility that "your" implementation has. In an acutal enterprise implementation, there typically would not be one-to-one relation between Controller and Business Model methods. For example, a Controller might have a single method called "execute" and the rest of the information is parameterized and/or contained in Controller supporting objects, e.g. Struts ActionServlet, ActionForward, and Action objects.

Keep in mind that examples illustrating design pattern principles may vary from how the pattern actually is implemented in practice.

The purpose of the Controller is to mediate communications between a particular View and the Model application. So, a View never should have a reference to something in the Model application. A Controller is the part that has the reference to a part of the Model application. A View connects to the Model application via a Controller. The Model application does not have any connection or reference to a particular Controller or anything in a particular View.

The Model application should be completely independent from a particular View/Controller pair.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Forwarding data changes in MVC