JavaFX检查是否正在侦听Node属性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaFX检查是否正在侦听Node属性相关的知识,希望对你有一定的参考价值。
我有一个方法可以在某个Node属性上添加一个侦听器,在执行过程中,该方法可能会被调用多次,这将为该Node属性添加另一个(但相同的)侦听器,因此我尝试删除添加另一个监听器之前,请先避免监听器重复,例如:
myProperty.removeListener(this::method);
myProperty.addListener(this::method);
这看起来是正确的,但是这里的问题是,在删除之前,我必须检查该属性当前没有侦听器,类似这样的东西:
if(myProperty.hasListener(this::method)) //
但是这似乎不存在,然后如何检查是否正在侦听Node属性?
谢谢。
[[编辑:已解决]
removeListener(ChangeListener)
方法不会导致错误,即使侦听器不存在。
答案
只是为了好玩(不推荐):
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.stage.Stage;
import java.lang.reflect.Field;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
ChangeListener changeListener = new ChangeListener() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
}
};
SimpleBooleanProperty simpleBooleanProperty = new SimpleBooleanProperty();
System.out.println(hasListener(simpleBooleanProperty,changeListener));
simpleBooleanProperty.addListener(changeListener);
System.out.println(hasListener(simpleBooleanProperty,changeListener));
simpleBooleanProperty.removeListener(changeListener);
System.out.println(hasListener(simpleBooleanProperty,changeListener));
}
public static boolean hasListener(ObservableValue observableValue, ChangeListener listener){
Object value;
ChangeListener[] list=null;
ChangeListener changeListener=null;
Field field = null;
try {
if(observableValue instanceof SimpleFloatProperty){
field = FloatPropertyBase.class.getDeclaredField("helper");
}
else if(observableValue instanceof SimpleBooleanProperty){
field = BooleanPropertyBase.class.getDeclaredField("helper");
}
else if(observableValue instanceof SimpleIntegerProperty){
field = IntegerPropertyBase.class.getDeclaredField("helper");
}
field.setAccessible(true);
value = field.get(observableValue);
try {
if(value==null){
return false;
}
field = value.getClass().getDeclaredField("listener");
field.setAccessible(true);
changeListener =(ChangeListener)field.get(value);
}catch (NoSuchFieldException e) {
//e.printStackTrace();
}
try {
field = value.getClass().getDeclaredField("changeListeners");
field.setAccessible(true);
list =(ChangeListener[])field.get(value);
}catch (NoSuchFieldException e) {
//e.printStackTrace();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if(list!=null){
for (ChangeListener c:list) {
if(c==listener){
return true;
}
}
return false;
}
else {
return changeListener==listener;
}
}
public static void main(String[] args) {
launch(args);
}
}
输出:
false
true
false
更合理的方法:使用地图或标志。
顺便说一句:
如果根本没有侦听器,您也可以删除,因此您无需在删除之前进行检查
以上是关于JavaFX检查是否正在侦听Node属性的主要内容,如果未能解决你的问题,请参考以下文章
JavaFX UI 在事件侦听器中的 JavaFX 应用程序线程中冻结,但可与 Platform.runLater 一起使用