kuhaku kuhaku - 2 months ago 10
Java Question

Low level bind of disableProperty and setDisable of a controller

Is there a way to do a low level bind but also be able to still do

setDisable(ture/false)
to a controller?

For example:

HBoxSomeBox.disableProperty().bind(new BooleanBinding() {
{
bind(someIntValue);
}

@Override
protected boolean computeValue() {
return someIntValue >=2 ;
}
});


And somewhere else in the code to do
HBoxSomeBox.setDisable(false)
.

Currently when I try to do that it throws an exception:


java.lang.RuntimeException: HBox.disable : A bound value cannot be set.


So is there another way to have a bound controller but also to be able to set it?

Answer

From the comments, you appear to want to disable your control anytime the value of someIntValue is at least two, or under other circumstances "dictated by the view". You could either create a BooleanProperty representing those other circumstances, and use it in the binding:

IntegerProperty someIntProperty = ... ;

BooleanProperty forceDisable = new SimpleBooleanProperty();

hboxSomeHBox.disableProperty().bind(new BooleanBinding() {
    {
        bind(someIntValue, forceDisable);
    }

    @Override
    public boolean computeValue() {
        return someIntValue.get() >= 2 || forceDisable.get() ;
    }
}

or, more succinctly,

BooleanProperty forceDisable = new SimpleBooleanProperty();

hboxSomeHBox.disableProperty().bind(someIntValue.greaterThanOrEqualTo(2).or(forceDisable));

Then calling forceDisable.set(true); will disable the control.

You can also achieve this simply with a listener:

someIntValue.addListener((obs, oldValue, newValue) -> {
    if (newValue.intValue() >= 2) {
        hboxSomeHBox.setDisable(true);
    }
});

Since the disable property is not bound, you are free to set it in the usual way.