Select multiple dates with DatePicker

前端 未结 2 588
孤城傲影
孤城傲影 2021-01-14 02:39

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. Proble

2条回答
  •  再見小時候
    2021-01-14 02:52

    Using M. S. answer, I was able to create this for JavaFX8 :

    public class MultiDatePicker
    {
    
        private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        private final ObservableSet selectedDates;
        private final DatePicker datePicker;
    
        public MultiDatePicker()
        {
            this.selectedDates = FXCollections.observableSet(new TreeSet<>());
            this.datePicker = new DatePicker();
            setUpDatePicker();
        }
    
    
        public ObservableSet getSelectedDates()
        {
            return this.selectedDates;
        }
    
        public DatePicker getDatePicker()
        {
            return this.datePicker;
        }
    
        private void setUpDatePicker()
        {
            this.datePicker.setConverter(new StringConverter()
            {
                @Override
                public String toString(LocalDate date)
                {
                    return (date == null) ? "" : DATE_FORMAT.format(date);
                }
    
                @Override
                public LocalDate fromString(String string)
                {
                    return ((string == null) || string.isEmpty()) ? null : LocalDate.parse(string, DATE_FORMAT);
                }
            });
    
            EventHandler mouseClickedEventHandler = (MouseEvent clickEvent) ->
            {
                if (clickEvent.getButton() == MouseButton.PRIMARY)
                {
                    if (!this.selectedDates.contains(this.datePicker.getValue()))
                    {
                        this.selectedDates.add(datePicker.getValue());
    
                    } else
                    {
                        this.selectedDates.remove(this.datePicker.getValue());
    
                        this.datePicker.setValue(getClosestDateInTree(new TreeSet<>(this.selectedDates), this.datePicker.getValue()));
    
                    }
    
                }
                this.datePicker.show();
                clickEvent.consume();
            };
    
            this.datePicker.setDayCellFactory((DatePicker param) -> new DateCell()
            {
                @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);
                    }
    
                    if (selectedDates.contains(item))
                    {
    
                        setStyle("-fx-background-color: rgba(3, 169, 244, 0.7);");
    
                    } else
                    {
                        setStyle(null);
    
                    }
                }
            });
    
        }
    
        private static LocalDate getClosestDateInTree(TreeSet dates, LocalDate date)
        {
            Long lower = null;
            Long higher = null;
    
            if (dates.isEmpty())
            {
                return null;
            }
    
            if (dates.size() == 1)
            {
                return dates.first();
            }
    
            if (dates.lower(date) != null)
            {
                lower = Math.abs(DAYS.between(date, dates.lower(date)));
            }
            if (dates.higher(date) != null)
            {
                higher = Math.abs(DAYS.between(date, dates.higher(date)));
            }
    
            if (lower == null)
            {
                return dates.higher(date);
            } else if (higher == null)
            {
                return dates.lower(date);
            } else if (lower <= higher)
            {
                return dates.lower(date);
            } else if (lower > higher)
            {
                return dates.higher(date);
            } else
            {
                return null;
            }
        }
    
    }
    

提交回复
热议问题