/*四、一个简单的万年历

功能要求:
1. 能够显示实现1800-2100年的日期,包括公历、农历、星期、二十四节气。
2. 能够按照月份格式显示,或按照星期格式显示。
3. 能够显示系统时间。
4. 能够设置闹钟。
5. 能够查询若干国际大城市(分布在不同时区)的时间。
界面要求:
必须使用图形界面实现,要符合日常软件使用规范来设计菜单和界面。
其他要求:
1. 标识符命名遵循Windows命名规范。
2. 能够注意各种异常处理,注重提高程序运行效率。
提交内容:
1. 全部源代码。
2. 软件设计和使用说明书(UML类图;实现的功能、主要技术;使用帮助文档)*/
package calendardemo;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class CalendarDemo extends JFrame implements ActionListener, ItemListener {
Date date = new Date();//设置一个Date类,可以输出当前的时间
GregorianCalendar gregorianCalendar = new GregorianCalendar();//构造一个GregorianCalendar使用当前时间在默认的时区和地区
String[] stringWeek = new String[] { "SUN", "MON", "TUE", "WED",
"THU", "FRI", "SAT" };
String[] stringWeekCn = new String[] { "星期天", "星期一", "星期二", "星期三",
"星期四", "星期五", "星期六" };
String[] stringMonth = new String[] { "Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" };
String[] strSysTime = new String[6];   //存储当前日期信息
    String[] strSysNowTime = new String[6];   //存储运行时日期信息
JButton[] buttonDay = new JButton[35]; 
JButton[] buttonWeek =new JButton[7]; 
JLabel labelMonth = new JLabel(); 
String times2;
JLabel lab;
JButton clock = new JButton("闹钟"); 
JButton buttonToday = new JButton(); //今天的按钮
    JButton buttonLastMonth =new JButton();//上月的按钮
JButton buttonNextMonth =new JButton();//下月的按钮
    JComboBox comboYear = new JComboBox();//创建一个JComboBox默认数据模型。默认的数据模型是一个空的对象列表
JComboBox comboMonth =new JComboBox(); 
JComboBox comboRegion =new JComboBox(); 
public void setSysDate(int year,int month) //将日期设置为year年month月1日
gregorianCalendar.set(year,month, 1); 
}
public void itemStateChanged(ItemEvent i)
setDate(0); 
}
public void getSysNowTimeInfo() //得到程序运行时的时间信息并存储在字符串数组strSysNowTime中
{  
 date =gregorianCalendar.getTime();
 strSysNowTime = (date +"").split(" "); 
public void getSysTimeInfo() //得到系统当前的时间信息并存储在字符串数组strSysTime中
{
date = gregorianCalendar.getTime();
strSysTime = (date +"").split(" "); 
public int getNowMonth()
int month = 0; 
for (int i =0; i < 12; i++) 
if(strSysNowTime[1].equalsIgnoreCase(stringMonth[i]))
{
month = i; break; 
}
        }
return month; 
public int weekStrat(String strWeek) //返回字符串strWeek与星期中的第几天匹配,SUN为第一天
int strat = 0; 
for (int i= 0; i < 7; i++) 
if(strWeek.equalsIgnoreCase(stringWeek[i]))
{
strat = i; break; 
}
}
return strat; 
public void setNowDate() //将时间设置为程序运行时的时间
{
setSysTime(getNowYear(),getNowMonth());
getSysTimeInfo();
setDayNull();
getDay(getMonthDays(getNowYear(), getNowMonth() - 1),getMonthDays(getNowYear(),getNowMonth()),
weekStrat(strSysTime[0]),getNowDay());
comboYear.setSelectedIndex(getNowYear()- 1800);
comboMonth.setSelectedIndex(getNowMonth());
public void setDate(int move) //将时间设置为选中的年月增加move个月之后的时间
setSysTime(getYear(),getMonth() + move);
getSysTimeInfo();
setDayNull();
getDay(getMonthDays(getYear(),getMonth() + move - 1),getMonthDays( getYear(),getMonth() + move),
  weekStrat(strSysTime[0]),-1);
if (move != 0) 
if(getMonth() == 0 && move < 0) 
move = 11;
comboYear.setSelectedIndex(getYear()- 1801); 
else if(getMonth() == 11 && move> 0)
move = -11;
comboYear.setSelectedIndex(getYear()- 1799); 
}
else
comboYear.setSelectedIndex(getYear()- 1800); 
comboMonth.setSelectedIndex(getMonth()+ move); 
    } 
