my dog learned polymorphism*
The moose likes Swing / AWT / SWT and the fly likes event handling for med sized MVC app Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "event handling for med sized MVC app" Watch "event handling for med sized MVC app" New topic
Author

event handling for med sized MVC app

Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
OK, here is my situation. I am creating an application that will have a main window and a number of different views. The way I have it set up now I am using an MVC type set up, where each view has a controller, as well as the main window. My question is this, in my views there will be any number of events that can and will be fired off while the app runs. I want to put the event handling in the controller for each view but not sure how to go about it.
My intent is to have all of the controllers in the app implement a common interface because there are some things that all of the controllers will need to do the same. How do I set up the controllers to be listeners for the events in their views? Each view can have different types of events, keyboard, mouse, action, etc so I can't extend any of the event adapter classes in the controllers. I guess I could have the base interface implement all of the listener interfaces but that just doesn't seem right.
From what I've read I dont want to make annonymous inner classes and just call a method in the controller either because I dont want all of the overhead and performance hit of that many extra classes.
Am I looking at some sort of adapter class to sit between the view and the controller and map events to controller methods? This is my first fairly large swing app and the reason I'm doing it is for just this purpose - to learn, so any advise, links or hints would be appreciated.
Thanks for any help
Dave
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Here's a chunk of something I did once. It has the negative of lots of little objects that you mentioned ...

Does that look useful? Or even sane?
[ November 05, 2003: Message edited by: Stan James ]

A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Thanks for the input Stan. You're right, your code shows one of the things I wanted to avoid. At the very least I'll just pass in na instance of the views controller to each listener as I register them. I guess my main question is how to implement the controller.
Having an abstract controller class that implements all of the listener interfaces and then extending that class and overriding the methods I need for each individual controller seems to be the route I'm leaning in now. It'll have the advantage of keeping the individual controllers relatively clutter free and also then each view only has to pass a reference to each event generator. The abstract controller class will be fairly long but not overly complicated. This way no matter what widgets I use in the view, the cooresponding controller will have the appropriate method.

On the other hand, it's not like the view are going to have hundreds of event generators, more like a dozen or so each. So all of this may not even be worth the worry. Of course it has been a good learning experience.
thanks
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6


From what I've read I dont want to make annonymous inner classes and just call a method in the controller either because I dont want all of the overhead and performance hit of that many extra classes.

Not quite sure what you mean here. Are these inner classes in the Controller or the View. What you want to do is have what is called Hook methods. You can have them in both the controller and the view if you want to really decouple things. But here you will have an "Adapter" class that sits in the middle. You would pass a reference to the view and to the controller to this middle class, and register each other with each other through their hook methods.
For instance,
in the View you will have a method like

In my work, I always used the Inner classes in the COntroller and it would call the above hook. But you can move this to the middle class pretty easily.
Here is my code in the controller using my inner class in the Controller.


So if you have a middle class that has a reference to both the view (called frontEnd) and the controller ( called actionHandler), you code in the middle "Adapter" class would look like this

Looks pretty much like the code I had in the controller, excpet now it is registered through the Middle class, instead of directly in the Controller. This approach can also make it so that you only need one controller for all the views, instead of one for each view. Which makes things even easier. "One true source" instead of many.
Good Luck
Mark
[/CODE]


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

Joined: May 10, 2001
Posts: 3244
Mark
Thanks for the reply, I understand what you're saying here but the more classes created increases the overhead of the app so if you're creating a new annonymous class each time you add a listner isn't that gong to create a lot of extra overhead and slow the app down?
My current line of thinking is to create an abstract base class for my controllers. This base class will implement all of the needed Listeners that I'll need for my views, and provide an empty stub for each method in them. Something like this:

Then when I extend this, each controller can implement the methods as they need to. When a view is created it will get a reference to its controller and use that as the listener for each event it can fire. When the events are fired I can have a switch in the controller to determine exactly what the event was and call the appropriate method in the controller to do whatever need to be done.
It seems that I get the same benefit without having to have the additional hook methods in the view to add the correct listener. Also, I don't have to have a method in my controller for each event in the view. This way adding a new event source to the view only requires adding code in the appropriate handler in the controller along with a method to do the work. Whereas if I use your way, I would have to add a method in the view to set the listener, one in the controller to send the listener, and then one to do the actual work.
Am I not seeing this correctly? My view is still disassociated with the model, the event will handle all of the interaction and the view only needs to have a reference to the controller for the purpose of registering the listeners. Granted, I've got a fairly large abstract class with a lot of methods in it, but then each controller can be smaller and doesn't have to implement any interfaces itself, it can just implement the methods it needs and ignore the rest.
Let me know if I'm off track or not seeing the benefit of your method clearly.
Thanks
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Hello, I want to share some thoughts.

