2009-08-13 12 views
4

OK、私はGUI要素にActionListenerを追加し、それは私が持つActionListenerことを使うのみ要素ですので、もし、それは私が次の行のどの(a、b)は重要ではありませんチェックボックスを選択状態にするために使用しますか?アクションリスナーとイベントソース

final JCheckBox checkbox = (JCheckBox)this.buildResult.get("cbDebugTick"); 
checkbox.addActionListener(new ActionListener() { 
    @Override public void actionPerformed(ActionEvent event){    
      boolean bChecked = 
      // (a) checkbox.isSelected(); 
      // (b) ((JCheckBox)event.getSource()).isSelected(); 
      model.setPrintDebugOn(bChecked); 
     } 
}); 

それは私が複数のGUI要素にActionListenerオブジェクトを追加した場合、その後、私は(B)を使用するべきであると私には理にかなっています。

と(B)で、それは私がアクションリスナーを追加した一人、または私は守備のプログラミングとinstanceofチェックを行う必要があるため、盲目的に、JCheckBoxevent.getSource()をキャストするOKでしょうか?

注:この質問は、一般的なイベントリスナーのコンテキストにあります。 kdgregoryには、特に私が考慮しなかったチェックボックスがあります。

答えて

0

(b)確かにインスタンスチェックを行うべきですが、それほど重要ではありません。私はこれらの行がうまく機能していると思いますが、(b)はより良いコードになります。

通常、アクションリスナーでは、チェックボックスにカスタマイズされた別のメソッドを呼び出します。だから、次のようになります。

@Override public void actionPerformed(ActionEvent event) {         
    //your treatment would be in this method, where it would be acceptable to use (a)     
    onCheckBoxActionPerformed(event) 
} 
+0

詳細を教えてください。匿名の内部クラスの同じメソッド/フィールドにアクセスできる場合、外部クラスへの転送はなぜですか? –

+0

このようにして、同じアクションリスナーに異なるコンポーネントを簡単に追加して、異なるやり方で多態性を扱うことができ、コードが「良くなる」 –

+1

私はdavidのアサーションに同意しません。このようにコールを転送すると、デカップリングが発生します(これが、最初はSwingのイベント通知にリスナーのアプローチが採用された理由です)。理想的なケースは、アクションビヘイビアを完全に取り除き、コントロールを含むビューの外部のアクションリスナーを使用することです。この場合、オプション(b)が優先されます。つまり、あなたが本当にやるべきことは、アクションを作成してそれにコントロールを付けることです。 –

0

ベストプラクティスのオプションであるので、私は防御的にプログラムしたいと思います。しかし、あなただけがコードを使用するつもりなら、あなたができない理由はありません。しかし、あなたが何か将来のポイントでそれに戻って何かを変えて、あなたが直接再利用できる良いコードを書いていることがあなた自身であれば、あなたがどれほどうれしいか想像してみてください...

3

私はどちらもしません。

このチェックボックスをクリックすると、何らかのアクションが開始されますが、ItemListenerを添付して、ItemEventの選択状態を確認してください。

ただし、チェックボックスは通常はアクションを呼び出さず、状態を管理します。したがって、より良いアプローチは、アクションを開始するものに応じて、すべてのチェックボックスを調べることです。


編集:OPが提起したより大きな問題に関するいくつかの解説。

まず、スイングの大きな部分は、コヒーレントな動作モデルではなく実装の利便性を表すことが重要です。 JCheckBoxJButtonは、そのスペース内でのクリックが意味があるという事実以外は共通点がありません。ただし、ボタンのラベルなどの実装の詳細を提供するAbstractButtonから継承します。また、ボタンが「押し込まれている」と仮定し、ボタンを押すと意味のある動作(アクション)が開始されることを前提としています。しかし、JCheckboxの場合、ボタンの押下は重要ではなく、状態の変更は重要ではありません。その状態の変更は、ItemListenerに通知されます。これは、状態の変更が他のボタンタイプ(JavaDocで「チェックボックス」と表示されていても意味がありません)でも、AbstractButtonで定義されます。

Swingが正しく行ったことの1つは、使用するのが難しい場合、Actionはその動作を開始するコントロールとは別のアイデアです。アクションオブジェクトは、メニュー項目、ダイアログ上の押しボタン、キーストロークなど、複数のコントロールから呼び出すことができます。デザインの観点からもっと重要なことは、何が起こる必要があるかを把握しようとする一般的な「リスナー」という考え方から離れてしまうことです。たとえば、単一のリスナーがメニューシステム全体から入力を受け取り、次に大きなif/elseチェーンを実行して、押されたメニュー項目を特定するアプリケーションを見てきました。アクションを使用すると、より多くのクラスがあることを意味しますが、長期的には、より保守的なアプリケーションを提供します。

最後に、ユーザビリティの観点からは、JCheckboxやJTextAreaなどの状態を維持するコントロールと、JButtonやJMenuItemなどのアクションを開始するコントロールの違いがあります。私は、ラジオボタンをクリックすると、別のページに移動する(Web)アプリを見てきました。それは良くないね。内部的にリスナーを使用する予定がある場合でも、一部のモデルの状態を更新するには、GUI要素のコレクション自体がモデルを提供しない理由を尋ねる必要があります。

+0

有効なポイント...しかしそれは私の質問ではありません –

+0

真実ですが、おそらく、この質問をGoogleから見つけ、APIを適切に使用する方がいらっしゃいます。むしろ2つのハッキングのどちらが "より良い。 " – kdgregory

+0

それは公正です、私はその質問に注意します。この場合、チェックボックスの知識がないモデルオブジェクトにチェックボックスの状態を伝えるためにリスナーを使用していましたが、代わりにjavax.swing.JToggleButton.ToggleButtonModelを使用する必要がありますイベントリスナー –

1

リスナーが排他的な場合(anonリスナーなど)は、(a)を使用します。

リスナーが再利用されます場合は(this、例えばのActionListenerのインスタンスである)私はとしてそれを記述します:あなたは、いくつかのチェックボックスがあり、それらが同じように処理された場合は、その後、

@Override 
public void actionPerformed(ActionEvent event) { 
    Object src = event.getSource(); 
    if (src == checkbox) { 
     boolean bChecked = checkbox.isSelected(); 
     // ... 
    } 
} 

instanceofが理にかなっています。

関連する問題