2009-10-22 64 views
0

我會盡可能地解釋我的問題:)。我正在使用PropertyChangeSupport來通知已註冊的視圖中的屬性更改。其中一個屬性是屬性每隔幾秒鐘更改一次的對象。我不想在每次更新時爲這個特定的對象創建新的實例(propertychangelistener注意到這個改變),所以我寫了我自己的equals方法,在這裏我省略了自己的比較。PropertyChangeSupport並等於方法

@Override 
public boolean equals(Object item) { 
    // do not compare 
    // if (this == item) { return true; } 

    if (!(item instanceof TransferQueueItem) || 
     item == null) { 

     return false; 
    } 

    TransferQueueItem newItem = (TransferQueueItem) item; 
    boolean value = 
      // ommited... properties comparation 
    return value; 
} 

不幸的是,這並沒有我正在尋找的效果。如果我創建了該對象的副本並激活其上的屬性更改方法,那麼它工作正常。

我在這裏錯過了什麼?

- 編輯

我意識到,因爲我使用的是相同的實例,而不是它的一個副本,該屬性pointig相同的地方,因此比較 - 總是會出來真。是否有解決方法(除了創建副本)。或者每秒創建一個對象的副本有多糟糕,例如。

+0

這不應該因爲任何改變同一個實例關係應該將事件發送給該實例的所有聽衆。你在這裏省略了一些重要的信息。 – 2009-10-22 08:53:06

回答

1

您必須始終返回true告訴PropertyChangeSupport您的對象確實不是更改。但這意味着equals()對於這個類的所有對象都是破壞的(例如,你不能在集合或地圖中使用它們)。

一個更好的方法是爲這種對象進行特殊處理的特殊方法firePropertyChange()。這樣,您甚至可以避免創建PropertyChangeEvent的實例。下面是用於處理BigDecimal(其中equals()不會在所有的工作)的例子:

protected transient PropertyChangeSupport changeSupport = null; 

public void addPropertyChangeListener (String propertyName, PropertyChangeListener listener) 
{ 
    if (changeSupport == null) 
     changeSupport = new PropertyChangeSupport (this); 

    changeSupport.addPropertyChangeListener (propertyName, listener); 
} 

public void firePropertyChange (String propertyName, BigDecimal oldValue, BigDecimal newValue) 
{ 
    if (changeSupport == null) 
     return; 

    if (oldValue != null && newValue != null && oldValue.compareTo (newValue) == 0) { 
     return; 
    } 
    changeSupport.firePropertyChange(new PropertyChangeEvent(this, propertyName, 
               oldValue, newValue)); 
} 

[編輯]你做的完全是另一回事:你有父母和一個孩子,你想要的的聽衆父母孩子發生變化時接收事件。

此處的正確方法是將PropertyChangeSupport添加到。當孩子被添加到父母時,父母必須在孩子中安裝必要的監聽者。當一個事件被觸發時,它必須觸發第二個事件,該事件通知父母的變化的聽衆(父母必須轉發事件)。

+0

其實我想要的是相反的。而且總是返回硬編碼的值並不完全等同於應該這樣做。 – stefita 2009-10-22 08:41:06

+0

在這種情況下,你的問題不清楚。您是否希望避免針對TransferQueueItem的任何更改觸發事件? TransferQueueItem更改時是否總是需要一個事件?當TransferQueueItem的屬性發生變化時,您是否總是需要一個事件? – 2009-10-22 08:42:59

+0

請注意,設置新的TransferQueueItem或更改TransferQueueItem的屬性是不同的。 – 2009-10-22 08:43:40

1

這是鏈接的PropertyChangeListeners的情況:

TransferQueueItem應該推出自己對PropertyChangeEvents必須由在其中插入

而且在響應TransferQueue必須通知他們的聽衆,一個擁有項目有TransferQueue被監聽改變。

每次我有這樣的問題,其中一個對象必須重新啓動我使用這種約定(我的工作團隊)事件:

1一個對象只能發射事件,源本身。

2如果它想要委託事件,它將啓動一個像這樣的事件:new PropertyChangeEvent(this,「DELEGATED_EVENT」,null,receivedEvent)。這樣聽衆可以跟蹤事件鏈。

Addicionally我必須在後面的事件鏈中的Util類的靜態方法和返回的第一個事件,一個whick屬性不是「DELEGATED_EVENT」

+0

感謝您的指點!以這種方式實施它確實有意義。 – stefita 2009-10-22 11:55:36