The NumberExpression.asString(String)
formats the number according to the rules of Formatter
, same as if using String.format
or Print[Stream|Writer].printf
. Unfortunately, unless I'm missing something, the Formatter
class expects date/time objects to represent a moment in time, not a duration of time. To format your property as a duration with a HH:MM:SS
format you'll need to create your own binding.
To get the String
you want you can still use String.format
, but by formatting as integral numbers rather than time. This requires you to calculate the hours, minutes, and seconds.
String str = String.format("%02d:%02d:%02d", hours, minutes, seconds);
If you're using Java 9+, calculating the hours, minutes, and seconds is made extremely easy with java.time.Duration
; the class had the toHoursPart
, toMinutesPart
, toSecondsPart
, and other similar methods added in Java 9. If using Java 8 you'll need to do the calculations manually or pull in a library, see this question for some help in that regard.
Here's an example assuming Java 9+ and using Bindings.createStringBinding
to create the binding:
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();
}
}