当前位置:首页 > 后端开发 > 正文

怎么用java做窗口日历

Java做窗口日历,可借助Swing库的JFrame搭建 窗口,结合Calendar类处理日期逻辑

基础框架搭建

  1. 导入依赖库
    需引入Swing组件库与AWT布局管理器:

    import javax.swing.;          // JFrame, JPanel等组件
    import java.awt.;             // 布局管理类如GridLayout
    import java.util.Calendar;      // 日期计算核心类
    import java.util.Date;          // 处理当前时间戳
  2. 创建主窗口(JFrame)
    继承JFrame并设置基本属性:

    public class MyCalendar extends JFrame {
        public MyCalendar() {
            setTitle("Java窗口日历");       // 窗口标题
            setSize(400, 300);              // 宽高尺寸
            setDefaultCloseOperation(EXIT_ON_CLOSE); // 关闭事件响应
            setLocationRelativeTo(null);     // 屏幕居中显示
            initializeUI();                  // 初始化用户界面
        }
    }
  3. 添加主面板(JPanel)
    使用双层嵌套布局实现结构化排版:外层采用BorderLayout划分区域,内层用GridLayout(7,7)构建表格形式的日期网格。

    private void initializeUI() {
        // 顶部标题栏 显示年月信息
        JLabel titleLabel = new JLabel("", SwingConstants.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
        add(titleLabel, BorderLayout.NORTH);
        // 中间主体 星期与日期表格
        JPanel gridPanel = new JPanel(new GridLayout(7, 7));
        // ...后续填充单元格内容...
        add(gridPanel, BorderLayout.CENTER);
    }

动态生成日历内容

关键算法实现

通过Calendar类获取当前月份的数据结构:

怎么用java做窗口日历  第1张

// 初始化当月第一天对应的星期几(周日=1,周一=2...饱和六=7)
int firstDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); 
// 注意:Java中周日被视为一周的第1天!
// 计算该月总天数(考虑闰年影响)
int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

可视化渲染逻辑

  1. 首行标注星期名称
    创建固定字符串数组存储中文星期标识:

    String[] weekdays = {"日", "一", "二", "三", "四", "五", "六"};
    for (String dayName : weekdays) {
        JLabel label = new JLabel(dayName);
        gridPanel.add(label);
    }
  2. 填充空白占位符
    若首日非周日(即索引>0),则在前几格插入空标签:

    for (int i = 0; i < firstDayOfWeek 1; i++) {
        gridPanel.add(new JLabel()); // 无文字的透明格子
    }
  3. 逐日添加交互元素
    循环生成带数字的按钮或标签,支持点击事件监听:

    for (int day = 1; day <= daysInMonth; day++) {
        final int finalDay = day; // 用于Lambda表达式捕获变量值
        JButton btn = new JButton(String.valueOf(day));
        btn.addActionListener(e -> System.out.println("选中日期:" + finalDay));
        gridPanel.add(btn);
    }

高级特性扩展

功能模块 实现方式 作用效果
实时时钟同步 结合Timer定时器每秒刷新界面显示 动态更新时间信息
主题切换 通过修改UIManager默认属性改变整体配色方案 暗黑/明亮模式自由切换
节假日标记 根据预存的特殊日期列表高亮对应单元格 直观展示法定休息日
跨月导航 栏两侧添加“<”“>”按钮触发前后月份切换 快速浏览相邻月份日程安排
事件提醒绑定 右键菜单关联备忘录编辑框,允许用户为特定日期添加备注 增强个人事务管理能力

完整示例代码整合