public void setSysTime(int year, int month) 
{
gregorianCalendar.set(year,month, 1); 
public int getNowYear() 
return Integer.parseInt(strSysNowTime[5]);
public int getNowDay()
return Integer.parseInt(strSysNowTime[2]);
public int getYear() 
{
return comboYear.getSelectedIndex()+ 1800; 
}
public int getMonth() 
return comboMonth.getSelectedIndex();
public void setDayNull() 
for (int d= 0; d < 35; d++) 
{
buttonDay[d].setText("");
   } 
public void getDay(int lastMonDays,int monthDays, int startWeek, int day)//设置日期颜色并打印 
for (int d = 0;d < startWeek + 1; d++)
{
buttonDay[d].setForeground(Color.GRAY);
buttonDay[d].setText((lastMonDays- startWeek) + d + 1 + ""); 
}
for (int d =startWeek; d < startWeek+ monthDays; d++) 
if((d - startWeek + 1) ==day) 
{
buttonDay[d].setForeground(Color.blue);
else if (d % 7 == 0 || d % 7 == 6) 
{
buttonDay[d].setForeground(Color.RED);
}
else 
{
buttonDay[d].setForeground(Color.BLACK);
buttonDay[d].setText(d- startWeek + 1 + "");
}
for (int d = monthDays +startWeek; d < 35; d++)
{
buttonDay[d].setForeground(Color.GRAY);
buttonDay[d].setText(d -(monthDays + startWeek) +1 + "");
public int getMonthDays(int year,int month) //返回year年month月的天数 
{//返回所选年月的天数,因为数组中的数值从0开始,所以3\5\8\10分别代表4\6\9\11几个小月.    
//而1代表2月,经过是否为闰年判断,选择返回28或29天.其余月份为大月,返回31天. 
switch(month) 
{
case 3: 
case 5:
case 8:
     case 10: return 30; 
     case 1: if(gregorianCalendar.isLeapYear(year))
            return 29; 
             else 
return 28; 
default:return 31;
}
}
class Clock extends JFrame implements ActionListener
{     
JLabel labelHead,labelDate,labelTime;     
JPanel panelCenter,panelSouth,panelEast;     
JPanel panelCenterGraphics= new JPanel();;//创建用于作画的画
Timer time;     
JButton buttonSet,buttonStop;     
Calendar calendar;      
String hour,minute,second, year,month,day;     
String hour2="00",minute2="00",second2="00";//用于设置闹钟的时候与当前时间进行比较     
File musicFile;     
URI uri;     
URL url;     
JRadioButton jrb1,jrb2;     
String drawClock="Clock1.jpg",musicClock="qichuang1.wav";//用于设置铃和钟表的背景    
AudioClip clip;//这个是用来播放音频的
Clock(String s)
{
this.setTitle(s);         
labelHead =new JLabel("闹钟");         
labelHead.setHorizontalAlignment(JLabel.CENTER);         
labelHead.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));//为闹钟设置日期LabelDate         
labelTime = new JLabel();         
labelDate = new JLabel();         
calendar = Calendar.getInstance();         
year = Integer.toString(calendar.get(Calendar.YEAR)) ;        
month = Integer.toString(calendar.get(Calendar.MONTH)+1);         
day= Integer.toString(calendar.get(Calendar.DATE));         
hour = Integer.toString(calendar.get(Calendar.HOUR_OF_DAY));         
minute = Integer.toString(calendar.get(Calendar.MINUTE)); 
second = Integer.toString(calendar.get(Calendar.SECOND));         
labelDate.setHorizontalAlignment(JLabel.CENTER);         
labelDate = new JLabel(year+" 年 "+month+" 月 "+day+" 号 "); 
//为闹钟设置当前时间LabelTime,要进行判断否则时间的秒会出现个位数         
labelTime.setHorizontalAlignment(JLabel.CENTER);          
if(Integer.parseInt(second)<10)
{
second = "0"+second;          
}
if(Integer.parseInt(minute)<10)
{
minute="0"+minute; 
}  
if(Integer.parseInt(hour)<10)
{
hour="0"+hour; 
}  
labelTime = new JLabel(hour+":"+minute+":"+second); //组织中间的一个panelCenter         
JPanel jp = new JPanel();//用于装labelTime,和labelDate         
labelDate.setBounds(10, 10, 500, 500);         
jp.add(labelDate);         
jp.add(labelTime);         
panelCenter = new JPanel();         
panelCenter.add(panelCenterGraphics,BorderLayout.CENTER);//组织最后一个panelSouth组件         
panelSouth =new JPanel();         
buttonSet = new JButton("设置闹钟");         
buttonSet.addActionListener(new ButtonListener());
buttonStop = new JButton("停止闹钟");         
buttonStop.addActionListener(new ButtonListener());        
panelSouth.add(buttonSet);         
panelSouth.add(buttonStop);//设置一些框架的基本情况        
this.setBounds(200, 200, 500, 500);         
this.add(labelHead,BorderLayout.NORTH);         
this.add(panelCenter,BorderLayout.CENTER);         
this.add(panelSouth,BorderLayout.SOUTH);         
this.setVisible(true);         
this.validate();         
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
time = new Timer();          
time.toString(); 
}
public void actionPerformed(ActionEvent e)
//把时间重新设计一次            
calendar = Calendar.getInstance();             
year = Integer.toString(calendar.get(Calendar.YEAR)) ;             
month = Integer.toString(calendar.get(Calendar.MONTH)+1);            
day= Integer.toString(calendar.get(Calendar.DATE));             
hour = Integer.toString(calendar.get(Calendar.HOUR_OF_DAY));            
minute = Integer.toString(calendar.get(Calendar.MINUTE));             
second = Integer.toString(calendar.get(Calendar.SECOND));             
labelDate.setHorizontalAlignment(JLabel.CENTER);             
labelDate.setText(year+" 年 "+month+" 月 "+day+" 号 ");             
if(Integer.parseInt(second)<10)
{
second = "0"+second; 
}             
if(Integer.parseInt(minute)<10)
{
minute="0"+minute;
}             
if(Integer.parseInt(hour)<10)
hour="0"+hour;
}             
labelTime.setText(hour+":"+minute+":"+second);
if(hour.equals(hour2)&&minute.equals(minute2)&&second.equals(second2))
musicFile = new File(musicClock);                     
uri = musicFile.toURI();                     
try
{
url = uri.toURL();                    
}catch(Exception ex)
{
ex.printStackTrace();
}                    
clip = Applet.newAudioClip(url);
clip.play();             
}            
panelCenterGraphics.repaint();         
}     
class PanelPaint extends JPanel
{         
public void paint(Graphics g)
{            
try
{                 
g.drawImage(javax.p_w_picpathio.ImageIO.read(new File(drawClock)),100,10,this);             
}catch (IOException ex) 
{                 
Logger.getLogger(Clock.class.getName()).log(Level.SEVERE, null, ex);             
}            
int xh,yh,xm,ym,xs,ys;              
int xcenter,ycenter;              
xcenter=248;              
ycenter=161;
xs=(int)(Math.cos((Integer.parseInt(second))*3.14f/30-3.14f/2)*80+xcenter);              
ys=(int)(Math.sin((Integer.parseInt(second))*3.14f/30-3.14f/2)*80+ycenter);//这个就是起点        
xm=(int)(Math.cos(Integer.parseInt(minute)*3.14f/30-3.14f/2)*60+xcenter);              
ym=(int)(Math.sin(Integer.parseInt(minute)*3.14f/30-3.14f/2)*60+ycenter);             
xh=(int)(Math.cos((Integer.parseInt(hour)*30+Integer.parseInt(hour)/2)*3.14f/180-3.14f/2)*30+xcenter);              
yh=(int)(Math.sin((Integer.parseInt(hour)*30+Integer.parseInt(hour)/2)*3.14f/180-3.14f/2)*30+ycenter);             
g.setColor(Color.orange);             
g.drawLine(xcenter,ycenter-1,xm,ym);              
g.drawLine(xcenter-1,ycenter,xm,ym);             
g.setColor(Color.green);             
g.drawLine(xcenter,ycenter,xs,ys);             
g.setColor(Color.blue);             
g.drawLine(xcenter,ycenter-1,xh,yh);             
g.drawLine(xcenter-1,ycenter,xh,yh);         
}     
}       
class ButtonListener implements ActionListener//用来设置闹钟的闹铃时间  
{       
public void actionPerformed(ActionEvent e) 
{                
new SetClock();          
}     
}     
    class SetClock extends JDialog implements ActionListener
    {         
private static final long serialVersionUID = 1L;
JTextField txtHour,txtMinute,txtSecond;         
JLabel labelHour,labelMinute,labelSecond;         
JPanel panelNorth2,panelCenter2,panelSouth2;         
JButton buttonYes,buttonNo;         
JComboBox list;         
SetClock()//配置一下设置对话框的基本信息      
{                   
this.setTitle("闹钟设置");             
this.setBounds(300, 300, 500, 300);             
this.setVisible(true);             
this.setLayout(new BorderLayout()); //配置panelNorth用于设置时间的部分            
panelNorth2 = new JPanel();             
txtHour = new JTextField("00",5);             
txtMinute = new JTextField("00",5);             
txtSecond = new JTextField("00",5);             
labelHour = new JLabel("时");             
labelMinute = new JLabel("分");             
labelSecond = new JLabel("秒");             
panelNorth2.add(labelHour);            
panelNorth2.add(txtHour);             
panelNorth2.add(labelMinute);             
panelNorth2.add(txtMinute);
panelNorth2.add(labelSecond);             
panelNorth2.add(txtSecond);             
JPanel panelNorth3 = new JPanel();             
panelNorth3.setLayout(new BorderLayout());             
panelNorth3.add(panelNorth2,BorderLayout.NORTH);             
this.add(panelNorth3,BorderLayout.NORTH);//设置按钮组panelCenter             
panelCenter2 = new JPanel();             
buttonYes = new JButton("yes");             
buttonYes.addActionListener(this);             
buttonNo = new JButton("no");             
buttonNo.addActionListener(this);             
panelCenter2.add(buttonYes);             
panelCenter2.add(buttonNo);             
this.add(panelCenter2,BorderLayout.CENTER);//设置选择歌曲的选项             
list  = new JComboBox();             
list.addItem("music1.mp3");             
list.addItem("music2.mp3");             
list.addItem("music3.mp3");             
panelNorth3.add(list,BorderLayout.SOUTH); 
}
public void actionPerformed1(ActionEvent e) 
{             
if(e.getSource()==buttonYes)
{                       
hour2 = txtHour.getText();                     
minute2 = txtMinute.getText();                     
second2 = txtSecond.getText();                    
if(Integer.parseInt(second2)<10&&second2.charAt(0)!='0') 
{
second2 = "0"+second2;
}
}                     
if(Integer.parseInt(minute2)<10&&minute2.charAt(0)!= '0')
{
minute2="0"+minute2; 
}
if(Integer.parseInt(hour2)<10&&hour2.charAt(0)!='0') 
{
hour2="0"+hour2;                                         
   this.setVisible(false);
}
   else
   {
  this.setVisible(false); 
   }
musicClock = (String)list.getSelectedItem();         
class ButtonStopListener implements ActionListener
{         
public void actionPerformed(ActionEvent e) 
{             
clip.stop();         
}
}
public void actionPerformed(ActionEvent e) {}
    }
    }
