magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Rational

There are many MVC web frameworks, but as far as I can see there are very few MVC frameworks for Swing (I actually don’t know of any, but there might be some out there). Outlined here is the rough design for one. Please note that this is in the very early stages of design, no code exists for it, and I might not do anything with it. Comments are nonetheless appreciated.

The View

The view would be a GUI Interface. Each view would provide the data necessary to perform some action – it might be a simple ‘OK’ button, or it could be a full blown multi-tabbed interface.

Mapping to an action

Our views cannot themselves perform a submit to an associated action – they know nothing of the action itself. On their own, they are of little use. If we take the view that a view can map to only a single action at any time, we could pass in contextual information to the view to handle submits. Here, a MappingContext object encapsulates this particular form/action mapping.


public class ExampleView {
  private MappingContext _mappingContext;

  public ExampleView(MappingContext context) {
    _mappingContext = context;
  }

  ..

  public void submit()
  {
    _mappingContext.submit(this);
  }
}

The advantage of this is that we can put our submit code wherever we like. A disadvantage is that a view instance can only be coupled to one action at a time. I am unsure as to whether or not this is actually a problem or not. We are coupling to an interface here, introducing a dependency to the underlying framework. I don’t like this, but cannot think of a way out of this at the moment, other that using AOP to generate the submit method. Using AOP might work, but I am unsure how to support submission to different action classes Dependant on the current context of the view – some further reading on AOP might enlighten me.

As for actually getting the view to display, well that would be achieved using a little bit of proxy magic. We do not want to enforce that our implementation implements interfaces, or worse still that it needs to be a Component subclass. Instead, we just create a method to return a displayable object, and in our framework configuration we’ll tell the controller what method to invoke to get it.
The controller will do this by creating a “Dynamic Proxy object”:http://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html#examples to wrap our form.

The Action

Our action is responsible for processing a view input, performing something, and returning a result. Our action implementations do not need to implement any interfaces. The web application framework can detail which method should be the entry point for the action, or a default can be assumed. Above we called submit on our MappingContext . Behind the scenes we are invoking are creating a Dynamic Proxy object to wrap the action class and provide an interface suitable for our framework.
We could overload our entry point method in order to handle submits from several views:


public ExampleAction {
  public void submit(ExampleView view) {
    //handle view
  }

  public void submit(AnotherView view) {
   //do something else
  }
}

And this will be handled by the framework.

The controller

The controllers job is to read the configuration, and produce the View/Action instance mappings when requested. This is clearly a task for an IoC framework. Configuration could be a simple XML file:







The display attribute tells the controller which method it should call on the view to get the displayable component, and similarly submit details the method to call on the action to invoke it. Of course, sensible defaults could be used.

Had you noticed?

That none of this is actually bound to Swing? Or any display technology? The display method that you create on your view can return anything you like – you just have to be in a environment that can display it. For Swing, another framework would wrap this and assume that the Object is a Component. I have the feeling I’ve reinvented something else out there, or else this is useless. Feedback would be appreciated.

10 Responses to “Thoughts on an MVC framework for Swing”

  1. Jason Carreira

    You just decribed XWork:

    http://wiki.opensymphony.com/space/XWork

    XWork is a generic Command Pattern implementation that is used as the core of WebWork2. You could define your Actions in an XML file, decoupling your screens from the classes which they execute, and get the power of Interceptors, type conversion, validation, etc. XWork already has the concept of a generic Result Interface. In WebWork, this can be a dispatch to a JSP or a redirect, or JasperReports to generate a PDF. In a Swing wrapper on top of XWork this could be a refresh of the current screen or telling it to show a new screen.

    Shouldn’t really be that difficult.

    Reply
  2. Rafael Alvarez

    Food for though: Why is that all MVC implementations seems to use the Command pattern? If you look into the Swing model there are complete MVC implementations (JTable comes to mind) WITHOUT commands.

    Reply
  3. Sam Newman

    The MVC used within Swing can be considered to be very localised – that is one MVC instance is used within the scope of getting a table to work, another within the scope of a combobox etc. They help seperate content from presentation within a very small scope, and by and large work well. They do nothing to help seperate your GUI layer from any backend business processing. I see the GUI layer including JTables TableModels, which are used to create commands. These commands are sent and processed by the next layer, which responds by telling the GUI layer to change (e.g. display error message, display this view etc).

    Reply
  4. Kevin Dangoor

    The problem with making a framework that works with both web and Swing is that the interaction models are different. The web is (generally, unless you’re doing fancy javascript) based on discrete requests which result in complete new page output. Swing can (and should) have all sorts of things (big and small) that can happen on a single screen.

    There is undoubtedly a whole bunch of code that can be shared between Swing and web implementations of an app. I’m just saying that you don’t want to sacrifice Swing interactivity by using a framework suited for the web.

    Reply
  5. Sam Newman

    Point taken Kevin. I’m going to see if XWork will let me do what I want – if not, I’ll either try and change it so it can or look elsewhere…

    Reply
  6. Jon Tirsen

    Jason, the most annoying thing with XWork is that you have to define your actions and their bindings in a separate XML file. Definining things in XML files was very trendy a couple of years ago but I’ve moved away from it completely and I also notice a lot more people doing that aswell.
    The problem with XML files are that it’s not a very powerful language, you don’t get compile time checking and it’s hard to get it to work really well with refactoring IDEs.
    With the birth of JDK 1.5 metadata I suspect that the Java community will completely move away from XML based stuff within a couple of years.

    Reply
  7. Sam Newman

    From looking over the Wiki pieces detailing integration of Spring (http://wiki.opensymphony.com/space/Spring+Framework+Integration) and Pico (http://wiki.opensymphony.com/space/PicoContainer+Integration) with WebWork 1.4, it seems they can be used as the Action respositories as opposed to WebWork itself. If the same applies for XWork, then assuming you can get a third party IoC framework integrated the problem of registering actions in a seperate file goes away as you register them there (reading between the lines of the XWork wiki I get the impression that XWork attempted to use Pico internally to provide IoC features a while back, but I might be wrong).

    Reply

Leave a reply to Sam Newman Cancel reply

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS