web-dev-qa-db-ja.com

クラスがActionListenerを実装するか、匿名のActionListenerクラスのオブジェクトを使用するか

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) {

            }
        });
    }
}
16
elias

一部の(ジーンズ/クレパトラ)は、ほとんど決してActionListenerを使用せず、代わりにAbstractActionなどのアクションを使用すると言います。 単一の責任の原則 に違反し、コードの維持と拡張が難しくなるため、GUIクラスにリスナーを実装させることは、ほとんど常に悪い理想です。そのため、そうしないことを強くお勧めします。

したがって、たとえば、このための内部クラス:

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");
      }
   }

}

2番目のオプション(匿名クラス)は確かに優れています。もう1つのオプションは、Foo内にクラスをネストすることです。

次の2つの理由により、最初のオプションは使用しません。

  • Fooのユーザーは、ActionListenerが実装されていることを知っている必要はありません。
  • 同じクラスに2つの異なるリスナーを実装することはできません。
8
casablanca

場合によります。複数のコンポーネント間でActionListenerを再利用する場合は、オプション1の方が適しています。 ActionListenerが1つのボタンにのみ関連付けられる場合は、オプション2で問題ありません。

通常、プロジェクトの成長が見込まれる場合は、別個のクラス(または内部クラス)を作成します。 Fooを実装するためにActionListenerを使用する必要はありません。

4
Rob Wagner