CalendarDemo() 
{
Container f1=new Container();
final Container f2=new Container();
JFrame f=new JFrame("万年历(丁梦力)");
Container con=f.getContentPane();
JSplitPane tpSplit;
f1.setLayout(new GridLayout(7, 7, 3, 5));
f2.setLayout(new GridLayout(1, 4));
comboYear.setForeground(new Color(0, 0, 255));
comboYear.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14)); 
for (int y = 1800;y < 2101; y++) //使能够显示1800-2100年的日期
comboYear.addItem("  " +new Integer(y).toString());//使用添加项addItem。 默认情况下的第一项数据模型变得选定的。 
f1.add(comboYear);
comboYear.addItemListener(this);
final JLabel labelYear =new JLabel();
labelYear.setForeground(Color.BLUE);
labelYear.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
f1.add(labelYear);
labelYear.setText("         年");
comboMonth.setForeground(new Color(0, 0, 255));
comboMonth.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
for (int m = 1; m <13; m++) 
comboMonth.addItem("    " + new Integer(m).toString()); 
f1.add(comboMonth);
comboMonth.addItemListener(this);
f1.add(labelMonth);
labelMonth.setForeground(Color.BLUE);
labelMonth.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
labelMonth.setText("        月");
f1.add(buttonLastMonth);
buttonLastMonth.setForeground(Color.BLUE);
buttonLastMonth.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
buttonLastMonth.setText("上月");
buttonLastMonth.addActionListener(new ActionListener(){//设置事件
public void actionPerformed(ActionEvent e) 
if(e.getSource() == buttonLastMonth) 
setDate(-1);
}
}) ;
f1.add(buttonToday);
buttonToday.setForeground(Color.BLUE);
buttonToday.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
buttonToday.setText("今天");
buttonToday.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) 
if (e.getSource()== buttonToday)
setNowDate();
}
}) ;
f1.add(buttonNextMonth);
buttonNextMonth.setForeground(Color.BLUE);
buttonNextMonth.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
buttonNextMonth.setText("下月");
buttonNextMonth.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) 
if(e.getSource() == buttonNextMonth) 
setDate(1);
}
}) ;
for (int i = 0; i < 7;i++) 
buttonWeek[i] =new JButton(); 
if (i == 0|| i == 6) 
buttonWeek[i].setForeground(Color.RED);
else 
buttonWeek[i].setForeground(Color.BLUE);
buttonWeek[i].setFont(new Font("Serief",Font.ITALIC + Font.BOLD,12));
buttonWeek[i].setText(stringWeekCn[i]);
f1.add(buttonWeek[i]);
for (int i = 0; i < 35;i++) 
buttonDay[i] = new JButton();
buttonDay[i].setText("");
f1.add(buttonDay[i]);
}
//接下来是设置显示系统的当前时间
Date date1 = new Date(); 
SimpleDateFormat from1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//format对象是用来以指定的时间格式格式化时间的  
String times1 = from1.format(date1); 
JButton butt1 = new JButton();
f2.add(butt1);
butt1.setForeground(Color.red);
butt1.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
butt1.setText("本机时间"+times1);
String[] s1 = new String[] {"美国","英国","日本"};
for(int i=0;i<3;i++)
comboRegion.addItem(s1[i]); 
f2.add(comboRegion);
comboRegion.addItemListener(this);
lab = new JLabel();
comboRegion.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
int uhour1=0,umin1=0,use1=0;//美国时间
int uhour2=0,umin2=0,use2=0;//英国时间
int uhour3=0,umin3=0,use3=0;//日本时间
TimeZone a =TimeZone.getTimeZone("America/Los_Angeles");
           TimeZone ee =TimeZone.getTimeZone("BST +01:00");//BST +01:00英国夏时制
           TimeZone c =TimeZone.getTimeZone("JST +09:00");
