8


Sorry for the title, probably too generic.

I already read How to Write an Action Listener tutorial by Java and I already read this question, but I still have some doubts: I was wondering which solution is the best when I have to perform the same action multiple time.

I'd want to reuse the same ActionListener, but I am not sure on how to achieve this in the best way (speaking in term of: code readability, code mantainability, performance and code style).

First the "standard" code (which I would use if I'm not going to reuse the action listener):

btnMenu.addActionListener(
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Navigator.showMenu();
        }
    }
);

This way I can't reuse anything obv, since it's an anonymous inner class...

Now, I can think of the following solutions:

  1. Store a reference of an Anonymous Inner Class in a field (that will most likely be static final);
  2. Write a new class that implements ActionListener interface.

Example code for solution 1:

public static final MENU_ACTION_LISTENER = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        Navigator.showMenu();
    }
};

btnMenu.addActionListener(MENU_ACTION_LISTENER);

Example code for solution 2:

// package-private, only GUI-package classes should be able to use it.
// most likely I won't ever need to subclass it, so why not making it final?
final class MenuActionListener implements ActionListener  {
    public void actionPerformed(ActionEvent e) {
        Navigator.showMenu();
    }
}

// now, wherever I need to use it:
btnMenu.addActionListener(new MenuActionListener());

I have some doubts about both solutions:

  1. Where to store references to Anonymous Action Listeners? I could have a sort of utility class (e.g. ActionListenersUtil) where store all action listeners I want to reuse in static final fields, but I don't like it... it seems to me poor design.

  2. It makes more sense, probably best follows the Command Pattern... I initially had some doubt about the packages... I'd like to have all listeners in a separate package (e.g. com.myapp.gui for gui elements and com.myapp.gui.listeners for listeners. But when I wrote down this I realized that I have no choice: the only place where it make sense is in the same package (because they must be package-private), even if for the sake of order I would have like to put them all in a separate package. I still have some doubt though, because most action listeners may be reusable even in case GUI changes; it still would be a good idea to have it in the same package?

Another question: what's the difference between calling btnMenu.addActionListener(MENU_ACTION_LISTENER); and btnMenu.addActionListener(new MenuActionListener()); (speaking in term of JVM, class loading, class compiling, memory occupied by each class, garbage collection and so on)?

Please help, I'm so confused right now! :(

4

1 回答 1

14

如果您必须将其附加到按钮、菜单等,最好的方法是创建一个Action而不是一个。ActionListenerAnAction是 a 的模型JButton,并且该模型旨在共享

这还使您能够同时更改Action附加到的所有按钮的文本、图标、启用状态和其他属性,而无需多次调用。另外,它也可以附加到菜单项等。

要创建一个,Action您不必从头开始。AbstractAction是一个很好的起点。SwingAction教程也是一本不错的读物。

于 2012-09-17T16:34:55.413 回答