Hi. I have attempted to build the client portion of the assignment using the MVC pattern. Namely, I am attempting to separate out all of the data manipulation from the view, coordinating the 2 with a controller. Is this overkill for the assignment? I have thought about just building a large gui class with the models as inner classes. If this is not overkill, what have you found to be the best way to separate the event handling into the controller, rather than in the view? For example, a button in my view fires an action that is dependent on selected data in the view (like a table column). How do you successfully propagate the selected data into the action when the action is defined within the controller?
Is there a more "MVC" way to do this? Thanks, Aaron
I don't know about everyone else, but my Controller only contains business logic, such as you can't select the same origin and destination when searching for records, etc. The View does one thing - paint the screen with data. Any logic related to that stays in the View. Anytime a request is made for data in any way - search, update, etc. it goes to Model. So, if an ActionListener is added to a Find button, that action (and any find criteria) is passed over to the Model (through a Facade) and the Model handles retrieving the data. If this is an improper way to implement, though, I sure would appreciate feed back from anyone.
SCJP, SCJD, SCWCD, SCEA Part I
Joined: May 10, 2002
I believe that all of the event handling (business logic) should be handled by the controller... not by the model. The model represents the data and should not know anything about how the view interacts with the controller to manipulate it. It should only get updated and then the controller will notify the view of a model update. Here is my problem: My JTable is a member of the view class (ResultPanel)... not the model that backs it. When a user selects a particular row in order to book a flight, I need a way to pass the selected flight information (only known to the view) to the controller. I am handling this problem by using SwingPropertyChangeSupport, but it is becoming quite convoluted. Whose responsibility is it to keep track of the selected row in the view's table? Thanks,
I would think it's the view's responsibility to know the selected row in its table. My controller holds references to the views. The controller listens for the action event that occurs when the user decides to book a flight. The controller then asks the view for its selected row. Any feedback is appreciated.
Whose responsibility is it to keep track of the selected row in the view's table?
Event handler should be in the controller. In this case, the controller serves the model/controller part for your GUI. Keep the table model in the controller.
Joined: May 01, 2002
I agree that the Event handler should be with the controller, but I think the TableModel is a view of the data and should be kept with the view. The Controller should pass actual data (DataInfo) to the view, and the view should construct the TableModel from that data. All the controller needs to know from the view is which record was selected.
Originally posted by Aaron Dressin: I believe that all of the event handling (business logic) should be handled by the controller... not by the model. The model represents the data and should not know anything about how the view interacts with the controller to manipulate it. It should only get updated and then the controller will notify the view of a model update.
Since the early part of the thread seemed to be heading in the "what is the proper way to use MVC?" direction, I just wanted to add a couple of comments. I'm not saying your approach isn't valid, just that there may be another way of thinking about it. People often get confused about the roles within MVC. Most of that stems from the fact that we get in the habit of thinking that there are three components, when that isn't what the pattern is about. The general scenario is multiple views, multiple controllers (both possibly changing in number or kind dynamically) and one model. When you think of MVC as three components and have some coding issue, you think "where should I put this piece of code?". You debate whether the issues feels view-like, etc. Generally the result is that the controller or view end up as a dumping ground for things they shouldn't contain. Business logic is a typical example. If you have one model, and multiple views and controllers, the answer is pretty obvious. Business logic is shared, and belongs in the model so that the model can enforce the business rules. Changing views and changing controllers doesn't change your business logic. That is the pattern. Events are not business logic, they are just a communications/notification mechanism. For more information on MVC, I'd suggest "Pattern-Oriented Software Architecture", Buschmann et al. I've got the older one-volume book; there is now a two-volume set (not sure which volume contains MVC).
Reid - SCJP2 (April 2002)
Joined: Feb 25, 2002
Originally posted by Robin Underwood: The Controller should pass actual data (DataInfo) to the view, and the view should construct the TableModel from that data. All the controller needs to know from the view is which record was selected.
What if you migrate this application CORBA or EJB architecture and there is no DataInfo class anymore? How many classes you want change to extend the current architecture? If the view knows about the business object or any architecure specific classes, it is a bad design. [ May 30, 2002: Message edited by: Sai Prasad ]
hi reid, very lucid description of a topic that i too have westled with. would you implement all calls to the db (which in my case is behind a facade) in the model? and would you agree that the tablemodel is the model in this case (as the name implies)? and thirdly, when i want to do a search i trigger an action in the controller. will this action call a method on the tablemodel, or would you make the model a listner on the controller? sincerely morten wilken
Reid M. Pinchback
Joined: Jan 25, 2002
Well, I'm only signing up today to start on the SCJD, so I haven't seen the project. I can only speak a bit off the top of my head. To me the most important initial architectural question is, where are the MVC components located? The view is pretty obvious; that is on the client side. What about the rest? There are multiple choices. In EJB, the model would definitely only be on the server side. The question would more be about locating the controller. At least part of it would be on the client (i.e. the web container) side. There might be a bit of it on the server side, e.g. if session beans are hiding entity beans or queueing requests via JMS. For an RMI project I'm not sure yet where the balance is. Obviously some of the controller is on the client side; I think probably all of the controller. What I'm not sure of is the model; does the model have a bit of a footprint in the client? I don't have any answers yet to your table questions; Swing is a new experience for me. I've been doing servlet and EJB stuff for a few years, but I'm taking the SCJD to motivate me to work with the Java technologies I otherwise wouldn't touch. Re: facade and calls to the db; I don't know your code, but I would assume that you are using a facade to simplify the interface to the model. If that is the case, then anything the facade would invoke sounds like it would be part of the model. The "where does the code really live" question can get a little fuzzy when you start entering the realm of pattern composition.
Joined: May 01, 2002
Sai, I thought about what you said and I changed my mind. I agree that the Table Model should go in the Controller. I'm going to pass a ready-to-go Table Model to my view so it won't need to know anything about DataInfo or FieldInfo. Thanks for your input! Robin
Joined: May 25, 2002
just to continue the discussion, in my design the JTable is the view, the controller is the class where i implement the inner listener classes. the model is the TableModel i have implemented that wraps a DataInfo. my question is: how does the controller change the model? do i put businesslogic methods (ie. bookflight) in the tablemodel? today i have a businessfacade with the methods, so i could also let the controller call by facade and let the tablemodel 'observe' (with Observer) the facade. im a bit puzzled here.... what do you think? sincerely morten wilken
Joined: Feb 25, 2002
I would keep the table model reusable. So I wouldn't use any flight or architecure specific objects in the table model. You can use Object to communicate between the controller and the table model.
I know this is an old thread, but here is how I am implementing MVC.
Since I have a client-remote, client-local, and server, I have 3 controllers with an appropriately designed hierarchy.
Views contain no business logic aside from what is needed to manipulate the GUI: the views are merely the components that are displayed.
The models back the views. Whatever data I need to propagate around the client is stored in the model. So, if any text field is updated or row is selected, or if a result set is returned from a search, these values are stored in the appropriate model.
All views instantiate their own models, but not all views have an associated model. For instance, I have a status bar whose displayable data is pushed to it from various view and controller events.
Each view and model is registered on the controller.
When an event occurs from a view, the event with appropriate data is sent to the controller and the controller notifies each registered model via reflection. If, a model is interested in listening to a particular event from a view it will be invoked. Once the model changes, all other views that are interested in the change will update accordingly.
For example, when I press 'search' on my search view, it invokes the controller. The controller, since it contains all the business components, will query the database (locally or remotely.) Upon returning with the results a Vector<E> is sent to the appropriate model, the model then passes the data to the search results view and updates the table: the model also passes the results to the status bar view and it updates it's status for number of records returned.
The controller, can also initiate an update to view components when it sees fit. If for example the network is inaccessible, it will push this information to the status bar, and disable the CSR main screen for all user inputs.
I was having the same trouble figuring out how to use AbstractActions within MVC. I'm also new to OOP. Glad to see this question...
MVC architecture sounds simple enough in theory but when it comes down to actually implementing it within a OOC environment, it's not as easy as it sounds.
The solution that I came up with was as follows:
1. Handle the button click using an AbstractAction inner class of the View.
2. The Action class identifies which button was clicked (via e.ActionCommand) and passes control back to the View (via appropriate View.method)
3. The View then handles the portion that it needs to handle and passes Application data and requests to the Controller directly via Controller.method calls
4. The Controller can then interface with the model. It can also pass data back to the View as necessary.
In order for this to work, when the app starts up, the Main method creates the M and V objects, then passes them to C (via constructor) when C is created. Then C (within the constructor) passes itself directly to V (via V.method call) (You can also do the same with M, if need be, but I'm not sure that M needs direct access to C). The V now has access to C directly and C has direct access to V (2way communication between the actual App instances of each). To pass data/requests between the two, just setup methods in each to handle each others requests. Or you might be able to create/setup port/channel methods linking the two, and just sort the requests like you would thru normal port communications. I haven't tried it that way yet, but am going experiment to see how that will work. I think the benefit of that approach would be a reduction in the number of unique methods that each class would have (sending data/requests along a dedicated dual-pipeline). We process online communication that way right? Why not in App MVC?
I was successful with the first approach but haven't tested the port/channel approach yet.
I came up with this by trial and error since I have no formal training in MVC and could not find anything online to show me how to 'physically' do it, especially when using AbstractAction in the View. My main draw to this is the benefits of controlling button/menu styles and enablement thru the actions themselves. Which to me is a better approach to maintaining the code in the future.
I would post the code, but it's in 4 separate class files and not sure if that's something others want cluttering up the page. Contact me if you want to see it.
Does this sound like an approach others are using to do MVC? Or am I making it more complex than it needs to be?
Joined: Jul 01, 2015
I know this is an old question and the OP probably has no use for this answer anymore, but I'm trying to sort thru these types of questions myself at the moment and it helps to 'process' some of this in my mind. My comments here are to gain clarification of understanding for myself about this topic. Feedback to my comments are welcome for my continued learning...
Aaron Dressin wrote:My JTable is a member of the view class (ResultPanel)... not the model that backs it. When a user selects a particular row in order to book a flight, I need a way to pass the selected flight information (only known to the view) to the controller. I am handling this problem by using SwingPropertyChangeSupport, but it is becoming quite convoluted.
Whose responsibility is it to keep track of the selected row in the view's table? Thanks,
My understanding is that the selected row is reflected through the ListSelectionModel, which is separate from the TableModel. A ListSelectionListener can be registered with the JTable and track this selected data. The View can let any changes take place on the JTable (as long as the JTable view and TableModel stay in sync) without needing to track the selections being made. It's only at the point when the user presses "Search" that the View needs to pass the request and selected data on to the controller so that the controller can interface with an outside object like the Model (query/database/etc).
Another point worth mentioning... TableModel should be thought of as Table Info/State/Data, and as such, the Table itself. Swing is the View portion of the MVC, but it has internal 'memory models' that describe each component. These memory models (ListModel, TableModel, etc.) should not be confused with the Model portion of the app level MVC architecture. The TableModel IS the table, just lives in memory. The word 'Model' has multiple meanings and is a large source of confusion regarding MVC architecture. I know it was for me until just recently.
In my opinion the Model portion of the App MVC should only respond to requests for data or store incoming data that is pushed to it. I don't think it should ever interact with the View directly (paper and pencils don't interact with each other without someone/something there to cause their interaction - person/controller). A pencil doesn't make a request from the person's hand to draw on the paper, or care whats being drawn in order to do it's job of storing and handing out lead. The Model may have an internal controller that requests data outside the MVC in order to perform it's duties, but in this case, it will be performing the controller function of a separate MVC entity. The only other responsibility would be that it might format the data when it is received or before it sends it out.
So to answer your question, I think it should be the View's responsibility for tracking the change, then it can submit directly to the controller
Again, this is the way I understand it (I'm very new to all of this and am still learning)
Hello Andy body!
Your concepts on MVC are good and should work. 1 or 2 points that come to the mind.
1) As I have gone through the previous posts, they seem to be discussing classes. In my view, Model is a package that contains all classes that fall into model category for a specific layer(tier). Similarly for view and controller.
2) If you use more than 1 MVC in your design, make sure that only controller of one MVC talks to controller of other MVC. Model or view should not be interacting with other MVC.
3) Design is an art. Your design would not be exactly like some one else's. And techniques (design patterns) you use, would have thier own advantages and disadvantages in your design.
**OCP, Java SE 6 Programmer**OCM, Java SE 6 Developer**
Joined: Jul 01, 2015
Thanks for the feedback Rehan! Glad to know that I'm on the right track. This stuff is complex but I like the challenge. I'll keep what you said in mind as I go forward.
I see your point about Design being an Art. I'm also finding that the design is largely influenced by the language features and limitations. For instance, when using a JTable in Swing, the user can sort a column and the data within the table view changes automatically (if not overridden). The local TableModel is unaware that this change has taken place which causes the table view and table model to be out of sync (don't understand this since the JTable is suppose to reflect the TableModel... is there another model that's involved with the table view... where is the JTable pulling its newly sorted data from?). Unless 'someone' is watching for a change like this (a listener), this introduces a bug. So 'someone' needs to be watching and then the local TableModel must be brought back in sync with the user view. Where do you place that responsibility? This can be placed within the View or the Controller (or even the model, depending on design). Which is best? I see the model as being a App-wide Model, rather than anything local to a particular component like a JTable, so I don't think the model is the best choice. Since I see the model as App-wide, I don't see any reason why the App controller needs to be involved with a local change that only affects a local view like a JTable. So I vote for handling the sync between JTable and TableModel in house, within View. With this being said, it also depends on whether each change made to the 'view' of data (within JTable) should be permanent (stored for later retrieval in another session) or if the viewer must press a button to make it permanent. I was describing the second example. If it's the first example then obviously the changes to the model must happen on the fly, and responsibility shifts to the controller being the listener. Then there are the selections of cells themselves (as the original poster asked about) which present more responsibility questions. Like you said, there's no 'one size fits all' scenario, only guidelines.
With either of these scenerios, I find it difficult to handle user interaction using AbstractAction techniques unless I intercept the events from within View (as I explained in a previous post). I see no way to point the button events (using AbstractActions) to the controller (due to issues of scope). Obviously I could place a controller listener on each button within View to intercept the events, but I like the features offered by Actions so would rather stick with that technique. If anyone can tell me how to use AbstractActions and still allow the controller to get these events directly, I would appreciate it. I would much rather have a central controller, then doing it the way that I mentioned in my previous post.
I have recently switched to JavaFX which should provide a solution to the problem (I think).