
一、题目陈述:
设计一个万年历,要求具有显示年份、月份、日期的功能,与windowsXP系统的日期与时间的界面和功能类似。
二、问题分析:
万年历的界面可由内容面板类panel和spinner、textArea、comboBox等容器构成;布局可以由BorderLayout、FlowLayout、GridLayout使其达到美观整齐的效果。万年历功能的实现是通过添加相应的和事件处理函数来完成的。
三、题目设计:
(一)、类设计:
1、面板类CalendarDemo:嵌入显示月份的comboBox和显示年份的spinner,以及显示日期的textArea。
2、窗口类CalendarTest:镶入面板,设计窗口大小等属性,并包含主函数。运行后显示该窗口。
3、类与类之间的关系:
(二)、界面设计:
根据windows的日期界面,利用JPanel提供的BorderLayout、FlowLayout,将包含comboBox和spinner的panel1放在NORTH区,包含textArea的panel2放在CENTER区。CalendarDemo类的对象panel的titledBorder设置为“日期”
(三)、事件处理:
匿名内部类事件做事件处理: 用comboBox实现月份变换改变日期变换的PopupMenuListener()、用spinner实现年份变换改变日期变换的ChangeListener()。
具体处理方式:
comboBox.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
thisMonth = comboBox.getSelectedIndex() + 1;
typeset();
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
});
spinner.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
thisYear = Integer.parseInt(spinner.getValue().toString());
typeset();
}
});
(四)、主要的成员变量和成员函数:
1、面板类CalculatorDemo:JComboBox comboBox;JSpinner spinner;JTextArea textArea;JPanel panel1,panel2;String[] monthsString[] date;int thisYear, thisMonth;Public void typeset() ;
2、窗口类CalculatorTest: CalendarDemo panel;public static void main;
四、源代码:
import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
public class CalendarDemo extends JPanel
{
JComboBox comboBox;
JSpinner spinner;
JTextArea textArea;
JPanel panel1,panel2;
String[] months = { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月十月", "十一月", "十二月" };
String[] date = { "日", "一", "二", "三", "四", "五", "六" };
int thisYear , thisMonth;
public CalendarDemo()
{
super(new BorderLayout());
setBorder(BorderFactory.createTitledBorder("日期"));
comboBox = new JComboBox(months);
spinner = new JSpinner(new SpinnerNumberModel(2006, 1980, 2099, 1));
textArea = new JTextArea();
panel1=new JPanel(new FlowLayout());
panel2=new JPanel(new FlowLayout());
panel1.add(comboBox);
panel1.add(spinner);
panel2.add(textArea);
add(panel1,BorderLayout.NORTH);
add(panel2,BorderLayout.CENTER);
comboBox.setSelectedItem( "十二月");
thisMonth =comboBox.getSelectedIndex()+1;
comboBox.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
thisMonth = comboBox.getSelectedIndex() + 1;
typeset();
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
});
spinner.setValue( 2006);
spinner.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
thisYear = Integer.parseInt(spinner.getValue().toString());
typeset();
}
});
textArea.setBorder(BorderFactory.createLoweredBevelBorder());
textArea.setEditable(false);
textArea.setTabSize(3);
typeset();
}
public void typeset()
{
textArea.setText( "");
int jan,march,may,july,augest,oct,dec;
int feb=28;
int april,june,sept,nov;
int day,days,tempdays;
int i,j,num=1;
jan=march=may=july=augest=oct=dec=31;
april=june=sept=nov=30;
i=j=0;
day=days=tempdays=0;
thisYear = 2006;
if(thisYear%4==0)
{if(thisYear%100==0)
{ if(thisYear%400==0) feb=29;
else feb=28;
}
else feb=29;
}
else feb=28;
tempdays=(thisYear-1980)/4*(365*3+366)+((thisYear-1980)%4)*365+29-feb;
switch (thisMonth)
{
case 1:days=jan;day=tempdays%7;break;
case 2:days=feb;day=(jan+tempdays)%7;break;
case 3:days=march;day=(jan+feb+tempdays)%7 ;break;
case 4:days=april;day=(jan+feb+march+tempdays)%7 ;break;
case 5:days=may;day=(jan+feb+march+april+tempdays)%7 ;break;
case 6:days=june;day=(jan+feb+march+april+may+tempdays)%7 ;break;
case 7:days=july;day=(jan+feb+march+april+may+june+tempdays)%7 ;break;
case 8:days=augest;day=(jan+feb+march+april+may+june+july+tempdays)%7 ;break;
case 9:days=sept;day=(jan+feb+march+april+may+june+july+augest+tempdays)%7 ;break;
case 10:days=oct;day=(jan+feb+march+april+may+june+july+augest+sept+tempdays)%7;break;
case 11:days=nov;day=(jan+feb+march+april+may+june+july+augest+sept+oct+tempdays)%7 ;break;
case 12:days=dec;day=(jan+feb+march+april+may+june+july+augest+sept+oct+nov+tempdays)%7 ;break;
}
for(i=0;i<7;i++)
textArea.append("\"+date[i]);
textArea.append( "\\n");
if(day<5)
{ textArea.append( "\ \ ");
for(i=0,j=3;i } else if(day==6) {textArea.append("\ "); j=2; } else j=1; for(num=1;num<=days;num++,j++) {if(num<10) textArea.append(" \" + num); else textArea.append("\" + num); if((j!=0)&&((j%7)==0)) textArea.append("\\n"); } textArea.append(""); } } import java.awt.*; import javax.swing.*; public class CalendarTest extends JFrame { CalendarDemo panel; public CalendarTest() { super("Karen's Calendar"); Container contentPane = getContentPane(); panel = new CalendarDemo(); contentPane.add(panel); setBounds(300, 200, 295, 240); setResizable(false); setVisible(true); } public static void main(String[] args) { CalendarTest calFr = new CalendarTest(); calFr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } 五、收获体会: 1、写类的时候要覆盖它的全部父类函数,因为它是抽象类 2、学会了使用java自带的库函数 3、类与类之间数据通过类对象的传递 4、尝试了创建事件的4种方法
