我有一个simpleIntegerProperty,表示要以hh:mm:ss格式表示的数量(以秒为单位)。
我想通过将Label textProperty绑定到simpleIntegerProperty在Label中呈现此内容。我知道我可以使用格式字符串执行类似的操作,例如
activeTimeText.textProperty().bind(model.activeTimeSeconds.asString("Seconds: %04d"));
渲染:
Seconds: 0000
那么问题是,如何实现更复杂的asString转换?例如,我当前所需的输出输出(其中的数字是秒钟simpleIntegerProperty的函数。):
00:00:00
我已经搜索了类似的问题,因为我认为这很普遍。但是还没有找到答案。抱歉,如果这是重复的话。
答案 0 :(得分:2)
您可以扩展SimpleIntegerProperty
以覆盖asString
:
class MySimpleIntegerProperty extends SimpleIntegerProperty{
@Override
public StringBinding asString(){
return Bindings.createStringBinding(() -> " hello " + get() , this);
}
}
要测试使用:
MySimpleIntegerProperty activeTimeSeconds = new MySimpleIntegerProperty();
activeTimeSeconds.set(7);
SimpleStringProperty activeTimeText = new SimpleStringProperty();
activeTimeText.bind(activeTimeSeconds.asString());
System.out.println(activeTimeText.get());
您当然可以将值处理委托给方法:
@Override
public StringBinding asString(){
return Bindings.createStringBinding(() -> processValue(get()), this);
}
private String processValue(int value){
return " hello " + get() ;
}
答案 1 :(得分:1)
NumberExpression.asString(String)
按照Formatter
的规则格式化数字,就像使用String.format
或Print[Stream|Writer].printf
一样。不幸的是,除非我缺少某些内容,否则Formatter
类期望日期/时间对象表示时间上的 moment ,而不是时间上的 duration 。要使用HH:MM:SS
格式将属性设置为持续时间,则需要创建自己的绑定。
要获得String
,您仍然可以使用String.format
,但要格式化为整数而不是时间。这需要您计算小时,分钟和秒。
String str = String.format("%02d:%02d:%02d", hours, minutes, seconds);
如果您使用的是Java 9+,则java.time.Duration
可以非常容易地计算小时,分钟和秒。该类在Java 9中添加了toHoursPart
,toMinutesPart
,toSecondsPart
和其他类似方法。如果使用Java 8,则需要手动进行计算或引入库,有关这方面的帮助,请参见this question。
下面是一个示例,假设使用Java 9+,并使用Bindings.createStringBinding
创建绑定:
import java.time.Duration;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
private final IntegerProperty seconds = new SimpleIntegerProperty(this, "seconds");
@Override
public void start(Stage primaryStage) {
Label label = new Label();
label.textProperty().bind(Bindings.createStringBinding(() -> {
// java.time.Duration
Duration duration = Duration.ofSeconds(seconds.get());
return String.format("%02d:%02d:%02d", duration.toHoursPart(),
duration.toMinutesPart(), duration.toSecondsPart());
}, seconds));
primaryStage.setScene(new Scene(new StackPane(label), 500, 300));
primaryStage.show();
Timeline timeline = new Timeline(
new KeyFrame(javafx.util.Duration.seconds(1.0), e -> seconds.set(seconds.get() + 1))
);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
}