Display Dates in a Custom Calendar #4
Chapter 1, Basic JComponents
|
21
HACK
This loads the images in the constructor and sets up date formatters for the
month, year, and day. Override the
paintComponent( ) method to turn on
anti-aliasing, draw the background, and then draw the month and year for
the current date.
You’ll notice that there is a default date in case the devel-
oper doesn’t set one (always a good practice).
Draw the Days of the Month
The java.util.Calendar object handles all date calculations, so let’s start
there. You’ll need two calendars: one to represent the current date (
today)
and one that you update as you loop through the grid of dates (
cal). Here’s
what that looks like in code:
Calendar today = Calendar.getInstance( );
today.setTime(date);
Calendar cal = Calendar.getInstance( );
cal.setTime(date);
protected SimpleDateFormat year = new SimpleDateFormat("yyyy");
protected SimpleDateFormat day = new SimpleDateFormat("d");
protected Date date = new Date( );
public void setDate(Date date) {
this.date = date;
}
public CalendarHack( ) {
background = new ImageIcon("calendar.png").getImage( );
highlight = new ImageIcon("highlight.png").getImage( );
day_img = new ImageIcon("day.png").getImage( );
this.setPreferredSize(new Dimension(300,280));
}
public void paintComponent(Graphics g) {
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(background,0,0,null);
g.setColor(Color.black);
g.setFont(new Font("SansSerif",Font.PLAIN,18));
g.drawString(month.format(date),34,36);
g.setColor(Color.white);
g.drawString(year.format(date),235,36);
}
}
Example 1-9. A Calendar base component (continued)
22
|
Chapter 1, Basic JComponents
#4 Display Dates in a Custom Calendar
HACK
cal.set(Calendar.DATE,1);
cal.add(Calendar.DATE,-cal.get(Calendar.DAY_OF_WEEK)+1);
for(int week = 0; week < 6; week++) {
for(int d = 0; d < 7; d++) {
Image img = day_img;
Color col = Color.black;
// only draw if it's actually in this month
if(cal.get(Calendar.MONTH) == today.get(Calendar.MONTH)) {
if(cal.equals(today)) {
img = highlight;
col = Color.white;
}
g.drawImage(img,d*30+46,week*29+81,null);
g.drawString(day.format(cal.getTime( )),
d*30+46+4,week*29+81+20);
}
cal.add(Calendar.DATE,+1);
}
}
You’ll notice that both calendars are initialized to date, but then the code
resets
cal’s date to the first of the month and subtracts the current day of the
week. This has the effect of setting
cal to the last Sunday before (or equal to)
the real current date. You have to perform this calculation because you need
to start drawing in the upper-lefthand corner of the calendar grid, which will
almost always include a few days from the previous month. Once all of that
is done, the code loops through each week and draws each day.
Now, here’s the tricky part:
cal goes back seven days, which is almost cer-
tainly going to run back into the previous month. Because the calendar is
month-based, those days in the previous month shouldn’t be drawn. That’s
why there is a check to see if
cal’s month is equal to today’s month. If they
are equal, then you can draw the day safely; if not, skip drawing and just
increment the date.
The last thing to check is if the current day in
cal is equal to the real current
date. If it is, you want to use a different color and background image
(
highlight). Finally, the image and day numbers are drawn, with the posi-
tion determined by the current day of the week and week number. You can
adjust the multipliers and offsets (
30, 46, 29, 81) to suit your taste. The
drawString( ) method has a few extra pixels of padding to make the day
number appear more centered in the day image.
And now you have a completely custom calendar, suitable for placement
within the zaniest of interfaces.

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.