《万年历》第3节:项目完整代码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《万年历》第3节:项目完整代码相关的知识,希望对你有一定的参考价值。
万年历项目总共有3个类,这3个类的作用已在21.1.2小节中做过介绍,此处不再赘述,以下是这3个类的源代码,读者也能在本书提供的源代码文件夹中直接下载它们。
CalendarFrame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
import java.util.TimerTask;
public class CalendarFrame extends JFrame
//内置资源
//定义4个时区(北京、巴黎、纽约、悉尼)
ZoneId[] zids =
ZoneId.of("Asia/Shanghai"),
ZoneId.of("Europe/Paris"),
ZoneId.of("America/Indianapolis"),
ZoneId.of("Australia/Sydney")
;
//当前时区下标
int zidIndex = 0;
//定义当前时间
ZonedDateTime curTime = ZonedDateTime.now(zids[zidIndex]);
//格式化工具
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//格式化当前时间形成的字符串
String strCurTime;
//定时器及定时器任务
Timer timer;
TimerTask task;
//日历显示的年月(YearMonth)
YearMonth shownYM;
//阳历节日
Festival[][] festivals=
new Festival(1,1,"元旦"),
new Festival(2,14,"情人节"),
new Festival(3,8,"妇女节"),
new Festival(4,1,"愚人节"),
new Festival(5,1,"劳动节"),
new Festival(6,1,"儿童节"),
new Festival(7,1,"建党节"),
new Festival(8,1,"建军节"),
new Festival(9,10,"教师节"),
new Festival(10,1,"国庆节"),
new Festival(11,11,"光棍节"),
new Festival(12,25,"圣诞节")
;
//区域1:当前时间区
JLabel lblCTip;//当前日期指示时间标签
JLabel lblCurTime;//当前日期显示时间标签
JComboBox<String> jcbCities;//城市选择下拉框
DefaultComboBoxModel<String> citiesData;//城市名称
//区域2:日历显示年月
JLabel lblShowTip;//桌面日历显示年月标签
//区域3:日历主体部分
JLabel[] lblweekDays = new JLabel[7];
String[] strWeekDays = "日","一","二","三","四","五","六";
JLabel[] lblDates = new JLabel[42];
JLabel[] lblFestivals = new JLabel[42];
//区域4:功能按钮
JLabel lblSelectTip;//选择年月指示标签
JComboBox<String> jcbYears;//年份选择下拉框
DefaultComboBoxModel<String> yearsData;//年份
JLabel lblYearTip;//年标签
JButton btnCurYM;//回到当前月
JButton btnPreYear;//前1年
JButton btnNextYear;//后1年
JButton btnPreMonth;//前1月
JButton btnNextMonth;//后1月
JComboBox<String> jcbMonths;//月份选择下拉框
DefaultComboBoxModel<String> monthsData;//月份
JLabel lblMonthTip;//月标签
public CalendarFrame()
init();
private void init( )
Container container = this.getContentPane();
container.setLayout(null);
//区域1
//初始化当前时间指示标签
lblCTip = new JLabel("当前时间");
lblCTip.setSize(100, 25);
lblCTip.setLocation(110, 30);
lblCTip.setFont(new Font("微软雅黑", Font.PLAIN, 20));
//初始化城市选择下拉框
citiesData = new DefaultComboBoxModel<String>();
citiesData.addElement("北京");
citiesData.addElement("巴黎");
citiesData.addElement("纽约");
citiesData.addElement("悉尼");
jcbCities = new JComboBox<String>(citiesData);
jcbCities.setSize(80, 25);
jcbCities.setLocation(20, 30);
jcbCities.setFont(new Font("微软雅黑", Font.PLAIN, 20));
jcbCities.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
zidIndex = jcbCities.getSelectedIndex();
if(isCoincideCurDate(shownYM)==true)
resetYearMonth();
showCurTime();
);
//初始化当前时间显示标签
lblCurTime = new JLabel();
lblCurTime.setSize(240, 25);
lblCurTime.setLocation(200, 30);
lblCurTime.setFont(new Font("微软雅黑", Font.PLAIN, 22));
lblCurTime.setForeground(Color.BLUE);
//区域2
//初始化当前时间显示标签
lblShowTip = new JLabel("日历显示年月:");
lblShowTip.setSize(300, 25);
lblShowTip.setLocation(20, 70);
lblShowTip.setFont(new Font("微软雅黑", Font.PLAIN, 20));
//区域3:
//排列周日到周六
for(int i=0;i<7;i++)
lblweekDays[i] = new JLabel();
lblweekDays[i].setText(strWeekDays[i]);
lblweekDays[i].setSize(60, 25);
lblweekDays[i].setLocation(20+i*60, 100);
lblweekDays[i].setFont(new Font("微软雅黑", Font.PLAIN, 22));
container.add(lblweekDays[i]);
for(int i=0;i<42;i++)
//排列日期标签组
lblDates[i] = new JLabel();
lblDates[i].setSize(60, 25);
lblDates[i].setLocation(20+i%7*60, 130+i/7*50);
lblDates[i].setFont(new Font("微软雅黑", Font.PLAIN, 20));
//排列节日标签组
lblFestivals[i] = new JLabel();
lblFestivals[i].setSize(60, 25);
lblFestivals[i].setLocation(20+i%7*60, 130+i/7*50+25);
lblFestivals[i].setFont(new Font("微软雅黑", Font.PLAIN, 12));
lblFestivals[i].setForeground(Color.RED);
container.add(lblDates[i]);
container.add(lblFestivals[i]);
//区域4
//初始化选择年月指示标签
lblSelectTip = new JLabel("跳转到");
lblSelectTip.setSize(80, 25);
lblSelectTip.setLocation(20, 450);
lblSelectTip.setFont(new Font("微软雅黑", Font.PLAIN, 22));
//初始化年份选择下拉框
yearsData = new DefaultComboBoxModel<String>();
jcbYears = new JComboBox<String>(yearsData);
jcbYears.setSize(80, 25);
jcbYears.setLocation(90, 450);
jcbYears.setFont(new Font("微软雅黑", Font.PLAIN, 20));
jcbYears.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
getNewYearMonth();
);
//初始化年标签
lblYearTip = new JLabel("年");
lblYearTip.setSize(20, 25);
lblYearTip.setLocation(170, 450);
lblYearTip.setFont(new Font("微软雅黑", Font.PLAIN, 20));
//初始化月份选择下拉框
monthsData = new DefaultComboBoxModel<String>();
jcbMonths = new JComboBox<String>(monthsData);
jcbMonths.setSize(60, 25);
jcbMonths.setLocation(200, 450);
jcbMonths.setFont(new Font("微软雅黑", Font.PLAIN, 20));
//循环加入月份
for (int i=1;i<=12;i++)
monthsData.addElement(""+i);
jcbMonths.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
getNewYearMonth();
);
//初始化月标签
lblMonthTip = new JLabel("月");
lblMonthTip.setSize(20, 25);
lblMonthTip.setLocation(260, 450);
lblMonthTip.setFont(new Font("微软雅黑", Font.PLAIN, 20));
//初始化回当前月按钮
btnCurYM = new JButton("回当前月");
btnCurYM.setSize(120, 25);
btnCurYM.setLocation(300, 450);
btnCurYM.setFont(new Font("微软雅黑", Font.PLAIN, 20));
btnCurYM.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
resetYearMonth();
);
//初始化前1年按钮
btnPreYear = new JButton("前1年");
btnPreYear.setSize(100, 25);
btnPreYear.setLocation(20, 490);
btnPreYear.setFont(new Font("微软雅黑", Font.PLAIN, 20));
btnPreYear.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
plusYearMonth(-1,0);
);
//初始化前1月按钮
btnPreMonth = new JButton("前1月");
btnPreMonth.setSize(100, 25);
btnPreMonth.setLocation(120, 490);
btnPreMonth.setFont(new Font("微软雅黑", Font.PLAIN, 20));
btnPreMonth.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
plusYearMonth(0,-1);
);
//初始化后1月按钮
btnNextMonth = new JButton("后1月");
btnNextMonth.setSize(100, 25);
btnNextMonth.setLocation(220, 490);
btnNextMonth.setFont(new Font("微软雅黑", Font.PLAIN, 20));
btnNextMonth.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
plusYearMonth(0,1);
);
//初始化后1年按钮
btnNextYear = new JButton("后1年");
btnNextYear.setSize(100, 25);
btnNextYear.setLocation(320, 490);
btnNextYear.setFont(new Font("微软雅黑", Font.PLAIN, 20));
btnNextYear.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
plusYearMonth(1,0);
);
container.add(lblCTip);
container.add(jcbCities);
container.add(lblCurTime);
container.add(jcbYears);
container.add(lblYearTip);
container.add(jcbMonths);
container.add(lblMonthTip);
container.add(lblSelectTip);
container.add(lblShowTip);
container.add(btnPreYear);
container.add(btnPreMonth);
container.add(btnNextMonth);
container.add(btnNextYear);
container.add(btnCurYM);
//初始化显示日历
initCalendarComp();
//启动时钟
startClock();
//显示日历
showCalendar(shownYM);
//初始化日历及相关组件
private void initCalendarComp()
//得到当前的年月
shownYM = YearMonth.from(curTime);
int year = shownYM.getYear();//得到年份数值
int month = shownYM.getMonthValue();//得到月份数值
int earliestYear = year-50;//earliestYear是当前年之前的50年
//以循环方式加入101年
for (int i=0;i<101;i++)
yearsData.addElement((earliestYear+i)+"");
//定位被选中的年和月
jcbYears.setSelectedIndex(50);
jcbMonths.setSelectedIndex(month-1);
//显示当前时间
private void showCurTime()
curTime = ZonedDateTime.now(zids[zidIndex]);//以某个时区为准获取当前时间
strCurTime = formatter.format(curTime);//格式化当前时间
lblCurTime.setText(strCurTime);//把当前时间显示到界面上
//启动时钟
private void startClock()
timer = new Timer();//创建定时器
task = new TimerTask() //以匿名内部类的形式创建TimerTask的实现类对象
@Override
public void run()
showCurTime();
;
timer.schedule(task,0,1000);//启动定时器并设置任务执行频率
//显示日历
private void showCalendar(YearMonth ym)
//清空日历
clearCalendar();
YearMonth lastYM = ym.minusMonths(1);//得到上个月
int lastLen = lastYM.lengthOfMonth();//算出上个月有多少天
LocalDate firstDay = ym.atDay(1);
int weekDay = firstDay.getDayOfWeek().getValue();//本月1号是星期几
int startIndex = weekDay;//本月第1天应该出现的位置
if(weekDay==7)
startIndex = 0;
int year = ym.getYear();
int month = ym.getMonthValue();
if(year<=0)
year = year-1;
lblShowTip.setText("日历显示年月:"+year+"年"+month+"月");
int startNum = lastLen-startIndex+1;
int date = startNum;
//打印上个月的最后几天
int i=0;
for(;i<startIndex;i++,date++)
lblDates[i].setText(""+date);
lblDates[i].setForeground(Color.LIGHT_GRAY);
date=1;
int monthLen = ym.lengthOfMonth();//本月的最后一天
boolean flag = isCoincideCurDate(ym);
Festival[] monthFestival = festivals[month-1];
for(;date<=monthLen;date++,i++)
lblDates[i].setText(""+date);
if(flag==true && date==curTime.getDayOfMonth())//如果要打印的date表示今天
lblDates[i].setForeground(Color.BLUE);//把今天显示为蓝色
for(int j=0;j<monthFestival.length;j++)
if(monthFestival[j].getDay()==date)
lblFestivals[i].setText(monthFestival[j].getName());
int maxNum;
if(startIndex+monthLen%7==0)
maxNum = startIndex+monthLen;
else
maxNum = (startIndex+monthLen)/7*7+7;
date=1;//设置下个月被打印日期的开始
//打印下个月的前几天
for(;i<maxNum;i++,date++)
lblDates[i].setText(""+date);
lblDates[i].setForeground(Color.LIGHT_GRAY);
//判断参数指定的年月与当前年月是否一致
private boolean isCoincideCurDate(YearMonth ym)
boolean flag = true;
if(curTime.getYear()!=ym.getYear() || curTime.getMonthValue()!=ym.getMonthValue())
flag = false;
return flag;
//更新到当前年和月
private void resetYearMonth()
curTime = ZonedDateTime.now(zids[zidIndex]);
shownYM = YearMonth.from(curTime);
showCalendar(shownYM);
//清空日历痕迹
private void clearCalendar()
for(int i=0;i<lblDates.length;i++)
lblDates[i].setText("");
lblDates[i].setForeground(Color.BLACK);
lblFestivals[i].setText("");
//获得新的年和月
private void getNewYearMonth()
int year = Integer.parseInt((String)jcbYears.getSelectedItem());
int month = Integer.parseInt((String)jcbMonths.getSelectedItem());
shownYM = YearMonth.of(year,month);
showCalendar(shownYM);
//增加年月
private void plusYearMonth(int year,int month)
shownYM = shownYM.plusYears(year);
shownYM = shownYM.plusMonths(month);
showCalendar(shownYM);
Festival.java
public class Festival
private int month;//节日所在月
private int day;//节日所在日
private String name;//节日名称
public Festival(int month,int day,String name)
this.month = month;
this.day = day;
this.name = name;
public int getMonth()
return this.month;
public int getDay()
return this.day;
public String getName()
return this.name;
MyCalendar.java
import javax.swing.*;
public class MyCalendar
public static void main(String[] args)
CalendarFrame calendarFrame = new CalendarFrame();
calendarFrame.setSize(450, 600);
calendarFrame.setLocationRelativeTo(null);
calendarFrame.setTitle("万年历");
calendarFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
calendarFrame.setVisible(true);
除阅读文章外,各位小伙伴还可以点击这里观看我在本站的视频课程学习Java!
以上是关于《万年历》第3节:项目完整代码的主要内容,如果未能解决你的问题,请参考以下文章