问题
Problem: I've two datepicker object checkIn_date and checkOut_date in the same scene. There is a way to change automatically the date field in the second datepicker object? For example : checkIn_date is set with 2015-08-10 and checkOut_date is set with 2015-08-11. If I change the date field in checkIn_date i.e. 2015-08-22, checkOut_date update automatically to 2015-08-23. Thanks for any advices.
回答1:
You can achieve this by adding a listener to your check-in DatePicker, fetch the new value, add the no of days you want to it and update the new value to the check-out DatePicker.
Here is a MCVE to give more idea on what I meant :
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
private final int noOfDaysToAdd = 2;
@Override
public void start(Stage primaryStage) throws Exception {
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
Label checkInLabel = new Label("Check In : ");
Label checkOutLabel = new Label("Check Out : ");
DatePicker picker1 = new DatePicker();
DatePicker picker2 = new DatePicker();
// Listener for updating the checkout date w.r.t check in date
picker1.valueProperty().addListener((ov, oldValue, newValue) -> {
picker2.setValue(newValue.plusDays(noOfDaysToAdd));
});
HBox checkInBox = new HBox(10, checkInLabel, picker1);
HBox checkOutBox = new HBox(10, checkOutLabel, picker2);
checkInBox.setAlignment(Pos.CENTER);
checkOutBox.setAlignment(Pos.CENTER);
root.getChildren().addAll(checkInBox, checkOutBox);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Output:
Update
You can re-write the snippet
picker1.valueProperty().addListener((ov, oldValue, newValue) -> {
picker2.setValue(newValue.plusDays(noOfDaysToAdd));
});
without the lambda as :
picker1.valueProperty().addListener(new ChangeListener<LocalDate>() {
@Override
public void changed(ObservableValue<? extends LocalDate> observable, LocalDate oldValue, LocalDate newValue) {
picker2.setValue(newValue.plusDays(noOfDaysToAdd));
}
});
回答2:
First thanks for the help! I've fixed my problem from another point of view. When scene/view has been loaded either datepicker are set to current date for check-in and the day after the curent day for check-out date. For check-in day I've disabled the selection of days before the current date and after check-out date. For check-out day I've disabled the selection of days before check-out date.
Unfortunately I can't post any image because my reputation is not 10!
But this is the code for the controller class:
import java.time.LocalDate;
import javafx.fxml.FXML;
import javafx.scene.control.DatePicker;
import com.main.controller.checker.DateChecker;
import com.main.controller.datautil.DataFetch;
import com.main.controller.datautil.DataStore;
import com.main.controller.util.Initilizable;
public class SearchCtrl implements Initilizable{
@FXML
private DatePicker check_in;
@FXML
private DatePicker check_out;
@Override
public void init() {
check_in.setValue(LocalDate.now());
check_out.setValue(check_in.getValue().plusDays(1));
DateChecker.setBeginDateBounds(check_in, check_out.getValue());
DateChecker.setEndDateBounds(check_out, check_in.getValue());
check_in.setOnAction( (event) -> {DateChecker.setEndDateBounds(check_out, check_in.getValue());});
datafine.setOnAction( (event) -> {DateChecker.setBeginDateBounds(check_in, check_out.getValue());});
}
This is the DateChecker class:
import java.time.LocalDate;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.util.Callback;
public class DateChecker {
private DateChecker(){
}
public static void setBeginDateBounds(DatePicker begin_date, LocalDate end_date ){
final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
@Override
public DateCell call(final DatePicker datePicker) {
return new DateCell() {
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
boolean cond = (item.isBefore(LocalDate.now()) || !item.isBefore(end_date));
if (cond){
setDisable(true);
setStyle("-fx-background-color: #d3d3d3;");
}else{
setDisable(false);
setStyle("-fx-background-color: #CCFFFF;");
setStyle("-fx-font-fill: black;");
}
}
};
}
};
begin_date.setDayCellFactory(dayCellFactory);
}
public static void setEndDateBounds(DatePicker end_date, LocalDate begin_date ){
final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
@Override
public DateCell call(final DatePicker datePicker) {
return new DateCell() {
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
boolean cond = (item.isBefore(LocalDate.now()) || !item.isAfter(begin_date));
if (cond){
setDisable(true);
setStyle("-fx-background-color: #d3d3d3;");
}else{
setDisable(false);
setStyle("-fx-background-color: #CCFFFF;");
setStyle("-fx-font-fill: black;");
}
}
};
}
};
end_date.setDayCellFactory(dayCellFactory);
}
}
I hope this will help!
来源:https://stackoverflow.com/questions/31460059/javafx-datepicker-how-to-update-date-in-a-second-datepicker-object