0

I'm developing a MVC Java Swing application, which will offer the user at least a dozen of different actions. Some of these actions will trigger execution of a SwingWorker object, while others are pretty simple (or common). I started with the approach discussed here, but I modified it in order to avoid to define an implementation of the AbstractAction class for any "common" action. This is the solution I implemented:

The Action enum class defines my "common" actions:

public enum Action {
//               label          mnemonic            modelObject  modelMethod
EXIT            ("Exit"     ,   KeyEvent.VK_E   ,   "SubModel", "openExitView")
,FLAG_1         ("Flag 1"   ,   KeyEvent.VK_1   ,   "Options",  "setFlag_1")
,FLAG_2         ("Flag 2"   ,   KeyEvent.VK_2   ,   "Options",  "setFlag_2")
,HELP           ("Help"     ,   KeyEvent.VK_L   ,   "SubModel", "openHelpView")
,ABOUT          ("About"    ,   KeyEvent.VK_A   ,   "SubModel", "openAboutView");

Then, in the Controller class, I added this method:

public AbstractAction getAction(final Action action) {

AbstractAction actionImpl = new AbstractAction(action.label) {
    {
        putValue(AbstractAction.MNEMONIC_KEY, action.mnemonic);
    }

    public void actionPerformed(ActionEvent e) {
        model.executeAction(action);
    }
}; 

return actionImpl;

}

so I get the actions like following (in the Controller) and I assign them to the target Swing components:

private AbstractAction exitAction = getAction(Action.EXIT);

private AbstractAction flag_1Action = getAction(Action.FLAG_1);
private AbstractAction flag_2Action = getAction(Action.FLAG_2);

private AbstractAction helpAction = getAction(Action.HELP);
private AbstractAction aboutAction = getAction(Action.ABOUT);

private AbstractAction complexAction = new ComplexAction("Complex");
...
    view.setExitAction(exitAction);
    view.setAboutAction(aboutAction);
    view.setHelpAction(helpAction);
    ...

where ComplexAction is a full implementation of AbstractAction, which is just an example of management of an action non listed in the enum class (because it's not a "common" action) but something deserving a custom full implementation.

Finally the "general purpose" executeAction method in the Model is responsible for dispatching the action to the specific sub-model class:

    public void executeAction(Action action) {

      Object obj = getModelInstance(action.modelObject);
      if (obj == null) return;

      Method method = null;
      try {
        method = obj.getClass().getMethod(action.modelMethod);
        ...

where getModelInstance just retrieves an instance of the target sub-model object from a model factory, given the model's class name listed in the enum.

Everything works fine, but I'm not convinced of this pattern: is this not boilerplate code? Are there some J2EE objects achieving the same results by writing less code? I have the feeling this is a very common pattern, and it seems strange to me that there isn't a better way do implement the MVC pattern using AbstractAction.

Community
  • 1
  • 1
serkelion
  • 73
  • 2
  • 8
  • You could generalize events through a sort of EventBus where you can register to events by a String, and then trigger events passing a String and an EventObject (superclass of ActionEvent). Your action listeners do nothing more than trigger the EventBus with a unique event name identifier that all listeners will receive notification. It allows you to disconnect the actual event generator and where the action needs to occur. – Neil Feb 18 '16 at 11:07
  • Voting to re-open based on update, but the question is still very broad; see also [*Examples of GoF Design Patterns in Java's core libraries*](http://stackoverflow.com/q/1673841/230513). – trashgod Feb 18 '16 at 17:58

1 Answers1

1

Create an abstract class that contains implementations of Action. The exact formulation depends on your domain, but EditorKit may serve as an example. As suggested here, concrete editor kits "export useful Action classes that operate on the Document model common to text components." More discussion may be found here, here and here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Re [update 2](http://stackoverflow.com/posts/35479248/revisions), `DefaultEditorKit.CopyAction` is shown [here](http://stackoverflow.com/a/34830519/230513). – trashgod Feb 18 '16 at 17:55