Swing and Design Patterns – Part 3. Command Pattern

 

Command Pattern

The command pattern is a commonly used pattern which encapsulates a method call or action-like code into a single class. The advantages of being able to package a method (or methods) into a class become evident when you have multiple invokers for a single action (for example a button and a menu item may perform the same action).

Swing uses the concept of the command pattern through the use of ‘Actions’. In Swing you create your actions by extending Swing AbstractAction. The code implemented in the actionPerformed() method is the code to be executed once the action has been fired. It’s really just a fancy realisation of the ActionListener interface adding some extra functionality such as mnemonics and accelerator keys.

An instance of SimpleAction can then be assigned to a menu item or a button.

Updating the GUI and Method Invocation

In my experience there are two key things that need to passed into the action.

The first is a reference to the application’s main frame, which contains references to all other components in the application. (If you don’t understand the concept of a GUI hierarchy, you can visualise the main application frame as the trunk of a tree through which it is possible to get references to any other component further down in the branches).

Having a handle on the main frame allows you to perform any kind of GUI action, for example refreshing a table, updating text in a label, switching indicators on or off. Swing Actions execute their behaviours in the event dispatch thread, so threading issues should not be of concern.

Alternatively to passing in a frame you could use the Mediator Pattern to get a handle on distant GUI objects.

The second thing to pass in is the delegate (or facade), that is, the class or classes which control communication from the application to outside systems. The delegate simply provides the method call that the action is really encapsulated around.

The Action would look something like this :

All exceptions should be handled within the action, showing error dialogs when appropriate. The action should encapsulate the method call and all exceptional situations that may arise.

Deviations from the Norm

Of course there are deviations from this. Inside the body of an action you might call multiple delegate calls, or you might even want to “fire and forget” by not having any GUI interaction at the end of the action. There is no concrete definition of what an action is, and what is a collection of actions bundled into one action. For example, do you create a ‘Cancel’ action for a simple dialog? Or should the activity that sits behind the dialog (and all its permutations) reside in its own action?

A swing action can be more broad and can take into consideration a number of actions (or activity). This avoids too many classes, and maps closer to a User Case than with a specific action. For example a Use Case like ‘Manage Settings’ could be handled within one Swing Action class :

 

 

 

 

Linking Actions

You can link up actions in Swing. There is nothing profound in how to call the next action. Simply code your action like this, making a call to another action :

It may seem a bit ugly at first, but it makes sense in most situations. Assuming that you are not interested in the ActionEvent. You are still in the Event Dispatch Thread when you call the second action. The second action does not need to know about the calling action. Of course, you have to make sure that you are not looking at the action events because you are passing in a null.

Further reading:

Posted in Design Pattern, Swing Design Pattern | Tagged , , | 1 Comment

One Response to Swing and Design Patterns – Part 3. Command Pattern

  1. Fernando says:

    Hail from Brazil!

    Congratulation for the great explanation,

    Thanks alot²

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

THREE_COLUMN_PAGE