import javax.swing.;
import java.awt.;
import java.util.Calendar;
import java.util.Date;
public class MyCalendar extends JFrame {
    private JLabel titleLabel;         // 显示年月的大标题
    private JPanel dayGrid;            // 存放日期按钮的网格面板
    private Calendar currentCal;       // 当前操作的日历实例
    public MyCalendar() {
        initComponents();             // 组件初始化入口
        loadCurrentMonthData();       // 加载初始数据
    }
    private void initComponents() {
        // ===== 整体布局配置 =====
        setLayout(new BorderLayout());
        setSize(500, 400);
        setVisible(true);
        // ===== 头部年份显示区 =====
        titleLabel = new JLabel("", SwingConstants.CENTER);
        titleLabel.setFont(new Font("SansSerif", Font.PLAIN, 24));
        add(titleLabel, BorderLayout.NORTH);
        // ===== 中央日历表格区 =====
        dayGrid = new JPanel(new GridLayout(6, 7)); // 最多6行×7列足够容纳所有情况
        add(dayGrid, BorderLayout.CENTER);
        // ===== 底部控制按钮区 =====
        JPanel controlPane = new JPanel();
        JButton preMonthBtn = new JButton("上个月");
        JButton nextMonthBtn = new JButton("下个月");
        controlPane.add(preMonthBtn);
        controlPane.add(nextMonthBtn);
        add(controlPane, BorderLayout.SOUTH);
        // ===== 事件监听绑定 =====
        preMonthBtn.addActionListener(e -> navigateMonth(-1));
        nextMonthBtn.addActionListener(e -> navigateMonth(1));
    }
    private void loadCurrentMonthData() {
        currentCal = Calendar.getInstance();
        updateTitle();                 // 更新标题栏文本
        renderDayCells();              // 重新绘制所有日期单元格
    }
    private void updateTitle() {
        String pattern = "yyyy年MM月";
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        titleLabel.setText(formatter.format(currentCal.getTime()));
    }
    private void renderDayCells() {
        dayGrid.removeAll();           // 清空现有内容
        int startPos = currentCal.get(Calendar.DAY_OF_WEEK) 1; // 转换为0基索引
        int totalDays = currentCal.getActualMaximum(Calendar.DAY_OF_MONTH);
        // 添加星期表头
        String[] weekdayNames = {"日", "一", "二", "三", "四", "五", "六"};
        for (String name : weekdayNames) {
            JLabel header = new JLabel(name);
            header.setHorizontalAlignment(SwingConstants.CENTER);
            dayGrid.add(header);
        }
        // 前置空白填充(当月第一天不是周日时)
        for (int i = 0; i < startPos; i++) {
            dayGrid.add(new JLabel());
        }
        // 正式日期项生成
        for (int d = 1; d <= totalDays; d++) {
            JButton dayBtn = new JButton(String.valueOf(d));
            dayBtn.setPreferredSize(new Dimension(40, 40)); // 统一按钮大小
            final int finalDay = d;                       // 解决闭包变量捕获问题
            dayBtn.addActionListener(ev -> selectedDateChanged(finalDay));
            dayGrid.add(dayBtn);
        }
        revalidate();                 // 通知容器重新布局组件
        repaint();                    // 强制重绘可视区域
    }
    private void selectedDateChanged(int selectedDay) {
        System.out.printf("您选择了 %d号n", selectedDay);
        // TODO: 此处可扩展更多业务逻辑,如弹出详情对话框等
    }
    private void navigateMonth(int offset) {
        currentCal.add(Calendar.MONTH, offset); // +1表示下个月,-1表示上个月
        loadCurrentMonthData();               // 重新加载新月份的数据视图
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MyCalendar()); // 确保EDT线程安全启动GUI程序
    }
}

FAQs

Q1: 为什么运行后看不到任何日期?
A: 检查是否遗漏了revalidate()repaint()调用,这两个方法必须成对出现才能触发Swing组件树的重构与重绘流程,特别是在动态修改面板子元素后(如removeAll()操作),必须显式通知布局管理器更新视图。

Q2: 如何让日历支持多语言显示?
A: 将硬编码的文字提取到资源文件中(如.properties格式),利用ResourceBundle类实现国际化适配,例如定义英文版资源文件CalendarEN.properties为:weekdays=Sun,Mon,Tue,Wed,Thu,Fri,Sat,运行时根据系统默认语言环境自动加载对应

0