JavaFX Checkbox不遵循绑定属性的值

时间:2016-01-01 20:09:44

标签: java user-interface javafx properties

我有一个具有可以切换的布尔属性的模型。但是,根据条件,属性切换可能会失败。

我想将此属性绑定到我的UI中的复选框,而且如果属性无法切换,我希望复选框保持其先前的状态。

我为此创建了一个SSCCE。我有一个布尔属性,通过简单地设置为false来模拟从false到true的失败切换,而不管参数如何。复选框最初为false,布尔属性也是如此。

我希望当我单击复选框时,它将保持未设置状态,因为这是它所绑定的booleanproperty的状态。但事实并非如此,它会很乐意切换。

我是否可以在布尔属性中对此做些什么,或者我是否需要通过不绑定属性并使用侦听器和事件处理程序来解决这个问题?

SSCCE:

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.stage.Stage;

public class PropertySSCCE extends Application {

    BooleanProperty property = new SimpleBooleanProperty(false) {
        @Override
        public void set(boolean newValue) {
            super.set(false);
            fireValueChangedEvent();
        }

        @Override
        public void setValue(Boolean v) {
            super.setValue(false);
            fireValueChangedEvent();
        }
    };

    @Override
    public void start(Stage aStage) throws Exception {
        CheckBox cb = new CheckBox();
        cb.selectedProperty().bindBidirectional(property);

        Scene scene = new Scene(cb);
        aStage.setScene(scene);
        aStage.show();
    }

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

1 个答案:

答案 0 :(得分:0)

根据@sillyfly的评论,这似乎是不可能的,所以我创建了以下帮助器将CheckBox显示的值绑定到布尔属性和(ab)使用Predicate类来设置和判断设置是否正常。

public static void bindTogglable(CheckBox aCheckBox, BooleanExpression aBooleanExpression,
        Predicate<Boolean> aSuccess) {
    aCheckBox.setSelected(aBooleanExpression.get());
    aBooleanExpression.addListener((aObservable, aOld, aNew) -> {
        aCheckBox.setSelected(aNew);
    });

    aCheckBox.setOnAction(e -> {
        boolean value = aCheckBox.isSelected();
        boolean oldValue = aBooleanExpression.get();
        if (value != oldValue && !aSuccess.test(value)) {
            aCheckBox.setSelected(oldValue);
        }
    });
}

对于OP的SSCCE,使用方法如下:

bindTogglable(cb, property, (value) -> false);

而不是:

 cb.selectedProperty().bindBidirectional(property);