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 Separating View-Controller in 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 "Separating View-Controller in MVC" Watch "Separating View-Controller in MVC" New topic
Author

Separating View-Controller in MVC

Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Hi Fellow Bloggers,

It has been suggested (Monkhouse book) that we should be able to "drop-in" a substitute HTML web interface for the Windows GUI interface, which we are designing for the SCJD assignment. My View and Controller are tightly coupled. (I know that tight coupling is bad). My View captures events generated in the presentation layer and signals the Controller for a response. My controller in its turn enables controlls on the View. This is how I teach the user to use my interface.

For instance on the menubar, I enable "Search Name And Location". In response, the Controller enables the "nameTextField" and the "locationTextField" and the "searchDatabase" button. The problem is that it would be very difficult to substitute an HTML webpage for my MVC View without redesigning the MVC Controller.

Did anyone else run into this problem? How did you solve it?

Best regards,
Harry
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5397
    
  13

Hi Harry,

I also have a GUI-controller. This class has a reference to my BusinessService and 2 methods: 1 to find rooms (which returns an instance of my tableModel) and 1 to book a room. In those methods the appropriate method on the BusinessService reference is invoked and the result is handled. If an Exception occurs, the exception is caught and a GuiControllerException is thrown with a clear message for the user.
My main window (View) only has a reference to my controller (Controller) which has a reference to the BusinessService (Model). So my controller has no references at all to any awt or swing class/interface.

And for the record: my menubar has only a "File" menu with a "Quit" menu-item.

Kind regards,
Roel


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11476
    
  94

Hi Harry

I am not a blogger, (or at least, I am a terrible blogger, as my family will attest), so I don't know if I am allowed to answer your question.

It is normal to have the view and controller coupled to a certain extent, however it should be possible to develop a solution where everything else is abstracted away. As an example, in the Denny's DVD project, once you have started the application you lose all knowledge of whether you have a direct connection to the database or whether you are connecting using RMI or Sockets. Similarly any class that calls the Data class has no way of knowing whether the data is stored in a physical file or in a commercial database or something else.

It is possible to convert Denny's DVD to have a web front end by only changing the view and controller - I have started work on an example of this. Caveat: If I were hosting this application on a server that I have 100% control over, that is all I would need do. Since this is a shared system, I have actually rewritten parts of the backend to use Log4J and to handle finding the data file within the Tomcat container. However these are only necessary due to my particular deployment - they were not necessary just for getting a web interface up - I had that section done on my development machine with only the view and controller changing.

I suppose I should really get around to finishing that system and posting code etc.


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5397
    
  13

Andrew Monkhouse wrote:I have started work on an example of this.
Really nice example of a web GUI. And I have to say it looks so much nicer and more contemporary than the Swing application. Great job, Andrew!

Kind regards,
Roel
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Thanks Roel and Andrew,

I've been working on my GUI most of today. I have two JPanels and a MenuBar in my GUI. One JPanel has some textfields and buttons. The other JPanel has my JTable. Methods in my Controller are invoked by event listeners in one of my 3 top-level components (classes) of the View. The problem was that the methods in my Controller were enabling individual menuItems, buttons, textfields, and JTable cells (spaghetti code). I moved the enabling/disabling actions for menuItems back into JMenuBar; I moved enabling/disabling actions for the buttons and textfields back into the the originating JPanel; finally, I moved the JTable cell controlling actions back into the JPanel with the JTable component. Now in my Controller, I have something like this:



As a result of this refactoring, I'm not controlling individual components in my Controller, but I'm controlling groups of components in each of the 3 major component subgroups of my View. With this degree of abstraction and programming to interfaces, I think that I would be able to adapt my SCJD assignment to a web presentation layer, now.

Thanks for your input,

Harry
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Hi Roel,

I perform most of my program controll from the JMenuBar. I have a File, Search, Modify, and Help menu.

Did you supply on-line Help for the user, or did you have a separate stand-alone document?

Best regards,

Harry
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5397
    
  13

Hi Harry,

