2009-04-13 17 views
15

GUIにドロップダウンボックスがあり、別のクラスのArrayListの内容が表示されます。 新しいオブジェクトをGUIの別の場所でArrayListに追加することができます。そのため、更新された時点を知る必要があるため、ドロップダウンメニューを更新できます。私が集めることから、私の2つの選択肢は、ArrayListクラスを拡張して自分自身のchangeListenerを追加したり、問題のArrayListを含むクラスを観察可能に拡張できるようにすることです。リスナーまたはオブザーバーを使用する必要がありますか?

どちらが適切な解決策ですか?

+1

を参照しているチェックアウトし、アプリケーションに新しいjarファイルを追加することができますか?もしそうなら、私はComboBoxModelとその実装を調べます。 – Avrom

答えて

10

2つの解決策は、(基本的に「オブザーバー」のパターンと同じルートデザインパターンの実装であります前者の場合は、ArrayList自体を「観測可能」にします。後者では、配列リストを「観測可能」にするドメインオブジェクトを作成しています。

私の傾向は、後者を行うことです。ドメインオブジェクトを観測可能にします。これは主に、ドメインオブジェクト(GUIを更新する必要がある)について変更する可能性がある他のものが最終的に存在する可能性があるためです。すでに観察可能な場合は、すでに設定済みです。

java.util.Observableを厳密に拡張する必要はありません。これを行わずにデザインパターンを実装できます。

+0

これは最も簡単な方法のようですが、他のすべての回答に感謝します。 – Simonw

9

Observable Javaの実装はめったに使用されず、Swingとうまく動作しません。代わりにEventListenerを使用してください。

特に、AbstractListModelを拡張しないでください。または、リストの内容を「GUIの他の場所」で管理するときにDefaultListModelを直接使用しないでください。その場合、コンボボックスは同じListModelインスタンスに委譲し、独自の実装を追加して選択状態を追跡するComboBoxModelを使用できます。

は、私はこのような心の何かを持っている(しかし、私はそれをテストしていない):によって定義されているよう

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); } 

} 
1

私の参照は、効果的なJavaと私の個人的な経験です。 ArrayListを拡張することは、クラスの不変条件のいずれにも違反しないという約束です。また、拡張している特定のリスト実装にもバインドされます。

0

GUI design patternに切り替えることができます。あるいは、限られた実装を構築する。

Xは、いくつかの意味のある名前であることと、メソッドDrawXArrayListを(持っているGUIフォームインターフェイスを作成これは、型のArrayList

のパラメータがGUIViewと呼ばれる新しいクラスを作成していることは、少なくとも二つの方法があります。。UpdateXArrayListをし、 RegisterForm

アプリケーションを初期化するGUIフォームGUIViewを実装するクラスに自身を登録しています。フォームにGUIViewを実装したクラスが見えることを確認します。

あなたのGUIフォームのArrayListを更新して何がそれがようUpdateXArrayList呼び出すたら最後のことです。 GUIViewを実装するクラスのUpdateXArrayListメソッドは、更新されたarraylistを渡すDrawXArrayListを呼び出します。 GUIFormInterfaceを実装するフォームクラスのDrawXArrayListは、ArrayListを表示するコントロールを更新する必要があります。

これは、観察者とリスナーの設定に比べて多くのステップのようですが。さまざまなユーザーアクションがUIにどのように影響し、次にオブザーバーリスナーパターンに影響するかをより詳細に制御できます。さらに、ユーザーアクションとUIの更新とのやりとりをコードで文書化しました。

2

なぜバインディングを使用しないのですか?あなたのリストにあなたのGUIウィジェットバインド

http://wiki.eclipse.org/index.php/JFace_Data_Binding

。変更は2つのオブジェクト間を透過的に伝播します。 ArrayListを直接使用する場合は、WritableListなどの適切なオブザーバブルでモデルをラップするようにしてください。

関連する問題