简体   繁体   中英

JavaFX check if a Node property is being listened

I have a method that adds a listener to a certain Node property, during the execution, this method might be called more than one time, and this will add another (but same) listener to that Node property, so I tried to remove the listener before adding another one to avoid duplicates like that :

myProperty.removeListener(this::method);
myProperty.addListener(this::method);

This looks correct, but the problem here is that, before removing, I must check that the property currently don't have a listener, something like that :

if(myProperty.hasListener(this::method)) //

But this doesn't seem to exist, then how to check if a Node property is being listened or no?

Thank you.

[EDIT : SOLVED]

the removeListener(ChangeListener) method will not cause an error even if the listener doesn't exist.

Just for fun(not recommended):

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

output:

false
true
false

More rational method: use a map or flag.

by the way:

you can remove also if there is no listener at all so you don't have to check before you remove在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM