wood burning stoves*
The moose likes Swing / AWT / SWT and the fly likes GUI application design 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 » Java » Swing / AWT / SWT
Bookmark "GUI application design" Watch "GUI application design" New topic
Author

GUI application design

Jeff Lloyd
Greenhorn

Joined: Sep 15, 2004
Posts: 4
Hi, being fairly new to this, I'd like some advice on how to go about designing a gui based application (not the gui itself), specifically how to link the gui to the application logic.

I've read stuff about MVC architecture. Am I write in thinking that in this setup: the gui should not know anything about the underlying model, and vice-versa? As far as I can see, you are left with an adapter class sitting between the gui and the rest of the app. with communication going through it. However, implementing this leads me to several questions.

1. the gui class is full of code like: button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { adapter.button1Pressed(); }}); So all the user's behaviour through the gui is passed onto the adapter to sort out. The adapter is full of code catching these events and passing them on to the business logic. But what is the advantage of that? If all the adapter does is call the appropriate method in the model then why not let the gui call the business logic itself?

2. If the adapter class is changing the gui, does it have to be done through getter/setter methods on the gui, or should the gui expose itself to the adapter so that it can directly change stuff such as visibility, enabled status, text, etc.? I don't see the advantage of filling the gui with loads of getter/setter methods if it's easier for the adapter just to reach in and change things directly. If the gui and adapter were in their own package, and the gui objects were default access, isn't it protected from other classes outside the package?

3. How intelligent should a gui be? The application will have different states. I.e. various menu items should not be enabled until the application has loaded data, certain options are only available if certain conditions are met. Is this something the gui should keep a track of (I toyed with the notion of various state constants, an instance state variable that changes as different buttons or menu objects are activated, and a method with a switch statement that turned buttons/menus on and off according to the state)? On the other hand, I wondered if the underlying model should fire events when its state changes, and that the adapter class (or a second one) catches the events and translates this into calls on the gui to change its appearance. Or, is that overly complicated? Maybe the model should simply make a call to the adapter when its state changes and the adapter changes the gui's appearance.

4. What is the advantage of the adapter layer? Is the idea that you can lay different gui's over the model? If so, then does the adapter class have to be rewritten to accommodate the new gui, or do the alternative gui's implement an interface that dictates what setter/getter methods it should have for the adapter to play with? I can't see this working very well. Afterall, different gui's might have different menus/buttons, or other ways of interfacing with the model which the adapter would not know about through an interface. So I think a different adapter would have to be written for every gui. So gui's and adapters are closely linked (which makes me wonder why do this, and not just beef up the gui class).

I'd really appreciate advice on this as I've read enough internet sites now to be just at the dangerously confused level!

thanks
Jeff Lloyd
Don Kiddick
Ranch Hand

Joined: Dec 12, 2002
Posts: 580
the gui should not know anything about the underlying model, and vice-versa?


The model should not know about the gui, but the gui will know about the model. The point of this is that you can add new guis without changing your model.

HTH,
D.
Garandi Garandi
Ranch Hand

Joined: Jan 07, 2003
Posts: 192
Don,
Can we use Observer/Observable pattern? (GUI Observer and Model Observable).
Thank you
Garandi
Jeff Lloyd
Greenhorn

Joined: Sep 15, 2004
Posts: 4
Hi Don, I can see that I've got a little confused. I've just been re-reading Roberts et al. "Complete Java 2 Certification" (2nd ed.) and realize that rather than having each button and menu item have its own inner adapter that simply calls a separate adapter class, I can register the separate adapter class with each component, and let the adapter class figure out which component just fired the event. That ties the gui and adapter classes much closer together and I see now that when you're laying a new gui over a model, the adapter class would be gui-specific and would be replaced as well. Thanks for your comments, they helped me see that.

