获取 ObservableValue 的所有注册监听器

ayv*_*ngo 5 javafx

如何让所有听众获得一个可观察的值?我可以扩展类并覆盖addListenerremoveListener方法将它们存储在一个集合中。但是该集合应该已经以某种方式存储在可观察值中。我怎么能拿到那套?

Sar*_*cht 1

我找到了解决它的方法,你无法直接访问监听器列表,但如果你使用调试器(我使用 IntelliJ),如果你像这样查看 ObservableProprty 内部,你可以看到它:(我希望这足够清楚) 在此输入图像描述

另一种方式:(你是个聪明人,你会知道如何适应你的情况)

    //SimpleFloatProperty we want to find its Listeners
    FloatPropertyBase f=ampPS.currentProperty();
    Object value;
    ChangeListener[] list;
    ChangeListener changeListener=null;
    Field field = null;
    try {
        field = FloatPropertyBase.class.getDeclaredField("helper");
        field.setAccessible(true);
        value = field.get(f);
        try {
            field = value.getClass().getDeclaredField("listener");
            field.setAccessible(true);
            changeListener =(WeakChangeListener)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();
    }
Run Code Online (Sandbox Code Playgroud)

结果: 在此输入图像描述

(注意 1 个听众或多于 1 个听众之间的区别)

我正在为几种类型的值添加示例

public static ChangeListener[] getChangeListeners(ObservableValue observableValue){

    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 {
            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){
        return list;
    }
    else {
        ChangeListener[] changeListeners = new  ChangeListener[1];
        changeListeners[0]=changeListener;
        return changeListeners;
    }
}
Run Code Online (Sandbox Code Playgroud)

我称之为:

    SimpleBooleanProperty booleanProperty = new SimpleBooleanProperty(true);
    SimpleFloatProperty simpleFloatProperty = new SimpleFloatProperty(0);
    SimpleIntegerProperty simpleIntegerProperty = new SimpleIntegerProperty(1);
    booleanProperty.addListener(changeListener);
    simpleFloatProperty.addListener(changeListener);
    simpleIntegerProperty.addListener(changeListener);
    simpleIntegerProperty.addListener(changeListener);
    System.out.println(getChangeListeners(booleanProperty).length);
    System.out.println(getChangeListeners(simpleFloatProperty).length);
    System.out.println(getChangeListeners(simpleIntegerProperty).length);
Run Code Online (Sandbox Code Playgroud)

结果:在此输入图像描述

所以我确实收到了警告,但工作已经完成了!