Предполагая, что у вас уже есть LocalDate
, но вам нужно только преобразовать в LocalDateTime
используя значения ComboBox
, вы можете использовать ComboBox<Number>
вместо ComboBox<String>
, и а NumberStringConverter
чтобы добавить префикс 0
для однозначных часов или минут (08:00
вместо 8:0
).
public class App extends Application {
@Override
public void start(Stage stage) {
LocalDate date = LocalDate.now();
ComboBox<Number> cbHourStart = new ComboBox<>();
ComboBox<Number> cbHourEnd = new ComboBox<>();
ComboBox<Number> cbMinuteStart = new ComboBox<>();
ComboBox<Number> cbMinuteEnd = new ComboBox<>();
NumberStringConverter converter = new NumberStringConverter("00");
cbHourStart.setConverter(converter);
cbHourEnd.setConverter(converter);
cbMinuteStart.setConverter(converter);
cbMinuteEnd.setConverter(converter);
IntStream.rangeClosed(8, 22).forEach(cbHourStart.getItems()::add);
IntStream.rangeClosed(8, 22).forEach(cbHourEnd.getItems()::add);
IntStream.iterate(0, i -> i + 15).limit(4).forEach(cbMinuteStart.getItems()::add);
IntStream.iterate(0, i -> i + 15).limit(4).forEach(cbMinuteEnd.getItems()::add);
cbHourStart.getSelectionModel().select(0);
cbHourEnd.getSelectionModel().select(0);
cbMinuteStart.getSelectionModel().select(0);
cbMinuteEnd.getSelectionModel().select(0);
ObjectProperty<LocalTime> startTime = new SimpleObjectProperty<>();
ObjectProperty<LocalTime> endTime = new SimpleObjectProperty<>();
cbHourStart.getSelectionModel().selectedItemProperty()
.addListener((obs, oldVal, newVal) -> startTime.setValue(
LocalTime.of(newVal.intValue(),
cbMinuteStart.getSelectionModel().getSelectedItem().intValue())));
cbMinuteStart.getSelectionModel().selectedItemProperty()
.addListener((obs, oldVal, newVal) -> startTime.setValue(
LocalTime.of(cbHourStart.getSelectionModel().getSelectedItem().intValue(),
newVal.intValue())));
cbHourEnd.getSelectionModel().selectedItemProperty()
.addListener((obs, oldVal, newVal) -> endTime.setValue(
LocalTime.of(newVal.intValue(),
cbMinuteEnd.getSelectionModel().getSelectedItem().intValue())));
cbMinuteEnd.getSelectionModel().selectedItemProperty()
.addListener((obs, oldVal, newVal) -> endTime.setValue(
LocalTime.of(cbHourEnd.getSelectionModel().getSelectedItem().intValue(),
newVal.intValue())));
startTime.addListener((obs, oldVal, newVal) ->
System.out.println("Start time: " + date.atTime(newVal)));
endTime.addListener((obs, oldVal, newVal) ->
System.out.println("End time: " + date.atTime(newVal)));
HBox hbStart = new HBox(5, cbHourStart, new Label(":"), cbMinuteStart);
HBox hbEnd = new HBox(5, cbHourEnd, new Label(":"), cbMinuteEnd);
VBox pane = new VBox(20, hbStart, hbEnd);
Scene scene = new Scene(new StackPane(pane));
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Примечание:
Пример можно упростить, используя binding
вместо добавления прослушивателей изменений. Однако они обновляются лениво, поэтому вам нужно будет добавить прослушиватели изменений в свойства, чтобы принудительно выполнить пересчет значений.
Если вы уже используете прослушиватели для свойств, вы можете заменить все прослушиватели изменений в предыдущем примере на:
startTime.bind(Bindings.createObjectBinding(() ->
LocalTime.of(
cbHourStart.getSelectionModel().getSelectedItem().intValue(),
cbMinuteStart.getSelectionModel().getSelectedItem().intValue()),
cbHourStart.getSelectionModel().selectedItemProperty(),
cbMinuteStart.getSelectionModel().selectedItemProperty()));
endTime.bind(Bindings.createObjectBinding(() ->
LocalTime.of(
cbHourEnd.getSelectionModel().getSelectedItem().intValue(),
cbMinuteEnd.getSelectionModel().getSelectedItem().intValue()),
cbHourEnd.getSelectionModel().selectedItemProperty(),
cbMinuteEnd.getSelectionModel().selectedItemProperty()));