Dates are one of the most fundamental data types, so any language or database provides support for them, either built in or as a class library. Java is no exception; the Java API provides support for representing, computing, comparing, displaying, and parsing dates in a portable, cross-platform and language-independent way. In this article I present a custom control for Swing that allows you to visually pick a date instead of typing it. This way you can avoid invalid dates altogether and offer the user a visual clue as a bonus.
Dates and Java
Java represents dates and times using the class java.util.Date and its subclasses. Despite its name, the Date class has no notion of dates (day, month, year, etc.) in the usual sense. Technically, it is just a point in time, represented as the number of milliseconds elapsed since Jan. 1, 1970, 00:00:00 GMT. Although the class Date has several methods to deal with dates, they were all deprecated.
In order to deal with dates in a portable way, JDK 1.1 introduced the abstract class java.util.Calendar. Concrete subclasses of Calendar convert a point in time into a meaningful date according to a calendar system. This is because different calendar systems employ different rules to compute dates (e.g. Gregorian calendar, Julian calendar, lunar calendar).
The Java API already provides the class java.util.GregorianCalendar to deal with dates according to the Gregorian calendar system, the one in use today.
Finally, the class java.text.DateFormat is an abstraction for formatting and parsing dates in a language-independent manner, following the rules and conventions of a given language/locale. Concrete subclasses of DateFormat performs the actual work. For example, the class java.text.SimpleDateFormat allows you to parse/format a date/time according to a given pattern.
Together, these three base classes (Date, Calendar, and DateFormat) provide a powerful and flexible framework to deal with dates. Although it may look confusing at first, once you understand it you’ll see that this organization makes sense and that there’s a logical reasoning behind it (check the JDK API documentation, which provides more extensive documentation and examples).
Custom date control
Although Java provides everything you need to work with dates, dealing with three different classes is a bit cumbersome—not to mention their API. Sometimes you need to call a lot of methods and employ several objects to carry on a simple task.
Besides that, Swing does not provide a component for entering dates. Of course, it’s not difficult to use a standard control, like a text box, to do that. However, dates are so common in applications that it‘s not unusual to write similar code over and over, across projects, to input, parse, and check dates.
For this reason I created a simple custom control you can use to enter a date. Basically, it’s just a standard button that displays a date (see Figure A).
|Custom date control|
When clicked, a calendar dialog pops up and allows you to select a new date (see Figure B). Clicking on the OK button updates the button's date.
|Calendar dialog popup|
This simplifies the application's logic because the user can't enter an invalid date. And since the dialog looks like a calendar, it’s easy to figure out which day of the week a date corresponds to, which is important in certain applications.
The custom button control is represented by the class DateButton (Listing A). Using it is straightforward—just instantiate a DateButton object and add it to a container, the same way you do with a standard control.
The button's date is represented as a Date object, implemented as a bound property named "date." That means you can set and get it, as well as register a PropertyChangeListener to be notified when the date changes. Table A shows DateButton's API, and Listing B is a simple example that shows how to use it.
The calendar dialog
Besides the custom DateButton control, I also created a custom dialog, CalendarChooser (see Listing C), that allows you to pick a date selecting a month and year from a list, and the day from a calendar (see Figure B). Although it is automatically displayed by the DateButton control, you can also use it on your own. Just create an instance of the CalendarChooser class and call one of its select methods (see Table B for the complete API).
The DateChooser class is a bit complex. I had to create a new control for the monthly calendar since none of the standard controls had the features I wanted. On the other hand, it’s a good example of how easy it is to create a new control, complete with mouse and keyboard interaction.
Notice that the years displayed in the year selection list box are predetermined by the constants FIRST_YEAR and LAST_YEAR. Likewise, other constants determine colors and other visual aspects of the dialog. With some effort, it’s not difficult to change them to properties you can change on the fly.
Also, it’s important to keep in mind that the DateChooser class and DateButton are customized for the English language (months and days of the weeks) and U.S. date format. These are also easy to change since they are all defined through constants. If you need to, it’s also possible to make it totally language independent.
Download the code covered in this article
Put it to good use
Java provides great support for dates. Although it doesn’t provide direct support for entering dates in interactive applications, it’s not difficult to create custom controls that are generic enough to reuse between applications.