2017-08-24 80 views
1

我想添加到属性侦听器,等待这个侦听器将被调用并删除这个侦听器。所以我写了下面的代码:如何在JavaFX中的ChangeListener中获取对Property ChangeListener的引用?

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的引用以将其删除?

+0

据我所知,如果你使用一个类(你只能这样做例如匿名内部类),而不是lambda表达式。 –

回答

2

从JLS,section 15.27.2

与出现在匿名类声明的代码,名称的含义,并引用声明的可访问性出现在拉姆达体,沿着这和超级关键字,是与周围环境相同(除了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); 
    } 
}); 
相关问题