I'm still wondering about the question of 'state'. Is it the gui, or model, that has state, or is it both, and how is this managed? E.g. my application has various menu options and buttons that are not enabled until a dataset is loaded into the model. Selecting the File:Load menu item brings up the file chooser. However, once a filename is selected it is the model that may (or may not if an exception occurs) load in the data. The state of the gui should be updated to reflect the presence of data in the model. If the model knows nothing about the gui, is this something that is done from the model side by calling a method in the adapter class (suggesting the adapter has to implement an interface?), or is there a mechanism for the gui to register itself as an listener to events fired in the model? I'm curious how other people deal with this.

Thanks again for your help!
Don Kiddick
Ranch Hand

Joined: Dec 12, 2002
Posts: 580
Note, all these answers are *one* way to do things, there are many others.

Is it the gui, or model, that has state, or is it both

I would say both. The model clearly has state. Your gui will also have state. e.g. a JMenuItem can be enabled or disabled, and you query that state by calling the isEnabled() method. Storing wether your menu item is enabled or disabled in your model as well, is a bad idea as you are duplicating that data.

The state of the gui should be updated to reflect the presence of data in the model. If the model knows nothing about the gui, is this something that is done from the model side by calling a method in the adapter class (suggesting the adapter has to implement an interface?), or is there a mechanism for the gui to register itself as an listener to events fired in the model?


Can we use Observer/Observable pattern? (GUI Observer and Model Observable).


Yep, exactly. Look at the TableModel interface, and the method addTableModelListener. The adaptor class (which, from what I can gather is the Controller in MVC), can listen to your model and update your gui appropriately.

What I should point out is that most applications have many models. They will have a "domain model". This will contain domain objects such as Person, Account, Trade etc... Your whole gui is the view on to your domain model.
Also inside your gui, you will have many more models, PersonTableModels, AccountListModels, TradeTreeModels etc... Lets call these "Swing models". The views for these models are JTables, JList and JTrees etc...

You can keep your swing models up to date with your domain model by the same technique - the Observer pattern.

HTH, D.
Matthew Taylor
Rancher

Joined: Jun 13, 2004
Posts: 110
I've seen it done in this manner:

Not only is there a Model, Controller, and multiple possible Views, but there are also ModelState and ViewState objects. These 'State' objects encapsulate the current state of the model and views. So if the user clicks a button, a ViewStateEvent is created that contains a ViewState object that defines exactly what state the view is currently in. This Event is fired to all the ViewStateListeners (usually the Controller) and they do what is necessary to accomplish the user directed action.

In this way, if anything changes in the Model or the Views, all objects that need notification are updated with the current States.


Grails Consultant
http://dangertree.net
Jeff Lloyd
Greenhorn

Joined: Sep 15, 2004
Posts: 4
Thanks again for all your comments. I had kind of stumbled onto a model state class when I was trying to work out how the model informs the gui that it needs to change its appearance. This is how I've coded the application now:

GUI - changes appearance according to the state of the model. I put all the adapter methods in the InterfaceAdpater class and registered the InterfaceAdapter as the action listener for all buttons, menus, etc.

InterfaceAdapter - acts as the go-between for the gui and the model. It implements an interface so that the model can rely on it having certain methods, such as getting user input, response. It holds all the actionListener methods for the gui. This class knows about the model and calls specific methods in the model to get things done. It is also registered as a listener for ChangeStateActions. Depending on the change in state, the adapter class alters the gui state.

Model - what does the business. If it changes state (i.e. moves from "no data held" to "data held" when the user loads a file) it tells the StateMonitor class which state it should move to.

StateMonitor class can register listeners (i.e. the interface adapter). When it changes state it fires a changestate event to all listeners.


So, the gui and interface adapter are closely linked. The adapter class knows about the gui and how to change its appearance. It also knows about methods in the model which it can call when the user interacts with the interface. The adapter is also a listener for state changes in the model. When it receives a statechange event it alters the gui to reflect this. The adapter also implements certain methods that allow the model to get user input that affects its behaviour/state.

It has been a real learning experience trying to code this application. I've gone from a messy gui-does-everything design, to a much cleaner separation of functions, and can now see an easy way of laying over different gui's without too much recoding. Thanks again for all your comments that have really helped me think this through.

Jeff
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: GUI application design