Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all registered listeners to an ObservableValue

Tags:

javafx

How to get all listeners to an observable value? I could extend the class and override addListener and removeListener methods to store them in a set. But the set should already be stored somehow inside observable value. How could I get that set?

like image 851
ayvango Avatar asked Nov 08 '22 15:11

ayvango


1 Answers

I find a way around it, you can't get direct access to the Listeners list but if you use a debugger(I use IntelliJ) you can see it if you look inside your ObservableProprty like this:(I hope this is clear enough) enter image description here

another way:(You're a smart guy, you'll know how to fit into your case)

    //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();
    }

the result: enter image description here

(Notice the difference between 1 listener or more than 1)

I I'm adding Example for several types of values

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;
    }
}

and I call it:

    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);

the result: enter image description here

so I do get warnings, but the job is done!

like image 143
Sarel Foyerlicht Avatar answered Dec 10 '22 13:12

Sarel Foyerlicht