As JavaFX 2.2 doesn’t contain a Calendar control we would have to create our own to provide a convenient way to enter a date. Fortunately, Christian Schudt has created a very nice DatePicker that we can use:

I modified Christian Schudt’s DatePicker class a little with a few additional lines at the end of the constructor. One change is to let the DatePicker grow horizontally with its parent and the other change passes the style sheet to the popup.
You can download a jar with my modified version and the stylesheet that goes with it. Harshad RJ has created a GitHub repository to host it:
- Download JavaFX Date Picker Release on GitHub.
- Download DatePicker.css
Integrating the Date Picker with AddressApp
I’ll show how you can use the DatePicker by integrating it with our AddressApp example. You can download the full AddressApp example from the AddressApp Tutorial Part 7.
Add the Library and CSS
Download and add the javafx-datepicker-x-x-x.jar file from above to the lib folder. Add it to the classpath with right-click | Build Path | Add to Build Path.
Add the DatePicker.css file to the ch.makery.address.view package.
Prepare the View for the DatePicker
In our PersonEditDialog we have a simple text field for the Date. This is not very convenient and we’d like to replace this with the new DatePicker.
First, delete the birthday text field from PersonEditDialog.fxml (using SceneBuilder).
We won’t be able to add the custom DatePicker directly in SceneBuilder (at least not with SceneBuilder 1.1). We’ll need to add it manually in the Java code. Delete the birthdayField from the PersonEditDialogController and add the following fields instead:
PersonEditDialogController.java
@FXML private GridPane gridPane; private DatePicker birthdayDatePicker;
Now, open the PersonEditDialog.fxml in SceneBuilder. Select the GridPane and choose gridPane as fx:id.
Initialize the DatePicker
Create the DatePicker in the initialize() method as follows:
@FXML
private void initialize() {
// Initialize the DatePicker for birthday
birthdayDatePicker = new DatePicker(Locale.ENGLISH);
birthdayDatePicker.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
birthdayDatePicker.getCalendarView().todayButtonTextProperty().set("Today");
birthdayDatePicker.getCalendarView().setShowWeeks(false);
birthdayDatePicker.getStylesheets().add("ch/makery/address/view/DatePicker.css");
// Add DatePicker to grid
gridPane.add(birthdayDatePicker, 1, 5);
}
Some Further Adjustments
Change in setPerson(...):
PersonEditDialogController.java
public void setPerson(Person person) {
this.person = person;
firstNameField.setText(person.getFirstName());
lastNameField.setText(person.getLastName());
streetField.setText(person.getStreet());
postalCodeField.setText(Integer.toString(person.getPostalCode()));
cityField.setText(person.getCity());
if (person.getBirthday() != null) {
birthdayDatePicker.setSelectedDate(person.getBirthday().getTime());
} else {
birthdayDatePicker.setSelectedDate(null);
}
}
Change in handleOk():
@FXML
private void handleOk() {
if (isInputValid()) {
person.setFirstName(firstNameField.getText());
person.setLastName(lastNameField.getText());
person.setStreet(streetField.getText());
person.setPostalCode(Integer.parseInt(postalCodeField.getText()));
person.setCity(cityField.getText());
Calendar c = Calendar.getInstance();
c.setTime(birthdayDatePicker.getSelectedDate());
person.setBirthday(c);
okClicked = true;
dialogStage.close();
}
}
Change in isInputValid():
private boolean isInputValid() {
String errorMessage = "";
if (firstNameField.getText() == null || firstNameField.getText().length() == 0) {
errorMessage += "No valid first name!\n";
}
if (lastNameField.getText() == null || lastNameField.getText().length() == 0) {
errorMessage += "No valid last name!\n";
}
if (streetField.getText() == null || streetField.getText().length() == 0) {
errorMessage += "No valid street!\n";
}
if (postalCodeField.getText() == null || postalCodeField.getText().length() == 0) {
errorMessage += "No valid postal code!\n";
} else {
// try to parse the postal code into an int
try {
Integer.parseInt(postalCodeField.getText());
} catch (NumberFormatException e) {
errorMessage += "No valid postal code (must be an integer)!\n";
}
}
if (cityField.getText() == null || cityField.getText().length() == 0) {
errorMessage += "No valid city!\n";
}
////////////////////////////////////////
// CHANGE STARTS HERE
////////////////////////////////////////
if (birthdayDatePicker.getSelectedDate() == null) {
errorMessage += "No valid birthday!\n";
} else {
if (birthdayDatePicker.invalidProperty().get()) {
errorMessage += "No valid birthday. Use the format yyyy-mm-dd!\n";
}
}
////////////////////////////////////////
// CHANGE ENDS HERE
////////////////////////////////////////
if (errorMessage.length() == 0) {
return true;
} else {
// Show the error message
Dialogs.showErrorDialog(dialogStage, errorMessage,
"Please correct invalid fields", "Invalid Fields");
return false;
}
}
Tweaking the DatePicker
For further details about how to tweak the DatePicker see JavaFX Calendar Control on Christian Schudt’s Blog.