File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes how to implement MVC? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "how to implement MVC?" Watch "how to implement MVC?" New topic
Author

how to implement MVC?

Holmes Wong
Ranch Hand

Joined: Feb 18, 2002
Posts: 163
Hi, ranchers:
To my undersatnding, I have to extend Observer/Observable to implement MVC pattern, and make it work, right? Thanks.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Nope, not at all. What you want to do to create a MVC for your gui, you have one class that is just GUI code, to display your screen. There are "Hook" methods in this class, that will accept the appropriate Listener class as the parameter. It will take this parameter and add the listener to the Components addListener method, which adds it to the list of class that is listeneing for actions on this component.
In your Controller class you will have a reference to the GUI class, and you will use anonymous inner classes to be the listener and call the corresponding hook method of the GUI, and in this inner class you will simply call a method that is in the controller class.
The controller will also have a reference to the Model, or Data classes that it needs.
Here is a simple example of what I am talking about.
GUI Code


OK now a method in the controller class


Hope that is clear.
Mark
[ May 30, 2002: Message edited by: Mark Spritzler ]

Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Holmes Wong
Ranch Hand

Joined: Feb 18, 2002
Posts: 163
Thank Mark. I will try out your advice. Thank
you very much. You are a real cowboy.
Holmes Wong
Ranch Hand

Joined: Feb 18, 2002
Posts: 163
Mark, I am still not very clear about this. I have a JComboBox for origin airport. I followed your advice to design my MVC code. I put a "hook method" in GUI class, put assignListeners method in Controller class, and used an anonymous inner class to process the event. Since we do not have to get data from model in this point, I do not have to call a method from the Model, right? You myButtonActionMethod() is also barely used to process events and get the action source, right?
My question is: since the method in the controller is calling a GUI method, how couls we execute this
piece of code in Controller class? Or should we reverse this?
Please bear with me, I am really new to this. Thanks.



OK now a method in the controller class

[ May 30, 2002: Message edited by: Holmes Wong ]
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

You myButtonActionMethod() is also barely used to process events and get the action source, right?
No need to get the source, that is built in there the source is that one and only one button that I called in that hook. The actual code in myButtonActionMethod is what I want to happen if someone clicks that button. So if it was a search button, it should do a search, or send a call to the "Data" class to do the search.
since the method in the controller is calling a GUI method,

The only method you are calling on the GUI is the hook method, which is just to pass the Controller Object to the list of Listeners of the button.
So after that you never have to call any methods on the GUI, because it is not the GUI's responsibility to respond to actions.
My question is: since the method in the controller is calling a GUI method, how couls we execute this
piece of code in Controller class? Or should we reverse this?

I don't understand your question. Your controller has a reference to the GUI object, so it can call any public methods of the GUI that it wants.
Mark
Holmes Wong
Ranch Hand

Joined: Feb 18, 2002
Posts: 163
Thanks, Mark. What I don't understand is how we could achieve the same thing using MVC as if we put all event handling code in GUI class. For example, for my origin JcomboBox, I can use the follwing code to handling the event and get the
user selection:

My question is, if we use MVC, we can do this following your advice:
In GUI:

Now in Controller:

From what you said, myBoxActionMethod should call a method to do search based on that built-in source. The question is, GUI has to get the search results to dispaly for the user, I only see the references will be passed from GUI and Model, how can we pass results from controller to
GUI to display them? I am not very familiar with MVC, just struggling to understand its mechanism, I may be missing something very simple here.
Jim Bedenbaugh
Ranch Hand

Joined: Nov 09, 2001
Posts: 171
Mark,
So the model has all the methods to access data, right? In my case, I wrote a DataClient that implements a DataInterface, and the DataClient makes all its calls to Data (or FieldInfo or DataInfo, as needed). Sound right?


Regards,
Jim
SCJP, SCJD, SCWCD, SCEA Part I
Holmes Wong
Ranch Hand

Joined: Feb 18, 2002
Posts: 163
Mark may be watching world cup now . Could anyone else clarify my doubts?
Sai Prasad
Ranch Hand

Joined: Feb 25, 2002
Posts: 560
Holmes,
Your myBoxActionMethod(), calls the appropriate method to search and get the search results in the form of DataInfo[][]. Now you need to convert the DataInfo[][] array to Object[][] and set this array to your table model which is contained in the controller.
In other words, your table model is encapsulated in the controller and it has a method setData(Object[][]) to populate the JTable to show the flight search results.
From your controller, if you want to communicate to the GUI to get or set any values, provide the appropriate methods in the GUI and try to communicate using only the String or Object objects. That way the GUI is not architecture dependent.
Holmes Wong
Ranch Hand

