如何在javaFX中自定义datepicker,以便我可以限制用户无法选择星期一的任何日期

1 javafx

我需要自定义我的日期选择器,以便它不接受一周中某些日期的任何日期.

我怎样才能做到这一点?

Jam*_*s_D 7

如果您对用户无法输入文本字段感到满意,则可以使日期选择器不可编辑,并使用单元工厂禁用显示星期一的单元格:

import java.time.DayOfWeek;
import java.time.LocalDate;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class IDontLikeMondays extends Application {

    @Override
    public void start(Stage primaryStage) {
        DatePicker datePicker = new DatePicker();
        datePicker.setDayCellFactory(picker -> new DateCell() {
            @Override
            public void updateItem(LocalDate date, boolean empty) {
                super.updateItem(date, empty);
                setDisable(empty || date.getDayOfWeek() == DayOfWeek.MONDAY);
            }
        });
        datePicker.setEditable(false);

        StackPane root = new StackPane(datePicker);
        primaryStage.setScene(new Scene(root, 300, 300));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果您希望日期选择器仍然可以编辑,则必须提出一些策略来处理用户键入表示星期一的日期的可能性.例如,以下使用converter只将星期一移回前一个星期日:

import java.time.DayOfWeek;
import java.time.LocalDate;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javafx.util.converter.LocalDateStringConverter;

public class IDontLikeMondays extends Application {

    @Override
    public void start(Stage primaryStage) {
        DatePicker datePicker = new DatePicker();
        datePicker.setDayCellFactory(picker -> new DateCell() {
            @Override
            public void updateItem(LocalDate date, boolean empty) {
                super.updateItem(date, empty);
                setDisable(empty || date.getDayOfWeek() == DayOfWeek.MONDAY);
            }
        });

        StringConverter<LocalDate> converter = new LocalDateStringConverter() {
            @Override
            public LocalDate fromString(String string) {
                LocalDate date = super.fromString(string);
                if (date.getDayOfWeek() == DayOfWeek.MONDAY) {
                    return date.minusDays(1);
                } else {
                    return date ;
                }
            }
        };
        datePicker.setConverter(converter);


        StackPane root = new StackPane(datePicker);
        primaryStage.setScene(new Scene(root, 300, 300));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

还要注意DatePicker转换器通过恢复到之前的值抛出的句柄异常,所以你也可以这样做:

StringConverter<LocalDate> converter = new LocalDateStringConverter() {
    @Override
    public LocalDate fromString(String string) {
        LocalDate date = super.fromString(string);
        if (date.getDayOfWeek() == DayOfWeek.MONDAY) {

            throw new IllegalStateException("I don't like Mondays");

        } else {
            return date ;
        }
    }
};
datePicker.setConverter(converter);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果用户键入代表星期一的日期,它将简单地拒绝它并恢复到当前值.

一般来说,我建议使日期选择器不可编辑,因为我认为这会给用户带来更直观的行为.