Java GUI:使用 Java Swing 编写的日历小程序


这是一个完全使用 Java Swing 编写的日历类,同时使用了 Java 的 Calendar 类和 Java AWT 中的触发事件。

话不多说,直接上结果。

运行结果截图如下:
运行结果

它支持显示当前日期,并使用红色高亮标注。
支持上下月翻页,支持查询指定年月的日历,支持一键返回当前日期。


项目源码地址:https://github.com/CoderGeshu/Java-Swing-Calendar。


这里也贴一下源码:
1、首先是一个设置背景透明的工具类,Background.java:

package mycalendar;

import javax.swing.*;
import java.awt.*;

/**
 * 设置背景工具类
 *
 * @Date: 2021/122 19:58
 * @author: Eric
 */
public class Background {
    
    
    //设置背景
    public static void setBackgroundPicture(JFrame jFrame, ImageIcon picture) {
    
    
        JLabel lbl_image = new JLabel(picture);
        jFrame.getLayeredPane().add(lbl_image, JLayeredPane.FRAME_CONTENT_LAYER);
        lbl_image.setSize(picture.getIconWidth(), picture.getIconHeight());
        Container cp = jFrame.getContentPane();
        cp.setLayout(new BorderLayout());
        //设成透明
        ((JPanel) cp).setOpaque(false);
        jFrame.setSize(picture.getIconWidth(), picture.getIconHeight());
    }
}

2、日历窗口类,MyCalendarUI.java:

package mycalendar;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @Date: 2021/1/22 20:02
 * @author: Eric
 */
public class MyCalendarUI extends JFrame implements ActionListener {
    
    
    private static JLabel lbl_BeijingTime;
    private JComboBox<Integer> cmb_year;
    private JComboBox<Integer> cmb_month;
    private JButton btn_confirm, btn_return;
    private JButton btn_lastMonth, btn_nextMonth;
    private JLabel[] labels;


    private Calendar calendar = Calendar.getInstance();

    public MyCalendarUI(String title) {
    
    
        super(title);
        ImageIcon picture = new ImageIcon("picture/background.png");
        Background.setBackgroundPicture(this, picture);
        //调用初始化面板方法
        initPane();
        //设置当前的日历详细信息
        setTodayCalendar();
        //设置窗口属性
        setVisible(true);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    
    
        int year, month;
        if (e.getSource() == btn_confirm) {
    
    
            year = (int) cmb_year.getSelectedItem();
            month = (int) cmb_month.getSelectedItem() - 1;
            showCalendar(year, month);
            return;
        }
        if (e.getSource() == btn_return) {
    
    
            setTodayCalendar();
            return;
        }
        if (e.getSource() == btn_lastMonth) {
    
    
            year = (int) cmb_year.getSelectedItem();
            //month第一次减一是因为月份是从零开始的
            //第二次减一是计算上一个月
            month = (int) cmb_month.getSelectedItem() - 1 - 1;
            if (month < 0) {
    
    
                month = 11; //12月
                --year;
            }
            showCalendar(year, month);
            return;
        }
        if (e.getSource() == btn_nextMonth) {
    
    
            year = (int) cmb_year.getSelectedItem();
            //month第一次减一是因为月份是从零开始的
            //然后加一是因为计算下一月份
            month = (int) cmb_month.getSelectedItem() - 1 + 1;
            if (month > 11) {
    
     // 11就已经代表12月了
                month = 0; //1月
                ++year;
            }
            showCalendar(year, month);
        }
    }

