万年历设计报告.docx
《万年历设计报告.docx》由会员分享,可在线阅读,更多相关《万年历设计报告.docx(15页珍藏版)》请在冰点文库上搜索。
万年历设计报告
陕西师范大学远程教育学院
题目:
java万年历设计
学习中心:
陕西省咸阳教育科技培训学院
学号:
层次:
高中起点专科
姓名:
张江
目录
一、设计分析1
1、需求分析1
2、功能设计1
3、概要设计1
3.1程序设计思路1
3.2程序运行界面2
二、程序结构3
三、各模块的功能及程序说明4
1、初始化组件4
2、初始化数据4
3、绘制程序界面5
四、操作方法14
五、试验结果14
六、设计体会16
一、设计分析
1、需求分析
本程序的要求为:
1.使用图形用户界面;2.实现日期与星期的查询。
2、功能设计
本程序要构建的万年历程序,其功能有以下几个方面:
(1)通过网页形式运行,实现图形界面。
(2)能以月历形式显示日期与星期。
(3)支持用户自己输入年份,并提供月份的下拉形式菜单来选择月份。
(4)通过点击“更新”来刷新日历。
3、概要设计
3.1程序设计思路
1、总天数的算法:
首先用if语句判断定义年到输入年之间每一年是否为闰年,是闰年,该年的总天数为366,否则,为365。
然后判断输入的年是否为定义年,若是,令总天数S=1,否则,用累加法计算出定义年到输入年之间的总天数,再把输入年的一月到要输出的月份之间的天数累加起来,若该月是闰年中的月份并且该月还大于二月,再使总天数加1,否则,不加,既算出从定义年一月一日到输出年的该月一日的总天数。
2、输出月份第一天为星期几的算法:
使总天数除以7取余加2得几既为星期几,若是7,则为星期日。
3、算出输出月份第一天为星期几的算法:
算出输出月份第一天为星期几后,把该日期以前的位置用空格补上,并总该日起一次输出天数直到月底,该月中的天数加上该月一日为星期几的数字再除以7得0换行,即可完整的输出该月的日历。
4、如果年份小于1582年则程序不予判断。
3.2程序运行界面
二、程序结构
流程图:
三、各模块的功能及程序说明
1、初始化组件
importjava.applet.Applet;
importjava.awt.*;
importjava.util.*;
2、初始化数据
publicclassCalendarAppletextendsApplet{
staticfinalintTOP=70;//顶端距离
staticfinalintCELLWIDTH=50,CELLHEIGHT=30;//单元格尺寸
staticfinalintMARGIN=3;//边界距离
staticfinalintFEBRUARY=1;
TextFieldtfYear=newTextField("2004",5);//显示年份的文本域
ChoicemonthChoice=newChoice();//月份选择下拉框
ButtonbtUpdate=newButton("更新");//更新按钮
GregorianCalendarcalendar=newGregorianCalendar();//日历对象
FontsmallFont=newFont("TimesRoman",Font.PLAIN,15);//显示小字体
FontbigFont=newFont("TimesRoman",Font.BOLD,50);//显示大字体
Stringdays[]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
Stringmonths[]={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
intdaysInMonth[]={31,28,31,30,31,30,31,31,30,31,30,31};//每个月的天数
intsearchMonth,searchYear;//查询的年份及月份
3、绘制程序界面
publicvoidinit(){
setBackground(Color.white);//设置背景颜色
searchMonth=calendar.get(Calendar.MONTH);//得到系统年份
searchYear=calendar.get(Calendar.YEAR);//得到系统月份
add(newLabel("年:
"));//增加组件到Applet
tfYear.setText(String.valueOf(searchYear));//设置文本域文字
add(tfYear);
add(newLabel("月:
"));
monthChoice.setFont(smallFont);//设置月份选择下拉框的显示字体
for(inti=0;i<12;i++){
monthChoice.addItem(months[i]);//增加下拉框选项
}
monthChoice.select(searchMonth);//设置下拉框当前选择项
add(monthChoice);
add(btUpdate);
intcomponentCount=this.getComponentCount();//得到Applet中的组件数量
for(inti=0;igetComponent(i).setFont(smallFont);//设置所有组件的显示字体
}
}
四、操作方法
1、出提示语句,并接受用户输入的年、月。
2、用户输入的年,先判断是否是闰年。
3、户输入的月来判断月的天数。
4、环计算用户输入的年份距1900年1月1日的总天数。
5、环计算用户输入的月份距输入的年份的1月1日共有多少天。
6、D与E的天数,得到总天数。
7、天数来计算输入月的第一天的星期数。
8、G的值,格式化输出这个月的日历!
五、试验结果
图2在年份输入框内输入1582后点击更新后的情况
图3月份下拉列表框
图4选择月份后的情况
图5点击更新按钮后显示的结果
六、设计体会
通过这次课程设计,我明白了编写程序,不仅要求对课本知识有较深刻的了解,同时要求程序设计者有较强的思维和动手能力。
还要熟悉常用的编程技巧和编程思想,不能只关心程序的运行结果,更要注重程序代码的结构,编程者更要有严谨地态度。
还有通过设计过程中大量地查阅网络文章,对一些关键知识点逐个地了解并解决相关问题。
所以网络这个强大的工具,确实是我们学习之中可以借助的一个很好的帮手。
网络是我们学习的最好的老师之一。
有问题,问网络,是一个很好的习惯。
源代码
importjava.applet.Applet;
importjava.awt.*;
importjava.util.*;
publicclassCalendarAppletextendsApplet{
staticfinalintTOP=70;//顶端距离
staticfinalintCELLWIDTH=50,CELLHEIGHT=30;//单元格尺寸
staticfinalintMARGIN=3;//边界距离
staticfinalintFEBRUARY=1;
TextFieldtfYear=newTextField("2004",5);//显示年份的文本域
ChoicemonthChoice=newChoice();//月份选择下拉框
ButtonbtUpdate=newButton("更新");//更新按钮
GregorianCalendarcalendar=newGregorianCalendar();//日历对象
FontsmallFont=newFont("TimesRoman",Font.PLAIN,15);//显示小字体
FontbigFont=newFont("TimesRoman",Font.BOLD,50);//显示大字体
Stringdays[]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
Stringmonths[]={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
intdaysInMonth[]={31,28,31,30,31,30,31,31,30,31,30,31};//每个月的天数
intsearchMonth,searchYear;//查询的年份及月份
publicvoidinit(){
setBackground(Color.white);//设置背景颜色
searchMonth=calendar.get(Calendar.MONTH);//得到系统年份
searchYear=calendar.get(Calendar.YEAR);//得到系统月份
add(newLabel("年:
"));//增加组件到Applet
tfYear.setText(String.valueOf(searchYear));//设置文本域文字
add(tfYear);
add(newLabel("月:
"));
monthChoice.setFont(smallFont);//设置月份选择下拉框的显示字体
for(inti=0;i<12;i++){
monthChoice.addItem(months[i]);//增加下拉框选项
}
monthChoice.select(searchMonth);//设置下拉框当前选择项
add(monthChoice);
add(btUpdate);
intcomponentCount=this.getComponentCount();//得到Applet中的组件数量
for(inti=0;igetComponent(i).setFont(smallFont);//设置所有组件的显示字体
}
}
publicvoidpaint(Graphicsg){
FontMetricsfontMetric;//显示字体的FontMetrics对象
intfontAscent;
intdayPos;
inttotalWidth,totalHeight;//总的宽度,高度
intnumRows;//行数
intxNum,yNum;//水平和垂直方向单元格数量
intnumDays;
StringdayStr;//显示天数字符串
intmargin;
g.setColor(Color.lightGray);//设置当前颜色
g.setFont(bigFont);//设置当前使用字体
g.drawString(searchYear+"年",60,TOP+70);//绘制字符串
g.drawString((searchMonth+1)+"月",200,TOP+130);
g.setColor(Color.black);
g.setFont(smallFont);
fontMetric=g.getFontMetrics();//获取变量初值
fontAscent=fontMetric.getAscent();
dayPos=TOP+fontAscent/2;
totalWidth=7*CELLWIDTH;//得到总的表格宽度
for(inti=0;i<7;i++){
g.drawString(days[i],(CELLWIDTH-fontMetric.stringWidth(days[i]))/2+i*CELLWIDTH,dayPos-20);//绘制表格标题栏
}
numRows=getNumberRows(searchYear,searchMonth);//计算需要的行的数量
totalHeight=numRows*CELLHEIGHT;//得到总的表格高度
for(inti=0;i<=totalWidth;i+=CELLWIDTH){
g.drawLine(i,TOP,i,TOP+totalHeight);//绘制表格线
}
for(inti=0,j=TOP;i<=numRows;i++,j+=CELLHEIGHT){
g.drawLine(0,j,totalWidth,j);//绘制表格线
}
xNum=(getFirstDayOfMonth(searchYear,searchMonth)+1)*CELLWIDTH-MARGIN;
yNum=TOP+MARGIN+fontAscent;
numDays=daysInMonth[searchMonth]+((calendar.isLeapYear(searchYear)&&(searchMonth==FEBRUARY))?
1:
0);
for(intday=1;day<=numDays;day++){
dayStr=Integer.toString(day);
g.drawString(dayStr,xNum-fontMetric.stringWidth(dayStr),yNum);//绘制字符串
xNum+=CELLWIDTH;
if(xNum>totalWidth){
xNum=CELLWIDTH-MARGIN;
yNum+=CELLHEIGHT;
}
}
}
publicbooleanaction(Evente,Objecto){
intsearchYearInt;
if(e.target==btUpdate){
searchMonth=monthChoice.getSelectedIndex();//得到查询月份
searchYearInt=Integer.parseInt(tfYear.getText(),10);//得到查询年份
if(searchYearInt>1581){
searchYear=searchYearInt;
}
repaint();//重绘屏幕
returntrue;
}
returnfalse;
}
privateintgetNumberRows(intyear,intmonth){//得到行数量
intfirstDay;
intnumCells;
if(year<1582){//年份小于1582年,则返回-1
return(-1);
}
if((month<0)||(month>11)){
return(-1);
}
firstDay=getFirstDayOfMonth(year,month);//计算月份的第一天
if((month==FEBRUARY)&&(firstDay==0)&&!
calendar.isLeapYear(year)){
return4;
}
numCells=firstDay+daysInMonth[month];
if((month==FEBRUARY)&&(calendar.isLeapYear(year))){
numCells++;
}
return((numCells<=35)?
5:
6);//返回行数
}
privateintgetFirstDayOfMonth(intyear,intmonth){//得到每月的第一天
intfirstDay;
inti;
if(year<1582){//年份小于1582年,返回-1
return(-1);
}
if((month<0)||(month>11)){//月份数错误,返回-1
return(-1);
}
firstDay=getFirstDayOfYear(year);//得到每年的第一天
for(i=0;ifirstDay+=daysInMonth[i];//计算每月的第一天
}
if((month>FEBRUARY)&&calendar.isLeapYear(year)){
firstDay++;
}
return(firstDay%7);
}
privateintgetFirstDayOfYear(intyear){//计算每年的第一天
intleapYears;
inthundreds;
intfourHundreds;
intfirst;
if(year<1582){//如果年份小于1582年
return(-1);//返回-1
}
leapYears=(year-1581)/4;
hundreds=(year-1501)/100;
leapYears-=hundreds;
fourHundreds=(year-1201)/400;
leapYears+=fourHundreds;
first=5+(year-1582)+leapYears%7;//得到每年第一天
returnfirst;
}
}