绑定到标签时格式化整数

Formatting integer while binding to label

我正在尝试格式化一个整数,同时将它绑定到标签的文本 属性。

我知道我可以在我的值中使用 setText() setter,但我宁愿通过绑定以正确的方式使用它。

在我的控制器初始化中我有:

sec = new SimpleIntegerProperty(this,"seconds");
secondsLabel.textProperty().bind(Bindings.convert(sec));

但是当秒数下降到 10 以下时,它显示为一位数,但我希望它保持为两位数。所以我尝试将绑定更改为以下内容:

 secondsLabel.textProperty().bind(Bindings.createStringBinding(() -> {
        NumberFormat formatter = NumberFormat.getIntegerInstance();
        formatter.setMinimumIntegerDigits(2);
        if(sec.getValue() == null) {
            return "";
        }else {
            return formatter.format(sec.get());
        }
    }));

这会对其进行格式化,但是当我覆盖它时 sec.set(newNumber); 值不会改变。

我也试过这个:

secondsLabel.textProperty().bind(Bindings.createStringBinding(() -> {
            if(sec.getValue() == null) {
                return "";
            }else {
                return String.format("%02d", sec.getValue());
            }
        }));

但那做了同样的事情。加载正常,显示两位数,但是当通过 sec.set(newNumber); 更改数字时,没有任何变化。这个数字永远不会超过六十或低于零

您需要告诉您的绑定,只要 sec 属性 失效,它就应该失效。 Bindings.createStringBinding(...) 在应该传递绑定需要绑定到的任何属性的函数之后采用可变参数。您可以直接调整您的代码如下:

secondsLabel.textProperty().bind(Bindings.createStringBinding(() -> {
    NumberFormat formatter = NumberFormat.getIntegerInstance();
    formatter.setMinimumIntegerDigits(2);
    if(sec.getValue() == null) {
        return "";
    }else {
        return formatter.format(sec.get());
    }
}, sec));

secondsLabel.textProperty().bind(Bindings.createStringBinding(() -> {
    if(sec.getValue() == null) {
        return "";
    }else {
        return String.format("%02d", sec.getValue());
    }
}, sec));

正如@fabian 指出的那样,IntegerProperty.get() 永远不会 returns 为空,因此您可以删除空检查并执行以下操作:

secondsLabel.textProperty().bind(Bindings.createStringBinding(
    () -> String.format("%02d", sec.getValue()),
    sec));

并且在绑定中有一个方便的版本 API:

secondsLabel.textProperty().bind(Bindings.format("%02d", sec));

IntegerProperty继承了很多有用的方法,包括asString:

secondsLabel.textProperty().bind(sec.asString("%02d"));