3

私は以下を含むシンプルなGUIを持っています:

  • プッシュボタン。
  • 2つのラジオボタン

今、私はこれらのボタンのそれぞれを聞きたいです。私がしていることはそのようなものです:

public class TestApp implements ActionListener {

    private JFrame frame;
    private JButton btn;
    private JRadioButton rdb1;
    private JRadioButton rdb2; 

    public static void main(String[] args) { /*....*/ }

    private void initialize() {
       //Each time I add a button, I add it to the listener:
       btn = new JButton("Button");
       btn.addActionListener(this);
       //..
       rdb1 = new JRadioButton("Value1");
       rdb1.addActionListener(this);
       //And so on...
    }

    //The ActionEvents  
    public void actionPerformed(ActionEvent e) {
       if(e.getSource()==btn)
       //...
       if(e.getSource()==rdb1)
       //...        
    }
}

これが良い/悪いスタイルと見なされるかどうかを知りたいですか?

4

5 に答える 5

5

リスナーが非常に長いメソッドでない限り、私は個人的に匿名のクラスパターンを好みます。

        final JButton btn = new JButton("Button");
        final JRadioButton rdb1 = new JRadioButton("Value1");
        final ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                if (e.getSource() == btn) {
                    //...
                } else if (e.getSource() == rdb1) {
                    //...        
                }
            }
        };
        btn.addActionListener(listener);
        rdb1.addActionListener(listener);

またはさらに良い:

    btn.addActionListener(new ActionListener (){
         public void actionPerformed(ActionEvent e) {      
             // btn handling code
             }
    });
    rdb1.addActionListener(new ActionListener (){
         public void actionPerformed(ActionEvent e) {      
             // rdb1 handling code
             }
    });

使用しているパターンにより、他のクラスがクラスTestAppを他のクラスによってリスナーとして設定されるように設定できます。これが意図されていない限り、これは良い習慣ではありません。

于 2012-11-09T23:52:48.680 に答える
4

アクションリスナーが行おうとしていることの複雑さに多くのことが帰着します。小さな使い捨てアクションが必要な場合は、匿名クラスが適しています。

このスタイルのリスナーを使用する主な利点は、アクションが実行していることと、アクションが実行しているユーザーを正確に分離できることです。欠点は、リスナーが実際にどこで終了するかを読み、知ることが難しくなり始めるため、リスナーに10行以上が含まれている場合に発生します。

この場合、内部クラスのようなものがより適切かもしれません。匿名クラス(それを使用するクラスに関連付けられている)の利点がありますが、読みやすくなっています。

再利用可能なアクション(開く、新規、保存など)が必要な場合は、自己構成可能性と自己完結型アクションリスナーを提供するActionAPIを使用することをお勧めします。

私見では

于 2012-11-10T00:33:03.690 に答える
3

よりオブジェクト指向の方法は、各リスナーを実装するための匿名クラスを作成することです。

イベントソースコンポーネントをオンにするリスナーを1つだけ作成することはあまり読みやすくありませんが、さらに、リスナーの数が増えると、エラーが発生しやすくなります。スイッチブロック(またはif-elseブロックのチェーン)で発生する可能性のあるすべてのイベントソースを処理することを簡単に忘れることができます。これにより、実行時例外のサイレントな誤った動作が発生します(その場合は何も起こりません)。

各コンポーネントに個別のリスナーを追加すると、コンパイル時に、すべてのコンポーネントを処理することを忘れていないことを確認できます。

public class TestApp {

    // you can initialize fields inline to make thing shorter and safer
    private JButton btn = new JButton("Button");
    private JRadioButton rdb1 = new JRadioButton("Value1");

    private void initialize() {
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // something
            }
        });
        rdb1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // something else
            }
        });
    }
}

匿名クラスの構文は非常に冗長であるため、リスナーをプライベートフィールドに移動することで、initializeメソッドのコードを短縮できます。

public class TestApp {

    private JButton btn = new JButton("Button");
    private JRadioButton rdb1 = new JRadioButton("Value1");

    private void initialize() {
        btn.addActionListener(btnListener);
        rdb1.addActionListener(rb1Listener);
    }

    private final ActionListener btnListener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // something
        }
    };

    private final ActionListener rb1Listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // something else
        }
    };
}
于 2012-11-10T00:02:59.473 に答える
2

他に2つのアイデアについて考えることができます。

  1. 各UI要素に独自のリスナーを与えます。彼らはそのように完全に独立しています。
  2. newを呼び出すのではなく、リスナーをSwingUIに挿入します。ユーザーに適切と思われる動作を変更する機会を提供します。Swing UIに、本来の目的である結果の表示を実行させます。それでおしまい。リスナーはコントローラーロジックの一部であると私は主張します。
于 2012-11-09T23:47:16.107 に答える
2

それはあなたがメソッドで何をしたいかにある程度依存しますactionPerformed。他のクラスがこのメソッドを呼び出したくない場合はactionPerformed、内部クラスを作成してメソッドのスコープを縮小したくなるかもしれません。例:-

public class TestApp {

    private JFrame frame;
    private JButton btn;
    private JRadioButton rdb1;
    private JRadioButton rdb2; 

    private class CombinedActionListener implements ActionListener {
         public void actionPerformed(ActionEvent e) {
             if(e.getSource()==btn)
             //...
             if(e.getSource()==rdb1)
             //...        
             }
    }

    public static void main(String[] args) { /*....*/ }

    private void initialize() {
       ActionListener listener = new CombinedActionListener()

       //Each time I add a button, I add it to the listener:
       btn = new JButton("Button");
       btn.addActionListener(listener);
       //..
       rdb1 = new JRadioButton("Value1");
       rdb1.addActionListener(listener);
       //And so on...
    }
}

ボタンインスタンスをコンストラクターに渡すことで、リスナークラスを静的内部クラスまたはトップレベルクラスにすることもできます。これにより、リスナークラスのテストが容易になります。

ただし、上記で述べたように、これはi)他の誰かがこのメソッドを呼び出す可能性があるかどうか、およびii)メソッド内のロジックの複雑さに大きく依存します。

于 2012-11-09T23:49:06.623 に答える