Joined: Feb 18, 2002
Posts: 163
Thanks, Sai:
That clarifies my doubts on this. I am thinking to
set up methods in GUI to get results back from controller. Since controller is calling GUI and Model methods, my thinking is that I have to find a way to interact with it, thats more logical. Actually, the results should be sent to table model then to GUI to get appropriate display, right?
Originally posted by Sai Prasad:
Holmes,
Your myBoxActionMethod(), calls the appropriate method to search and get the search results in the form of DataInfo[][]. Now you need to convert the DataInfo[][] array to Object[][] and set this array to your table model which is contained in the controller.
In other words, your table model is encapsulated in the controller and it has a method setData(Object[][]) to populate the JTable to show the flight search results.
From your controller, if you want to communicate to the GUI to get or set any values, provide the appropriate methods in the GUI and try to communicate using only the String or Object objects. That way the GUI is not architecture dependent.
Sai Prasad
Ranch Hand

Joined: Feb 25, 2002
Posts: 560
Yes. When you update the results in the model, gui will automatically get updated.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

I tried posting this earlier but my connection was really slow. This is refering to a couple of posts above that most recent two.

In theory, except for hooking into the Actions, I never send any method calls to the GUI.
Now in the TablePanel, I do have one method called getTable which returns the JTable, so I can call setModel when I need to change the data in the JTable.
Now you need to convert the DataInfo[][] array to Object[][] and set this array to your table model which is contained in the controller.

I actually put this conversion in my FlightTableModel, I have a setDataArray method that takes a DataInfo[] as a parameter, as well as an integer that represents the number of fields to set the second array length, The setDataArray method converts it into an Object[][].
This setDataArray is private and is called by the constructor of my FlightTableModel, there is a constructor in my FlightTableModel that accepts a DataInfo[] parameter only.
Hope that helps
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi Ranchers
Why we need to convert the DataInfo[][] array to Object[][] for TableModel ?
In my case MyTableModel's setData(..) mrthod takes an array of DataInfo[]
Pls Comment
Amit
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Amit, my setData also takes a DataInfo[][] as it's parameter and found I like it that way the best. I think that is why they have you make your own TableModel by extending that DefaultTableModel.

The code in that method was real small too, and made the code for refreshing the JTable really quick.
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Thanks Mark for all your replies. Its being a gr8 help.
So this means that there is no need to convert DataInfo[] into Object[]. The methods in CustomTableModel will take care of returning the desired result e.g getValueAt(..) etc by iterating through the DataInfo[] instead of Object[].
One more thing :
Why we need a hook method in GUI, i think we can directly assign the Listeners to the GUI components by calling the following method
in Controller class:
gui_reference.getSearchButton().addActionListener(this);
where getSearchButton() is a proctected method inside GUI
Pls Comment
Amit
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Yes that is ture, unless you want all your instance objects to be private and only available through methods.
Although looking at my code, they were public anyway. Hmmm.
But if you did want it encapsulated, this would be a clean way. I also like having a more descriptive method that the controller calls rather than addActionListener. But, this is completely my preference and not something that you have to follow at all.
Mark
Gosling Gong
Ranch Hand

Joined: Jun 20, 2002
Posts: 51
Hi, Mark,
did you hardcode the title string of the table,
or stripe it from the DataInfo[], which means we have to use DataInfo[] as parameter to TableModel rather than String[][].
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Originally posted by Gosling Gong:
Hi, Mark,
did you hardcode the title string of the table,
or stripe it from the DataInfo[], which means we have to use DataInfo[] as parameter to TableModel rather than String[][].

Do you mena column names. No I got it from DataInfo[], and that is my parameter to the setDataArray method of my TableModel
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi mark
What is the cleaner way of assigning the controller to GUI
1) GUI will instantiate the GUI controller for itself and the constructor of Contoller will assign listeners or call hook methods to its components when instanitiated
Right now what i have following methods in GUI is
// constructor of gui
gui()
{
addController();
}
addController()
{
new Controller(this)
}

Amit

2) any other way ???
Amit
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

