在Java中,如何将LocalDate和时间格式的String连接到LocalDateTime的一个可观察属性中?

我的尝试是将DatePicker(处理日期选择,但不处理时间)和TextField(处理时间)的值统一为可观察的LocalDateTime都加入了。

我已经在模型中为这两个设置了可观察的属性,但是我很难加入它们。

到目前为止,我已经尝试使用Bindings.createObjectBinding()进行了一些尝试,但是我似乎并没有取得多少成功。

我想至少知道我是在正确的道路上还是应该以不同的方式去做?

visionhansome 回答:在Java中,如何将LocalDate和时间格式的String连接到LocalDateTime的一个可观察属性中?

通过使用LocalDateTime#of(LocalDate,LocalTime),可以从LocalDateTimeLocalDate创建LocalTime。您现在需要的是一种同时获取LocalDateLocalTime实例的方法。幸运的是,DatePicker控件为您提供了LocalDate的值,因此我们已经在此处完成了。接下来是找到一种从LocalTime获取TextField的方法。这可以通过使用TextFormatterStringConverter来实现,它们知道如何将String转换为LocalTime,反之亦然。此用例有一个内置的StringConverterLocalTimeStringConverter

一旦我们同时拥有DatePickerTextFormatter,我们需要创建一个绑定,该绑定根据这两个值创建一个LocalDateTime。由于DatePickerTextFormatter都具有value属性,该属性分别持有LocalDate和在这种情况下分别为LocalTime,因此创建绑定是相对的Bindings#createObjectBinding(Callable,Observable...)很简单。

DatePicker dp = new DatePicker();
// Have to associate the TextFormatter with a TextField
TextFormatter<LocalTime> tf = new TextFormatter<>(new LocalTimeStringConverter());

ObjectBinding<LocalDateTime> binding = Bindings.createObjectBinding(() -> {
    LocalDate ld = dp.getValue();
    LocalTime lt = tf.getValue();
    return ld == null || lt == null ? null : LocalDateTime.of(ld,lt);
},dp.valueProperty(),tf.valueProperty());

这是一个完整的例子:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.converter.LocalTimeStringConverter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class App extends Application {

  @Override
  public void start(Stage primaryStage) {
    DatePicker datePicker = new DatePicker();
    datePicker.setValue(LocalDate.now());

    TextField timeField = new TextField();
    TextFormatter<LocalTime> timeFieldFormatter =
        new TextFormatter<>(new LocalTimeStringConverter());
    timeField.setTextFormatter(timeFieldFormatter);
    timeFieldFormatter.setValue(LocalTime.now());

    HBox dateTimeBox = new HBox(10,datePicker,timeField);
    dateTimeBox.setAlignment(Pos.CENTER);

    ObjectBinding<LocalDateTime> ldtBinding = Bindings.createObjectBinding(() -> {
      LocalDate date = datePicker.getValue();
      LocalTime time = timeFieldFormatter.getValue();
      return date == null || time == null ? null : LocalDateTime.of(date,time);
    },datePicker.valueProperty(),timeFieldFormatter.valueProperty());

    Label ldtLabel = new Label();
    ldtLabel.textProperty().bind(Bindings.createStringBinding(() -> {
      LocalDateTime dateTime = ldtBinding.get();
      return dateTime == null ? null : dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    },ldtBinding));

    VBox root = new VBox(15,dateTimeBox,ldtLabel);
    root.setAlignment(Pos.CENTER);
    root.setPadding(new Insets(25));

    primaryStage.setScene(new Scene(root));
    primaryStage.show();
  }
}

以上内容将Label的文本绑定到ObjectBinding<LocalDateTime>。每当“提交”文本时,TextFormatter的值就会更新(例如,在TextField处于焦点状态时,按 Enter )。

我构建LocalTimeStringConverter的方式意味着它将使用我的LocaleFormatStyle.SHORT来解析和格式化LocalTime。例如,对我来说,这意味着类似3:30 PM11:25 AM。这是可自定义的,请参见LocalTimeStringConverter的各种构造函数。

本文链接:https://www.f2er.com/3167509.html

大家都在问