javajavafxchangelistener

Change listener doesn't detect changes - BooleanProperty JavaFX


I was trying to figure out how to detect changes in some object properties. So at the beginning I realized how to do it, and it works. I don't know if there is a better way to do it (If you guys know if there is a better way, tell me please).

Well The problem is that I have another problem to solve, and is that I don't want to detect changes, I just want to get the new set values of the properties. So I know that with the javafx.beans.value.ChangeListener interface you can detect every change on some property, and that's my problem because I created a class which implements the ChangeListener (With Object type, to detect multiple type properties changes. e.g. Boolean, Integer, etc.) and for some reason it doesn't detect all the changes. Let me show you the code sample:

 CustomInterface ci = new CustomInterface();

 for ( XBeeNode snode : nodes ) {

        Sensors sensors = snode.getSensors();
        ci.setMessagePacket(messagePacket);
        ci.setNode(snode);

        sensors.luxLowProperty().addListener(ci);
        ci.setProperty(sensors.luxLowProperty());
        sensors.luxLowProperty().set((int) luxesController.minSlider.getValue());

        sensors.luxHighProperty().addListener(ci);
        ci.setProperty(sensors.luxHighProperty());
        sensors.luxHighProperty().set((int) luxesController.maxSlider.getValue());

        sensors.luxIntermediateProperty().addListener(ci);
        ci.setProperty(sensors.luxIntermediateProperty());
        sensors.luxIntermediateProperty().set((int) luxesController.medSlider.getValue());

        sensors.photocellProperty().addListener(ci);
        ci.setProperty(sensors.photocellProperty());
        sensors.setPhotocell(luxesController.pheToggleButton.selectedProperty().getValue()); 
}

I'm cycling through some "nodes" objects and getting the values from Ui controls to set them to node properties. And here is the essential part of CustomInterface class:

public class CustomInterface implements javafx.beans.value.ChangeListener<Object> {

Property property;
MessagePacket messagePacket;
XBeeNode node;
boolean someValueHasChanged = false;


public CustomInterface() {
}

public CustomInterface(Property property, MessagePacket messagePacket, XBeeNode node) {
    setProperty(property);
    setMessagePacket(messagePacket);
    setNode(node);
}

@Override
public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {

    Sensors sensors = node.getSensors();

    System.out.println(newValue);

    if (newValue != oldValue)
        someValueHasChanged = true;

    if (newValue instanceof Number)
    {
        if (newValue != oldValue || GeneralConstants.ForceMode.get()) {
            String value = ((Number)newValue).toString();
            if (property.equals(sensors.luxLowProperty()))
                messagePacket.setParameter(PARAM.LUX_LOW, value);
            else if (property.equals(sensors.luxIntermediateProperty()))
                messagePacket.setParameter(PARAM.LUX_INTERMEDIATE, value);
            else if (property.equals(sensors.luxHighProperty()))
                messagePacket.setParameter(PARAM.LUX_HIGH, value);


        }
    } else if (newValue instanceof Boolean)
    {
        if ( ((! newValue.equals(oldValue)) || GeneralConstants.ForceMode.get())) {
            if (property.equals(sensors.photocellProperty()))
                messagePacket.setParameter(PARAM.EXTERN_PHOTOCELL_MODE, (sensors.photocellProperty().get()) ? "1" : "0");
            else if (property.equals(sensors.movementProperty()))
                messagePacket.setParameter(PARAM.MOVEMENT_SENSOR, (sensors.movementProperty().get()) ? "1" : "0");

        }
    }

    property.removeListener(this);

}
}

As you see I'm reusing the same ChangeListener. But for some weird reason, the change listener doesn't get triggered when the Boolean Properties are set false.


Solution

  • Well I discovered that ChangeListener doesn't get triggered unless the property gets invalidated, that happens only when the property value change its value (old value must be different to the new value).

    There are some ways to solve the problem. I found 2 discussions here in StackOverflow maybe could help you:

    1. [JavaFX ObjectProperty that fires change events even if newValue == oldValue
    2. [How to make JavaFX Property Listener to fire an event even if the oldVaule and newValue are the same?

    Particularly I solved it in another way, I create a Helper class where I use the ChangeListener and if I want to force getting a new value just use that Class. I don't share it with you because the code it's very suited to my project, it's not generic, so for that reason the above links.