これは、内部クラスの使用方法を説明するためのものです:
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 つの優れた機能が提供されます。
- アクション作業をメソッドにカプセル化し、後で必要に応じてプログラムからアクセスできるようにします
- メソッドの作業が Swing イベント スレッドから離れていることが保証されるため、集中的な処理中に GUI がハングアップすることはありません。