JDateEditComponent is the base class for all date editing components and inherits from JDateComponent. The inherited features are explained in the respective tutorial section. A date edit component provides the following features for all of its descendants:
A date model to manage the edited date.
Custom date formats to allow the editing of any date aspect.
Built-in structured date editor that forces users to type correct dates. Users can type in a new value or use the up and down arrows to increment or decrement it.
Free text entries that are converted to dates using a custom date parser. This makes it possible to plug special parsers that can convert shortcut strings like 'today' to an appropriate date.
The editor can be used to enter dates in any date format. For instance if the editor is configured to use the "MM/dd/yyyy" format, moving the cursor at the beginning and typing 01022004 would set the date to "01/02/2004".
Also, months can be entered by their names if the date format allows it. For instance if you are using the "MMM/dd/yyyy" format, then the above date is displayed as "Jan/02/2004". If you want to edit the month and change it to February then you can either type "02" (the numeric equivalent of the month) in the month field or "February" (its actual name). Instead of typing the entire name, you could just type "F", "Fe" or "Feb" and the component knows you mean February.
This section uses the application shown below to explore all these capabilities. Although the demo application contains a customized instance of JDateField, the capabilities discussed in this section are inherited by all of JDateEditComponent's subclasses.
Try this:
Run DateEditComponentDemo using Java Web Start or consult the source code for yourself.
Use different date formats (including custom ones) and locales.
Click on the Free Text Editing check box to enable free text editing. The component will be configured with a date parser that converts the "today" text to the today date. Then type "today" and press ENTER to tell the component to select the today date.
Click on the Selection Model combo box and choose "No Weekends". Then try typing a weekend date. It cannot be selected as it is not allowed by the date selection model.
Use various combinations of autoValidation, autoRestore and beepOnError to see what happens at validation time.
Click on the Null Date Text text field to change the text used to represent null dates and press Apply. Then click in the date field, erase the whole date and press ENTER. The component will display the null date using the specified null date text.
The date edit component in the DateEditComponentDemo can be configured to edit a date according to a predefined or custom date format.
The predefined formats are DateFormat.SHORT, DateFormat.MEDIUM, DateFormat.LONG or DateFormat.FULL and together with the locale they determine how dates are displayed by the component. The default value for the format is DateFormat.DEFAULT (= DateFormat.MEDIUM).
The following code changes the date format to DateFormat.FULL:
editComponent.setDateFormat(DateFormat.FULL);
A custom format can be used whenever the predefined formats are not enough. Such custom formats are described using the Date Format Pattern Syntax. For instance if you want to format dates like "12:08 PM" you must use "h:mm a" as custom date pattern.
The following code changes the date format to "h:mm a":
editComponent.setDateFormat("h:mm a");As with any other Swing component, date edit components use a model to represent the edited date. A date edit component's model is an instance of a class that implements the DateModel interface. It provides the following services:
Manages the edited date and its fields
Notifies listeners about date and date field changes
The com.standbysoft.component.date package provides an DefaultDateModel that is the model used by default in all date edit components.
For different reasons, like activating a save action, you might want to know when a date field has changed.
The DateEditComponentDemo program uses a date listener to display a message when a date field changes. The following line of code registers an instance of MyDateListener as a listener on the date edit component's date model:
editComponent.addDateListener(new MyDateListener());
Here's the implementation of MyDateListener:
class MyDateListener implements DateListener {
public void dateFieldChanged(DateEvent evt) {
messageArea.append(evt + "\n");
}
public void dateChanged(DateEvent evt) {
messageArea.append(evt + "\n");
}
}The date edit components can be configured to have a very flexible input. Once the free text feature is enabled, a date parser can be registered to transform shortcut strings into dates. For instance, one could create a parser that translates strings like 'today', 'yesterday', '3 days ago' or 'next month' to appropriate dates.
A date parser is an instance of a class that implements DateParser interface. The com.standbysoft.component.date package provides a DefaultDateParser that is the date parser used by default in all date edit components. The default parser tries to build a date from specified text only if it matches the specified date pattern. For advanced parsers, you would have to do your own implementation.
The DateEditComponentDemo program uses a custom date parser that extends a default date parser to convert the "today" string to the today date. The following line of code registers an instance of MyDateParser as a date parser for date edit component:
editComponent.setDateParser(new MyDateParser());
Here's the implementation of MyDateParser:
class MyDateParser extends DefaultDateParser {
private Calendar cal = Calendar.getInstance();
public MyDateParser() {
cal.clear(Calendar.HOUR);
cal.clear(Calendar.HOUR_OF_DAY);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
}
public Date parse(String text, Date reference, DateFormat format) throws DateParserException {
if (text.toLowerCase().equals("today")) {
return cal.getTime();
} else {
return super.parse(text, reference, format);
}
}
}The validation of a date is one of the most important issues when it comes to typing or selecting one. The date selection model contains all the rules that indicate semantically valid dates while the built-in date editor forces the users to enter syntactically valid dates.
A date edit component can detect a semantically invalid date only when the editing finishes. This happens when the user requests it, hits ENTER, or when the component loses focus. Validation on lost focus can be configured using the autoValidation property.
The following line of code disables automatic validation:
editComponent.setAutoValidation(false);
You can also request a date edit to be validated from the API by calling the commitEdit method. To detect whether the current edited date is valid or not use the isEditValid method.
Because the entered date might not be semantically valid, some actions could be triggered at validation time. Such actions are automatic restoring of the last valid date and sounding a beep. In addition to this configurable actions, you could build your own policy for handling invalid edits by overriding the invalidEdit method.
The following code listing disables automatic date restoring and enables beep on error:
editComponent.setAutoRestore(false); editComponent.setBeepOnError(true);
By default, if a user initiates an edit on a JDateEditComponent component with the keyboard, the entered values are inserted where the cursor is positioned. This behavior can be configured using the JDateEditComponent.clearDateOnEdit client property.
If JDateEditComponent.clearDateOnEdit is set on Boolean.TRUE, the date is cleared when the user initiates an edit with the keyboard. But, if the user initiates an edit by clicking in the field with the mouse, the date is NOT cleared and the cursor is placed exactly where the user clicked.
The following example shows how you can enable the "clear on edit" behavior:
editComponent.putClientProperty("JDateEditComponent.clearDateOnEdit", Boolean.TRUE);The How to Configure UI Delegates API section explains why we use client properties to configure the components.