1、湖 南 农 业 大 学 课 程 论 文学 院 : 信 息 科 学 技 术 班 级 : 08 级 信 息 工 程 2 班姓 名 : 郭 显 勇 、 刘 彦 波 、 任 涛 学 号 : 200841843227、 200841843228、 200841843219课 程 论 文 题 目 : JAVA 日 历 小 程 序课 程 名 称 : Java 程 序 设 计 ( 双 语 )评 阅 成 绩 :评 阅 意 见 :成 绩 评 定 教 师 签 名 :日 期 : 年 月 日目 录摘 要 - 1 -关键词 - 1 -1需求分析 - 1 -1.1需求分析 - 1 -1.2功能设计 - 1 -2概要设计 -
2、 1 -2.1开发环境 - 1 -2.2程序设计思路 - 1 -2.3具体功能设计 - 2 -2.4程序运行界面 - 2 -2.5程序流程图 - 3 -3详细设计 - 3 -3.1初始化组件 - 3 -3.2初始化程序数据,绘制程序面板 - 3 -3.3显示日期的方法 - 6 -3.4点击按钮产生的效果 - 8 -4程序测试 - 9 -4.1程序不能完全退出 - 9 -4.2下拉列表数据不能返回 .- 10 -5心得体会 .- 10 -6参考文献 .- 11 -致谢 .- 11 -附:程序源代码 .- 12 - 1 -JAVA 日历小程序学 生:郭显勇、刘彦波、任涛湖南农业大学信息科学技术学院
3、 2008级信息工程 2班学号 200841843227、200841843228、200841843219摘 要: 万年历是一个强大的日历系统 ,通过它可以实现对过去,现在以及将来日期的查询,通过在年份对话框中输入要查询的年份,再相应的在月份对应的下拉菜单选择要查询的月份,则可得到相应的日历。本实验是对图形用户界面,布局管理器的综合运用,理解 JAVA的时间处理机制,编写独立运行的窗口。关键词: 日历;swing;布局管理器; 1 需求分析1.1 需求分析本程序的要求为:1.使用图形用户界面;2.本程序能够实现日期与星期的查询。1.2 功能设计本程序要构建的万年历程序,其功能有以下几个方面:
4、1.实现图形界面。2.能以月历形式显示日期与星期。工作日、双休日、当天分别以黑色、红色和蓝色显示。3.支持用户通过下拉形式菜单来选择月份。4.通过点击“现在日期”来刷新日历。2 概要设计2.1 开发环境开发平台:Microsoft Windows XP Professional Service Pack 2开发工具:Eclipse SDK 3.2.0 + JDK 1.6.0_022.2 程序设计思路1.月份总天数的算法:直接根据 month_int,即月份序号判断该月的天数。- 2 -当 month_int等于 2时,调用 isLeapYear()方法判断是否为闰年。2.网格内容算法:用 dt
5、.getDate()方法算出输出月份第一天为星期几,第一天的格子序号应该为 7+第一天的星期序号。算出输出月份第一天为星期几后,把该日期以前的位置用空格补上,并从该日起一次输出天数直到月底,该月中的天数加上该月一日为星期几的数字再除以 7得 0换行,即可完整的输出该月的日历。3.日期颜色的算法:格子数从 0开始,第一行为星期序号,则日期从第 7格开始。根据格子序号 i进行判断,当 i模 7余数为 0或者 6时日期为周末,置为红色;当 i等于第一天的格子序号加上当前日期减一时,置为蓝色;其余日期为黑色。4.如果年份小于 2001年大于 2031年则程序不予判断。2.3 具体功能设计数据选择列表:
6、年份选择列表、月份选择列表。点击日期跳转按钮,即在日历中显示用户选择日期数据;点击现在日期按钮,即在日历中显示当前日期数据。2.4 程序运行界面(图 2.4.1:程序运行界面截图)- 3 -2.5 程序流程图(图 2.5.1:程序流程图)3 详细设计3.1 初始化组件import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.*;3.2 初始化程序数据,绘制程序面板在初始化模块中,首先定义一个公共类 CalenderTrain,它继承自JFrame。ActionListener 是一个接口,在实
7、现此接口的类 CalenderTrain中,给需要关注其动作的组件跳转按钮 button_jump和现在日期按钮 button_today添加监听器(addActionListener(this),之后在事件处理方法 public void actionPerformed (ActionEvent e) 中,对每个事件进行不同处理。在这个类中,定义用到的标签、下拉列表框、按钮,放置面板。是否计算,绘制屏幕是否选择日期提交年月变更数据 程序初始化结束获取当前系统时间年份等数据开始- 4 -public class CalenderTrain extends JFrame implements A
8、ctionListener JComboBox Month = new JComboBox(); JComboBox Year = new JComboBox(); JLabel Year_l = new JLabel(“年份:“); JLabel Month_l = new JLabel(“月份:“); Date now_date = new Date(); JButton button_day = new JButton49; JButton button_jump = new JButton(“日期跳转“); JButton button_today = new JButton(“现在日
9、期“); int now_year = now_date.getYear() + 1900; int now_month = now_date.getMonth(); boolean bool = false;String year_int = null; int month_int; JPanel pane_ym = new JPanel(); JPanel pane_day = new JPanel();JPanel pane_parent = new JPanel(); 调用 CalenderTrain,设定面板标题为“JAVA 日历程序“。只给窗口设置frame.setDefaultC
10、loseOperation(JFrame.EXIT_ON_CLOSE)的话,点击关闭按钮,执行的其实只有把窗口隐藏动作,在任务管理器中可以看到进程仍在运行。于是加上后面的代码,确保点击关闭,程序直接退出 system。面板的大小设置为不能变化。public CalenderTrain() super(“JAVA日历程序“); setDefaultCloseOperation(DISPOSE_ON_CLOSE);addWindowListener(new WindowAdapter() public void windowClose(WindowEvent e) System.exit(0);)
11、;setResizable(false); 设定年月时,规定年份的区间是当前年份的过去 10年到当前年份的未来20年,月份区间为正常 1-12月。由于在年份区间中,今年是所有年份中的第十一个,所以 Year.setSelectedIndex()指定要选择的列表项的整数,其中 0 指定列表中的第一项的参数为 10时,年份刚好是 2011。Pane_ym 即放置年月下拉列表框以及两个控制按钮的面板。给“跳转按钮”和“现在日期”按钮添- 5 -加监听事件。for (int i = now_year - 10; i = now_year + 20; i+) Year.addItem(i + “);fo
12、r (int i = 1; i 13; i+) Month.addItem(i + “);/addItem(Object anObject)为项列表添加项。仅当 JComboBox 使用可变数据模型时此方法才有效。anObject- 要添加到列表的 ObjectYear.setSelectedIndex(10); button_jump.addActionListener(this); button_today.addActionListener(this); 初始化日期按钮并绘制。由于每一月第一天不能确定,即所在列的位置(星期)不能确定,加上第一行的星期序号,画一个 7*7网格布局管理器Gr
13、idLayout。GridLayout 把容器分成指定行和列的若干个网格,每个组件占一个网格,从左向右、从上到下依次把组件添加进来。所有的网格都是同样大小的。GridLayout(7, 7)设置行列数为 7*7。pane_day.setLayout(new GridLayout(7, 7); for (int i = 0; i 49; i+) button_dayi = new JButton(“ “);pane_day.add(button_dayi);本程序中,对组件的布置、整形和定位授权给一个布局管理器,由布局管理器来负责。利用布局管理器可以做到:(1)计算一个容器的所选尺寸和最小尺寸(
14、2)布置一个容器的组件。这里采用的是 BorderLayout,按东南西北和中心将组件布置在容器的四周和中心。用 setContentPane()方法把容器置为JFrame的内容面板。用 pack()方法调整此窗口的大小,以适合其子组件的首选大小和布局实现全部显示,然后用 show()方法显示出来。pane_parent.setLayout(new BorderLayout();/先把子容器 pane_parent设置为东南西北中setContentPane(pane_day);setContentPane(pane_ym);pane_parent.add(pane_day, BorderLa
15、yout.SOUTH);- 6 -pane_parent.add(pane_ym, BorderLayout.NORTH);/把内容面板添加到子容器 pane_parent中setContentPane(pane_parent);/把子容器添加到栏框中pack();/调整此窗口的大小show();3.3 显示日期的方法根据 bool的值,由 if语句进行判断执行哪一显示日期的语句块,为 true时,显示现在的时间;为 false时,显示用户选定的时间。网格第一行,即 0至 6号格子,内容固定为星期序号,即“星期日”到“星期六” 。void setDay()if (bool) year_int
16、= now_year + “;month_int = now_month; else year_int = Year.getSelectedItem().toString();month_int = Month.getSelectedIndex();/getSelectedIndex()指定当前选择的列表项的整数,其中 0 指定列表中的第一项;如果没有选择任何项或者当前所选项不在列表中,则返回 -1int year_sel = Integer.parseInt(year_int) - 1900; /Integer构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int
17、 值。使用与 parseInt 方法(对基数为 10 的值)相同的方式将该字符串转换成 int 值。 Date dt = new Date(year_sel, month_int, 1); GregorianCalendar cal = new GregorianCalendar(); cal.setTime(dt);String week = “星期日“, “星期一“, “星期二“, “星期三“, “星期四“, “星期五“, “星期六“ ;int day = 0; int day_week = 0; for (int i = 0; i 7; i+) button_dayi.setText(w
18、eeki);- 7 -判断当前月份的天数,根据它来设定 day的值,其中二月份要判断是否是闰年。因为第一行的星期序号已经占用了 7个格子,所以 day_week的值要加上7,即 day_week = 7 + dt.getDay()。if (month_int = 0| month_int = 2| month_int = 4| month_int = 6| month_int = 7| month_int = 9| month_int = 11) day = 31; else if (month_int = 3| month_int = 5| month_int = 8| month_int
19、= 10) day = 30; else if (cal.isLeapYear(year_sel) day = 29; else day = 28;day_week = 7 + dt.getDay();绘制 GridLayout网格的内容。首先要根据选定的月份的第一天是星期几来确定我们绘制按钮的起始位置。前段代码中的 day_week就是我们要绘制的起始位置。对于那些没有数值可以显示的按钮要置空。星期六和星期日以红色字体显示,工作日以黑色字体显示,当天以蓝色字体显示。对于没有日期数值显示的按钮进行置空处理。Count 的值即网格的内容,值从 1一直到 day(当月的总天数) 。int coun
20、t = 1;for (int i = day_week; i day_week + day; count+, i+) if (i % 7 = 0| i = 13| i = 20| i = 27| i = 48- 8 -| i = 34| i = 41) if (i = day_week + now_date.getDate() - 1)button_dayi.setForeground(Color.blue);button_dayi.setText(count + “); else button_dayi.setForeground(Color.red);button_dayi.setText
21、(count + “);elseif (i = day_week + now_date.getDate() - 1) button_dayi.setForeground(Color.blue);button_dayi.setText(count + “); else button_dayi.setForeground(Color.black);button_dayi.setText(count + “);3.4 点击按钮产生的效果对监听器关注的按钮动作进行处理,点击“日期跳转”按钮时,将 bool置为 false,并调用 setDay()方法重新绘制网格内容;点击“现在日期”按钮时,将 boo
22、l置为 true,得到今天的日期,将月份置为当前月份,将年份置为当前年份。public void actionPerformed(ActionEvent e) if (e.getSource() = button_jump) bool = false;this.setDay(); else if (e.getSource() = button_today) bool = true;this.setDay(); Month.setSelectedIndex(now_month);Year.setSelectedIndex(10); - 9 -4 程序测试4.1 程序不能完全退出点击窗口右上角的关
23、闭按钮,程序窗口消失,但是,查看任务管理器,可以发现进程仍然在运行。(图 4.1.1:程序不能完全退出)解决方法:将关闭部分的代码修改为下段代码后,程序能够完全退出。setDefaultCloseOperation(DISPOSE_ON_CLOSE);addWindowListener(new WindowAdapter() public void windowClose(WindowEvent e) System.exit(0);- 10 -4.2 下拉列表数据不能返回运行程序,跳转日期后,再点击“当前日期”按钮,日期面板显示的是当前的日期数据,年份、月份下拉列表的值还是停留在跳转时所选定的
24、值,不能正常返回。(图 4.2.1:下拉列表数据不能返回)解决方法:把 button_day的处理事件,修改为下段代码else if (e.getSource() = button_today) bool = true;this.setDay(); Month.setSelectedIndex(now_month);Year.setSelectedIndex(10); 5 心得体会经过短暂的两周的 Java程序设计,使我又学到了很多的知识,尤其是运用Java知识去解决实际问题的能力又得到了很大的提高。尽管所设计的程序比较简单,但是程序中的每个功能的实现都经过了自己的一定认真的思考。由于把所学的
25、知识做到很灵活的运用在实际中,对于现在的我还有一定的难度,故而,在设计的每个的环节中,都会多多少少的遇到一些问题,这就促使我去查阅各种资料,或者请教同学,极大的提高我的专业素养,同时对在有些书上的理论知识在实际的运用,以及应该注意的问题有了比较深刻的认识。当然,仍然有些理论问题不是很好的去运用,或者是了解的不深刻。这就使的在实践中的所设计的程序有些功能不是自己所想的那样的完美。不过,既然发现了问题的所- 11 -在,我就不会放弃的,直至问题得到解决。这些也同时反映出了平时运用知识去实践这方面做的太少。太缺乏经验。对所设计中将所面临的问题认识不够。是 Java课程设计让我认识到了这些问题的存在。
26、同时给我提供了去面对这些问题的平台。也使我充分的认识到在以后也应该怎样去实践,怎样去学习一门计算机语言,以及如何去运用这门语言去解决实际问题等等。总之,在经过这次 Java的课程设计,使我认识到了自己很多的缺点,同时,也是我学到新知识和新方法的一个机会。这给我在以后继续学习好这门语言指明了方向。6 参考文献1.曾令明 索 望 甘 刚 宋 波,Java 程序设计教程,西安电子科技大学出版社,2007.82.孙全党 王吴迪 赵枫朝,Java 程序设计应用教程,电子工业出版社,2006.23.赵玉阳,Java 从入门到精通,清华大学出版社,2006.8致 谢本设计及报告是在指导老师张老师的指导下完成
27、的,所此在此衷心感谢张老师的悉心教诲以及耐心的讲解。同时还要感谢在设计程序和报告期间给予我帮助和启示的同学,让我了解了很多自己没有注意或忽视的地方,希望我们一起分享成功的喜悦。- 12 -附:程序源代码import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.*;public class CalenderTrain extends JFrame implements ActionListener JComboBox Month = new JComboBox(); /月份下拉列表框JCombo
28、Box Year = new JComboBox(); /年份下拉列表框JLabel Year_l = new JLabel(“年份:“); /定义标签JLabel Month_l = new JLabel(“月份:“); /定义标签Date now_date = new Date(); /获取今天的日期JButton button_day = new JButton49; /定义一个数组用来存放日期JButton button_jump = new JButton(“日期跳转“); /现实选择日期JButton button_today = new JButton(“现在日期“); /显示今
29、天日期按钮int now_year = now_date.getYear() + 1900; /获取年份值int now_month = now_date.getMonth(); /获取月份值( 当前月份-1)boolean bool = false;String year_int = null; /存放年份int month_int; /存放月份JPanel pane_ym = new JPanel(); /放置下拉列表框和控制按钮面板JPanel pane_day = new JPanel(); /放置日期面板JPanel pane_parent = new JPanel(); /放置以上
30、两个面板/定义方法绘制面板public CalenderTrain() super(“JAVA 日历程序“); /设定面板标题/-以下几行使得关闭面板时退出程序setDefaultCloseOperation(DISPOSE_ON_CLOSE);addWindowListener(new WindowAdapter() public void windowClose(WindowEvent e) /System.out.print(“CLOSING THE WIN“);System.exit(0););setResizable(false); /面板的大小不能变化/设定年月/*年份的区间是当前
31、年份的过去 10 年到当前年份的未来 20 年* 月份正常 1-12 月*/for (int i = now_year - 10; i = now_year + 20; i+) - 13 -Year.addItem(i + “);for (int i = 1; i 13; i+) Month.addItem(i + “);Year.setSelectedIndex(10); /设定年份下拉列表为当前年份/Year.setText()pane_ym.add(Year_l); /添加年份标签pane_ym.add(Year); /添加年份下拉列表框Month.setSelectedIndex(no
32、w_month); /设定月份下拉列表为当前月份pane_ym.add(Month_l); /添加月份标签pane_ym.add(Month); /添加月份下拉列表框pane_ym.add(button_jump); /添加跳转按钮pane_ym.add(button_today); /添加“现在日期” 按钮button_jump.addActionListener(this); /跳转按钮添加 监听事件button_today.addActionListener(this); /“现在日期”按钮添加 监听事件/年月设定结束/初始化日期按钮并绘制pane_day.setLayout(new G
33、ridLayout(7, 7);for (int i = 0; i 49; i+) button_dayi = new JButton(“ “);pane_day.add(button_dayi);this.setDay(); /调用 setDay()方法pane_parent.setLayout(new BorderLayout(); /设定布局管理器setContentPane(pane_day);setContentPane(pane_ym);pane_parent.add(pane_day, BorderLayout.SOUTH);pane_parent.add(pane_ym, Bo
34、rderLayout.NORTH);setContentPane(pane_parent);pack();show();/SET DAY 方法,显示日期void setDay() if (bool) year_int = now_year + “;month_int = now_month; else year_int = Year.getSelectedItem().toString();month_int = Month.getSelectedIndex();/year_int=Year.getText();/month_int=Integer.parseInt(Month.getText
35、();- 14 -int year_sel = Integer.parseInt(year_int) - 1900; /获得年份值Date dt = new Date(year_sel, month_int, 1); /构造一个日期GregorianCalendar cal = new GregorianCalendar(); /创建一个 Calendar 实例cal.setTime(dt);String week = “星期日“, “星期一 “, “星期二“, “星期三“, “星期四“, “星期五“, “星期六“ ;int day = 0; /day 中存放某个月份的天数int day_we
36、ek = 0; /用来存放某个月的第一天是星期几的数值/-将星期添加到前 7 个按钮中for (int i = 0; i 7; i+) button_dayi.setText(weeki);/-/*判断是几月份,根据它来设定 day 的值* 其中二月份要判断是否是闰年*/if (month_int = 0| month_int = 2| month_int = 4| month_int = 6| month_int = 7| month_int = 9| month_int = 11) day = 31; else if (month_int = 3| month_int = 5| month
37、_int = 8| month_int = 10) day = 30; else if (cal.isLeapYear(year_sel) day = 29; else day = 28;day_week = 7 + dt.getDay();int count = 1;/*绘制按钮*首先要根据选定的月份的第一天是星期几来确定我们绘制按钮的起始位置* 其中 day_week 就是我们要绘制的起始位置* 对于那些没有数值可以显示的按钮要置空- 15 -*/for (int i = day_week; i day_week + day; count+, i+) if (i % 7 = 0| i =
38、13| i = 20| i = 27| i = 48| i = 34| i = 41) if (i = day_week + now_date.getDate() - 1) button_dayi.setForeground(Color.blue);button_dayi.setText(count + “); else button_dayi.setForeground(Color.red);button_dayi.setText(count + “); else if (i = day_week + now_date.getDate() - 1) button_dayi.setForegr
39、ound(Color.blue);button_dayi.setText(count + “); else button_dayi.setForeground(Color.black);button_dayi.setText(count + “);/-对于没有日期数值显示的按钮进行置空处理if (day_week = 0) for (int i = day; i 49; i+) button_dayi.setText(“ “); else /第一天前面的按钮置空for (int i = 7; i day_week; i+) button_dayi.setText(“ “); /最后一天后面的按
40、钮置空for (int i = day_week + day; i 49; i+) button_dayi.setText(“ “);- 16 -/点击按钮产生的效果public void actionPerformed(ActionEvent e) if (e.getSource() = button_jump) bool = false;this.setDay(); /如果点击跳转按钮就调用 setDay()方法重新绘制按钮 else if (e.getSource() = button_today) bool = true;this.setDay(); /如果点击现在日期按钮,得到今天的日期Month.setSelectedIndex(now_month);/将月份置为当前月份Year.setSelectedIndex(10); /将年份置为当前年份public static void main(String args) CalenderTrain ct = new CalenderTrain();