使用Java创建窗口日历的完整指南
在Java开发中,创建一个图形用户界面(GUI)的窗口日历是一项常见的需求,无论是用于桌面应用还是学习Swing/AWT框架,本文将详细介绍如何使用Java的Swing库构建一个功能完善的窗口日历,包括界面设计、日期计算、事件处理等核心步骤。

环境准备与项目初始化
在开始编码前,确保已安装Java开发工具包(JDK)7或更高版本,并配置好集成开发环境(IDE),如IntelliJ IDEA或Eclipse,创建一个新的Java项目,并确保项目中包含Swing库(JDK自带,无需额外依赖)。
主窗口框架设计
窗口日历的基础是一个主窗口(JFrame),我们需要设置窗口的标题、大小和默认关闭操作,以下是初始化主窗口的代码示例:
import javax.swing.*;
import java.awt.*;
public class CalendarApp {
public static void main(String[] args) {
JFrame frame = new JFrame("Java窗口日历");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLayout(new BorderLayout());
// 后续将添加日历组件
frame.setVisible(true);
}
}
日历布局与组件添加
日历的核心是显示日期的网格,通常包含月份标题、星期标签和日期数字,我们可以使用JPanel和GridLayout来构建日期网格,同时使用JLabel显示月份和年份。
1 月份和年份显示
在窗口顶部添加一个面板,用于显示当前月份和年份,并提供“上一月”和“下一月”按钮:
JPanel headerPanel = new JPanel(new BorderLayout());
JLabel monthLabel = new JLabel("2023年11月", SwingConstants.CENTER);
JButton prevButton = new JButton("上一月");
JButton nextButton = new JButton("下一月");
headerPanel.add(monthLabel, BorderLayout.CENTER);
headerPanel.add(prevButton, BorderLayout.WEST);
headerPanel.add(nextButton, BorderLayout.EAST);
frame.add(headerPanel, BorderLayout.NORTH);
2 星期标签
在日期网格上方添加星期标签(周日至周六),使用一个JPanel和GridLayout:

String[] weekDays = {"日", "一", "二", "三", "四", "五", "六"};
JPanel weekPanel = new JPanel(new GridLayout(1, 7));
for (String day : weekDays) {
JLabel dayLabel = new JLabel(day, SwingConstants.CENTER);
weekPanel.add(dayLabel);
}
frame.add(weekPanel, BorderLayout.CENTER);
日期网格动态生成
日历的核心是动态生成当前月份的日期网格,我们需要计算当前月份的第一天是星期几,以及该月的天数,然后填充日期数字。
1 计算日期信息
使用Java的Calendar类或java.time包(Java 8+)获取当前月份的信息:
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
public class CalendarUtils {
public static int getFirstDayOfMonth(int year, int month) {
YearMonth yearMonth = YearMonth.of(year, month);
LocalDate firstDay = yearMonth.atDay(1);
return firstDay.getDayOfWeek().getValue() % 7; // 转换为周日=0的格式
}
public static int getDaysInMonth(int year, int month) {
return YearMonth.of(year, month).lengthOfMonth();
}
}
2 填充日期网格
创建一个6×7的网格(覆盖最多31天和6周),并动态填充日期:
JPanel datePanel = new JPanel(new GridLayout(6, 7));
int year = 2023;
int month = 11;
int firstDay = CalendarUtils.getFirstDayOfMonth(year, month);
int daysInMonth = CalendarUtils.getDaysInMonth(year, month);
// 填充空白日期(上个月的日期)
for (int i = 0; i < firstDay; i++) {
datePanel.add(new JLabel(""));
}
// 填充当前月日期
for (int day = 1; day <= daysInMonth; day++) {
JButton dayButton = new JButton(String.valueOf(day));
datePanel.add(dayButton);
}
frame.add(datePanel, BorderLayout.CENTER);
事件处理:切换月份
为“上一月”和“下一月”按钮添加事件监听器,实现月份切换功能:
prevButton.addActionListener(e -> {
month--;
if (month < 1) {
month = 12;
year--;
}
updateCalendar(year, month);
});
nextButton.addActionListener(e -> {
month++;
if (month > 12) {
month = 1;
year++;
}
updateCalendar(year, month);
});
private void updateCalendar(int year, int month) {
monthLabel.setText(year + "年" + month + "月");
datePanel.removeAll();
int firstDay = CalendarUtils.getFirstDayOfMonth(year, month);
int daysInMonth = CalendarUtils.getDaysInMonth(year, month);
for (int i = 0; i < firstDay; i++) {
datePanel.add(new JLabel(""));
}
for (int day = 1; day <= daysInMonth; day++) {
JButton dayButton = new JButton(String.valueOf(day));
datePanel.add(dayButton);
}
datePanel.revalidate();
datePanel.repaint();
}
美化与优化
为了提升用户体验,可以对界面进行美化:

- 设置字体和颜色:
monthLabel.setFont(new Font("微软雅黑", Font.BOLD, 16)); - 添加鼠标悬停效果:
dayButton.setBackground(Color.LIGHT_GRAY); - 限制窗口大小:
frame.setResizable(false);
完整代码与运行
将上述代码整合后,运行CalendarApp类即可看到一个功能完整的窗口日历,用户可以通过按钮切换月份,点击日期按钮可进一步扩展功能(如显示事件提醒)。
扩展功能建议
如果需要更高级的功能,可以考虑以下扩展:
- 添加日期选择器(JDatePicker)
- 支持事件标记(在特定日期显示红点)
- 实现农历或节假日显示
- 保存日历数据到文件或数据库
通过以上步骤,你已经掌握了使用Java Swing创建窗口日历的核心技术,从基础布局到动态数据交互,这一过程不仅巩固了GUI开发技能,也为后续复杂项目奠定了基础。



















