Zakładając, że masz już LocalDate
ale wystarczy tylko przekształcić w LocalDateTime
za pomocą wartości ComboBox
można użyć ComboBox<Number>
zamiast ComboBox<String>
i a NumberStringConverter
aby dodać prefiks 0
dla pojedynczych godzin lub minut (08:00
zamiast 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();
}
}
Uwaga:
Przykład ten można uprościć stosując binding
zamiast dodawać detektorów zmian. Jednak są one aktualizowane leniwie, więc trzeba będzie dodać detektory zmian w właściwości, aby wymusić ponowne przeliczenie wartości.
Jeśli korzystasz już z detektory właściwości, można wymienić wszystkie detektory zmian w powyższym przykładzie na:
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()));