package de.uniluebeck.mi.projmi6.view; import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.IntegerPropertyBase; import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.effect.DropShadow; import javafx.scene.effect.Effect; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; import java.time.LocalDate; import java.time.LocalTime; import java.util.Arrays; import java.util.stream.IntStream; import java.time.LocalDateTime; /** * A picker for date and time, composed from a DatePicker and two ComboBoxes. It also has an optional Button to set * date and time to the current system time. * * @author Johannes Oehm */ public class DateTimePicker extends HBox { private DatePicker datePicker = new DatePicker(); private NumberTextField hourText = new NumberTextField(); private NumberTextField minuteText = new NumberTextField(); private Button btnNow = new Button("Jetzt"); private Effect invalidValue = new DropShadow(10, Color.RED); /** * Empty constructor for the FXMLLoader. */ public DateTimePicker(){ this.setAlignment(Pos.CENTER_LEFT); hourText.setOnKeyReleased(event ->{ if(hourText.getCaretPosition()>=2){ int hour = Integer.parseInt(hourText.getText()); if(hour>=0 && hour <= 24){ minuteText.requestFocus(); } } }); hourText.setAlignment(Pos.CENTER_RIGHT); hourText.setBackground(null); hourText.setPadding(Insets.EMPTY); hourText.setPromptText("HH"); HBox.setHgrow(hourText, Priority.ALWAYS); minuteText.setBackground(null); minuteText.setPadding(Insets.EMPTY); minuteText.setPromptText("MM"); HBox.setHgrow(minuteText, Priority.ALWAYS); hourText.effectProperty().bind(Bindings.createObjectBinding(()->{ String text = hourText.getText(); if(text.isEmpty()){ return null; } int value = Integer.parseInt(text); if(value>=0&&value<24){ return null; } return invalidValue; }, hourText.textProperty())); minuteText.effectProperty().bind(Bindings.createObjectBinding(()->{ String text = minuteText.getText(); if(text.isEmpty()){ return null; } int value = Integer.parseInt(text); if(value>=0&&value<59){ return null; } return invalidValue; }, minuteText.textProperty())); Label colon = new Label(":"); HBox timePicker = new HBox(hourText, colon,minuteText); timePicker.maxHeightProperty().bind(datePicker.heightProperty()); timePicker.setMinWidth(55); timePicker.setMaxWidth(70); timePicker.getStyleClass().add("button"); //Set Now-Button action btnNow.setOnAction(event -> setToCurrentDateTime()); //Make it large enough to read the text btnNow.setMinWidth(50); btnNow.getStyleClass().add("now-button"); //Add the subcomponents to the view. this.getChildren().addAll(datePicker,timePicker,btnNow); this.setSpacing(5); } /** * Setter for the DateTime that is set in the view. * @param localDateTime The date to be set in the view. */ public void setDateTime(LocalDateTime localDateTime){ if(localDateTime==null){ hourText.setText(""); minuteText.setText(""); datePicker.setValue(null); }else{ hourText.setText(Integer.toString(localDateTime.getHour())); minuteText.setText(Integer.toString(localDateTime.getMinute())); datePicker.setValue(LocalDate.from(localDateTime)); } } /** * Sets the date set in the view to the current systems time. */ public void setToCurrentDateTime(){ setDateTime(LocalDateTime.now()); } /** * Getter for date and time that is currently set in the view. * @return A LocalDateTime object or null, if one or more fields are not set. */ public LocalDateTime getDateTime(){ if(datePicker.getValue()==null ){ return null; } try{ int hour = Integer.parseInt( hourText.getText()); int minute = Integer.parseInt(minuteText.getText()); if(hour>=24|| hour<0||minute<0||minute>=60){ return null; } return LocalDateTime.of(datePicker.getValue(), LocalTime.of(hour, minute)); }catch (Exception e){ return null; } } /** * A property for hiding the "Set date and time to now"-Button. * @return A BooleanProperty, true if the button is visible. */ public BooleanProperty nowButtonVisiblePropety(){ return btnNow.visibleProperty(); } /** * Setter for the {@link DateTimePicker#nowButtonVisiblePropety}. * @param visible When set to true, the button will be shown. */ public void setNowButtonVisible(boolean visible){ btnNow.setVisible(visible); } /** * Getter for the {@link DateTimePicker#nowButtonVisiblePropety}. * @return true if the now-Button is visible, false otherwise. */ public boolean isNowButtonVisible(){ return btnNow.isVisible(); } }