Eng.Fouad Eng.Fouad - 10 months ago 100
Java Question

JavaFX 8 DatePicker features

I just start using the new JavaFX 8 control

. In DatePicker User Experience Documentation, it is stated that it has couple of cool features that I would like to have in my GUI application:

  1. I want to change the format from

  2. I would like to restrict the date that can be selected. The user can only select from today until the same day of next year.

  3. Display Hijri dates besides the original ones:

enter image description here

How to implement these features? The JavaDoc doesn't say much about them.

Answer Source

Here is the full implementation:

import java.net.URL;
import java.time.LocalDate;
import java.time.chrono.HijrahChronology;
import java.time.format.DateTimeFormatter;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.util.Callback;
import javafx.util.StringConverter;

 * @author Fouad
public class FXMLDocumentController implements Initializable
    private DatePicker dpDate;

    public void initialize(URL url, ResourceBundle rb)

        Callback<DatePicker, DateCell> dayCellFactory = dp -> new DateCell()
            public void updateItem(LocalDate item, boolean empty)
                super.updateItem(item, empty);

                if(item.isBefore(LocalDate.now()) || item.isAfter(LocalDate.now().plusYears(1)))
                    setStyle("-fx-background-color: #ffc0cb;");
                    Platform.runLater(() -> setDisable(true));

                    /* When Hijri Dates are shown, setDisable() doesn't work. Here is a workaround */
                    //addEventFilter(MouseEvent.MOUSE_CLICKED, e -> e.consume());

        StringConverter converter = new StringConverter<LocalDate>()
            final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

            public String toString(LocalDate date)
                if(date != null) return dateFormatter.format(date);
                else return "";

            public LocalDate fromString(String string)
                if(string != null && !string.isEmpty())
                    LocalDate date = LocalDate.parse(string, dateFormatter);

                    if(date.isBefore(LocalDate.now()) || date.isAfter(LocalDate.now().plusYears(1)))
                        return dpDate.getValue();
                    else return date;
                else return null;