J2ME编写Calendar

本文介绍了一个使用Java编写的日历程序,由三个核心文件组成:MyCalendar.java负责展示日历和数字,MyCalendarHeader.java用于显示年月并调整日期,CalendarDemo.java作为程序入口。程序实现了日期选择和调整功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       这个程序主要优3个.java文件组成,

MyCalendar.java  (主要显示Calendar的方格和方格里面的数字,并根据日期确定每个小方格里的数字)

MyCalendarHeader.java (在Calendar的上方显示年和月,并能调整年,月,同时反映到Calendar.java中)

CalendarDemo.java (程序的运行类)

       在编写这个程序的时候,主要遇到了如下几个问题:

  1. 获得系统当前的时间Calendar.getInstance(); 里面最好加上TimeZone.getTimeZone("GMT+8:00"),要不然显示的日期会是错误的,比如系统时间为19号00:04分的时候,用Calendar.getInstance(); 调用返回的系统日期还是18号。

  2. Calendar.MONTH返回的月份是 一月对应0,二月对应1;星期天对应1,星期一对应2,依此类推

 

//////////////MyCalendar.java////////////////////////
package MyCalendar;

import java.util.Calendar;
import java.util.TimeZone;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CustomItem;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemCommandListener;

public class MyCalendar extends CustomItem implements ItemCommandListener {
    
private final static Command CMD_SELECT = new Command("Select", Command.ITEM,1);
    
protected Display display;
    
private int rows = 6;    //定义表格行数
    private int cols = 7;    //定义表格列数
    private int dx   = 20;    //定义表格宽度
    private int dy   = 20;    //定义表格高度
    
    
private int currentX = 0;    //定义当前的行数
    private int currentY = 0;    //定义当前的列数
    
    
private Calendar cal;        //记录当前的日期
    private int curyear, curmonth, curday;        //存储本机的年月日
    
    
private static int[] dayOfMonth = {312831303130
                                         
313130313031}
;    //保存非闰年的每个月的天数
    
    
private String[][] data = new String[rows][cols];    //存储日历表格中的数字
    /*测试数据 
     private String[][] data = {{" 1"," 2"," 3"," 4"," 5"," 6"," 7"},
                    {" 8"," 9","10","11","12","13","14"},
                    {"15","16","17","18","19","20","21"},
                    {"22","23","24","25","26","27","28"},
                    {"29","30","31","  ","  ","  ","  "},
                    {"  ","  ","  ","  ","  ","  ","  "}
            };
    
*/

    
    
public MyCalendar(String title, Display d) {
        
super(title);
        display 
= d;
        
this.setDefaultCommand(CMD_SELECT);
        
this.setItemCommandListener(this);
        
        cal 
= Calendar.getInstance(TimeZone.getTimeZone("GMT+8:00"));
        curyear 
= cal.get(Calendar.YEAR);
        curmonth 
= cal.get(Calendar.MONTH);
        curday 
= cal.get(Calendar.DAY_OF_MONTH);
        setData(curyear, curmonth, curday);
    }


    
protected int getMinContentWidth() {
        
return (cols * dx) + 1;
    }


    
protected int getMinContentHeight() {
        
return (rows * dy) + 1;
    }


    
protected int getPrefContentWidth(int arg0) {
        
return (cols * dx) + 1;
    }


    
protected int getPrefContentHeight(int arg0) {
        
return (rows * dy) + 1;
    }


    
protected void paint(Graphics g, int w, int h) {
        
for (int i = 0; i <= rows; i++{
            g.drawLine(
0, i*dy, cols*dx, i*dy);
        }

        
for (int i = 0; i <= cols; i++{
            g.drawLine(i
*dx, 0, i*dx, rows*dy);
        }

        
int oldColor = g.getColor();    //保存当前颜色
        g.setColor(0x00d0d0d0);
        
//填充灰色方格
        g.fillRect((currentX * dx) + 1, (currentY * dy) + 1, dx - 1, dy - 1);
        g.setColor(oldColor);    
//恢复原来颜色
        
//填写数字
        for (int i = 0; i < rows; i++{
            
for (int j = 0; j < cols; j++{
                
if (data[i][j] != null{
                    
int oldClipX = g.getClipX();
                    
int oldClipY = g.getClipY();
                    
int oldClipWidth = g.getClipWidth();
                    
int oldClipHeight = g.getClipHeight();
                    
//设置裁减区大小,并填写数字
                    
//注意:必须在setClip的地方写数字,要不然就写不上去的
                    g.setClip((j*dx) + 1, (i*dy) + 1, dx - 1, dy - 1);
                    
//g.setColor(0x000000ff);
                    g.drawString(data[i][j], (j*dx) + 5, (i * dy) + 5, Graphics.TOP | Graphics.LEFT);
                    
//恢复画布g的原来信息
                    g.setClip(oldClipX, oldClipY, oldClipWidth, oldClipHeight);
                    
                }

            }

        }

        
        
    }

    
    
protected boolean traverse(int dir,
            
int viewportWidth,
            
int viewportHeight,
            
int[] visRect_inout) {
        
switch (dir) {
            
case Canvas.DOWN:
                
if (currentY < (rows - 1)) {
                    currentY
++;
                    repaint(currentX 
* dx, (currentY - 1* dy, dx, dy);    //把上一次填灰的方块填白
                    repaint(currentX * dx, currentY * dy, dx, dy);            //把当前方块填灰
                    
                }
 else {
                    
return false;
                }

                
break;
            
case Canvas.UP:
                
if (currentY > 0{
                    currentY
--;
                    repaint(currentX 
* dx, (currentY + 1* dy, dx, dy);    //把上一次填灰的方块填白
                    repaint(currentX * dx, currentY * dy, dx, dy);            //把当前方块填灰
                }
 else {
                    
return false;
                }

                
break;
            
case Canvas.LEFT:
                
if (currentX > 0{
                    currentX
--;
                    repaint((currentX 
+ 1* dx, currentY * dy, dx, dy);    //把上一次填灰的方块填白
                    repaint(currentX * dx, currentY * dy, dx, dy);            //把当前方块填灰
                }
 else {
                    
return false;
                }

                
break;
            
case Canvas.RIGHT:
                
if (currentX < (cols - 1)) {
                    currentX
++;
                    repaint((currentX 
- 1* dx, currentY * dy, dx, dy);    //把上一次填灰的方块填白
                    repaint(currentX * dx, currentY * dy, dx, dy);            //把当前方块填灰
                }
 else {
                    
return false;
                }

                
break;
            
        }

        visRect_inout[
0= currentX;
        visRect_inout[
1= currentY;
        visRect_inout[
2= dx;
        visRect_inout[
3= dy;
        
//System.out.println(visRect_inout[0]);
        
//System.out.println(visRect_inout[1]);
        
//System.out.println(visRect_inout[2]);
        
//System.out.println(visRect_inout[3]);
        
        
return true;
    }

    
    
//设置方格中需要显示的数字
    public void setText(String text) {
        data[currentX][currentY] 
= text;
        repaint(currentY 
* dx, currentX * dy, dx, dy);
    }

    
    
protected void setData(int year, int month, int day) {
        
//System.out.println(year + "--"+ month + "--"+ day);
        
//一月对应0,星期天对应1,星期一对应2,依此类推
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, 
1);    //用1是为了获得1号是星期几
        
        

        
int daysofmonth = getDaysOfMonth(year, month);    //获得当前月的天数

        
int whichDay = cal.get(Calendar.DAY_OF_WEEK) - 1;    //获得当前月的第一天是星期几(因为已经设置cal为1号)

        
int number = 1;        //为下面的循环记录天数
        
        data[
0][0= "";
        data[
0][1= "";
        data[
0][2= "";
        data[
0][3= "";
        data[
0][4= "";
        data[
0][5= "";
        data[
0][6= "";
        
        
for (int i = 1; i < rows; i++{
            
for (int j = 0; j < cols; j++{
                
if (j < whichDay && i == 1{
                    data[i][j] 
= "";
                    
continue;
                }

                
if (number <= daysofmonth) {
                    data[i][j] 
= String.valueOf(number);
                    number
++;
                    
continue;
                }

                data[i][j] 
= "";
            }

        }

        
        
//有可能日历五行显示不下,那么最后显示不下的那几天在第一行显示
        for (int i = 0; number <= daysofmonth; i++,number++{
            data[
1][i] = String.valueOf(number);
        }

        
        
//设置当前日期在方格的位置以便填灰色    
        cal.set(Calendar.DAY_OF_MONTH,day);    //由于刚才把当前天设为1号,现在为了显示当前天再设回来
        int daysofweek = cal.get(Calendar.DAY_OF_WEEK);    //记录当前天是一周的第几天
        currentX = daysofweek - 1;
        currentY 
= (day + whichDay) / 7 ;
        
if((day + whichDay) % 7 != 0{        //如果不能整除
            currentY++;
            
if (currentY > 5{
                currentY 
= 1;
            }

        }

            
    }

    
    
private int getDaysOfMonth(int year, int month) {
        
if (month != 1//如果不是2月
            return dayOfMonth[month];
        
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
            
return 29;
        
return 28;
    }


    
public void commandAction(Command c, Item i) {
        
    }


    
public void setSelectedDate(int year, int month, int day) {
    
//    if (day > getDaysOfMonth(year, month)) {
    
//        day = getDaysOfMonth(year, month);
    
//    }
        
//防止在调整月份的时候显示当前天会有问题(比如在8月31号就不能跳到9月31号)
        day = (day>getDaysOfMonth(year, month))?getDaysOfMonth(year, month):day;
        
        setData(year, month, day);
        repaint();
    }

}

////////////////MyCalendarHeader.java//////////////////////////
package MyCalendar;

import java.util.Calendar;
import java.util.TimeZone;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.CustomItem;
import javax.microedition.lcdui.Graphics;

public class MyCalendarHeader extends CustomItem {
    
//确定是选了年还是月
    private final static int SELECT_YEAR = 0;
    
private final static int SELECT_MONTH = 1;
    
private final static int SELECT_NONE = 2;
    
    
private int location = SELECT_NONE;    //开始默认为什么都没有选中
    
    
private Calendar cal;
    
private MyCalendar myCal;
    
    
private int year, month, day;
    
    
public MyCalendarHeader(String title, MyCalendar myCal) {
        
super(title);
        
this.myCal = myCal;
        
        cal 
= Calendar.getInstance(TimeZone.getTimeZone("GMT+8:00"));
        year 
= cal.get(Calendar.YEAR);
        month 
= cal.get(Calendar.MONTH) + 1;
        day 
= cal.get(Calendar.DAY_OF_MONTH);
    }


    
protected int getMinContentWidth() {
        
return 130;
    }


    
protected int getMinContentHeight() {
        
return 40;
    }


    
protected int getPrefContentWidth(int arg0) {
        
return 130;
    }


    
protected int getPrefContentHeight(int arg0) {
        
return 40;
    }


    
protected void paint(Graphics g, int w, int h) {
        
int oldColor = g.getColor();
        
        
if (location == SELECT_YEAR) {
            g.setColor(
0x00d0d0d0);
            g.fillRect(
3026018);
        }
 else if (location == SELECT_MONTH) {
            g.setColor(
0x00d0d0d0);
            g.fillRect(
35225038);
        }

        g.setColor(oldColor);
        
        
//保存裁减区
        int oldClipX = g.getClipX();
        
int oldClipY = g.getClipY();
        
int oldClipWidth = g.getClipWidth();
        
int oldClipHeight = g.getClipHeight();
        
        
//设置裁减区的大小
        g.setClip(30210018);
        g.drawString(
"<<" + String.valueOf(year) + "年>>"312, Graphics.LEFT | Graphics.TOP);
        
        g.setClip(
352210038);
        g.drawString(
"<<" + String.valueOf(month) + "月>>"3522, Graphics.LEFT | Graphics.TOP);
        
//保存原来画布信息
        g.setClip(oldClipX, oldClipY, oldClipWidth, oldClipHeight);
    }


    
protected boolean traverse(int dir,
            
int viewportWidth,
            
int viewportHeight,
            
int[] visRect_inout) {
        
switch (dir) {
            
case Canvas.DOWN:
                
if (location == SELECT_YEAR) {
                    location 
= SELECT_MONTH;
                }
 else if (location == SELECT_MONTH) {
                    location 
= SELECT_NONE;
                    
return false;
                }
 else if (location == SELECT_NONE) {
                    location 
= SELECT_YEAR;
                }

                repaint();
                
break;
            
case Canvas.UP:
                
if (location == SELECT_YEAR) {
                    location 
= SELECT_NONE;
                    
return false;
                }
 else if (location == SELECT_MONTH) {
                    location 
= SELECT_YEAR;
                }
 else if (location == SELECT_NONE) {
                    location 
= SELECT_MONTH;
                }

                repaint();
                
break;
            
case Canvas.LEFT:
                
if (location == SELECT_YEAR) {
                    year
--;
                    repaint();
                    myCal.setSelectedDate(year, month
-1, day);
                }

                
if (location == SELECT_MONTH) {
                    
if (month > 1{
                        month
--;
                    }
 else {
                        month 
= 12;
                    }

                        
                    repaint();
                    myCal.setSelectedDate(year, month
-1, day);
                }

                
break;
            
case Canvas.RIGHT:
                
if (location == SELECT_YEAR) {
                    year
++;
                    repaint();
                    myCal.setSelectedDate(year, month
-1, day);
                }

                
if (location == SELECT_MONTH) {
                    month 
= month % 12 + 1;
                    repaint();
                    myCal.setSelectedDate(year, month
-1, day);
                }

                
break;
        }

        
return true;
    }

}

/////////////////CalendarDemo.java/////////////////////////////
package MyCalendar;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class CalendarDemo extends MIDlet implements CommandListener {
    
private final static Command CMD_EXIT = new Command("Exit", Command.EXIT,1);
    
private Display display;
    
private Form mainForm;
    
    
public CalendarDemo() {
        mainForm 
= new Form("My Calendar");
    }


    
protected void startApp() throws MIDletStateChangeException {
        display 
= Display.getDisplay(this);
        MyCalendar myCal 
= new MyCalendar("", display);
        mainForm.append(
new MyCalendarHeader("", myCal));
        mainForm.append(myCal);
        mainForm.addCommand(CMD_EXIT);
        mainForm.setCommandListener(
this);
        
        display.setCurrent(mainForm);
    }


    
protected void pauseApp() {
        
    }


    
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        
    }


    
public void commandAction(Command c, Displayable d) {
        
if (c == CMD_EXIT) {
            
try {
                destroyApp(
false);
            }
 catch (MIDletStateChangeException e) {
                e.printStackTrace();
            }

            notifyDestroyed();
        }


    }


}

程序运行效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值