【问题标题】:DatePicker: how to customizejavafx datepicker如何自定义
【发布时间】:2014-12-07 10:46:23
【问题描述】:

我有日期选择器的简单代码,它会禁用所选日期之前的所有日期,但我还需要能够禁用其他日期(例如:17.10.2014 到 19.10.2014)。我怎样才能以禁用特定日期的方式更改它?

public class DatePickerSample extends Application {

private Stage stage;
private DatePicker checkInDatePicker;
private DatePicker checkOutDatePicker;

public static void main(String[] args) {
    Locale.setDefault(Locale.US);                  
    launch(args);
}

@Override
public void start(Stage stage) {
    this.stage = stage;
    stage.setTitle("DatePickerSample ");
    initUI();
    stage.show();
}

private void initUI() {
    VBox vbox = new VBox(20);
    vbox.setStyle("-fx-padding: 10;");
    Scene scene = new Scene(vbox, 400, 400);
    stage.setScene(scene);
    checkInDatePicker = new DatePicker();
    checkOutDatePicker = new DatePicker();
    checkInDatePicker.setValue(LocalDate.now());
    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);
                        if (item.isBefore(
                                checkInDatePicker.getValue().plusDays(1))
                            ) {
                                setDisable(true);
                                setStyle("-fx-background-color: #ffc0cb;");
                        }
                        long p = ChronoUnit.DAYS.between(
                                checkInDatePicker.getValue(), item
                        );
                        setTooltip(new Tooltip(
                            "You're about to stay for " + p + " days")
                        );
                }
            };
        }
    };
    checkOutDatePicker.setDayCellFactory(dayCellFactory);
    checkOutDatePicker.setValue(checkInDatePicker.getValue().plusDays(1));
    GridPane gridPane = new GridPane();

    gridPane.setHgap(10);
    gridPane.setVgap(10);
    Label checkInlabel = new Label("Check-In Date:");
    gridPane.add(checkInlabel, 0, 0);
    GridPane.setHalignment(checkInlabel, HPos.LEFT);
    gridPane.add(checkInDatePicker, 0, 1);
    Label checkOutlabel = new Label("Check-Out Date:");
    gridPane.add(checkOutlabel, 0, 2);
    GridPane.setHalignment(checkOutlabel, HPos.LEFT);
    gridPane.add(checkOutDatePicker, 0, 3);
    vbox.getChildren().add(gridPane);
 }
}

【问题讨论】:

    标签: java datepicker javafx


    【解决方案1】:

    如果你想禁用多个日期范围,你可以创建这个 POJO:

    class DisabledRange {
    
        private final LocalDate initialDate;
        private final LocalDate endDate;
    
        public DisabledRange(LocalDate initialDate, LocalDate endDate){
            this.initialDate=initialDate;
            this.endDate = endDate;
        }
    
        public LocalDate getInitialDate() { return initialDate; }
        public LocalDate getEndDate() { return endDate; }
    
    }
    

    现在您可以在日历中定义要禁用的范围集合。例如:

    private final ObservableList<DisabledRange> rangesToDisable = 
        FXCollections.observableArrayList(
            new DisabledRange(LocalDate.of(2014,10,17), LocalDate.of(2014,10,19)),
            new DisabledRange(LocalDate.of(2014,10,27), LocalDate.of(2014,10,29)));
    

    最后,如果item 在以下任一范围内,您只需检查Callback

    @Override
    public void updateItem(LocalDate item, boolean empty) {
        super.updateItem(item, empty);
    
        boolean disable = rangesToDisable.stream()
                .filter(r->r.initialDate.minusDays(1).isBefore(item))
                .filter(r->r.endDate.plusDays(1).isAfter(item))
                .findAny()
                .isPresent();
    
        if (item.isBefore(checkInDatePicker.getValue().plusDays(1)) || 
                disable) {
                setDisable(true);
                setStyle("-fx-background-color: #ffc0cb;");
        }
        ...
    }
    

    【讨论】:

    • 抱歉只是无法理解这里的注释..它应该从哪里调用超级..或者我根本无法理解代码..因为我认为这一切都属于类 DisabledRange 并且每当我我需要创建一个 DisabledRange 的实例,然后给出我想取消的日期..还是我理解错了:(
    • DisabledRange 它只是两个日期的包装器,可用于构建要在日历中禁用的可能日期范围列表...我刚刚将此列表添加到 updateItem Callback 的方法。每次显示弹出窗口时,对于每个item(显示的日期之一),我们都会检查是否在这些范围内找到它,以便将其样式设置为禁用,就像您已经禁用所有日期一样在初始日期之前。我们只是覆盖每个单元格的更新方法,以按照您最初的要求启用/禁用日期。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    相关资源
    最近更新 更多