Hi all ! I have implemented my GUI in a generic way, which means that any kind of view can be easily plugged in the MVC structure. The controller class defines a number of methods which can recieve parameters, like nrOfSeats or recordNo. The controller has no knowledge of the view, the view is registered as an observer of the model and updated when it is notified by the model. There is, hoewever, a problem with the Swing actions. Because it is not possible to pass parameters to the actionPerformed method, the Swing actions have a reference "hook" to the view to obtain the information filled in by the user. I use an AbstractView class which defines a number of getter methods to read those data. The AbstractView class implements the Observer interface and takes care of the updating by calling the abstract method updateView in its update(Observable o, Object arg) method. This is an example of the Template method pattern. The abstract methods getSelectedRecord, getSeats etc. are also defined in the AbstractView method, and implemented in the concrete SwingView subclass.
So far so good. But when we would use another view, for example a text-based view (or Web view), we have no Swing Action classes, so we van call the Controller methods directly from this view, passing to them the needed parameters. This would make the use of a "hook" to the view in fact unnecessary !
So, is it a good idea to define an AbstractView which already defines these getter methods ? Using Swing actions, we have little choice. But the idea of the AbstractView class is that it is the commom baseclass for all types of views ! Of course, it is still possible to use the getter methods of the View class anyway. In a swing view, these getter methods read from the JTable and the model, and in a text based view, the underlying properties are simply set using an assignment statement.
Pretty complicated !!! Who want to share these thoughts with me to come to a good design desicion ???
[ September 07, 2004: Message edited by: Klaas van Gelder ] [ September 07, 2004: Message edited by: Klaas van Gelder ]
"What you don't know, can't help you"
SCJP (81%), SCWCD (81%), SCJD (354/400), SCBCD (85%)
Joined: Sep 23, 2003
Originally posted by Klaas van Gelder: ... the Swing actions have a reference "hook" to the view to obtain the information filled in by the user. I use an AbstractView class which defines a number of getter methods to read those data.
I am just commenting on one small part of what you posted. I don't think you should get data from the view at all. That data will be in a Swing model and you should hold those models separately, register them on the view and obtain the required data from the model. Just an opinion, I know it is valid to combine model & view, but perhaps this is ellaborate enough to warrant them being kept separately.
Another thig, if your view calls the controller, is that by type ControllerInterface ?
My design couldn't be more different, but that doesn't make it right. Flippin' hope it is okay though since I've just uploaded it
SCJP 1.4, SCJD
Klaas van Gelder
Joined: Jul 08, 2004
Mike, do you mean that an extra model should be used that holds the values for the data filled in by the user ? My app currently uses a FlightDataModel, which is the "main" model in the MVC structure and holds a reference to the FlightDataServices (and so to the database). Furthermore, I have a FlightDataTableModel, which is tightly coupled to the JTable, and therefore part of the Swing gui. If I understand your point well, I should introduce a new class, for example called GuiDataModel. Maybe you can explain a bit more...
Actually, I don't use a ControllerInterface. Maybe this should be better indeed. I will reconsider this.... Regards, Klaas
Joined: Sep 23, 2003
I've spent alot of time searching for the one truth as regards GUI class design. One thing I've learnt is that everyone seems to have a different approach. I think this area of design is very open to debate.
If you think you have a valid design then you probably have, and I am certainly no expert.
I'll describe my design, but I know I'd like it better.
Controller talks to view and model. View is unaware of anything. Controller instantiates view and models then registers models with view via hooks. All event driven updates take place via the internal swing event model.
My controller is the design 'mess' & mess!
Controller has horid inner classes for all the actions - populate fields, populate table, book room - I'd like to move these out to top level classes, but they are almost inextricably linked with the controller. So lots of thoughts needed on best way to do this. Too late now though, it's winging it's way to the exminer.
do you mean that an extra model should be used that holds the values for the data filled in by the user
Well I did, and that would be a Swing Model, so Document for a JTextComponent for example. But I wouldn't use the word should, more could.
Personally I only have swing models, but that is because I have thin client design and my main model is my business model which can be the Remote object
Klaas van Gelder
Joined: Jul 08, 2004
Well this is not making it a lot easier !
Your design appears to be pretty different from mine:
ad 3. Because of ad 1., the controller cannot instantiate the view (which class should it instantiate ?).
ad 4. I use the Observer/Observable system to notify the view when the model has been updated. Within the view, the TableModel notifies the Table using its own fireTableDataChanged method.
This still leaves the original problem of: how to get the filled-in data (comboboxes, text fields) to the controller from the gui ? IMO, the two options are:
1. Let the controller hold a reference ("hook") to the View, so that it can obtain all data it wants from the view. This makes the controller view-aware. The controller methods receive no parameters. The view needs to implement an interface which defines getter methods to all relevant data.
2. The controller has no reference to the view. So all data needs to be passed into the controller methods.
I still prefer option 2, because it provides a better decoupling bwtween controller and view. The problem of passing in the controller arguments to the controller reference in the Swing actions is in fact a "view-internal". It would be sufficient to pass a hook to the view in the Action contructors. Because this is a Swing-only issue, it makes no sense to provide the hook/callback methods for the viewdata-retrieval in a generic View interface or abstract class. Maybe the Swing view sould implement a special "SwingViewReference" interface to define the hook methods...
I would like to hear more opinions about this issue... So forum-gurus, i hope to hear from you ! [ September 08, 2004: Message edited by: Klaas van Gelder ]
Joined: May 22, 2004
Create your Model with methods for the Controller(any EventListener class) to call when user fires a event.
Create an interface that contain methods that can be called when an action is finished, like public void recordBooked(boolean result).
Your View will implement the interface and define what will be displayed upon receiving the result:
Your model will then have methods like processRecordBooking(String ownerName, long recNo), for example:
Then when your Listener detects a user event, get the user inputs and invoke the processRecordBooking method by passing in the user inputs.