Привязать simpleStringProperty к simpleIntegerProperty с помощью пользовательского метода asString - PullRequest
0 голосов
/ 31 января 2019

У меня есть simpleIntegerProperty, представляющий количество в секундах, которое я хочу представить в формате чч: мм: сс.

Я хотел бы отобразить это в метке, связав текстовое свойство Label с simpleIntegerProperty.Я понимаю, что могу сделать нечто похожее на строки форматирования, например,

activeTimeText.textProperty().bind(model.activeTimeSeconds.asString("Seconds: %04d"));

рендеринга:

Seconds: 0000

Итак, вопрос, как реализовать более сложное преобразование asString?Например, мой текущий желаемый выходной результат (где цифры являются функциями секунд simpleIntegerProperty.):

00:00:00

Я уже искал похожий вопрос, так как считаю, что это должно быть довольно распространенным явлением.Однако не нашли ответа.Извиняюсь, если это дубликат.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

NumberExpression.asString(String) форматирует число в соответствии с правилами Formatter, так же, как если бы использовать String.format или Print[Stream|Writer].printf.К сожалению, если я что-то упустил, класс Formatter ожидает, что объекты даты / времени будут представлять момент во времени, а не продолжительность времени.Чтобы отформатировать собственность как длительность в формате HH:MM:SS, вам нужно создать собственную привязку.

Чтобы получить String, который вы хотите, вы все равно можете использовать String.format, но форматируя как целые числа, а не как время.Для этого требуется рассчитать часы, минуты и секунды.

String str = String.format("%02d:%02d:%02d", hours, minutes, seconds);

Если вы используете Java 9+, вычисление часов, минут и секунд становится чрезвычайно простым с java.time.Duration;класс имеет toHoursPart, toMinutesPart, toSecondsPart и другие подобные методы, добавленные в Java 9. Если вы используете Java 8, вам нужно будет выполнить вычисления вручную или получить библиотеку, см. этот вопрос для некоторой помощи в этом отношении.

Вот пример, предполагающий 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();
  }

}
0 голосов
/ 31 января 2019

Вы можете расширить 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() ;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...