まともなカレンダー表示〜スケジュール管理ソフトをS!アプリで作ってみよう(その7)

前回で表示月の移動が出来るようになったが、全ての月が31日まで表示されてしまう。今回は、

  • 曜日のカラムヘッダを表示する。
  • 月の末日を正しく表示する。
  • 日付の欄に罫線をつける。
ようにする。

プログラムの修正


CalCanvasクラスを以下のように修正する。


package com.ettem.scheduler;

import java.util.Calendar;

import javax.microedition.lcdui.*;

public class CalCanvas extends Canvas {
private Calendar now;
private Calendar dateToDisplay;

public CalCanvas() {
now = Calendar.getInstance();
dateToDisplay = Calendar.getInstance();
dateToDisplay.setTime(now.getTime());
}

protected void paint(Graphics graphics) {
Calendar firstInMonth; // その月の最初の日
Calendar lastInMonth; // その月の最後の日

// 描画前に白で画面をクリアする。
graphics.setColor(0xFFFFFF);
graphics.fillRect(0, 0, getWidth(), getHeight());

// その月の最初の日を求める
firstInMonth = Calendar.getInstance();
firstInMonth.setTime(dateToDisplay.getTime());
firstInMonth.set(Calendar.DAY_OF_MONTH, 1);

// その月の最後の日を求める
lastInMonth = Calendar.getInstance();
lastInMonth.setTime(dateToDisplay.getTime());
lastInMonth.set(Calendar.MONTH, lastInMonth.get(Calendar.MONTH) + 1);
lastInMonth.getTime(); // getTimeを呼び出さないと、次の処理が上手く行かない。
// setTimeの処理は遅延され、纏めて評価されるようだ。
lastInMonth.set(Calendar.DAY_OF_MONTH, 0);

// 色を黒に戻す。
graphics.setColor(0x000000);
// フォントの設定
Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
Font.SIZE_SMALL);
graphics.setFont(font);

/*
* 曜日のカラムを作成
*/
int dayOfWeekHeight = font.getHeight();
int dayOfWeekWidth = getWidth() / 8;
int dayOfWeekStringOffset = dayOfWeekWidth / 2;
String[] dayOfWeek = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};

for (int i = 0; i < 7; i++) {
graphics.drawString(dayOfWeek[i],
(i + 1) * dayOfWeekWidth + dayOfWeekStringOffset, 0,
Graphics.TOP | Graphics.HCENTER);
}

/*
* 日付欄を作成
*/
int cellWidth = getWidth() / 8;
int cellHeight = (font.getHeight() * 5) / 2;
int dateStringOffset = 2;

// 線を描画
drawLine:
for (int i = 0, x = 0, y = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (i >= 5 && j >= 2) {
break drawLine;
}

x = (j + 1) * cellWidth;
y = i * cellHeight + dayOfWeekHeight;
graphics.drawRect(x, y, cellWidth, cellHeight);
}
}

// 日付を描画
for (int i = 1, x = 0, y = dayOfWeekHeight,
tmpDayOfWeek = firstInMonth.get(Calendar.DAY_OF_WEEK);
i <= lastInMonth.get(Calendar.DAY_OF_MONTH);
i++, tmpDayOfWeek++) {

if (tmpDayOfWeek > 7) {
tmpDayOfWeek = 1;
y += cellHeight;
}

x = tmpDayOfWeek * cellWidth;
graphics.drawString(String.valueOf(i),
x + dateStringOffset, y + dateStringOffset,
Graphics.TOP|Graphics.LEFT);
}
}

protected void keyPressed(int keyCode) {
Calendar dateTmp = Calendar.getInstance();

switch (keyCode) {

// "*"キーが押されたら、1ヶ月前に戻る。
case KEY_STAR:
dateTmp.setTime(dateToDisplay.getTime());
dateTmp.set(Calendar.MONTH,
dateToDisplay.get(Calendar.MONTH) - 1);
dateTmp.getTime();
if (dateTmp.get(Calendar.MONTH) ==
dateToDisplay.get(Calendar.MONTH)) {
dateTmp.set(Calendar.DAY_OF_MONTH, 0);
}
break;

// "#"キーが押されたら、1ヶ月先に進む。
case KEY_POUND:
dateTmp.setTime(dateToDisplay.getTime());
dateTmp.set(Calendar.MONTH,
dateToDisplay.get(Calendar.MONTH) + 1);
if (dateTmp.get(Calendar.MONTH) >
dateToDisplay.get(Calendar.MONTH) + 1) {
dateTmp.set(Calendar.DAY_OF_MONTH, 0);
}
break;
}

dateToDisplay = dateTmp;
repaint();
}
}


以上でまともなカレンダーが表示されるようになった。まだ、日曜日や祝日が黒色なので違和感があるが、色使いはまだまだ先で修正するつもり。