Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX property remove listener not working

I try to add, remove and add again a listener to a JavaFX BooleanProperty but it is not working.

Here is my code

public class PropListenerTest {

    BooleanProperty test = new SimpleBooleanProperty(false);

    public PropListenerTest() {
        System.out.println("\nTest 1\tadd the listener"); //NON-NLS
        test.addListener(this::onChangeTest);
        test.set(true);
        test.set(false);

        System.out.println("\nTest 2\tremove the listener, but not possible! Why?"); //NON-NLS
        test.removeListener(this::onChangeTest);
        test.set(true);
        test.set(false);

        System.out.println("\nTest 3\tAdd the listener again, but now i have two listener but I want only one!"); //NON-NLS
        test.addListener(this::onChangeTest);
        test.set(true);
        test.set(false);
    }

    private void onChangeTest(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        System.out.println("observable = [" + observable + "], oldValue = [" + oldValue + "], newValue = [" + newValue + "]"); //NON-NLS
    }

    public static void main(String[] args) {
        new PropListenerTest();
    }
}

The result is the following

Test 1  add the listener
observable = [BooleanProperty [value: true]], oldValue = [false], newValue = [true]
observable = [BooleanProperty [value: false]], oldValue = [true], newValue = [false]

Test 2  remove the listener, but not possible! Why?
observable = [BooleanProperty [value: true]], oldValue = [false], newValue = [true]
observable = [BooleanProperty [value: false]], oldValue = [true], newValue = [false]

Test 3  Add the listener again, but now i have two listener but want only one
observable = [BooleanProperty [value: true]], oldValue = [false], newValue = [true]
observable = [BooleanProperty [value: true]], oldValue = [false], newValue = [true]
observable = [BooleanProperty [value: false]], oldValue = [true], newValue = [false]
observable = [BooleanProperty [value: false]], oldValue = [true], newValue = [false]

I think in Test 2 there should be no result and in Test 3 it should display the same result as in Test 1. I don't know what I am doing wrong. Can someone help me?

Thanks

like image 293
Patric Hollenstein Avatar asked Jun 10 '16 03:06

Patric Hollenstein


1 Answers

The method reference will act as though it creates a distinct object each time.

Imagine doing

ChangeListener<Boolean> changeListener1 = new ChangeListener() {
    @Override
    public void changed(Observable<? extends Boolean> obs, Boolean oldValue, Boolean newValue) { }
};

ChangeListener<Boolean> changeListener2 = new ChangeListener() {
    @Override
    public void changed(Observable<? extends Boolean> obs, Boolean oldValue, Boolean newValue) { }
};

then changeListener1 == changeListener2 and changeListener1.equals(changeListener2) would be false.

Similarly,

ChangeListener<Boolean> changeListener1 = this::onChangeTest ;
ChangeListener<Boolean> changeListener2 = this::onChangeTest ;

would also result in changeListener1 == changeListener2 being false.

If you do

ChangeListener<Boolean> changeListener = this::onChangeTest ;

System.out.println("\nTest 1\tadd the listener"); //NON-NLS
test.addListener(changeListener);
test.set(true);
test.set(false);

System.out.println("\nTest 2\tremove the listener, but not possible! Why?"); //NON-NLS
test.removeListener(changeListener);
test.set(true);
test.set(false);

System.out.println("\nTest 3\tAdd the listener again, but now i have two listener but I want only one!"); //NON-NLS
test.addListener(changeListener);
test.set(true);
test.set(false);

it will behave as you expect.

like image 164
James_D Avatar answered Nov 02 '22 23:11

James_D