使用 DatePicker 选择多个日期 [英] Select multiple dates with 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
时,都会有一个类型 MOUSE_CLICKED
的 EventHandler
添加到其中.当用户单击单元格时,此处理程序将调用 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屋!