2011-09-12 59 views
3

如何實現兩個綁定屬性之間的雙向同步?實用類PropertyChangeSupport提供了一個避免無限循環的簡單機制。在某些情況下,我覺得它是不夠的。有更好的選擇嗎?雙向豆同步

採取了最簡單的類與字符串界屬性:

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 
} 

確定。 現在我嘗試使用通知來執行該屬性值之間的雙向sincronization,該屬性值由該類的兩個實例擁有。

這是(很簡單)的代碼:

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

} 

這裏沒有無限循環,因爲的PropertyChangeSupport抑制通知其轉彎時回原始的類,因爲屬性oldValue大於等於newValue。
恕我直言,這是一個「微不足道的」實現,而更好的原則可能是「不應該將事件通知給造成它的類」。

使用基於「相等的值」這種實現的問題是:
1.加註到始發類的變化的不必要的,冗餘的事件(即THEN始發類抑制)
2.抑制事件當舊值等於新值時,如果它是新的值而不是「回頭」。在大多數情況下,抑制是正確的,但在一些(罕見)情況下,事件可能是有用的。本身是「信息性的」。想一想在每次收到事件時必須清除的超時。
3.它有一個「奇怪的」實現。如果你這樣做:

o1.setMyProperty(null); <br/> 

你得到了無限循環和隨之而來的stackoverflow。
因爲如果值等於且不爲空,則事件被抑制。但「空」在很多情況下是合法的價值。

+0

問題不在於bean屬性模型,而在於你想要對它們做什麼。如果所有'T01'實例共享相同的'myProperty',make是一個靜態成員。如果你不能使用那個特定的解決方案,你必須重新設計你的代碼來擺脫任何雙向屬性變化。 – toto2

+0

尊敬的託託,有時問一個問題,你必須解釋爲什麼「當前」的實施是不夠的。如果你仔細閱讀我的問題,你會看到這是一個事實清單,而不是意見。此外,有關「改進」的問題必定比基本特徵請求更爲冗長。 – AgostinoX

+0

@Toto:static表示所有實例的值。我只談論兩個實例,不一定是同一個類的類型。就像數據模型及其視圖一樣。在這裏,我使用同類屬性來提供一個更簡單的示例,但對於具有表示控件的屬性的數據類(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(); 

現在綁定屬性的o1myProperty將與o2,反之亦然同步。

+0

我不喜歡JGoodies,因爲它是付費套件。我願意付錢以獲得更多的尊重。但在這個具體的例子中,我並沒有購買swing高級組件的JGodies,而是爲了修復beans模型(或者解決我對它的不瞭解)。 – AgostinoX

+0

次要的,我不喜歡「修復模型」。所有關於java和swing的官方文檔都將其作爲非常先進的東西。期望是「有很多要研究」,但不必購買一些「援助」工具。如果最終的解決方案是這樣的話,我會在評估MyEclipse等其他「一體化」解決方案之前(通過paing)承諾所有您合理期望開發的內容,而不僅僅是修復。 – AgostinoX

+0

Bindings庫(單機版)是BSD許可的,可以免費下載並使用(我們在我的工作中使用)。 Swing Suite(包含綁定lib +很多其他)另一方面,你必須付費。 – Uhlen