使用DatePicker选择多个日期 [英] Select multiple dates with DatePicker

查看:706
本文介绍了使用DatePicker选择多个日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个选择多个日期的DatePicker。我可以选择多个日期,但是在选择它们时我想保持DatePicker处于打开状态。问题是,每次我选择一个日期时,DatePicker都会关闭。

I am trying to create a DatePicker that selects multiple dates. I am able to select multiple dates but I would like to keep the DatePicker open while I select them. Problem is, the DatePicker will close every time I select a date.

我不想使用私有API。我正在考虑添加以下内容:

I don't want to use a private API. I was thinking of adding this:

datePicker.setOnHiding(event -> {            
    event.consume();
});

但这不起作用。

这是我的代码:

public static DatePicker getDatePicker() {
    ObservableList<LocalDate> selectedDates = FXCollections.observableArrayList();
    String pattern = "yyyy-MM-dd";
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
    DatePicker datePicker = new DatePicker();
    datePicker.setPromptText(pattern);

    datePicker.setConverter(new StringConverter<LocalDate>() {
        @Override
        public String toString(LocalDate date) {
            return (date == null) ? "" : dateFormatter.format(date);
        }

        @Override
        public LocalDate fromString(String string) {
            return ((string == null) || string.isEmpty()) ? null : LocalDate.parse(string, dateFormatter);
        }
    });

    datePicker.setOnAction(event -> {
        selectedDates.add(datePicker.getValue());
        event.consume();
    });

    datePicker.setDayCellFactory((DatePicker param) -> new DateCell() {
        @Override
        public void updateItem(LocalDate item, boolean empty) {
            super.updateItem(item, empty);
            boolean alreadySelected = selectedDates.contains(item);
            setDisable(alreadySelected);
            setStyle(alreadySelected ? "-fx-background-color: #09a30f;" : "");
        }
    });

    return datePicker;
}


推荐答案

如果选中 DatePickerContent 类,您可以发现每次创建新的 DateCell 时,都会创建一个 EventHandler MOUSE_CLICKED 的$ c>被添加到其中。当用户单击单元格时,此处理程序将调用 selectDayCell(DateCell) selectDayCell(DateCell)设置新的日期值并隐藏 DatePicker

If you check DatePickerContent class, you can find that each time a new DateCell is created, an EventHandler of type MOUSE_CLICKED is added to it. This handler will call selectDayCell(DateCell) when the user clicks on a cell. selectDayCell(DateCell) sets the new date value and hides the DatePicker:

protected void createDayCells() {
    final EventHandler<MouseEvent> dayCellActionHandler = ev -> {
        if (ev.getButton() != MouseButton.PRIMARY) {
            return;
        }
        DateCell dayCell = (DateCell)ev.getSource();
        selectDayCell(dayCell);
        lastFocusedDayCell = dayCell;
    };
    for (int row = 0; row < 6; row++) {
        for (int col = 0; col < daysPerWeek; col++) {
            DateCell dayCell = createDayCell();
            dayCell.addEventHandler(MouseEvent.MOUSE_CLICKED, dayCellActionHandler);
            dayCells.add(dayCell);
        }
    }
    dayCellDates = new LocalDate[6 * daysPerWeek];
}

public void selectDayCell(DateCell dateCell) {
    datePicker.setValue(dayCellDate(dateCell));
    datePicker.hide();
}

如果您使用的是Java 9或更高版本,则可以扩展 DatePickerContent 类并覆盖 selectDayCell(DateCell)方法以不隐藏 DatePicker 在选择单元格之后:

If you're using Java 9 or newer, you can extend DatePickerContent class and override the selectDayCell(DateCell) method to not hide the DatePicker after a cell is selected:

public void selectDayCell(DateCell dateCell) {
    datePicker.setValue(dayCellDate(dateCell));
}

不幸的是,在Java 8中, DatePickerContent 具有程序包专用的构造函数,因此您不能从其扩展。解决方法是,您可以在鼠标单击上添加另一个 EventHandler ,这将在单击单元格后再次显示 DatePicker

Unfortunately, in Java 8, DatePickerContent has a package-private constructor so you can't extend from it. As a workaround, you can add another EventHandler on mouse click that will show the DatePicker again after a cell is clicked:

EventHandler<MouseEvent> mouseClickedEventHandler = clickEvent -> {
    if (clickEvent.getButton() == MouseButton.PRIMARY) {
        datePicker.show();
    }
    clickEvent.consume();
};

在您的单元工厂中:

@Override
public void updateItem(LocalDate item, boolean empty) {
    super.updateItem(item, empty);
    //...
    if (item != null && !empty) {
        //...
        addEventHandler(MouseEvent.MOUSE_CLICKED, mouseClickedEventHandler);
    } else {
        //...
        removeEventHandler(MouseEvent.MOUSE_CLICKED, mouseClickedEventHandler);
    }
}

这篇关于使用DatePicker选择多个日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