I always look at it this way. The GUI code only knows one thing and one thing only, How to display itself. If you put any other code that does action, business logic, or instantiation of any object other than display type objects then you have coupled those other classes.
So the GUI should know zero about the controller. The controller will have an instance variable that holds a reference to the GUI. The controller can also call methods on the GUI, get values from objects on the GUI etc. Now you can encapsulate the GUI better by making the Objects on it private, and then provide assessor methods in the GUI.
The only other thing you will need to do to create this 100% seperation of GUI from all others is to provide Hooks methods in your GUI class. This hook method takes Listeners as its parameter and hooks it to a corresponing GUI Object like a JButton.
You can do a search and find more detail explanation of this hook method from my other posts on it.
Good Luck
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
I agree with you mark that GUI and Controller should be seperate.
However somebody needs to instantiate your controller class that will further call your assignListeners() method of controller class to take the advantage of hooks. Which class will do that ?

Amit
[ July 04, 2002: Message edited by: Amit Kr Kumar ]
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

You rmain class instantiates the controller. THe GUI cannot, as it doesn't know it's controller. That is why the controller is called a controller, because it controls everything, and the only way it can is if it knows about the Model and the View. So it should be the only class that has that information.
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Thanks Mark
I got it !!!
Amit
Sam Stackly
Ranch Hand

Joined: May 04, 2002
Posts: 109
Hi Mark,
I just followed this thread and have two questions about hook method you mentioned. The first question is: Should we have a hook method per action (like for search when user hit searchButton and same thing for booking flight) or can we use source of event in Controller then call proper function.
And second question is: Do we have to deal with all actions in Controller ( like when user press help menu) or just specific action which is somehow related to Model
Thanks
Sam
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Hi Sam, I had a Hook method for each and every type of action that was needed. I did not use a single Action method that had to getSource to figure out where it came from, that would mean you would need many if statements. Yes that means there is a Hook method for the search button, one for the help menu, one for the focus listener in the number of seats to book JTextfield.
Hope that helps
Mark
Gosling Gong
Ranch Hand

Joined: Jun 20, 2002
Posts: 51
Hi,Mark,
if I have seperate class for each panel(Search Panel, Result Panel), does that mean my controller has to know all of them, including the Main frame which assemble all of the parts,
or should I have to create seperate controller for each of them?
thanks
Sam Stackly
Ranch Hand