I don't use menus, because my application simply don't need them. If you want to search, simply enter the text in one (or both) of the text fields. If you want to book a room, simply click on the book-button (after you have selected a room, otherwise button won't be enabled). My main window always has the same layout and controls on it, so a CSR will be very familiar with the application (no panels appearing or disappearing). And he can book a room very quickly (in my opinion very important, because a customer calls to book a room and I always hate it myself when I have to wait because the computer/application reacts very slow when I call or get called for some booking or inquiry). A CSR types hotel name, presses enter, a list with matching rooms appear, he selects one, clicks on the book-button, enters the customer-id in a seperate dialog and confirms by pressing ok and the room is booked.

I just used a plain text help document, so no online help nor a fancy html-document with several pictures. My user guide is just as my application: easy and simple And because my application is very intuitive (if I may say so myself), it needs not a whole lot of explanation and screen shots to explain the working of the application.

Kind regards,
Roel
Bernd Wollny
Ranch Hand

Joined: May 15, 2006
Posts: 59

Roel,

so how can you see if an entry is already booked? I took a different background color. What about you?

Kind regards,
Bernd


SCJP 1.4, SCJD/OCMJD
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5397
    
  13

Hi Bernd,

If the customer-id is filled in, the room is booked. So no background color changing, no seperate indication in the table. A room with an empty customer-id is bookable, otherwise it is booked (and the book-button will be disabled).

Kind regards,
Roel
Bernd Wollny
Ranch Hand

Joined: May 15, 2006
Posts: 59

Ok,

i prefer some solution that the user notices at a glance that a record is either booked or not (colored indication). In your case the user has to mark that entry first to see if that record is booked right? But each solution to his own...

Kind regards
Bernd
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5397
    
  13

Bernd Wollny wrote:In your case the user has to mark that entry first to see if that record is booked right?
No! The JTable has a column holding the customer-id. if this field is empty for a record, the room is bookable. Otherwise the room is booked. Simple and easy. Disabling the book-button is just a part of my restrictive gui: don't allow the user to click a button, perform an action if it is not allowed or if it the action is useless (booking an already booked room)

Kind regards,
Roel
Bernd Wollny
Ranch Hand

Joined: May 15, 2006
Posts: 59

Roel De Nijs wrote:The JTable has a column holding the customer-id. if this field is empty for a record, the room is bookable

Ahhh, that's the way i did it too... including a supporting indication through color-highlighting... well, back to topic...
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Hi Roel,

Sorry for taking so long to respond to your message. Since I was still figuring-out the details of my MVC design, I didn't see any point in thrashing about my deliberations on this blog. I think I have a true MVC design. The "Model" is my TableModel that holds the data for the "View". When the data changes, the "Model" notifies the "View" with the fireTableDataChanged() method. Since there is only one "View" that is interested in data changes, it doesn't make sense to use a true Observer pattern. But, the "Model" does notify the single "View", when its state changes, and the "View" updates. The "View" has two JPanels and one JMenuBar that are added to a JFrame. After some serious refactoring, my "View" now has very few widgets. One of the JPanels has a JTable. All events that are activated by the "View" listeners cause a corresponding method call in the "Controller". The "Controller" responds by calling methods on the "View" components and by calling methods on the "Model" (such as Search() and Book()). The "Model" interacts with the Business Layer directly, which has methods that are really groups of methods that were specified in the Sun supplied Interface.

I'm still working on cleaning up my "Model" <-> Business Layer <-> Database connectivity. I have the standalone version of the project working, but in some aspects it isn't concise, nor pretty.

Best regards,
Harry


Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Hi Roel,

I have two JTextFields (Name & Location) and two JButtons (Search & Exit) and one JTable and one JMenuBar. The JMenuBar has three JMenus, i.e. File, Search, and Help. The Search JMenu isn't really necessary, because I could have always enabled the Search button in the JPanel. You don't have to use the JTextFields in my design, if you don't want to; just press Search. I use the JTable itself, when booking a contractor. When I add data to the "Owner" field on the JTable and press "VK_ENTER", after the input data is confirmed to be well formed, the database is automatically updated . I don't have to press a "Book" button. It took a few hours to figure-out how to do this. My first iteration of the design used a "Book" button, but I felt that this implementation was annoying. It added an unnecessary extra step to the process of booking a contractor.

Do you have any comments about using the "VK_ENTER" key to capture changes to the JTable?

Best regards,
Harry
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2266
    
    3

Howdy, Harry!

Just one curiosity: what do you mean by "model"? Do you mean model as in TableModel or as in MVC? Because if it is as in MVC, then you can consider "model" and "business layer" the same thing (even though they are different things, if we take these concepts too seriously).


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Hi Roberto,

My "Model" is a class called Model that extends AbstractTableModel;

In an MVC design, the "Model" holds the state of the system. It also uses the Observer pattern to notify its Subscribers when the state of the system has changed. In my "Model", there is a data structure that is specified as Object[][] data. This two dimensional array contains the data that is presented in the "View" of the JTable. I consider this data to be the "state" of the MVC design.

Remember that the individual widgets that make up the "View" hold their own state within each widget. It is unnecessary to save the state of the widgets of the "View" in the "Model". But, the "Model" certainly holds the state of the JTable, which is the important part of the MVC state.

The "View" communicates with the "Controller" by calling "Controller" methods in response to events caught by the widget Listeners.

In response to these events, the "Controller" invokes methods on the "View" that update the "View" widgets.

Also in response to widget Listeners, the "Controller" invokes methods on the "Model" such as searchDatabase() and updateDatabase().

In response, the "Model" performs database searches and updates (changing the MVC state), and then invokes fireTableDataChanged() method, which notifies a "View" Listener to update the JTable. There isn't an Observer-Subscriber pattern between the "Model" and the "View" because it is unnecessary. There is only one Subscriber, and that is the JTable.

Roberto Perillo wrote:
Because if it is as in MVC, then you can consider "model" and "business layer" the same thing (even though they are different things, if we take these concepts too seriously).


I have a separate class called "BusinessLayer". I'm not certain that I like the name, but my "Model" calls methods on the BusinessLayer class. I don't aggregate any of the methods that implement the Sun supplied interface in my "Model". In fact I'm trying to write a thin-client. I want the BusinessLayer class to reside on the Server.

The "Model" will just invoke searchDatabase() and updateDatabase() using RMI. The BusinessLayer class will have methods that combine lockRecord(), updateRecord(), and unlock() for example.

Thanks for any help you've provided in the past and your comments at this time. They are appreciated.

Best regards,
Harry

Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5397
    
  13

Hi Harry,

First a small remark: don't just quote complete posts from others (like in your one but last post in this thread). It has no added value at all and just wastes disk space. Use quotes wisely!

You don't have to use the JTextFields in my design, if you don't want to; just press Search.
Of course this is also possible in my application, resulting in all (valid) records being shown in the JTable.

Do you have any comments about using the "VK_ENTER" key to capture changes to the JTable?
No, not really. You did a great job I prefer a consistent experience for the CSR (so he will easily get used to the application). So the dialog to enter the customer-id will also be used to confirm deletion, update of other fields, unbook, create a new record,... (when added to the application of course). All these actions will be represented by a row with buttons below the JTable.
You prefer an editable JTable, which is also a good approach. And you just will have to use it consistently: VK_DELETE to delete record, VK_INSERT to insert new record, VK_XXX to unbook, VK_XXX to update other fields,... The only drawback(s) of this approach: your code might be a bit complexer and harder to maintain (than with a simple extra dialog) and a new CSR will have to know all these shortcuts to use the application (efficiently) and you'll have to add these also in a menu bar, because you can not expect that a CSR always remembers all possible actions and their shortcuts.
And of course I can add later on some shortcuts (like your booking-approach) for actions which are widely used (like booking). But for now I decided just to have a simple and easy approach (and an editable JTable is not a synonym for simple and easy).

Kind regards,
Roel
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Hi Roel,

My implementation isn't as complex as you might think. The trick was catching the event when the user stopped editing the "Owner" cell. This trick is very easily extended to all of the columns of the JTable. The other trick was figuring out how to restore the old data if the user input isn't well formed. Once you press "VK_ENTER", your change is saved in the Model, and the old data value is gone. Like I said, the trick is restoring the previous value to the cell.

I use the automatic JTable feature that checks to see if my input corresponds to the Integer.class, but I must only use an 8-digit Integer. Integers can hold -2 billion to +2 billion, which is 10-digits. The JTable checker feature will allow a 10-digit number in the "Owner" cell. This is why I have to check to see if my input is well formed, and restore the old value manually if it isn't well formed.

I made the assumption that using Dialogs was undesirable from reading this blog. I guess I'm wrong, because you scored very well on your assignment.

Best regards,
Harry
Jianping Wang
Ranch Hand

Joined: May 29, 2010
Posts: 60
Roel De Nijs wrote:Hi Harry,

I don't use menus, because my application simply don't need them. If you want to search, simply enter the text in one (or both) of the text fields. If you want to book a room, simply click on the book-button (after you have selected a room, otherwise button won't be enabled). My main window always has the same layout and controls on it, so a CSR will be very familiar with the application (no panels appearing or disappearing). And he can book a room very quickly (in my opinion very important, because a customer calls to book a room and I always hate it myself when I have to wait because the computer/application reacts very slow when I call or get called for some booking or inquiry). A CSR types hotel name, presses enter, a list with matching rooms appear, he selects one, clicks on the book-button, enters the customer-id in a seperate dialog and confirms by pressing ok and the room is booked.

I just used a plain text help document, so no online help nor a fancy html-document with several pictures. My user guide is just as my application: easy and simple And because my application is very intuitive (if I may say so myself), it needs not a whole lot of explanation and screen shots to explain the working of the application.

Kind regards,
Roel



Hi Roel, Sorry for quote the whole message. I need to explain my concern.

Your user interface should be designed with the expectation of future functionality enhancements, and it should establish a framework that will support this with minimal disruption to the users when this occurs.


I think your design may be hard to make functionality enhancements like adding cancellation of reservation. My opinion is we may need a tab or toolbar something like that so we can easily add a button to go to another interface.


SCJP 6 with 93%
Oracle Database SQL Expert with 98%
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5397
    
  13

Jianping Wang wrote:I think your design may be hard to make functionality enhancements like adding cancellation of reservation. My opinion is we may need a tab or toolbar something like that so we can easily add a button to go to another interface.

If that's your opinion, just go for it. I know my design can easily be extended with cancellation of reservations. Even creating new rooms, updating or deleting existing rooms can easily be added.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Separating View-Controller in MVC