你的类应该实现 ActionListener 还是使用匿名 ActionListener 类的对象

Posted

技术标签:

【中文标题】你的类应该实现 ActionListener 还是使用匿名 ActionListener 类的对象【英文标题】:Should your class implement ActionListener or use an object of an anonymous ActionListener class 【发布时间】:2012-07-11 17:22:45 【问题描述】:

实现java.awt.event.ActionListener 接口的最佳方式是什么?

让您的班级实现 ActionListener 并将其添加为 ActionListener:

class Foo implements ActionListener

    public Foo() 
        JButton button = new JButton();
        button.addActionListener(this);
    

    public void actionPerformed(ActionEvent e) 

    

或者添加一个匿名 ActionListener 类的对象:

class Foo

    public Foo() 
        JButton button = new JButton();
        button.addActionListener(new ActionListener()      
            public void actionPerformed(ActionEvent e) 

            
        );
    

【问题讨论】:

【参考方案1】:

有些人(jeanette/kleopatra)说几乎从不使用ActionListener,而是使用ActionListener,比如AbstractAction。让您的 GUI 类实现您的侦听器几乎总是一个糟糕的理想,因为这会破坏 Single Responsibility Principle 并使您的代码更难以维护和扩展,因此我强烈建议您不要这样做。

例如,为此的内部类:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;

class Foo 

   public Foo() 
       JButton button = new JButton(new ButtonAction("Action", KeyEvent.VK_A));
   

   private class ButtonAction extends AbstractAction 
      public ButtonAction(String name, Integer mnemonic) 
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      

      @Override
      public void actionPerformed(ActionEvent e) 
         System.out.println("button pressed");
      
   


【讨论】:

+1 对于AbstractActionSingle Responsibility Principle 不错,但它似乎更复杂(在代码维护方面),更难阅读。还是我错了? 随着您对它的熟悉,它会变得很容易阅读。当我试图维护一个分离良好的 MVC 模式时,我使用过它,并让我的 Control 将 Actions 注入到我的 JButtons 中。 别忘了,更容易测试。当动作类不绑定到你的 UI 时,你可以简单地测试它 相关示例——以及 cmets 中的建设性评论——here.【参考方案2】:

第二种选择(匿名类)当然更好,另一种选择是在Foo 中拥有一个嵌套类。

我不会选择第一个选项,原因有两个:

Foo 的用户不必知道它实现了ActionListener。 您不能在同一个类中实现两个不同的侦听器。

【讨论】:

我会因为第一个原因赞成这个答案,但第二个原因是错误的恕我直言。您可以检查ActionEvent 的来源并决定您应该采用的代码路径。这是否是一个优雅的解决方案是另一个讨论,但它肯定是可能的 @Robin:你是对的,但这不是我的意思。我的意思是一个人不能在同一个类中两次实现ActionListener【参考方案3】:

这取决于。如果您想跨多个组件重用ActionListener,选项一更好。如果ActionListener 只会与一个按钮相关联,那么选项二就可以了。

通常,如果您预计项目会有所增长,您会创建一个单独的类(或内部类)。 Foo 不需要实现ActionListener

【讨论】:

有一个 gui 类实现 ActionListener 仅适用于玩具程序。既然他问的是“最佳实践”,那么在任何情况下都没有用。

以上是关于你的类应该实现 ActionListener 还是使用匿名 ActionListener 类的对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个类中的 JPanel 类中实现 ActionListener?

当(当前)只有一个实现它的类时,您是不是应该创建一个接口?

在java里actionPerformed是做什么用的

我应该继承列表还是创建具有列表作为属性的类?

获取 onVisibilityChange ActionListener

我应该使用简单的类还是高维矩阵?