2011-09-12 13 views
3

2つのバインドされたプロパティ間で双方向のシンクロージャを実装する方法は?ユーティリティクラスPropertyChangeSupportは、無限ループを回避する簡単なメカニズムを提供します。場合によっては、それが不十分であることがわかります。よりよい選択肢がありますか?双方向ビーン同期

のString有界性を有する可能な限り単純なクラスを取る:

private String myProperty; 
//obviuos getter and setter omitted. (ok, setter contains propertyChangeSupport.firePropertyChange. should be obvious the same) 


public void addPropertyChangeListener(PropertyChangeListener listener) { 
    //delegate to propertyChangeSupport 
} 

public void removePropertyChangeListener(PropertyChangeListener listener) { 
    //delegate to propertyChangeSupport 
} 

OK。 今、このクラスの2つのインスタンスが所有するこのプロパティ値の間で双方向のシンクロナイズを実行するために通知を使用しようとしています。

これは(非常に簡単)符号である:それは元のクラスに折り返したときOLDVALUEがより等しいのでによってPropertyChangeSupportは、通知を抑制するため、ここには無限ループが存在しない

public static void main(String [] args) { 

    final T01 o1 = new T01(); 

    final T01 o2 = new T01(); 

    o1.addPropertyChangeListener(new PropertyChangeListener() { 
     public void propertyChange(PropertyChangeEvent evt) { 
      o2.setMyProperty(o1.getMyProperty()); 
     } 
    }); 

     o2.addPropertyChangeListener(new PropertyChangeListener() { 
     public void propertyChange(PropertyChangeEvent evt) { 
      o1.setMyProperty(o2.getMyProperty()); 
     } 
    }); 

    o1.setMyProperty("test"); 

} 

newValue
IMHOこれは「些細な」実装ですが、より良い原則は「それを引き起こしたクラスにイベントを通知すべきではない」ということです。

「等しい値」に基づいて、この実装に問題がある:
1変化の元のクラスに不要な冗長イベントを発生させ(THEN発信クラスは抑制すること)
2.イベントを抑制する古い値がnewvalueに等しいときにも、それは新しいものであり、「戻っている」ものではない。ほとんどの場合、抑止は正しいが、一部の(まれな)ケースでは、イベントが有用かもしれない。それ自体が「有益」である。イベントが受信されるたびにクリアする必要のあるタイムアウトを考えてください。
3.「奇妙な」実装があります。あなたがする場合:

o1.setMyProperty(null); <br/> 

あなたは無限ループと結果的なstackoverflowを取得します。
値が等しく、NULLでない場合、イベントは抑制されるためです。しかし、「ヌル」は多くの場合正当な価値です。

+0

問題はBeanプロパティモデルではなく、それらで何をしようとしているのですか。すべての 'T01'インスタンスが同じ' myProperty'を共有する場合、makeは静的メンバーです。その特定のソリューションを使用できない場合でも、両方向のプロパティ変更を取り除くためにコードを再設計する必要があります。 – toto2

+0

皆さん、時には「現在の」実装が十分でない理由を説明する必要がある場合があります。あなたが慎重に私の質問を読むなら、それは意見ではなく事実のリストであることがわかります。さらに、「改善」に関する質問は、必然的に基本的な要求よりも冗長である。 – AgostinoX

+0

@Toto:staticはすべてのインスタンスの値を意味します。私はちょうど2つの例について話しているが、必ずしも同じクラスの型ではない。データモデルとそのビューについては、同様のことが起こります。ここでは、シンプルなサンプルを提供するために同じクラスのプロパティを使用しましたが、コントロールを表すプロパティを持つデータクラス(pojoスタイル)とguiクラス(JFrame拡張など)の場合、コアはまったく同じになります。場合によっては(JCheckBox)、MVCパターンは使用できないか、実装するには複雑すぎます。 – AgostinoX

答えて

1

あなたはjGoodies Binding LibraryPropertyConnectorを試すことができます。

final T01 o1 = new T01(); 
final T01 o2 = new T01(); 
PropertyConnector.connect(o1, "myProperty", o2, "myProperty").updateProperty2(); 

今すぐo1のバウンドプロパティmyPropertyo2とその逆と同期されます。

+0

私はJGoodiesが好きではありません。私は標準にもっと敬意を払うために払うつもりです。しかし、この具体的なケースでは、スイングの高度なコンポーネントのためにJGodyを購入するのではなく、Beanモデルを修正する(またはそれに関する知識が不足している)問題を解決するためです。 – AgostinoX

+0

二次的な、私は "固定モデル"が好きではありません。 javaとswingに関するすべての公式ドキュメントは、非常に高度なものとしてそれを示しています。期待は「勉強するのが大事ですが、いくつかの「援助」ツールを購入する必要はありません。最終的な解決策がこれなら、MyEclipseのような他の「オールインワン」ソリューションを評価する前に、(修正することによって)合法的に開発することを約束します。 – AgostinoX

+0

Bindingsライブラリ(スタンドアローン)はBSDライセンスであり、無償でダウンロードして使用することができます(これは私の仕事で行います)。一方、Swing Suite(バインディングlib +たくさんの他のものを含む)は、あなたが支払う必要があります。 – Uhlen