Joined: May 04, 2002
Posts: 109
Thanks for reply Mark,
I am just wondering which way is more practical in OOP? having list of methods in UI or having one method inside of Controller in order to map all functions to Model(well I know I will end up with lot's of if.. elseif)?
Thanks again , your comments are always helpful.
Sam
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Personally I like the multiple methods rather than an umanagable if statements. I also think it is more OOP because it allows a lot of flexibility.
As far as multiple panels, they are still put into one class that makes the GUI, so the controller knows about that one class. I had multiple Panels, one for the search and one for the JTable, but they were both in the FlyByNightGUI class, so the hooks were in that class, and the controller had a reference to that one class.
Mark
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Hi everyone. I have followed Marks comments about creating hook methods to register event listeners. However in another thread in the Patterns forumn
MVC Thread one poster commented that the concept of having the Controller as the event listener does not seem right. I also hae some reservations.
His opinion was that the Controller is the point of contact with the domain (business) layer from your GUI layer. Your event handler code should be in the GUI layer itself, where from you will call the Controller passing the appropriate information. You can have an event listener class (not necessarily an anonymous one) which obtains the information from the event object and then calls the Controller.
This also aids in the separation of the View and the Controller as the Controller does not have any code which directly accesses the View.
1.Using the hook method means that the Controller has explicit knowledge of each component that exists on the GUI (as there is a hook method for each GUI component). Surely this cant be good??
2.The other option is to register a single event listener and have a number of if statements in the Controller to figure out the event called( doesnt seem perfect either but possibly preferrable!!).

However if we do not use the Contoller as the event listener (using the hook method) this means that 3.either the GUI event listeners have explicit knowledge of which method to call in the Contoller (which we dont want either !!)or 4. else a generic event handler is called but this will need some way of figuring out the event executed ( means possibly using a set of static int's or whatever to match the event caught in the GUI, pass this int in the call to the Controller event handler and then execute a Controller method based on the value of the int ).

So of the four methods outlined none seem to be perfect. Right now i am more confused than ever!! Any thoughts that might give me some clarity on this would be appreciated....
John
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

So of the four methods outlined none seem to be perfect.

Here is an (almost) perfect method to completely isolate controller from the GUI (all GUI controls are private, controller should know nothing about how the data is rendered in GUI):

That's what I did in my solution that I submitted a few days ago, we will see what Sun thinks about it.
Eugene.
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
So Eugene. From the options I outlined in my previous post you have selected number 3 where the GUI is the event listener as oppossed to the Controller being the event listener. However the GUI has references to the methods in the Controller to be called for each event.
So is the perceived benefit is that the methods in the Controller will always stay the same irrespective of how the GUI is constructed. If you were creating hooks from the Controller to the GUI then the methods in the Controller would have to change to account for each new widget that could receive an event??
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

But that is all backwards. What if you want to change the controller? you can't because the GUI is completely coupled with the controller. Yuor GUI should only know about the UGI and nothing else, you have also coupled the Model with the GUI.
My point is why do you think they call it the controller. Maybe because it controls everything, so therefore it is the only class that should know about others.
If you need any background information on my experiences. This comes from 7 years of experience. Starting with Visual Foxpro, which uses Controllers extensively. From the GOF design patterns book, from all MVC web pages.
By having the controller be the only class that knows about the other classes you can change out the GUI, the Model, and the Controller easily and quickly.
I don't mean to sound defensive or aggressive here, and you can choose however you want to go, but I just really want to help and to see everyone get high marks on their score in SCJD.
Good Luck
Mark
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
I see your points mark but you haven't really addressed this issues i outlined in my first post under points 1 and 2.....
You think that it is perfectly correct that the controller know about each widget in the GUI. Yes??
Im interested in your arguments because im only getting started with the MVC.
Thanks,
John
Robin Underwood
Ranch Hand

Joined: May 01, 2002
Posts: 117

You could do #1 without the controller knowing about GUI components. The controller could send a ready-made action listener (with controller methods) to a set method in the GUI. The GUI could then set the action listener for the appropriate GUI components.
Personally, I did #2 where the controller only handled a handful of events from the GUI's. I thought it was easier to follow when all the event handling code branched out from one place.
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Originally posted by Robin Underwood:

You could do #1 without the controller knowing about GUI components. The controller could send a ready-made action listener (with controller methods) to a set method in the GUI. The GUI could then set the action listener for the appropriate GUI components.

Yes but the Controller has to call a hook method/set method in the GUI and more than likely there will be a different controller method to be executed for each component so the Controller does really know about the GUI components or at least about he setMethods that exist for each GUI component.....
Perhaps method 2 is preferable.....
Robin Underwood
Ranch Hand

Joined: May 01, 2002
Posts: 117

I guess you can think about this as both the controller and the GUI need to agree about which actions the controller will listen to. The GUI could have a method setBookFlightListener. The controller would only need to know that the GUI generated the event. The GUI would only need to know that someone else listened to the event.
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

John wrote (and I formatted):
1. Using the hook method means that the Controller has explicit knowledge of each component
that exists on the GUI (as there is a hook method for each GUI component).
Surely this cant be good??

2. The other option is to register a single event listener and have a number of if statements
in the Controller to figure out the event called( doesnt seem perfect either but possibly preferrable!!).
3. either the GUI event listeners have explicit knowledge of which method to call in the Contoller
(which we dont want either !!) or
4. else a generic event handler is called but this will need some way of figuring out the event executed
( means possibly using a set of static int's or whatever to match the event caught in the GUI, pass
this int in the call to the Controller event handler and then execute a Controller method based on
the value of the int ).

How about option #5:
-- Keep all GUI components private
-- Use the hook method in GUI, but do not let controller access values from GUI
-- When the GUI control changes, the GUI invokes a method in the Model to alter
the model state, for the corresponding value. For example, when the origin airport changes
in combo box, do this from the combobox listener in GUI:
String origin = originAirportCombo.getSelectedItem().toString();
model.setOriginAirport(origin)
-- When the user clicks on the "Search Flights" button, the controller will handle
the event (using the hook in the GUI). But the first thing it will do is to retreive
the values that it needs from the model:
String origin = model.getOriginAirport();
String destination = model.getDestinationAirport();
Now it can call the serach method: searchFlights(origin, destination)
Or, if the search() method is defined in the model, the controller will call it without
parameters: model.SearchFlights(), and the model already knows what the origin and destinations are
-- When the search is complete, the model updates the GUI (displays the flights in the table)
With this option:
-- controller doesn't know anything about the GUI or its methods
-- The GUI doesn't know anything about the controller or its methods
-- The model doesn't know anything about the controller
-- The only disadvantage that I see is that the GUI updates the model directly when the user selects a new value in one of the GUI controls, and also the model is updated more frequently than it really needs to.
Eugene.
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Okay guys. Thanks for the informed opinions. Im going to go with the hook methods right now anyway....
John
 
Consider Paul's rocket mass heater.
 
subject: how to implement MVC?