2010-04-30 57 views

回答

15

聽起來就像你想在一個類中包裝一個布爾值,你可以監聽它的變化。

class ObservableBoolean { 

    // "CopyOnWrite" to avoid concurrent modification exceptions in loop below. 
    private final List<ChangeListener> listeners = 
      new CopyOnWriteArrayList<ChangeListener>(); 

    private boolean value; 

    public boolean getValue() { 
     return value; 
    } 

    public synchronized void setValue(boolean b) { 
     value = b; 
     for (ChangeListener cl : listeners) 
      cl.stateChanged(new ChangeEvent(this)); 
    } 

    public synchronized void addChangeListener(ChangeListener cl) { 
     listeners.add(cl); 
    } 

    public synchronized void removeChangeListener(ChangeListener cl) { 
     listeners.remove(cl); 
    } 
} 

後來乾脆:

ObservableBoolean b = new ObservableBoolean(); 

//... 

// Start the "period of time": 
b.addChangeListener(iWantToBeNotifiedOfChanges); 

// ... 

// End the "period of time": 
b.removeChangeListener(iWantToBeNotifiedOfChanges); 

這實際上是MVC模式(和觀察者模式)的簡單情況。這種情況下的模型是ObservableBoolean,並且視圖將是想要被通知更改的「視圖」。

你也可以,如果你想避免一個奇怪的看着javax.swing...進口

+0

+1對於觀察者模式。我想知道是否要監視布爾本身,或者如果您應該讓更改狀態的類擁有偵聽器列表,並在布爾上執行mod時觸發更改事件。 – akf 2010-04-30 10:50:33

+0

@aioobe - >現在看我的編輯 – Xorty 2010-04-30 11:01:09

+1

+1 ...但有幾點:偵聽器列表應該可能是最終的,getValue()不會同步,如果偵聽器在通知時嘗試將自己作爲偵聽器移除,將導致到ConcurrentModificationException。您可以通過使用CopyOnWriteArrayList而不是ArrayList來解決這個最終問題。 – Adamski 2010-04-30 11:02:49

1

使用Timer或寫自己的類擴展Thread寫自己的ChangeListener接口。

Google上搜尋這些東西應該給你良好的開端

編輯:從問題也不太清楚什麼是他的打算。也許他想要在確切的時間段內引用某種方法,而不是在事件後立即引用。對於這種模式,我寧願堅持計時器,或寫我自己的線程。編寫自己的線程仍然是解釋特定用戶需求的最佳方式。另一方面,如果這真的是偵聽事件的情況,我的Timer模式將完全錯誤。

示例:如果用戶請求(請求= true),我想每5分鐘更新一次數據庫(想象Web瀏覽器遊戲)。有了錯誤的請求,我不需要更新數據庫。立即更新數據庫(遊戲部落戰爭中的玩家數量統計)完全是矯枉過正。

+1

從true - > false - > true的快速變化會被忽視,除非你在某些「check-if-changed-since-last-pall」類中封裝了布爾值。 – aioobe 2010-04-30 10:41:47

+0

是真實的,但問題不是立即檢查,而是在一定的時間(時間段)內檢查。 這取決於模型設計。 擴展線程類基本上是監聽器的實現(不是字面上,但幾乎相同) – Xorty 2010-04-30 10:50:22

+0

「如果在該時間段內發生更改,則執行一個方法」。我在說,如果在這段時間內進行了兩次*更改,那麼您*需要一個額外的布爾型'stateHasChanged'來跟蹤這個(否則這種改變很可能未被注意到)。 – aioobe 2010-04-30 11:13:50

-2

看起來像你應該看看實施某種Model View Controller Pattern。 看看here

基本的想法是,當布爾值被改變時,你應該觸發一個事件,然後該事件被觸發,你的監聽器應該處理該事件。

+0

艾姆,爲什麼投票呢? – 2010-04-30 16:47:29

6

做,這是一個包裝類最簡單的方法...

public class Bool 
{ 
    public Bool(){ _val = false; } 
    public Bool(boolean val) { _val = val; } 

    public boolean getValue(){ return _val; } 
    public void setValue(boolean val){ 
     _changesupport.firePropertyChange("value",_val,_val=val); 
    } 

    public void addPropertyChangeListener(PropertyChangeListener listener){ 
     _changesupport.addPropertyChangeListener(listener); 
    } 

    public void removePropertyChangeListener(PropertyChangeListener listener){ 
     _changesupport.removePropertyChangeListener(listener); 
    } 

    private boolean _val = false; 
    private final PropertyChangeSupport _changesupport = new PropertyChangeSupport(this); 
} 

這是擺一個共同的模式,並且可以使用PropertyChangeSupport簡化上,你可以觀察對象的創建和傾聽財產變化。通過這樣的課程,您可以註冊PropertyChangeListener來處理由此產生的結果PropertyChangeEvent

+0

與'PropertyChangeSupport'很好。它爲什麼不位於更「通用」的包中?用於PropertyChangeSupport的 – aioobe 2010-04-30 10:58:37

+0

+1。雖然我只是把它作爲final和public並跳過Bool類的add和remove方法。 – 2010-04-30 12:48:29