java课程设计程序设计报告万年历
XXX学院
学生课程设计(论文)
题目:万年历
学生姓名: XXX 学号:
所在院(系):数学与计算机学院
专业:网络工程
班级: 2012级
指导教师:职称:讲师
2013年12月30日
XXX学院本科学生课程设计任务书
注:任务书由指导教师填写。
课程设计(论文)指导教师成绩评定表
摘要
Java编程语言自诞生十几年来,已经成功地运用在网络计算及移动等各个领域。对于开发者来说,它具有简单、面向对象、健壮、安全、结构中立、可移植和高效能等众多优点。此次我们用JAVA来设计一个万年历程序,该程序以网页形式运行,并且支持图形化界面,能以日历的形式显示日期与星期,用户能自己输入日期,支持查找日期,并且能够更新日期,是一个简单易用的小应用。
关键词JAVA,图形化界面,万年历
1 需求分析
1.1 需求概述
日历是生活中必不可少的物品,传统纸张日历不仅浪费资源而且不易携带,设计这个万年历,以小程序的形式取代传统日历,具有很大的使用性,简单方便。
1.2 需求环境
本课程设计需要的设备为硬件要求和软件配置要求具体要求如下:
1.硬件要求:一台计算机。
2.软件配置:JDK1.6,Eclipse。
1.3 功能描述
本程序要构建的万年历程序,其功能有以下几个方面:
(1)通过网页形式运行,实现图形界面。
(2)能以月历形式显示日期与星期。
(3)支持用户自己输入年份,并提供月份的下拉形式菜单来选择月份。
(4)通过点击“更新”来刷新日历。
2 概要设计
2.1 程序设计思路
1. 总天数的算法:首先用if语句判断定义年到输入年之间每一年是否
为闰年,是闰年,该年的总天数为366,否则,为365。然后判断输入的年是否为定义年,若是,令总天数S=1,否则,用累加法计算出定义年到输入年之间的总天数,再把输入年的一月到要输出的月份之间的天数累加起来,若该月是闰年中的月份并且该月还大于二月,再使总天数加1,否则,不加,既算出从定义年一月一日到输出年的该月一日的总天数。
2. 输出月份第一天为星期几的算法:使总天数除以7取余加2得几既
为星期几,若是7,则为星期日。
3. 算出输出月份第一天为星期几的算法:算出输出月份第一天为星期几
后,把该日期以前的位置用空格补上,并总该日起一次输出天数直到月底,该月中的天数加上该月一日为星期几的数字再除以7得0换行,即可完整的输出该月的日历。
4. 如果年份小于1582年则程序不予判断。
2.2 程序流程图
图2.1 程序流程图
3 详细设计
各模块的功能及程序说明
3.1.初始化组件
import java.applet.Applet;
import java.awt.*;
import java.util.*;
3.2.初始化数据
public class CalendarApplet extends Applet{
static final int TOP = 70; //顶端距离
static final int CELLWIDTH=50,CELLHEIGHT = 30; //单元格尺寸
static final int MARGIN = 3; //边界距离
static final int FEBRUARY = 1;
TextField tfYear = new TextField("2004", 5); //显示年份的文本域
Choice monthChoice = new Choice(); //月份选择下拉框
Button btUpdate = new Button("更新"); //更新按钮
GregorianCalendar calendar=new GregorianCalendar(); //日历对象
Font smallFont = new Font("TimesRoman", Font.PLAIN, 15); //显示小字体Font bigFont = new Font("TimesRoman", Font.BOLD, 50); //显示大字体
String days[] = {"星期日", "星期一", "星期二", "星期三","星期四", "星期五", "
星期六"};
String months[] = {"一月", "二月", "三月", "四月","五月", "六月", "七月", "八月", "九月","十月", "十一月", "十二月"};
int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //每个月的天数
int searchMonth,searchYear; //查询的年份及月份
3.3.绘制程序界面
public void init(){
setBackground(Color.white); //设置背景颜色
searchMonth = calendar.get(Calendar.MONTH); //得到系统年份
searchYear = calendar.get(Calendar.YEAR); //得到系统月份
add(new Label(" 年:")); //增加组件到Applet
tfYear.setText(String.valueOf(searchYear)); //设置文本域文字
add(tfYear);
add(new Label(" 月:"));
monthChoice.setFont(smallFont); //设置月份选择下拉框的显示字体
for (int i = 0; i < 12; i++) {
monthChoice.addItem(months[i]); //增加下拉框选项
}
monthChoice.select(searchMonth); //设置下拉框当前选择项
add(monthChoice);
add(btUpdate);
int componentCount=this.getComponentCount(); //得到Applet中的组件数量
for (int i=0;i getComponent(i).setFont(smallFont); //设置所有组件的显示字体} } 3.4.程序代码 import java.applet.Applet; import java.awt.*; import java.util.*; public class A extends Applet{ static final int TOP = 70; //顶端距离 static final int CELLWIDTH=50,CELLHEIGHT = 30; //单元格尺寸 static final int MARGIN = 3; //边界距离 static final int FEBRUARY = 1; TextField tfYear = new TextField("2004", 5); //显示年份的文本域 Choice monthChoice = new Choice(); //月份选择下拉框 Button btUpdate = new Button("更新"); //更新按钮 GregorianCalendar calendar=new GregorianCalendar(); //日历对象 Font smallFont = new Font("TimesRoman", Font.PLAIN, 15); //显示小字体 Font bigFont = new Font("TimesRoman", Font.BOLD, 50); //显示大字体 String days[] = {"星期日", "星期一", "星期二", "星期三","星期四", "星期五", "星期六"}; String months[] = {"一月", "二月", "三月", "四月","五月", "六月", "七月", "八月", "九月","十月", "十一月", "十二月"}; int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //每个月的天数 int searchMonth,searchYear; //查询的年份及月份 public void init(){ setBackground(Color.white); //设置背景颜色 searchMonth = calendar.get(Calendar.MONTH); //得到系统年份 searchYear = calendar.get(Calendar.YEAR); //得到系统月份 add(new Label(" 年:")); //增加组件到Applet tfYear.setText(String.valueOf(searchYear)); //设置文本域文字 add(tfYear); add(new Label(" 月:")); monthChoice.setFont(smallFont); //设置月份选择下拉框的显示字体 for (int i = 0; i < 12; i++) { monthChoice.addItem(months[i]); //增加下拉框选项 } monthChoice.select(searchMonth); //设置下拉框当前选择项 add(monthChoice); add(btUpdate); int componentCount=this.getComponentCount(); //得到Applet中的组件数量for (int i=0;i getComponent(i).setFont(smallFont); //设置所有组件的显示字体} } public void paint(Graphics g){ FontMetrics fontMetric; //显示字体的FontMetrics对象 int fontAscent; int dayPos; int totalWidth, totalHeight; //总的宽度,高度 int numRows; //行数 int xNum, yNum; //水平和垂直方向单元格数量 int numDays; String dayStr; //显示天数字符串 int margin; 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 (int i = 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 (int i = 0; i <= totalWidth; i += CELLWIDTH) { g.drawLine(i, TOP , i, TOP+ totalHeight); //绘制表格线 } for (int i = 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 (int day = 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; } } } public boolean action(Event e, Object o){ int searchYearInt; if (e.target==btUpdate){ searchMonth = monthChoice.getSelectedIndex(); //得到查询月份 searchYearInt = Integer.parseInt(tfYear.getText(), 10); //得到查询年份 if (searchYearInt > 1581) { searchYear = searchYearInt; } repaint(); //重绘屏幕 return true; } return false; } private int getNumberRows(int year, int month) { //得到行数量 int firstDay; int numCells; 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)) { return 4; } numCells = firstDay + daysInMonth[month]; if ((month == FEBRUARY) && (calendar.isLeapYear(year))) { numCells++; } return ((numCells <= 35) ? 5 : 6); //返回行数 } private int getFirstDayOfMonth(int year, int month) { //得到每月的第一天int firstDay; int i; if (year < 1582) { //年份小于1582年,返回-1 return (-1); } if ((month < 0) || (month > 11)) { //月份数错误,返回-1 return (-1); } firstDay = getFirstDayOfYear(year); //得到每年的第一天 for (i = 0; i < month; i++) { firstDay += daysInMonth[i]; //计算每月的第一天 } if ((month > FEBRUARY) && calendar.isLeapYear(year)) { firstDay++; } return (firstDay % 7); } private int getFirstDayOfYear(int year){ //计算每年的第一天int leapYears; int hundreds; int fourHundreds; int first; 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; //得到每年第一天 return first; } } 4 测试与运行 图2在年份输入框内输入2013后点击更新后的情况 图3 月份下拉列表框 图4选择月份后的情况 图5点击更新按钮后显示的结果 总结 在这次课程设计中,我完成了任务,通过设计这个程序,我更加理解了JAVA 面向对象编程的原理,即在拿到一个程序任务时,先不用考虑具体的实现,应该站在一种统筹全局的角度,思考这个程序的整体结构,要用到哪些类,类与类之间的关系是什么,可以引用JAVA里的哪一些类,对外应该提供哪些接口,怎样设计能够有利于程序的后期维护和可扩展性。然后,定下了程序的整体架构后,再去思考每个方法要怎么实现。 在编程的过程中,我也发现了许多问题,比如多态的不熟练,接口回调的不熟练,图形化界面的设计问题,但通过查阅书籍,上网查询,请教老师同学终于成功的完成了本次课程任务。通过本次编写程序,更加激发了我编程的兴趣和信心,相信通过自己的努力,一定能成为一个合格的程序员。