如何在JavaFX中的ChangeListener中引用Property ChangeListener?

时间:2017-08-24 17:18:31

标签: java javafx

我想添加到属性侦听器,等待调用此侦听器并删除此侦听器。所以我写了下面的代码:

    ChangeListener<String> listener = (observable, oldValue, newValue) -> {
        textField.setStyle("-fx-border-color:black");
        textField.textProperty().removeListener(listener); //LINE X
    };
    textField.textProperty().addListener(listener);

然而,在LINE X,我得到Variable listener might not have been initialized。如何在ChangeListener中引用属性ChangeListener以将其删除?

1 个答案:

答案 0 :(得分:3)

来自JLS,section 15.27.2

  

与匿名类声明中出现的代码不同,名称的含义以及出现在lambda主体中的this和super关键字以及引用声明的可访问性与周围上下文中的相同(除了lambda参数引入新的名)。

     

...

     

实际上,lambda表达式需要谈论自己(要么递归地调用自身还是调用其他方法)是不寻常的,而更常见的是想要使用名称来引用封闭中的内容。否则将被遮蔽的类(this,toString())。 如果lambda表达式需要引用自身(就好像通过它),则应该使用方法引用或匿名内部类。

(我的重点。)

因此,简而言之,lambda表达式无法引用自身。您需要将其重构为匿名内部类:

ChangeListener<String> listener = new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
        textField.setStyle("-fx-border-color:black");
        textField.textProperty().removeListener(this); 
    }
};
textField.textProperty().addListener(listener);

当然,此时您可能不再需要参考:

textField.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
        textField.setStyle("-fx-border-color:black");
        textField.textProperty().removeListener(this); 
    }
});