Calendar udate1 = Calendar.getInstance(a,Locale.US);
Calendar udate2 = Calendar.getInstance(ee,Locale.ENGLISH);
Calendar udate3 = Calendar.getInstance(c,Locale.JAPAN);
                uhour1 = udate1.get(Calendar.HOUR_OF_DAY);
                umin1 = udate1.get(Calendar.MINUTE);
                use1 = udate1.get(Calendar.SECOND);
                uhour2 = udate2.get(Calendar.HOUR_OF_DAY);
                umin2 = udate2.get(Calendar.MINUTE);
                use2 = udate2.get(Calendar.SECOND);
                uhour3 = udate3.get(Calendar.HOUR_OF_DAY);
                umin3 = udate3.get(Calendar.MINUTE);
                use3 = udate3.get(Calendar.SECOND);
                String meiguo = uhour1+"时"+umin1+"分"+use1+"秒";
                String yingguo = uhour2+"时"+umin2+"分"+use2+"秒";
                String riben = uhour3+"时"+umin3+"分"+use3+"秒";
String petName = (String)comboRegion.getSelectedItem();
if(petName == "美国")
{
times2 = meiguo;
//System.out.println(times2);
}
if(petName == "英国")
{
times2 = yingguo; 
//System.out.println(times2);
}
if(petName == "日本")
{
times2 =riben;
//System.out.println(times2);
}
lab.setText(times2);
lab.setForeground(Color.BLUE);
lab.setFont(new Font("Serief",Font.ITALIC + Font.BOLD,14));
}
}) ;
f2.add(lab);
clock.addActionListener(new ActionListener()//设置事件
{
public void actionPerformed(ActionEvent e) 
if(e.getSource() == clock) 
new Clock("闹钟");
}
});
f2.add(clock);
tpSplit=new JSplitPane(JSplitPane.VERTICAL_SPLIT,f1,f2);//上下分割
tpSplit.setDividerSize(25);//设置上下分割线的宽度
tpSplit.setOneTouchExpandable(true);//设置上下分割处的花纹 
con.add(tpSplit);
f.setBounds(150, 200, 1000,350);//使用绝对定位
f.setVisible(true);
getSysNowTimeInfo();//得到程序运行时的时间信息
setNowDate();//将时间设置为程序运行时的时间
getSysTimeInfo();
    }
public static void main(String args[]) {
try{
new CalendarDemo();
}catch(Exception e){
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) {}
}