Home
of
 In Feb 2000, my Java IDE FrenchRoast won honorable mention in the 2nd JavaWorld CodeMasters series.
About Javazoid
Gervase Gallant Resume
Download
Articles
WordFind
applet
IO,IO...
Wizard...
Oct 2000 Below is a work in progress... a version of Minesweeper.
|
Date Chooser adventures with
java.util.Calendar...
This type of Date selection GUI widget is
an almost classic exercise for user interface developers.
There are several approaches to the development of the
interface, which shed a lot of insight into user
interface design techniques. Perhaps the most intriguing
is a design developed by Alan Cooper,
which featured a rolling Calendar instead of a
month-by-month display.
This Date Chooser is closer to standard, featuring a
single-month display with a "rolling" feature,
i.e., last month, next month, last year, next year.

My main interest in the Date Chooser was not the user
interface, which I've implemented previously in VB and
FoxPro, but instead the Calendar class which provides the
data for the front end.
The history of the Calendar class must be an intriguing
one. If you every use the java.util.Date class, you'll
find the now deprecated String constructor which allowed
you to create a date from a String representation. Many
programmers complain that it is now deprecated, but the
fact is that the code in this constructor is huge,
convoluted and -- frankly -- routinely breaks down. The
problem is, of course, that there are just too many ways
to pass the String parameter and this code simply can't
handle them all.
To deal effectively with Date construction from
applications, you need to use the java.util.Calendar
class, which is owned and copyrighted by IBM's Taligent
Inc. I'll admit that it's a dense design, with its
Factory approach to object creation and a series of field
attributes that allow you to build and manipulate a date.
It takes a while to understand the behaviour of the code,
but it definitely solves a problem and provides great
flexibility in date manipulation.
First of all, don't try to instantiate it. It's abstract.
Instead, you should either instantiate a
GregorianCalendar or call its getInstance() method, which
also provides a new GregorianCalendar. (I think Taligent
was anticipating we would need a JulianCalendar or a
MartianCalendar or something... but these appear not to
have made it to the java.util package just yet).
For starters, the Calendar by default uses today's date.
Or you can set the date with the setTime() method. For
this implementation, I use today's date. From the variety
of Calendar fields, I pull out integers and convert them
to Strings.
//set month
monthLabel.setText(months[cal.get(Calendar.MONTH)] +
" " + cal.get(Calendar.YEAR));
//set to first day
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
1);
//now work the day labels
startPos = cal.get(Calendar.DAY_OF_WEEK);
for (int i = startPos - 1; i < days.length; i++) {
days[i].setText(String.valueOf(cal.get(Calendar.DATE)));
cal.roll(Calendar.DATE, true);
if (cal.get(Calendar.DATE) == 1) {
//clear remaining labels going forward
for (int j = i + 1; j < days.length; j++) {
days[j].setText("");
}
break;
}
}
The above code is about all that is necessary to feed the
display portion for any given month. The Calendar is nice
enough to handle leap years because if the calendar rolls
from 28 to 1 during the month of February, it isn't a
leap year and the display doesn't worry about it.
The roll method of Calendar is truly cool in the context
of Date Chooser, since the same method that tells me to
stop labelling days is the same method I use to move from
year to year or month to month.
The buttons at the bottom of DateChooser are set to move
months or years. The action handler just calls the
DateChooser's roll method and it in turn calls the
Calendar's roll method.
private void roll(String direction)
{
int field;
if (direction.equals(">>"))
calendar.roll(Calendar.YEAR,true);
if (direction.equals(">"))
calendar.roll(Calendar.MONTH,true);
if (direction.equals("<<"))
calendar.roll(Calendar.YEAR,false);
if (direction.equals("<"))
calendar.roll(Calendar.MONTH,false);
caption();
}
When the user clicks on a particular day label, the
DateChooser hides itself and allows the caller to access
the Calendar's date field. The following sets a TextField
on the calling frame.
jff.setText("" +
dc.getCalendar().getTime());
Download source
Any questions, please
contact me ggallant@bigfoot.com .
Copyright (c) Gervase Gallant 1999,2000.
|