[我的尝试是将DatePicker
(处理日期选择,但不处理时间)和TextField
(处理时间)的值统一为可观察到的LocalDateTime
,两者都结合在一起。
我已经在模型中为这两个设置了可观察的属性,但是在加入它们时遇到了困难。
到目前为止,我设法使用Bindings.createObjectBinding()
进行了几次尝试,但在那儿似乎没有太大的成功。
我想至少知道我是在正确的道路上还是应该以不同的方式去做?
通过使用LocalDateTime#of(LocalDate,LocalTime)
,您可以从LocalDateTime#of(LocalDate,LocalTime)
和LocalDateTime
创建一个LocalDate
。您现在需要的是一种同时获取LocalTime
和LocalDate
实例的方法。幸运的是,LocalTime
控件为您提供了作为DatePicker
的值,因此我们已在此处完成。接下来是找到一种从LocalDate
中获取LocalTime
的方法。这可以通过使用TextField
和TextFormatter
来实现,它们知道如何将TextFormatter
转换为StringConverter
,反之亦然。该用例有一个内置的StringConverter
:String
。
一旦我们同时具有LocalTime
和StringConverter
,我们需要创建一个绑定,该绑定从这两个值创建一个LocalTimeStringConverter
。由于LocalTimeStringConverter
和DatePicker
都具有TextFormatter
属性,该属性分别拥有LocalDateTime
和在这种情况下分别具有DatePicker
,因此使用TextFormatter
创建绑定相对简单。
value
这是一个完整的例子:
LocalDate
以上将LocalTime
的文本绑定到Bindings#createObjectBinding(Callable,Observable...)
。每当“提交”文本时,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());
具有焦点的情况下,按Enter)。
我构造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
或LocalTimeStringConverter
。这是可自定义的,请参见Locale
的各种构造函数。