java - java中的监听器是如何工作的?

标签 java javafx

当我们将监听器添加到 JavaFx 中的 Parent 对象(例如 TextField)时,我们到底在做什么?我们是否正在创建一个线程来观察特定的 TextField 并且当某些内容发生变化时,线程会采取行动?

我感到困惑,因为每个单线程程序都按顺序工作,所以如何在变量发生变化时观察它们 - 我假设某些事情必须同时执行(?)。

最佳答案

您的假设不正确:向属性添加监听器不涉及线程。

JavaFX 属性基本上是 Observer pattern 的一个实现.使用的实现非常复杂,因为这些属性支持“延迟评估”,这意味着可以通知其他对象当前值不再有效,但除非请求,否则无需重新计算该值。

然而,基本思想非常简单:该属性只保留一个监听器列表,并在 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]

关于java - java中的监听器是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48845232/

相关文章:

java - 如何从枚举构造函数中抛出异常?

java - 在处理事物时创建模态 JDialog

java - 有效 JDK 的 IntelliJ Linux javafx 错误

java - 内存中的第二张卡无法正面朝上

JavaFX - TableCell 中带有添加数据按钮的单选按钮

JAVAFX:setMaxWidth() 和 maxWidthProperty().set() 之间的区别

java - 如何为 JavaFX TextField 文本启用抗锯齿?

java - 如何为方法实例生成唯一的哈希码?

Java Swing JFrame 中的许多 JPanel - getter 还是全合一?

JavaFX,鼠标输入时