    /**
     * 初始化窗口面板
     */
    private void initPane() {
    
    
        //初始化顶部今日信息面板
        SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        lbl_BeijingTime = new JLabel(df.format(calendar.getTime()), JLabel.CENTER);
        lbl_BeijingTime.setFont(new Font("楷体", Font.PLAIN, 30));

        //初始化顶部查询日期面板
        cmb_year = new JComboBox<>();
        for (int i = 1900; i <= 2100; i++)
            cmb_year.addItem(i);
        JLabel lbl_year = new JLabel("年");
        lbl_year.setFont(new Font("楷体", Font.BOLD, 25));

        cmb_month = new JComboBox<>();
        for (int i = 1; i <= 12; i++)
            cmb_month.addItem(i);
        JLabel lbl_month = new JLabel("月");
        lbl_month.setFont(new Font("楷体", Font.BOLD, 25));

        btn_confirm = new JButton("确定查询");
        btn_confirm.setOpaque(false);
        btn_confirm.setBackground(Color.darkGray);
        btn_confirm.setFont(new Font("楷体", Font.BOLD, 20));
        btn_confirm.addActionListener(this);
        btn_return = new JButton("返回当前日期");
        btn_return.setOpaque(false);
        btn_return.setBackground(Color.darkGray);
        btn_return.setFont(new Font("楷体", Font.BOLD, 20));
        btn_return.addActionListener(this);

        JPanel jp_search = new JPanel();
        jp_search.setOpaque(false);
        jp_search.setBorder(new TitledBorder("查询日期"));
        jp_search.add(cmb_year);
        jp_search.add(lbl_year);
        jp_search.add(cmb_month);
        jp_search.add(lbl_month);
        jp_search.add(new JLabel("         "));
        jp_search.add(btn_confirm);
        jp_search.add(new JLabel("    "));
        jp_search.add(btn_return);

        //添加至顶部面板
        JPanel jp_top = new JPanel(new BorderLayout());
        jp_top.setOpaque(false);
        jp_top.add(lbl_BeijingTime, BorderLayout.NORTH);
        jp_top.add(jp_search, BorderLayout.CENTER);

        //初始化中间详细日期面板
        JPanel jp_display = new JPanel(new GridLayout(7, 7));
        jp_display.setOpaque(false);
        labels = new JLabel[49];
        for (int i = 0; i < 49; i++) {
    
    
            labels[i] = new JLabel(" ", JLabel.CENTER);
            labels[i].setFont(new Font("楷体", Font.PLAIN, 35));
            jp_display.add(labels[i]);
        }
        labels[0].setText("日");
        labels[1].setText("一");
        labels[2].setText("二");
        labels[3].setText("三");
        labels[4].setText("四");
        labels[5].setText("五");
        labels[6].setText("六");
        for (int i = 0; i < 7; i++) {
    
    
            labels[i].setForeground(Color.WHITE);
            labels[i].setBackground(Color.darkGray);
            labels[i].setOpaque(true);
        }

        //设置上一月或下一月查询按钮
        btn_lastMonth = new JButton("<<");
        btn_lastMonth.setBorder(null);
        btn_lastMonth.setOpaque(false);
        btn_lastMonth.setBackground(Color.darkGray);
        btn_lastMonth.setForeground(Color.WHITE);
        btn_lastMonth.setFont(new Font("楷体", Font.PLAIN, 30));
        btn_lastMonth.addActionListener(this);
        btn_lastMonth.addMouseListener(new MouseAdapter() {
    
    
            @Override
            public void mouseEntered(MouseEvent e) {
    
    
                btn_lastMonth.setForeground(Color.green);
            }

            @Override
            public void mouseExited(MouseEvent e) {
    
    
                btn_lastMonth.setForeground(Color.white);
            }
        });

        btn_nextMonth = new JButton(">>");
        btn_nextMonth.setBorder(null);
        btn_nextMonth.setOpaque(false);
        btn_nextMonth.setBackground(Color.darkGray);
        btn_nextMonth.setForeground(Color.WHITE);
        btn_nextMonth.setFont(new Font("楷体", Font.PLAIN, 30));
        btn_nextMonth.addActionListener(this);
        btn_nextMonth.addMouseListener(new MouseAdapter() {
    
    
            @Override
            public void mouseEntered(MouseEvent e) {
    
    
                btn_nextMonth.setForeground(Color.green);
            }

            @Override
            public void mouseExited(MouseEvent e) {
    
    
                btn_nextMonth.setForeground(Color.white);
            }
        });

        //添加至主窗口
        this.add(jp_top, BorderLayout.NORTH);
        this.add(jp_display, BorderLayout.CENTER);
        this.add(btn_lastMonth, BorderLayout.WEST);
        this.add(btn_nextMonth, BorderLayout.EAST);
        this.validate();
    }

    /**
     * 根据年份和月份设置日历详细信息,并返回当前月第一天是周几
     * 注意:月份下标从0开始
     *
     * @param year  年份
     * @param month 月份
     * @return 第一天是周几
     */
    private int showCalendar(int year, int month) {
    
    
        //设置当前的下拉框为选择的日期
        cmb_year.setSelectedItem(year);
        cmb_month.setSelectedItem(month + 1);
        //把以前的日历信息清空
        for (int i = 7; i < 49; ++i) {
    
    
            labels[i].setText("");
            labels[i].setForeground(Color.black);
        }
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        System.out.println("当前选择的是:" + year + "年" + (month + 1) + "月");
        //获得这一月有多少天
        int daysOfMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println("这月一共有" + daysOfMonth + "天");
        //得到每月第一天是一周中的第几天,从周日开始计算
        //如:firstDay=0,表示周日;firstDay=1则表示周一,以此类推
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int firstWeekOfMonth = cal.get(Calendar.DAY_OF_WEEK) - 1;
        System.out.println("这月第一天为周 " + firstWeekOfMonth);
        //为这月的每一天的标签赋值
        for (int i = 0; i < daysOfMonth; ++i) {
    
    
            labels[7 + firstWeekOfMonth + i].setText(i + 1 + "");
        }
        return firstWeekOfMonth;
    }

    /**
     * 设置当前年月的日历,并标出当前日期
     */
    private void setTodayCalendar() {
    
    
        cmb_year.setSelectedItem(calendar.get(Calendar.YEAR));
        cmb_month.setSelectedItem(calendar.get(Calendar.MONTH) + 1);
        int firstWeekOfMonth = showCalendar(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH));
        int today = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println("今天是" + today + "号");
        labels[7 + firstWeekOfMonth + today - 1].setForeground(Color.red);
    }

    public static void updateBeijingTime() {
    
    
        Timer timer = new Timer(true);
        timer.schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                lbl_BeijingTime.setText(df.format(new Date().getTime()));
            }
        }, 0, 1000);

    }

    public static void main(String[] args) {
    
    
        new MyCalendarUI("MyCalendar");
        updateBeijingTime();
    }
}

在上述代码中,MyCalendarUI 的构造方法中使用到了一张背景图片,其路径在项目的 picture 目录下,命名为 background.png,此处也放上此背景图片,以便大家根据自己需要调整:
在这里插入图片描述
此图片来源于网络,此小程序也仅用于学习使用。


如有疑问,请参考项目源代码及目录结构,地址:https://github.com/CoderGeshu/Java-Swing-Calendar。


最后,欢迎大家微信搜索关注:CoderGeshu,一个热爱生活的程序员。

猜你喜欢

转载自blog.csdn.net/weixin_43653599/article/details/113032421