4

コードの設計に問題があります。ボタン グループにない 3 つのボタンがあります。選択したボタンに基づいて、アクションを実行したい。このアクションでは、クラス内のオブジェクトを変更する必要があります。これは、外部にアクセスできないため、内部クラスを使用できないことを意味します。ボタン グループにイベント リスナーを追加できれば、これははるかに簡単になりますが、ラジオ ボタンごとにイベント ハンドラーが必要になることがわかりますが、これは正しいですか? そうでない場合、どうすればそれを行うことができますか?ありがとう

簡単な例

public class Test(){
    RadioButton 1 = new RadoButton();
    RadioButton 2 = new RadoButton();
    RadioButton 3 = new RadoButton();
    Object myObject = new Object();

   public void clickEvent(){
       if(1.isSelected()){
           myObject.doOne();
       }else if(2.isSelected()){
           myObject.doTwo();
       }.....
   }
}
4

2 に答える 2

2

すべてのボタンに同じリスナーを設定できます。

擬似コード:

radioButton1 = new RadioButton();
radioButton2 = new RadioButton();
radioButton3 = new RadioButton();

listener = new ActionListener() {
...
}


radioButton1.addActionListener(listener);
radioButton2.addActionListener(listener);
radioButton3.addActionListener(listener);
于 2013-03-13T14:21:47.283 に答える
2

これは、内部クラスの使用方法を説明するためのものです:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JRadioButton;

public class TestInnerClass {

    JRadioButton radioOne = new JRadioButton();
    JRadioButton radioTwo = new JRadioButton();
    JRadioButton radioThree = new JRadioButton();
    Object myObject = new Object();

    public TestInnerClass() {
        ActionListener myInnerClass = new MyActionListener();
        radioOne.addActionListener(myInnerClass);
        radioTwo.addActionListener(myInnerClass);
        radioThree.addActionListener(myInnerClass);
    }

    private class MyActionListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            if(radioOne.isSelected()) myObject.toString();
            else if(radioTwo.isSelected()) myObject.notify();
            else if(radioThree.isSelected()) myObject.getClass().getName();
        }
    }
}
  • gontard のコメントに記載されているように、内部クラスが静的ではないことに注意してください。したがって、myObject への可視性があります。そして、それを非公開にしておくのが最も安全です。

この場合のように、すべてのイベントを 1 つのリスナーで処理することをお勧めします。ただし、各コンポーネントに固有のイベント処理が必要な場合もあります。たとえば、これらのケースでは、radioThree がイベントをトリガーする可能性があります。これらのボタンはグループに属していないため、radioOne がまだ選択された状態にある可能性があります。この単一のハンドラーが起動し、最初の無線でのみ動作します。これを修正する 1 つの方法は、次のようにソースのチェックを追加することです。

public void actionPerformed(ActionEvent event) {
    if(event.getSource() == radioOne && radioOne.isSelected()) 
        myObject.toString();
    if(event.getSource() == radioTwo && radioTwo.isSelected()) 
        myObject.notify();
    if(event.getSource() == radioThree && radioThree.isSelected())
        myObject.getClass().getName();
}

もう 1 つの方法は、コンポーネントごとに 1 つのリスナーを使用することです。そこで、匿名クラスが非常に役立ちます。

radioOne.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        myObject.doOne();
    }
}); 

私のお気に入りのパターンの 1 つは、特に作業が重要な場合に、まず作業を行うメソッドを作成し、次にリスナーから呼び出すというものです。また、SwingUtilities.invokeLater() で呼び出しをラップして、Swing イベント スレッドから作業を取得します。

public class Test {

    JRadioButton radioOne = new JRadioButton();

    Object myObject = new Object();

    private void handleRadioOne() {
        myObject.toString();
        // etc, etc.
    }

    public Test() {

        radioOne.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        handleRadioOne();
                    }
                });
            }
        });
    }
}

これにより、次の 2 つの優れた機能が提供されます。

  1. アクション作業をメソッドにカプセル化し、後で必要に応じてプログラムからアクセスできるようにします
  2. メソッドの作業が Swing イベント スレッドから離れていることが保証されるため、集中的な処理中に GUI がハングアップすることはありません。
于 2013-03-14T08:51:53.953 に答える