These are the rules for optimization for performance:
1 Don't do it.
2 Don't do it yet
3 Do it only after pinpointed the bottleneck

Having an anonymous listener instance, per GUI object(or a related group), invoking the appropiate action instead of only a few listeners cannot harm performance unless there is memory constraints, or the GUI is really huge. But the tests should confirm that. Other special case could be a high ratio of events such as monitoring a real time process. But user input does not correspond to that.

StandarController seems a bit artificial. I was wondering about the reasons to generalize the existing controller classes into this common base class. There is not common state, neither common associations. It seems that acts as a tagging interface because it does not provide any concrete funcionality. "java.util.EventListener" is a tagging interface to which each controller could be casted, as long as implements any of the XXListener interfaces. The downside is that we need to downcast when registering our controller.

Now the questions about MVC that I always wanted to ask, but I never dare to.
1) Why do we really need to decouple the view from the controller?
A view can be coupled to the controller and be completly ignorant of the model.
One of the benefits of decoupling is being able to replace easily a view with another. But I guess few programs need this funtionality, am I wrong?
Replacing a view to use it in another programs seems unlikey because the view is the most specific part of the application, at least from the Layers Arquitectural Pattern perpective.
I think that several views can be coupled to the controller(s), thus we do not need to decouple them for allowing more than one view for the same model.

2) Considering that a non-bloated coherent controller could be enough for an application, and that otherwise a controller per use case is recommended; when it is necessary a view per controller relationship?
Maybe when the view is executing in a client and the controller in a server?
Maybe when the views are really of a different nature?

TIA.


SCJP2. Please Indent your code using UBB Code
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Jose:
You're right about the optimizing and in my own defense I don't think I was optimizing, just trying to avoid having a future problem
My StandardController class will also provide other methods that are used by all of the controllers in the app and also with a common base class I can, of course, register all of them in the same place and update them as needed or do whatever needs to be done to all of 'StandardControllers' in the app.
As far as MVC, I am by no means an expert. I also had/have a hard time wrapping my mind around it sometimes as to why. For me the most swaying answer is simplicity. The fact that the view knows nothing about the data, only how to display what it is given, makes a certain odd kind of sense to me. Maybe I'm just a victim of all the MVC propoganda floating about Another reason for it could be if you're creating some sort of framework that is meant to be extendable then t makes sense to be able to extend all fo your controllers from one plae and all of your views from another. I guess this would be something similiar to the Eclipse IDE and how they have it set up. Not sure if that s a really good example or not though, like I said it'll take someone with more experience on it than me.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
More ideas:
A) The view knows the controller
class View {
...
public void actionPerformed(ActionEvent e) {
myController.startProcess();
}
....
}
class MyController {
...
public void startProcess() {
myModel.startProcess();//maybe in other thread
}
...
}
The view is coupled only to the controller. If we were to replace the view we need knowledge of the controller, but at least this is left untouch.

B) The view notifies the controller
class View {
...
public void registerListener(EventListener controller) {
myButton.addActionListener((ActionListener) controller);
}
...
}
class MyController implements ActionListener, MouseListener... {
...
public void actionPerformed(ActionEvent e) {
if(e.getSource() == myButton) myModel.startProcess();
...
}
...
}
Now the view is decoupled from the controller but this is horribly coupled to the view (myButton)

