簡體   English   中英

Java 屬性更改監聽器

[英]Java PropertyChangeListener

我試圖弄清楚如何監聽另一個類中的屬性更改。 下面是我的代碼:

ClassWithProperty 有我想聽的屬性:

public class ClassWithProperty {
    private PropertyChangeSupport changes = new PropertyChangeSupport(this); 
    private int usersOnline;

    public int getUsersOnline() {
        return usersOnline;
    }

    public ClassWithProperty() {
        usersOnline = 0;
        while (usersOnline<10) {
            changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
        }
    }

    public void addPropertyChangeListener(
        PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }
    public void removePropertyChangeListener(
        PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }
}

主要是我需要了解財產變化的地方:

public class Main {

    private static ClassWithProperty test;

    public static void main(String[] args) {
        test = new ClassWithProperty();
        test.addPropertyChangeListener(listen());

    }

    private static PropertyChangeListener listen() {
        System.out.println(test.getUsersOnline());
        return null;
    }

}

我只在最后一次觸發了該事件(usersOnline=10)。 我是 Java 新手並試圖找到解決方案,但無濟於事。

代碼:

private static PropertyChangeListener listen() {
    System.out.println(test.getUsersOnline());
    return null;
}

返回null這意味着“沒有對象”,這反過來意味着test.addPropertyChangeListener(listen())實際上是test.addPropertyChangeListener(null) ,它不會注冊任何東西。

您必須將PropertyChangeListener的有效實例傳遞給addPropertyChangeListener()方法。

編輯

我建議你閱讀 Java 教程關於 PropertyChangeListeners 的章節:
http://download.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

您的代碼的另一個問題是您在ClassWithProperty的構造函數中調用了firePropertyChange() 但當時,不可能注冊任何偵聽器,因此它沒有任何效果。 addPropertyChangeListener()任何調用都發生您觸發事件之后。

這是您修改的代碼,以便它可以工作(雖然尚未對其進行測試...):

public class ClassWithProperty {
    private PropertyChangeSupport changes = new PropertyChangeSupport(this);
    private int usersOnline = 0;

    public ClassWithProperty() {
    }

    public void setupOnlineUsers() 
    {
        while (usersOnline < 10) {
            changes.firePropertyChange("usersOnline", usersOnline, ++usersOnline);
        }
    }

    public int getUsersOnline() {
        return usersOnline;
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }
}

public class MainListener implements PropertyChangeListener {
    private ClassWithProperty test;

    public MainListener() {
        test = new ClassWithProperty();
        test.addPropertyChangeListener(this);
        test.setupOnlineUsers();
    }

    public void propertyChange(PropertyChangeEvent evt) {
        System.out.println(test.getUsersOnline());
    }

    public static void main(String[] args) {
        new MainListener(); // do everything in the constructor
    }
}

我所做的是在 ClassWithProperty 類中放置一個方法:

public PropertyChangeSupport getPropertyChangeSupport() {
    return changes;
}

然后,在 Main() 類的構造函數中注冊屬性更改事件:

private void initializeListeners() {
    test.getPropertyChangeSupport().addPropertyChangeListener((PropertyChangeEvent event) -> {
        if (event.getPropertyName().equals("usersOnline"))   {
            String passedEventData = (String) event.getNewData(); 
        }
    });
}

這使得您不會使用 PropertyChangeSupport 類中已有的方法重復 ClassWithProperty 中的代碼。

當您需要在 ClassWithProperty 類中觸發事件時,請執行以下操作:

changes.firePropertyChange("usersOnline", oldValue, newValue);

這種方法的一個顯着特點是,如果
event.getOldValue() 和 event.getNewValue() 相等,事件不會觸發。 如果要觸發具有相同信息的重復事件,請在 oldValue 字段中使用 null; firePropertyChange() 方法只傳遞 int、boolean 和 Object。 因此,如果您沒有傳遞 int 或 boolean,則需要轉換在接收端的事件中傳遞的值。

你的方法在這里:

public ClassWithProperty() {
    usersOnline = 0;
    while (usersOnline<10) {
        changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
        usersOnline++;
    }
}

有一個 while 循環,它將不斷循環並阻塞線程。 我對屬性更改偵聽器的有限了解是它們偵聽綁定屬性的更改,這里是usersOnLine變量,這意味着屬性更改應該僅在此數字更改時觸發(可能在任何setUserOnLineaddUserOnLineremoveUserOnLine和類似方法中)。 有關綁定屬性的更多信息,請查看此處: 綁定屬性

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM