2010-04-30 9 views

cevap

15

Değişiklikler için dinleyebileceğiniz bir sınıfa bir sınıf sarmak istediğiniz gibi görünüyor. Sonra

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

basitçe yapın:

ObservableBoolean b = new ObservableBoolean(); 

//... 

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

// ... 

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

Bu aslında MVC deseni (ve gözlemci desen) basit bir durumdur. Bu durumda model GözlemlenebilirBölge'dir ve görüş, değişikliklerden haberdar edilmek istenen "görüş" olacaktır. Bir garip görünümlü javax.swing... ithalatını

+0

+1. Boolean'ın kendisini izlemek isteyip istemediğinizi merak edersiniz veya bunun yerine, değişen statüsünde olan listeyi dinleyici listesine sahip olup olmamanız ve boolean'daki modunu gerçekleştirdiğinde değişiklik olaylarını tetiklemeniz gerekir. – akf

+0

@aioobe -> şimdi düzenle düzenleme – Xorty

+1

+1 ... ama birkaç nokta: dinleyiciler listesi muhtemelen final olmalı, getValue() senkronize edilmez, Bir dinleyici bildirildiğinde bir dinleyici olarak kendisini kaldırmaya çalışırsa ConcurrentModificationException için. Bu son sorunu ArrayList yerine bir CopyOnWriteArrayList kullanarak çözebilirsiniz. – Adamski

1

kullanımını Timer önlemek veya kendi sınıf Thread uzanan yazmak istersen

Ayrıca kendi ChangeListener arayüzünü yazabiliriz.

böyle şeyler Googling iyi bir başlangıç ​​size

düzenlemeyi vermelidir: o onun niyetinde ne oldukça açık değildir sorudan. Belki de, olaydan hemen sonra değil, tam bir süre içinde bir yöntem çağırmak istiyordur. Bu model için, zamanlayıcıya sadık kalmayı ya da kendi İpucumu yazmayı tercih ediyorum. Kendi Thread'ını yazmak, belirli kullanıcı gereksinimlerini yorumlamanın en iyi yoludur. Diğer taraftan, eğer bu olayları gerçekten dinlemek durumundaysa, Timer desenim tamamen yanlış olur.

Örnek: Kullanıcılar isterse (istekleri = doğru) isterse veritabanını (web tarayıcı oyununu hayal et) her 5 dakikada bir güncellemek istiyorum. Yanlış istek ile veritabanını güncellemem gerekmiyor. Immediatelly güncelleme veritabanı (örneğin, oyuncuların toushands ile oyun Tribal Wars istatistikleri) tamamen overkill.

+1

true -> false -> true değerinden hızlı bir şekilde değiştirilen bir değişiklik, boole'yu bazı "check-if-change-last-pall" -class olarak değiştirmedikçe fark edilmeden gider. – aioobe

+0

doğru, ama soru hemen değil, belirli bir süre (zaman periyodu) kontrol etmek değildi. Model tasarımına bağlıdır. Genişletme İş parçacığı temel olarak Dinleyicilerin (tam anlamıyla değil, hemen hemen aynı) gerçekleştirilmesidir – Xorty

+0

"Eğer bu süre boyunca bir değişiklik yapıldıysa, bir yöntem gerçekleştirilir". Diyorum ki, o zaman * iki * değişiklik yapılıyorsa, * bunu * takip eden ekstra bir boolean 'stateHasChanged'e ihtiyacınız var (aksi takdirde bu değişikliğin fark edilmemesi oldukça olasıdır). – aioobe

-2

Bir çeşit Model View Controller Pattern uygulamasına bakmanız gerektiği gibi görünüyor. Bir göz atın here

Temel fikir, boolean değiştiğinde bir olayı tetiklemeniz ve o olayın tetiklendiğinden, dinleyicinizin bunu işlemesi gerekir.

+0

Ehm, neden aşağı oy? –

6

bu bir sarıcı sınıfı ile yapmanın en kolay yolu ...

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

Bu Swing bir modeldir ve siz gözlemleyebilirsiniz hangi nesnelerin oluşturulmasını basitleştirmek için PropertyChangeSupport kullanabilir ve Mülk değişikliklerini dinle. Bu tür sınıflar ile, sonuçta ortaya çıkan PropertyChangeEvent s'yi işlemek için PropertyChangeListener kayıt olabilirsiniz. Gözlemci deseni için

+0

"PropertyChangeSupport" ile hoş. Neden daha "jenerik" bir pakette yer almıyor? PropertyChangeSupport için – aioobe

+0

+1. Her ne kadar final ve herkese açık yapmalıyım ve Bool sınıfındaki metodları ekleyip kaldıralım. –