3

I am currently replacing my anonymous ActionListeners

new ActionListener() {
    @Override
    public void actionPerformed(final ActionEvent event) {
        // ...
    }
}

with class files representing actions:

public class xxxxxxxAction extends AbstractAction {
}

However, my GUI is able to perform a lot of actions (eg. CreatePersonAction, RenamePersonAction, DeletePersonAction, SwapPeopleAction, etc.).

Is there a good way to organize these classes into some coherent structure?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
sdasdadas
  • 23,917
  • 20
  • 63
  • 148
  • 2
    Please provide some context; see [*How to Use Actions*](http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html). – trashgod Feb 06 '13 at 19:08
  • @trashgod What do you mean by context? I'm just feeling the strain of converting ~60 ActionListeners into separate classes and I was unsure if there is a better way to organize Actions in my code. – sdasdadas Feb 06 '13 at 19:11

3 Answers3

8

You can keep your actions in a separate package to isolate them. Sometimes, it is useful to keep them in one class, especially if actions are related or have a common parent, for example:

public class SomeActions {
    static class SomeActionX extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }

    static class SomeActionY extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }

    static class SomeActionZ extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }
}

Then to access them:

JButton button = new JButton();
button.setAction(new SomeActions.SomeActionX());
tenorsax
  • 21,123
  • 9
  • 60
  • 107
  • 1
    You could also use the [Action API](http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html) which would also allow you to store properties about the action, which many of the Swing components are capable of configuring them selves with – MadProgrammer Feb 06 '13 at 20:07
6

I'm just feeling the strain of converting ~60 ActionListeners into separate classes.

Only you can decide if 60 is minimal. This example uses four instances of a single class. StyledEditorKit, seen here, is a good example if grouping as a series of static factory methods. The example cited here uses nested classes. JHotDraw, cited here, generates suitable actions dynamically.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
4

First of all, you should provide public methods for all actionPerformed used in your actions (createPerson, removePerson, etc.). All these action methods should be in one class (I call it PersonController). Then, you need to define your AbstractPersonAction:

public class AbstractPersonAction extends AbstractAction {
  private PersonController controller;

  public AbstractPersonAction(PersonController aController) {
    controller = aController;
  }

  protected PersonController getController() {
    return controller;
  }
}

Now you can extract all your actions into separate classes.

public class CreatePersonAction extends AbstractPersonAction {

  public CreatePersonAction(PersonController aController) {
    super(controller);
  }

  public void actionPerformed(ActionEvent ae) {
    getController().createPerson();
  }
}

These actions can be a part of an outer class or be placed in a separate "actions" package.

Johan Nilsson
  • 77
  • 3
  • 8
Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
  • This is definitely in a similar vein to the other answers, but it would be helpful if I could pass the controller only once - and not to every action I create (without being forced to "initialize it" when my program starts up). – sdasdadas Feb 06 '13 at 19:37