JavaFX 8 Bindings.when和Bindings.divide创建零除

JavaFX 8 Bindings.when和Bindings.divide创建零除,java,javafx-8,Java,Javafx 8,我正在和绑定做斗争。当。。。我试图创建一个百分比分数,当成功测试的数量发生变化(在下面的代码中反映为“successCountProperty”)或测试的总数发生变化(在“results”的sizeProperty中反映)时,该分数会更新。当我执行这段代码时,我得到java.lang.arithmetricexception:/by零。当我最初遇到异常时,我找到了Bindings.When().then().otherwise(),这在我脑海中应该可以解决问题。不幸的是,在执行此代码时,“the

我正在和绑定做斗争。当。。。我试图创建一个百分比分数,当成功测试的数量发生变化(在下面的代码中反映为“successCountProperty”)或测试的总数发生变化(在“results”的sizeProperty中反映)时,该分数会更新。当我执行这段代码时,我得到java.lang.arithmetricexception:/by零。当我最初遇到异常时,我找到了Bindings.When().then().otherwise(),这在我脑海中应该可以解决问题。不幸的是,在执行此代码时,“then”正在执行,尽管“when”返回false。有人能帮忙吗

public void foo()
{
    DoubleProperty scoreProperty = new SimpleDoubleProperty(0);
    ListProperty<String> results = new SimpleListProperty<>(FXCollections.observableArrayList());

    IntegerProperty successCountProperty = new SimpleIntegerProperty(0);

    scoreProperty.bind(Bindings.when(results.sizeProperty().greaterThan(0))
            .then(Bindings.divide(successCountProperty, results.sizeProperty())).otherwise(0));
}
public void foo()
{
DoubleProperty scoreProperty=新的SimpleDoubleProperty(0);
ListProperty结果=新的SimpleListProperty(FXCollections.observableArrayList());
IntegerProperty successCountProperty=新的SimpleIntegerProperty(0);
scoreProperty.bind(Bindings.when(results.sizeProperty().greaterThan(0))
。然后(Bindings.divide(successCountProperty,results.sizeProperty())。否则(0));
}

使用
绑定方法的更复杂的绑定
或属性本身很容易变得难以阅读和维护

在这种情况下,我建议使用自定义评估方法创建一个
双重绑定

scoreProperty.bind(Bindings.createDoubleBinding(() -> {
    int size = results.size();
    return size == 0 ? 0d : ((double) successCountProperty.get()) / size;
}, results.sizeProperty(), successCountProperty));
你的问题是

Bindings.divide(successCountProperty, results.sizeProperty())
立即进行评估,您似乎正在期待

您可以编写自己的惰性除法器,该除法器仅在实际查询值时进行除法:

class LazyDivision extends DoubleBinding
{
    private IntegerProperty dividend;
    private ReadOnlyIntegerProperty divisor;

    LazyDivision(final IntegerProperty dividend, final ReadOnlyIntegerProperty divisor)
    {
        this.dividend = dividend;
        this.divisor = divisor;
    }

    @Override
    protected double computeValue()
    {
        return dividend.getValue() / divisor.getValue().doubleValue();
    }
}
然后像这样使用:

scoreProperty.bind(
    Bindings
        .when(results.sizeProperty().greaterThan(0))
        .then(
            new LazyDivision(successCountProperty, results.sizeProperty())
        )
        .otherwise(0)
);

此代码从不将侦听器添加到
successCountProperty
。如果仅修改此值,则不会更新绑定属性。这肯定不是理想的效果。