湖南农业大学
JAVA课程设计报告
JAVA小日历组件
学生姓名:杨姣姣
学 号:200741841210
年级专业:07级电子商务2班
指导老师:王明宇
学 院:信息科学技术学院
湖南·长沙
提交日期:20##年11月
目 录
1.设计目标…………………………………………………3
2.设计思想…………………………………………………3
3.类及对象设计……………………………………………3
4.程序源代码………………………………………………4
5.调试记录…………………………………………………14
6.总结………………………………………………………15
7.参考文献…………………………………………………17
8.致谢…………………………………………………17
JAVA小日历组件设计
1.设计目标
本课程设计是一个JAVA小日历组件的设计,利用Frame框架类、面板类进行图形化界面设计,实现小日历的公历显示等功能。
2.设计思想
(1)本小日历设计主体结构为:设计一个框架MainFrame,然后在MainFrame里添加一个MainPanel面板。定义一个MainPanel面板类,该面板以边布局格式,所有其他面板、标签等均添加到该面板中。
(2)MainPanel面板北部(上方),添加一个年月面板YearMonthPanel。该年月面板主要放年份显示、月份显示、标题显示。YearMonthPanel面板也使用边布局格式,西部添加一个年份面板,放年份信息;中部添加一个TextPanel面板,放标题文本显示信息;东部添加一个月份面板MonthPanel,放月份下拉框信息。
(3)MainPanel主面板的中部,添加一个DaysPanel面板用于放置月份的天数表格信息。
(4)MainPanel主面板的南部(下方),添加一个InfoPanel面板,主要用于放置显示个人信息。
(5)InfoPanel面板上设计添加一个超级链接标签,链接到个人博客。
3.设计类及对象设计
在本程序中:定义了一个Frame类,主要定义一个窗体框架,用于显示日历信息,并在主函数中只创建一个该窗体对象实现程序功能。
定义了一个主日历面板类Xiaorili,其中包含了日历设计所用到的全局变量、功能函数等,在Frame类里定义了其对象。在该日历面板类里又设计了一个内部类CalendarTable表格类,用于布局日历天的显示格式。
为了设计一个超级链接,定义了一个LinkLable类,单独保存在一个文件LinkTbale.java中,在日历面板类Xiaorili里定义了其对象。
4.程序源代码
(1)xiaoril.java文件代码:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class Xiaorili extends JApplet {
//==================================================
/*定义全局变量*/
public static final Color background = Color.white;//背景色
public static final Color foreground = Color.black;//前景色
public static final Color headerBackground = Color.DARK_GRAY;//星期
public static final Color headerForeground = Color.white;//星期前景色
public static final Color selectedBackground = Color.green;//选中背景色
public static final Color selectedForeground = Color.white;//选中前景色
public static final String WeekSun = "星期日"; //星期标签名称
public static final String WeekMon = "星期一";
public static final String WeekTue = "星期二";
public static final String WeekWed = "星期三";
public static final String WeekThu = "星期四";
public static final String WeekFri = "星期五";
public static final String WeekSat = "星期六";
private JPanel MainPanel;//日历面板
private JLabel yearsLabel;//“年份”标签
private JSpinner yearsSpinner;//年份组合框
private JLabel monthsLabel;//“月份”标签
private JComboBox monthsComboBox; //12月份下拉框
private JLabel textLabel;//标题显示标签
private JLabel InfoLabel;//个人信息显示标签
private JTable daysTable; //日表格
private AbstractTableModel daysModel;//天单元表格
private Calendar calendar;//日历对象
//==================================================
/*函数定义*/
public Xiaorili() {//构造函数
MainPanel = (JPanel) getContentPane();
}
public void init() {//初始化面板界面函数
MainPanel.setLayout(new BorderLayout());
calendar = Calendar.getInstance();//默认方式,以本地的时区和地区来构造Calendar
//--------------------------------------
yearsLabel = new JLabel("年份: "); //设置年份标签显示
yearsSpinner = new JSpinner();//构造年份spinner组合框
yearsSpinner.setEditor(new JSpinner.NumberEditor(yearsSpinner, "0000"));
yearsSpinner.setValue(new Integer(calendar.get(Calendar.YEAR)));
yearsSpinner.addChangeListener(new ChangeListener() {//注册该组合框的事件监听器
public void stateChanged(ChangeEvent changeEvent) {
int day = calendar.get(Calendar.DAY_OF_MONTH);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.YEAR, ((Integer) yearsSpinner.getValue()).intValue());
int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
calendar.set(Calendar.DAY_OF_MONTH, day > maxDay ? maxDay : day);
updateView();//更新显示
}
});
//--------------------------------------
JPanel yearMonthPanel = new JPanel();//定义年月面板
MainPanel.add(yearMonthPanel, BorderLayout.NORTH);//添加年月面板到日历面板的南面(最上方)
yearMonthPanel.setLayout(new BorderLayout());//边布局模式
JPanel yearPanel = new JPanel();//构建年份面板
yearMonthPanel.add(yearPanel, BorderLayout.WEST);//年份面板添加到年月面板西部(左边)
yearPanel.setLayout(new BorderLayout());//设置年份面板为边布局并添加年份标签和组合框
yearPanel.add(yearsLabel, BorderLayout.WEST);
yearPanel.add(yearsSpinner, BorderLayout.CENTER);
//--------------------------------------
monthsLabel = new JLabel("月份: "); //设置月份标签显示
monthsComboBox = new JComboBox();//月份下拉框
for (int i = 1; i <= 12; i++) { //构造下拉框的12个月份
monthsComboBox.addItem(new Integer(i));
}
monthsComboBox.setSelectedIndex(calendar.get(Calendar.MONTH));//下拉框当前月份为选中状态
monthsComboBox.addActionListener(new ActionListener() { //注册月份下拉框的事件监听器
public void actionPerformed(ActionEvent actionEvent) {
int day = calendar.get(Calendar.DAY_OF_MONTH);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.MONTH, monthsComboBox.getSelectedIndex());
int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
calendar.set(Calendar.DAY_OF_MONTH, day > maxDay ? maxDay : day);
updateView();//更新面板显示
}
});
//--------------------------------------
JPanel monthPanel = new JPanel();//定义月份面板
yearMonthPanel.add(monthPanel, BorderLayout.EAST);//添加月份面板到年月面板的东面(右面)
monthPanel.setLayout(new BorderLayout());//月份面板设为边布局方式
monthPanel.add(monthsLabel, BorderLayout.WEST);//添加月份名称标签到月份面板西面(左面)
monthPanel.add(monthsComboBox, BorderLayout.CENTER);//添加月份下拉框到月份面板中间
//--------------------------------------
textLabel = new JLabel("JAVA小日历-061114052"); //设置标题标签显示
JPanel txetPanel = new JPanel();//定义标题文本显示面板
yearMonthPanel.add(txetPanel,BorderLayout.CENTER);//添加标题文本显示面板到年月面板中间
txetPanel.add(textLabel,BorderLayout.CENTER);//添加标题文本标签到面板
//--------------------------------------
InfoLabel = new JLabel("学号:061114052 姓名:李志文 班级:06教育班"); //设置个人信息标签显示
JPanel InfoPanel = new JPanel();//定义底部个人信息显示面板
MainPanel.add(InfoPanel,BorderLayout.SOUTH);//添加个人信息显示面板到日历面板南方(下方)
InfoPanel.add(InfoLabel);//添加信息标签文本标签到面板
//--------------------------------------
JPanel Link = new JPanel();//设置超级链接到我的博客
InfoPanel.add(new LinkLabel("访问志文工作室", "http://www.zhiwenweb.cn"));
//--------------------------------------
daysModel = new AbstractTableModel() { //设置7行7列
public int getRowCount() {
return 7;
}
public int getColumnCount() {
return 7;
}
public Object getValueAt(int row, int column) {
if (row == 0) { //第一行显示星期
return getHeader(column);
}
row--;
Calendar calendar = (Calendar) Xiaorili.this.calendar.clone();
calendar.set(Calendar.DAY_OF_MONTH, 1);
int dayCount = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
int moreDayCount = calendar.get(Calendar.DAY_OF_WEEK) - 1;
int index = row * 7 + column;
int dayIndex = index - moreDayCount + 1;
if (index < moreDayCount || dayIndex > dayCount) {
return null;
} else {
return new Integer(dayIndex);
}
}
};
daysTable = new CalendarTable(daysModel, calendar); //构造日表格
daysTable.setCellSelectionEnabled(true);//设置表格单元格可选择
daysTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
daysTable.setDefaultRenderer(daysTable.getColumnClass(0), new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
String text = (value == null) ? "" : value.toString();
JLabel cell = new JLabel(text);
cell.setOpaque(true); //绘制边界内的所有像素
if (row == 0) { //第一行显示星期,设置为星期的前景色和背景色
cell.setForeground(headerForeground);
cell.setBackground(headerBackground);
} else {
if (isSelected) { //日期单元格如果选中,则设置为日期选中的前、背景色
cell.setForeground(selectedForeground);
cell.setBackground(selectedBackground);
} else { //设置日期单元格的普通前、背景色
cell.setForeground(foreground);
cell.setBackground(background);
}
}
return cell;
}
});
updateView();
MainPanel.add(daysTable, BorderLayout.CENTER);//添加日面板到日历面板中间
}
//--------------------------------------
public static String getHeader(int index) {//设置第一行星期的显示
switch (index) {
case 0:
return WeekSun;
case 1:
return WeekMon;
case 2:
return WeekTue;
case 3:
return WeekWed;
case 4:
return WeekThu;
case 5:
return WeekFri;
case 6:
return WeekSat;
default:
return null;
}
}
//--------------------------------------
public void updateView() {//更新面板显示方法
daysModel.fireTableDataChanged();
daysTable.setRowSelectionInterval(calendar.get(Calendar.WEEK_OF_MONTH),
calendar.get(Calendar.WEEK_OF_MONTH));
daysTable.setColumnSelectionInterval(calendar.get(Calendar.DAY_OF_WEEK) - 1,
calendar.get(Calendar.DAY_OF_WEEK) - 1);
}
//==================================================
public static class CalendarTable extends JTable {//表格类
private Calendar calendar;
public CalendarTable(TableModel model, Calendar calendar) {//构造方法
super(model);
this.calendar = calendar;
}
//--------------------------------------
public void changeSelection(int row, int column, boolean toggle, boolean extend) {//选择表格单元格时
super.changeSelection(row, column, toggle, extend);
if (row == 0) {//选择为第一行(星期)时不改变单元格
return;
}
Object obj = getValueAt(row, column);
if (obj != null) {
calendar.set(Calendar.DAY_OF_MONTH, ((Integer)obj).intValue());
}
}
}
}
(2)LinkLabel.java文件代码:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class LinkLabel extends JLabel {
private String text, url;
private boolean isSupported;
public LinkLabel(String text, String url) {
this.text = text;//显示文本
this.url = url;//链接地址
try {
this.isSupported = Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE);
}
catch (Exception e) {//捕获浏览器异常
this.isSupported = false;
}
setText(false);
addMouseListener(new MouseAdapter() {//注册鼠标单击事件监听器
public void mouseEntered(MouseEvent e) {
setText(isSupported);
if (isSupported)
setCursor(new Cursor(Cursor.HAND_CURSOR));//鼠标形状为hand形式
}
public void mouseExited(MouseEvent e) {//移开鼠标时
setText(false);
}
public void mouseClicked(MouseEvent e) {//鼠标单击时
try {
Desktop.getDesktop().browse(new java.net.URI(LinkLabel.this.url));//调用默认浏览器打开链接
}
catch (Exception ex) {
}
}
});
}
private void setText(boolean b) {//设置标签显示文本
if (!b)
setText("<html><font color=red><u>" + text);//鼠标移到标签外显示为红色字体
else
setText("<html><font color=green><u>" + text);//鼠标移到标签上面显示为绿色字体
}
}
(3)MainFrame.java文件代码:
/**
* @(#) MainFrame.java
* 主窗体
* @author 志文工作室:www.zhiwenweb.cn
*/
import java.awt.*;
import javax.swing.*;
//构造窗体类
public class MainFrame extends JFrame{
public MainFrame(){
super("JAVA小日历-志文工作室-http://www.zhiwenweb.cn");//创建窗体并设置标题
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//单击窗口关闭按钮关闭窗体
Xiaorili Xiaorili = new Xiaorili();//创建小日历对象
Xiaorili.init();//初始化面板
this.getContentPane().add(Xiaorili);
this.setSize(450, 200); //框架大小
this.setVisible(true);//设置可见性
this.setResizable(false);//窗体不可改变大小
this.pack();
}
/*主函数调用*/
public static void main(String[] args){
new MainFrame();
}
}
5.调试记录
程序功能调试如下:
(1)运行程序,出现日历界面:
(2)单击年份的组合框侧边箭头,改变年份,则日历跟随改变:
(3)单击月份下拉框,改变月份,则日历也跟随改变:
(4)鼠标移动到“访问志文工作室”标签上,则字体颜色变为绿色:
(5)鼠标单击超级链接标签,则调用默认浏览器打开了我的博客主页:
6.总结
(1)选题目的:本次课程设计为课本后设计题目任选一题进行设计。思考一段时间后,我决定做一个小日历组件的设计。主要考虑到本学期时间少课程内容多,JAVA课程基础内容掌握并不是很抓实,而对于设计一个小日历组件,由于其功能简单设计也相对较易,对于我个人的学习情况比较合适,并且通过设计这样的一个日历小组件,也能使自己对JAVA的一些基础知识掌握的更加牢固。
(2)对于本小日历的设计,首先考虑其功能有哪些,需要显示什么,如何进行窗体构建布局,需要用哪些知识点,如相关的类和对象等。最后,就是根据初步设计的功能和布局构架,考虑用源代码进行实现了。
(3)本小日历组件在设计过程中参考了一些网络上的日历组件设计程序,只是那些程序大都使用功能相对较丰富,涉及到的知识也比较多,对于自己目前所掌握的内容来说有点广博。不过那些程序对日历实现的一些思想对我确实有很多启发。本小日历组件设计过程中也参考了一些他人设计的代码。在设计本小日历组件过程中遇到过许多问题,最后都是在网络搜集询问的帮助下一一得以解决。下面列举几个参考中比较重要的相关内容:
u .JAVA Calendar方法:Calendar 抽象类定义了足够的方法,让我们能够表述日历的规则。我们也可以自己的 Calendar 实现类,然后将它作为 Calendar 对象返回(面向对象的特性)。在 Calendar 的方法中,get() 和 add() 会让 Calendar 立刻刷新。本程序的中心设计即是利用Calendar类来实现。
u javax.swing.JSpinner用法:让用户从一个有序序列中选择一个数字或者一个对象值的单行输入字段。它能够方便地选择日期、数字或列表中的选项。Spinner 通常提供一对带小箭头的按钮以便逐步遍历序列元素。键盘的向上/向下方向键也可循环遍历元素。也允许用户在 spinner 中直接输入合法值。JSpinner显示不同的内容,采用不同的模型,像SpinnerDateModel,SpinnerListModel,SpinnerNumberModel,只要对模型修改,就可以实现想要的精确的功能。本程序利用该组件实现了年份的修改。
u setOpaque 用法:setOpaque (false)的作用是将button的背景色改为其parent的背景色。如果为 true,则该组件绘制其边界内的所有像素。否则该组件可能不绘制其某些或所有像素,从而允许其下面的像素透视出来。
u 基于Java Swing的超链接标签和超链接按钮的实现: java.awt.Desktop类的java.awt.Desktop.isDesktopSupported()可以获取当前系统是否支持java awt桌面扩展.如果支持可以获取当前系统的Desktop ,则使用:
java.awt.Desktop dp = java.awt.Desktop.getDesktop();
dp.browse(java.net.URI); 就可以启动系统默认的浏览器。本程序自定义一个超链接标签控件[LinkLabel]类进行实现该功能。
u java中实现表格的多表头显示:主要就是三个应用类ColumnGroup, GroupableTableHeader,GroupableTableHeaderU和一个示例类GroupableHeaderExample。
经过了长时间的反复编写调试,课本和网上查阅相关资料相关文章,终于完成了整个课程设计。在这个过程中,在把书本上的知识给系统的复习了一下的同时,同时也发现了自己的太多不足,对JAVA2语言整体知识构架不够熟悉,不能灵活地运用所学的知识点。自己的编程方式也不是太标准,经常出现代码写错而调试很久的低级错误情况出现。
通过这次课程设计,我明白了编写程序,不仅要求对课本知识有较深刻的了解,同时要求程序设计者有较强的思维和动手能力。还要熟悉常用的编程技巧和编程思想,不能只关心程序的运行结果,更要注重程序代码的结构,编程者更要有严谨地态度。还有通过设计过程中大量地查阅网络文章,对一些关键知识点逐个地了解并解决相关问题。所以网络这个强大的工具,确实是我们学习之中可以借助的一个很好的帮手。网络是我们学习的最好的老师之一。有问题,问网络,是一个很好的习惯。
7. 参考资料:
[1] 叶核亚.《JAVA2程序设计实用教程(第2版)》,北京:电子工业出版社,2008.4.
[2] http://hi.baidu.com/eredlab/blog/item/000f9cec33b8562463d09f1b.html
[3] http://blog.cnw.com.cn/index.php/36770/viewspace-11956
[4] http://www.mldn.cn/articleview/20##-1-23/article_view_1031.htm
[5] http://webservice.org.cn/dispbbs.asp?boardid=41&id=52488&star=1
[6] http://topic.csdn.net/t/20060128/11/4536759.html
[7] http://www.blogjava.net/kissjava/articles/187739.html
[8] http://www.programbbs.com/doc/604.htm
8. 致谢:本论文是在指导老师王明宇的悉心指导下完成的。这次毕业设计能够顺利的完成,要感谢很多人无私的帮助。
首先是王明宇老师,在技术上给了我很大的帮助和启发,他在实验课上的讲解让我对java语言有了大概的了解。同时激起我对java编程的兴趣。
其次,感谢班上同学对我的帮助和指点。没有他们的帮助和提供资料对于我一个对编程知识不是很精通的人来说要想在短短的几个月的时间里完成一个系统的设计是几乎不可能的事情。
在此表示最诚挚的感谢!