My current application has a JFrame with about 15 actions stored as fields within the JFrame. Each of the actions is an anonymous class and some of them are pretty long.
If it is possible that your actions could be reusable (e.g., from keyboard shortcuts, other menus, other dialogs, etc.) and especially if they can work directly on the underlying model (rather than on the UI), then it is generally better not to have them as anonymous classes.
Rather, create a separate package, and create classes for each.
Often, it also makes sense to not instantiate these directly but rather have some sort of a manager that defines constants and initializes and returns sets of actions, so that you could, for example, offer different action sets at different versions or set certain actions only for internal releases.
Finally, check whether your actions can be refactored into a class hierarchy. They often can, which saves code replication, and also helps you add robustness (e.g., check for certain conditions before letting the action execute).
That's typically how I do it. Each action gets it's own class which has a reference to the "app" object so it can get to resources it needs. I usually have an action manager that holds all the actions so there's one place to access them as well as one place to update their enablement and stuff.
Eventually this also becomes unmanageable at which point you should start thinking about using an app framework like Eclipse RCP, the NetBeans framework, JIDE, etc. This is especially true if you want to support user-defined keymaps and stuff like that.
What I do is create a package (package tree actually) for action classes, then instantiate each class according to context. Almost all of my action classes are abstract with abstract methods to get the context (ala Spring).
public abstract class CalcAndShowAction extends AbstractAction {
//initialization code - setup icons, label, key shortcuts but not context.
public void actionPerformed(ActionEvent e) {
//abstract method since it needs ui context
String data = getDataToCalc();
//the actual action - implemented in this class,
// along with any user interaction inherent to this action
String result = calc(data);
//abstract method since it needs ui context
putResultInUI(result);
}
//abstract methods, static helpers, etc...
}
//actual usage
//...
button.setAction(new CalcAndShowAction() {
String getDataToCalc() {
return textField.getText();
}
void putResultInUI(String result) {
textField.setText(result);
}
});
//...
(sorry for any mistakes, I've written it by hand in this text box, not in an IDE).