C) Trying to decouple both
class View {
...
public void registerListener(EventListener controller) {
myButton.addActionListener((ActionListener) controller);
}
...
}
class MyController implements ActionListener {
...
public void actionPerformed(ActionEvent e) {
if( e.getSource() instanceof AbstractButton &&
( (AbstractButton) e.getSource()).getActionCommand().equals("Start") )
myModel.startProcess();
...
}
...
}
"Start" is not the text of the button but is part of of a common set of commands shared between the view and the controller. We could use and enumerated type for this purpose.
Are we restricted to ActionEvents in order to prevent the controller from knowing the view? I do not know. The low events such as Mouse and Keys seem not appropiate, after all we are constructing an application not a GUI widget. But what about ItemEvent, ChangeEvent and PropertyChangeEvent would they be useful?
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Jose:
Your 'B' code is the route I am looking at right now. I see what you mean about the it coupled fairly tightly to the button but thee isn't any way around it. My line of thinking is that the view doesn't do anything except display the data and present some buttons and/or menus for the user to perform some action on the data. So all the view needs to do is register its controller as the listener for the event generators that need to be handled in the controller. Then the controller has to know what action to take based on the event passed. So the view has no knowledge of the controller while the controller has to have some fairly specific knowledge of the view, at least in so far as the possible event sources (in order to test for them) and then it needs to know what action to tell the model to perform.
I'm not sure I like the 3rd way you showed because then there would have to be some agreed on set of shared commands. the view would have to know the appropriate command in order to set it correctly in the widget. Whereas, in 'B', the view doesn't need to know anything except where to send the event.
As for the other events you mentioned, the mouse events and change events and even the list events wont need to be handled by the controller unless the user specifically clicks a button or menu item. ie they can reorder data, move it around delete it, etc but none of that matters to the controller until the user says 'ok, save it'.
I appreciate your input it is helping me to think through all of this. If I misinterpreted anythig you said let me know, like I'm by no means a GUI expert. In fact, this'll be my first semi-large undertaking aside from the ever popular, 'click this button, to change the background color' school asignment.
Thanks
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
My knowlegde is more theoretical than practical though I am writting a program that uses MVC and will be released as open source some day :roll:
I would like to add more ideas to the said above, hoping to prompt answers and comments.
A) I like scheme A because anybody can write views to a program without having to change the controller. This one acts as a Facade into the application for the view. If we elicit the interface that expresses the system operations that the view will invoke on the program, the controller will implement it. The view is now only couple to an interface. We can even change the controller dinamically.
B) I understand the scheme B in which the controller knows about specific GUI widgets is preffered over A. Maybe because it is easy to tell the view that it should update the data that presents to the user. To manage this in the squeme A we need either a Facade into the View for the controller, or having the model to notify the view.
C) Scheme C is similar to A regarding the fact that the controller does not know specific GUI widgets.
We could go for a tecnique similar to a state machine. The system must carry out actions (commands above) whenever the corresponding events (user input for instance) arrived to the system.

Now again a question about MVC:
Is it MVC compliant having a model of a GUI widget, say a DefaultTreeModel, inside the model of our application and its corresponding JComponent (say a Jtree) in the view ?
Pros: notification model to view is taken for granted.
Cons: Our model seems coupled to view.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I've been away from this form for a bit, and this discussion has been going quite nicely. A few thoughts ...
re too many little objects ... have you looked at Swing! Good grief they go nuts with little objects. My half-dozen are a drop in the bucket. But seriously, I'm usually willing to use a bunch of little objects to eliminate if-else-if or case statements.
re coupling ... I built my controller with no import swing beyond the frame itself. That could be eliminated by using an interface perhaps. The view knows the controller and interprets user gestures into controller.method calls. The view can change from one widget to another, one event type to another, one listener type to another, and the controller need not know.
re Swing classes in the model ... I'd draw the line at that.
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Thanks for the input Stan. A couple of questions for you though...
When you talk about using a bunch of little objects to eliminate the if-else statements, is there a reason for thator just personal preference. I'm figuring probably in the neighborhood of 75 to 100 widgets in my app all together. Granted, only a few would be firing events at any one time but for the most part I wanted to avoid creating all those objects if there was no need to.
This leads into your comment on coupling. If I create all of my widgets with annon inner classes then they have to know what method in the controller to call, of call a method in themselves. In some cases it makes sense to call a method in the view itself if the triggering event only effects that view. for the most part though I like the idea of having the handlers in the controller. That way the view can be unchanged if I make a change to the controller. Just so long as the view knows where to send the events it doesn't care what they do or what they are for. If an update to view is required by the event then the controller tells the view what to do.
I understand what you're saying about if the view changes but I dont see that as happening as frequently as the controller itself changes.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
When you talk about using a bunch of little objects to eliminate the if-else statements, is there a reason for that
talking about an event handler, within a controller, with a switch of if, I thing the only disadvantage is the size of such clause.
[ November 14, 2003: Message edited by: Jose Botella ]
 
Consider Paul's rocket mass heater.
 
subject: event handling for med sized MVC app
 
Similar Threads
Doubt In MVC..
Model View Controller Question...
More on MVC
Is MVC Pattern Overkill?
GUI Frustration - help NEEDED!