The MVC design pattern is widely recognized as the preferred patter for developing UI-type applications, whether they be web applications or
more traditional client applications. While there are an abundance of widely accepted and quite mature MVC web frameworks, there are very
few for Swing applications. I believe this is because Swing does a good job of solving the “M” and the “V” portions of “MVC”, while leaving the “C” portion open.Swing provides native support for using models, having a rich set of model interfaces and abstract classes for most of their UI components; I.e.
TableModel, TreeModel etc… Views are defined by the rich ui components that are driven by these models. It is when tying together the
interactions between the models and views (the controller portion) that Swing’s paradigm falls apart. Swing’s event/listener model is what can be
considered the controller part of the MVC, but is much too diffucult to maintain is it manifests itself as a graph of events and actions to listeners.
Thus Swing’s native controller is an unmaintainable myriad of event to listener to bound object relationships:
So while it’s clear that there is control logic, it’s all seperated between various listeners that are responsible for which bound objects to manipulate
upon which events. In addition, when forming these listener to event relationships you have to have a way to retrieve the reference to the actual
object you need to add the listener to. The same goes for getting the references to the bound objects that the listeners will need to manipulate.
What results is that you have to expose every object that wants to be a part of this system of events and listeners, independent of whether or not
it’s good design to expose these objects.The first step to solving this problem is to consolidate the control logic into a more respectable, singular controller entity:
Instead of maintaining seperate listeners for every event, the controller has exposed methods to capture all system events and perform the
necessary response actions to the bound objects. While this consolidates the control logic, and forms a controller entity, it still does not clean up the
relationships between objects or the need to expose every object that needs to be part of this eco-system. I.e. the controller still must know of every
event and every bound object. What we need is a way for each event to log the event to a registry, and for each bound object to specify which
events they want to be notified of. Going even one step further, we need a more generic way for the bound objects to specify which events they
want to be notified of and not to refer directly to the event. This sounds a lot like the bus paradigm to me.When an event occurs the object firing the event places an event message on the event bus. Any object that wishes to respond to an event can register itself with the event bus to be notified on the applicable events:
In this model, none of the events need to know anything about the bound objects and none of the bound objects need to know about the events.
And instead of having one big conglomeration of event/object bindings in the form of a controller, we can allow the bus to marshal event messages
to any object that cares about them. This offers the perfect seperation of logic without sacrificing flexibility.In code I imagine this event model will manifest itself like so;
<i>Event firing object</i>
public void onEvent1() {
EventBus.placeEvent(new Event("event1", this.eventContext));
}
<i>Event receiving object</i>
public void handleEvent(String eventId, EventContext context) {
if(eventId == "event1") {
aTextField.value = context.getProperty("userId");
}
}
Thinking even further of the type of configuration and enhancements that could be applied here:
- Events can be further organized by a heirarchical set of topics. So an event could be send on the “ui.mouse.movement” topic with an id of
“panelHover”. Any bound object that has registered itself to listen to the “ui.mouse” topic would get notification of this event. This would make
things like logging and other such wide-area functionality very basic to implement. The logging object would just register itself for the root or all
(”*”) topic to receive notification of every event. - Using such frameworks as spring, or even utilizing aspect-oriented-programming, we can fully wire events to event bus to listening objects
using an external XML configuration file. For instance, we can say which events are sent to which topics, and can then specify which objects
listen to events of which topics. We can even specify which methods to execute when a particular event is received.<events> <event objectClass="com.ryandaigle.ui.MyButton" eventClass="java.awt.ActionEvent" topic="ui.button" /> </events> <receivers> <receiver-ref id="logger"> <subscribeTopic id="ui.*" /> </receiver-ref> </receivers>Now granted there is a lot here that I haven’t solved yet, but you get the idea.
I haven’t had a chance to look at how to maximize XWork in Swing, although
I’ve heard some rumblings about it recently. I’ve also been intrigued with Spring’s spring-rcf but have yet to see any code or documention for it.
My hope is that one of these two, or the combination thereof will implement a decoupled event bus-like model. It just seems to be the prefect model
for Swing/Java UI applications.

uterogestation planetarily rampingly trielaidin isanemone matchstick zephyranthes uneventful ECB keeps interest rates on hold http://www.expresspress.com/