リスナーまたはオブザーバーを使用する必要がありますか?
-
09-09-2019 - |
質問
GUI に別のクラスの ArrayList の内容を表示するドロップダウン ボックスがあります。新しいオブジェクトは GUI の他の場所で ArrayList に追加できるため、ドロップダウン メニューを更新できるように、いつ更新されるかを知る必要があります。私が収集した情報によると、私の選択肢は 2 つあり、ArrayList クラスを拡張して独自の ChangeListener を追加できるようにするか、問題の ArrayList を含むクラスを拡張監視可能にするかです。
より適切な解決策はどれでしょうか?
解決
二つの溶液は、本質的に同じルートデザインパターンの実装である前者の場合、あなたは後者で、「観察」のArrayList自体を作っているあなたがいます配列リストを使用してドメインオブジェクトづくり「に観察を。」
私の傾向は、後者を行うには、次のようになります。ドメインオブジェクトが観察します。あなたが最終的にドメインオブジェクトについて、変更される可能性があり、他のものの持っている可能性があるため、これは主に(GUIを更新する必要のあるを。)それはすでに観測可能であるならば、あなたはすでに設定されています。
あなたは厳密にjava.util.Observable
を拡張する必要はないことに注意してください - 。あなたはそれを行うことなく、デザインパターンを実装することができます。
他のヒント
の Observable
Java での実装はほとんど使用されず、Swing とうまく相互運用できません。を使用してください EventListener
その代わり。
特に延長しない理由はありますか? AbstractListModel
または使用することさえ DefaultListModel
「GUI の他の場所」でリストの内容を管理するときに直接?次に、コンボボックスで ComboBoxModel
同じものに委任する ListModel
インスタンスを作成し、選択状態を追跡するための独自の実装を追加します。
私は次のようなことを念頭に置いています(ただし、テストしていません)。
final class MyComboBoxModel
extends AbstractListModel
implements ComboBoxModel
{
private final ListModel data;
private volatile Object selection;
MyComboBoxModel(ListModel data) {
/*
* Construct this object with a reference to your list,
* which contents are managed somewhere else in the UI.
*/
this.data = data;
data.addListDataListener(new ListDataListener() {
public void contentsChanged(ListDataEvent evt) {
fireContentsChanged(this, evt.getIndex0(), evt.getIndex1());
}
public void intervalAdded(ListDataEvent evt) {
fireContentsChanged(this, evt.getIndex0(), evt.getIndex1());
}
public void intervalRemoved(ListDataEvent evt) {
fireContentsChanged(this, evt.getIndex0(), evt.getIndex1());
}
});
}
public void setSelectedItem(Object selection) {
this.selection = selection;
fireContentsChanged(this, 0, data.getSize() - 1);
}
public Object getSelectedItem() { return selection; }
public int getSize() { return data.getSize(); }
public Object getElementAt(int idx) { return data.getElementAt(idx); }
}
なぜバインディングを使用していない?
http://wiki.eclipse.org/index.php/JFace_Data_Bindingする
あなたのリストにあなたのGUIウィジェットをバインドします。変更は透過的に2つのオブジェクト間のpropogateます。 (直接のArrayListを使用している場合)などWritableListとして、適切な観測可能で、あなたのモデルを包むようにしてくださいます。
は、必ず延長上の組成を好む(私の参照は、効果的なJavaと私の個人的な経験です)。 ArrayListのを拡張することは、単にあなたがクラス不変条件のいずれにも違反していないだろう約束です。また、あなたが拡張され、特定のリストの実装にあなたをバインドします。
あなたは GUIデザインパターンを使用するように切り替えることができます。または限られた実装を構築します。
Xは、いくつかの意味のある名前であると方法DrawXArrayListを有する(GUIフォームインターフェイスを作成します。これは、型のArrayList
のパラメータを有しますGUIViewと呼ばれる新しいクラスを作成します。 UpdateXArrayList、およびRegisterForm
:それは、少なくとも二つの方法がありますあなたのアプリケーションを初期化するとGUIフォームGUIViewを実装するクラスに自身を登録しています。フォームにGUIViewを実装したクラスが見えることを確認します。
あなたのGUIフォームで何かが、それはそれがない最後のものとしてUpdateXArrayList呼んでいるのArrayListを更新します。 GUIViewを実装するクラスでUpdateXArrayListメソッドは、順番に更新のArrayListを渡すDrawXArrayListを呼び出します。 GUIFormInterfaceを実装するフォームクラスでDrawXArrayListは、ArrayListの表示制御を更新するために必要な手順を取ります。
これはオブザーバーとリスナーのセットアップに比べて、ステップの多くのように思えますが。あなたは、さまざまなユーザーのアクションは、その後、観察者のリスナーパターンをUIにどのように影響するかをより詳細に制御を持っています。また、あなたは、コード内で、ユーザーのアクションとUIの更新の間の相互作用を文書化します。
あなたがチェックアウトし、アプリケーションに新しいjarファイルを追加することができた場合はガラス張りリストの