武汉理工大学学生实验报告书实验课程名称软件开发工具开课学院计算机科学与技术学院指导老师姓名张能立学生姓名学生专业班级2013—2014学年第1学期学生学号实验课成绩-1-JAVA日历小程序摘要:万年历是一个强大的日历系统,通过它可以实现对过去,现在以及将来日期的查询,通过在年份对话框中输入要查询的年份,再相应的在月份对应的下拉菜单选择要查询的月份,则可得到相应的日历。本实验是对图形用户界面,布局管理器的综合运用,理解JAVA的时间处理机制,编写独立运行的窗口。关键词:日历;swing;布局管理器;引言:Java是现在全球最为流行的开发工具之一,它拥有一套庞大且完善的类库,内置了其他语言需要靠库甚至是操作系统才能支持的功能。Java的产生与流行是Internet发展的客观要求。Java作为一门“一次编译,随处运行”的语言,其强大的兼容性给予程序员高效的开发,而是用eclipse作为IDE开发Java程序成了人们的首选因为作为一个开源的编辑环境,Eclipse其众多的插件支持给予了开发者很好的体验效果。现在就让我们用JAVA编写一个日历小程序来体验Eclipse开发带来的高效性。Eclipse简介:Eclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse附带了一个标准的插件集,包括Java开发工具(JavaDevelopmentTools,JDT)。-2-一、需求分析1.1需求分析本程序的要求为:1.使用图形用户界面;2.本程序能够实现日期与星期的查询。1.2功能设计本程序要构建的万年历程序,其功能有以下几个方面:1.实现图形界面。2.能以月历形式显示日期与星期。工作日、双休日、当天分别以黑色、红色和蓝色显示。3.支持用户通过下拉形式菜单来选择月份。4.通过点击“现在日期”来刷新日历。二、概要设计2.1开发环境开发平台:MicrosoftWindowsXPProfessionalServicePack2开发工具:EclipseSDK3.2.0+JDK1.6.0_022.2程序设计思路1.月份总天数的算法:直接根据month_int,即月份序号判断该月的天数。当month_int等于2时,调用isLeapYear()方法判断是否为闰年。2.网格内容算法:用dt.getDate()方法算出输出月份第一天为星期几,第一天的格子序号应该为7+第一天的星期序号。算出输出月份第一天为星期几后,把该日期以前的位置用空格补上,并从该日起一次输出天数直到月底,该月中的天数加上该月一日为星期几的数字再除以7得0换行,即可完整的输出该月的日历。3.日期颜色的算法:格子数从0开始,第一行为星期序号,则日期从第7格开始。根据格子序号i进行判断,当i模7余数为0或者6时日期为周末,置为红色;当i等于第一天的格子序号加上当前日期减一时,置为蓝色;其余日期为黑色。4.如果年份小于2001年大于2031年则程序不予判断。-3-2.3具体功能设计数据选择列表:年份选择列表、月份选择列表。点击日期跳转按钮,即在日历中显示用户选择日期数据;点击现在日期按钮,即在日历中显示当前日期数据。2.4程序运行界面(图2.4.1:程序运行界面截图)-4-2.5程序流程图(图2.5.1:程序流程图)三、详细设计3.1初始化组件importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjava.util.*;3.2初始化程序数据,绘制程序面板在初始化模块中,首先定义一个公共类CalenderTrain,它继承自JFrame。ActionListener是一个接口,在实现此接口的类CalenderTrain中,给需要关注其动作的组件跳转按钮button_jump和现在日期按钮button_today添加监听器(addActionListener(this),之后在事件处理方法publicvoidactionPerformed(ActionEvente)中,对每个事件进行不同处理。在这个类中,定义用到的标签、下拉列表框、按钮,放置面板。是否计算,绘制屏幕是否选择日期提交年月变更数据程序初始化结束获取当前系统时间年份等数据开始-5-publicclassCalenderTrainextendsJFrameimplementsActionListener{JComboBoxMonth=newJComboBox();JComboBoxYear=newJComboBox();JLabelYear_l=newJLabel(年份:);JLabelMonth_l=newJLabel(月份:);Datenow_date=newDate();JButton[]button_day=newJButton[49];JButtonbutton_jump=newJButton(日期跳转);JButtonbutton_today=newJButton(现在日期);intnow_year=now_date.getYear()+1900;intnow_month=now_date.getMonth();booleanbool=false;Stringyear_int=null;intmonth_int;JPanelpane_ym=newJPanel();JPanelpane_day=newJPanel();JPanelpane_parent=newJPanel();调用CalenderTrain,设定面板标题为JAVA日历程序。只给窗口设置frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)的话,点击关闭按钮,执行的其实只有把窗口隐藏动作,在任务管理器中可以看到进程仍在运行。于是加上后面的代码,确保点击关闭,程序直接退出system。面板的大小设置为不能变化。publicCalenderTrain(){super(JAVA日历程序);setDefaultCloseOperation(DISPOSE_ON_CLOSE);addWindowListener(newWindowAdapter(){publicvoidwindowClose(WindowEvente){System.exit(0);}});setResizable(false);设定年月时,规定年份的区间是当前年份的过去10年到当前年份的未来20年,月份区间为正常1-12月。由于在年份区间中,今年是所有年份中的第十一个,所以Year.setSelectedIndex()的参数为10时,年份刚好是2011。Pane_ym即放置年月下拉列表框以及两个控制按钮的面板。给“跳转按钮”和“现在日期”按钮添加监听事件。-6-for(inti=now_year-10;i=now_year+20;i++){Year.addItem(i+);}for(inti=1;i13;i++){Month.addItem(i+);}Year.setSelectedIndex(10);button_jump.addActionListener(this);button_today.addActionListener(this);初始化日期按钮并绘制。由于每一月第一天不能确定,即所在列的位置(星期)不能确定,加上第一行的星期序号,画一个7*7网格布局管理器GridLayout。GridLayout把容器分成指定行和列的若干个网格,每个组件占一个网格,从左向右、从上到下依次把组件添加进来。所有的网格都是同样大小的。GridLayout(7,7)设置行列数为7*7。pane_day.setLayout(newGridLayout(7,7));for(inti=0;i49;i++){button_day[i]=newJButton();pane_day.add(button_day[i]);}本程序中,对组件的布置、整形和定位授权给一个布局管理器,由布局管理器来负责。利用布局管理器可以做到:(1)计算一个容器的所选尺寸和最小尺寸(2)布置一个容器的组件。这里采用的是BorderLayout,按东南西北和中心将组件布置在容器的四周和中心。用setContentPane()方法把容器置为JFrame的内容面板。用pack()方法调整此窗口的大小,以适合其子组件的首选大小和布局实现全部显示,然后用show()方法显示出来。pane_parent.setLayout(newBorderLayout());setContentPane(pane_day);setContentPane(pane_ym);pane_parent.add(pane_day,BorderLayout.SOUTH);pane_parent.add(pane_ym,BorderLayout.NORTH);setContentPane(pane_parent);pack();show();}-7-3.3显示日期的方法根据bool的值,由if语句进行判断执行哪一显示日期的语句块,为true时,显示现在的时间;为false时,显示用户选定的时间。网格第一行,即0至6号格子,内容固定为星期序号,即“星期日”到“星期六”。voidsetDay(){if(bool){year_int=now_year+;month_int=now_month;}else{year_int=Year.getSelectedItem().toString();month_int=Month.getSelectedIndex();}intyear_sel=Integer.parseInt(year_int)-1900;Datedt=newDate(year_sel,month_int,1);GregorianCalendarcal=newGregorianCalendar();cal.setTime(dt);Stringweek[]={星期日,星期一,星期二,星期三,星期四,星期五,星期六};intday=0;intday_week=0;for(inti=0;i7;i++){button_day[i].setText(week[i]);}判断当前月份的天数,根据它来设定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;}elseif(month_int==3||month_int==5||month_int==8||month_int==10){-8-day=30;}else{if(cal.isLeapYear(year_sel)){day=29;}else{day=28;}}day_week=7+dt.getDay();绘制GridLayout网格的内容。首先要根据选定的月份的第一天是星期几来确定我们绘制按钮的起始位置。前段代码中的day_week就是我们要绘制的起始位置。对于那些没有数值可以显示的按钮要置空。星期六和星期日以红色字体显示,工作日以黑色字体显示,当天以蓝色字体显示。对于没有日期数值显示的按钮进行置空处理。Count的值即网格的内容,值从1一直到day(当月的总天数)。intcount=1;for(inti=day_week;iday_week+day;count++,i++){if(i%7==0||i==13||i==20||i==27||i==48||i==34||i==41){if(i==day_week+now_date.getDate()-1){button_day[i]