簡體   English   中英

java中的監聽器如何工作?

[英]How does the listeners in java work?

當我們向JavaFx中的Parent對象添加一個監聽器(例如TextField )時,我們真正在做什么呢? 我們是否正在創建一個觀察特定TextField的線程,當某些內容發生變化時,線程的動作會發生?

我感到很困惑,因為每個線程程序都是按順序工作的,所以每當它們發生變化時都可以看到一些變量 - 我認為某些變量必須同時執行(?)。

您的假設不正確:在向屬性添加偵聽器時不涉及線程。

JavaFX屬性基本上是Observer模式的實現。 使用的實現非常復雜,因為這些屬性支持“延遲評估”,這意味着可以通知其他對象當前值不再有效,但不會重新計算該值,除非它被請求。

然而,基本思想非常簡單:屬性只保留一個監聽器列表,並在調用set方法時通知它們。 下面的代碼不是如何在庫中實現StringProperty ,但它會讓你知道發生了什么:

public class ExampleStringProperty {

    private final List<ChangeListener<? super String>> changeListeners
        = new ArrayList<>();

    private String value ;

    public String get() {
        return value ;
    }

    public void set(String value) {
        if (! Objects.equals(value, this.value)) {
            String oldValue = this.value ;
            this.value = value ;
            for (ChangeListener<? super String> listener : changeListeners) {
                listener.changed(this, oldValue, value);
            }
        }
    }

    public void addListener(ChangeListener<? super String> listener) {
        changeListeners.add(listener);
    }

    public void removeListener(ChangeListener<? super String> listener) {
        changeListeners.remove(listener);
    }
}

如您所見,不涉及線程:如果設置了屬性,則在同一線程上調用偵聽器的changed(...)方法。

這是一個快速測試,使用庫中的實際SimpleStringProperty

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class StringPropertyTest {

    public static void main(String[] args) {
        StringProperty prop = new SimpleStringProperty();
        prop.addListener((obs, oldValue, newValue) -> {
            System.out.printf("Property changed from %s to %s on thread %s%n", 
                    oldValue, newValue, Thread.currentThread());
        });

        System.out.println("Running on thread "+Thread.currentThread());
        System.out.println("Setting property to \"value\"");
        prop.set("value");

        System.out.println("Setting property to \"new value\" on thread "+Thread.currentThread());
        prop.set("new value");
    }
}

產生輸出

Running on thread Thread[main,5,main]
Setting property to "value"
Property changed from null to value on thread Thread[main,5,main]
Setting property to "new value" on thread Thread[main,5,main]
Property changed from value to new value on thread Thread[main,5,main]

暫無
暫無

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

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