Java使用JFrame实现日历显示,及日期选择,重复代码未封装

记一个JFrame日历组件

前言

因编写插件需要一个日历展示界面用于选择日期,因此编写该组件

代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class JPanelByCalendar extends JPanel {
    String[] weekName=new String[]{"一","二","三","四","五","六","日"};

    private int status=0;//0日期,1月份,2年份
    private LocalDate focusDate;
    private JLabel focusDayJLabel;

    private LocalDate nowDate=LocalDate.now();
    private JLabel nowMonthJLabel;

    private JLabel head;//头部容器
    private JPanel yearJPanel;//年份显示容器
    private List<JLabel> yearJLabel=new ArrayList<>(12);
    private JPanel monthJPanel;//月份显示容器
    private List<JLabel> monthJLabel=new ArrayList<>(12);
    private JPanel dayJPanel;//日期显示容器
    private List<JLabel> dayJLabel=new ArrayList<>(49);

    private JLabel viewJLabel;//动态显示月份/年份
    private JLabel upJLabel;//上一页按钮
    private JLabel downJLabel;//下一页按钮



    public JPanelByCalendar() {
        super();
        this.setLayout(null);
        head = new JLabelForImage();
        head.setBounds(0,0,300,50);
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        focusDate=currentDate;
        int year = currentDate.getYear();
        int month = currentDate.getMonthValue();
        int dayOfMonth = currentDate.getDayOfMonth();
        String dayOfWeek = currentDate.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
        JLabel nowDateJLabel=new JLabel(String.format("%s年%s月%s日,%s",year,month,dayOfMonth,dayOfWeek));
        nowDateJLabel.setBounds(0,0,300,20);
        nowDateJLabel.setHorizontalAlignment(JLabel.CENTER);
        nowDateJLabel.setOpaque(true);
        nowDateJLabel.setBackground(Color.LIGHT_GRAY);
        viewJLabel=new JLabel(String.format("\t%s年%s月",year,month));
        viewJLabel.addMouseListener(new MouseUpListener(viewJLabel,0) {
            @Override
            public void mouseClicked(MouseEvent e) {
                //修改选框
                if(status==0){
                    status=1;
                    //展示月份
                    refreshMonthJPanel();
                    JPanelByCalendar.this.remove(1);
                    JPanelByCalendar.this.add(monthJPanel,1);
                    JPanelByCalendar.this.repaint();
                }else if(status==1){
                    status=2;
                    //展示年份
                    refreshYearJPanel();
                    JPanelByCalendar.this.remove(1);
                    JPanelByCalendar.this.add(yearJPanel,1);
                    JPanelByCalendar.this.repaint();
                }
            }
        });
        viewJLabel.setBounds(15,22,170,24);
        viewJLabel.setOpaque(true);
//        viewJLabel.setBackground(Color.lightGray);
        //向上翻页
        upJLabel=new JLabel("㊤");
        upJLabel.addMouseListener(new MouseUpListener(upJLabel,0) {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(status==0){
                    focusDate=focusDate.minusMonths(1);
                    refreshDayJPanel();
                }else if(status==1){
                    focusDate=focusDate.minusYears(1);
                    refreshMonthJPanel();
                }else {
                    focusDate=focusDate.minusYears(16);
                    refreshYearJPanel();
                }
                JPanelByCalendar.this.repaint();
            }
        });
        upJLabel.setBounds(195,22,40,24);
        upJLabel.setOpaque(true);
//        upJLabel.setBackground(Color.lightGray);
        upJLabel.setHorizontalAlignment(JLabel.CENTER);

        //向下翻页
        downJLabel=new JLabel("㊦");
        downJLabel.addMouseListener(new MouseUpListener(downJLabel,0) {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(status==0){
                    focusDate=focusDate.plusMonths(1);
                    refreshDayJPanel();
                }else if(status==1){
                    focusDate=focusDate.plusYears(1);
                    refreshMonthJPanel();
                }else {
                    focusDate=focusDate.plusYears(16);
                    refreshYearJPanel();
                }
                JPanelByCalendar.this.repaint();
            }
        });
        downJLabel.setBounds(245,22,40,24);
        downJLabel.setOpaque(true);
//        downJLabel.setBackground(Color.lightGray);
        downJLabel.setHorizontalAlignment(JLabel.CENTER);
        head.add(nowDateJLabel,0);
        head.add(upJLabel,1);
        head.add(downJLabel,2);
        head.add(viewJLabel,3);
        head.setBorder(BorderFactory.createMatteBorder(0,0,2,0,Color.gray));
        this.add(head,0);
        //初始化年份
        yearJPanel=new JPanel();
        yearJPanel.setLayout(new GridLayout(4,4));
        yearJPanel.setBounds(0,50,300,212);
        yearJPanel.setBorder(BorderFactory.createLineBorder(Color.gray,1));
        for (int i = year; i <year+16; i++) {
            JLabel jLabel = new JLabel();
            jLabel.setOpaque(true);
            jLabel.setBackground(Color.white);
            jLabel.setHorizontalAlignment(JLabel.CENTER);
            jLabel.addMouseListener(new MouseUpListener(jLabel) {
                @Override
                public void mouseClicked(MouseEvent e) {
                    status=1;
                    jLabel.setBackground(Color.white);
                    int year = Integer.valueOf(jLabel.getText());
                    focusDate=LocalDate.ofYearDay(year,1);
                    //展示月份
                    refreshMonthJPanel();
                    JPanelByCalendar.this.remove(1);
                    JPanelByCalendar.this.add(monthJPanel,1);
                    JPanelByCalendar.this.repaint();
                }
            });
            yearJLabel.add(jLabel);
            yearJPanel.add(jLabel);
        }
        //初始化月份
        monthJPanel=new JPanel();
        monthJPanel.setLayout(new GridLayout(3,4));
        monthJPanel.setBounds(0,50,300,212);
        monthJPanel.setBorder(BorderFactory.createLineBorder(Color.gray,1));
        for (int i = 1; i <= 12; i++) {
            JLabel jLabel = new JLabel();
            jLabel.setOpaque(true);
            jLabel.setBackground(Color.white);
            jLabel.setHorizontalAlignment(JLabel.CENTER);
            jLabel.setText(String.valueOf(i));
            jLabel.addMouseListener(new MouseUpListener(jLabel) {
                @Override
                public void mouseClicked(MouseEvent e) {
                    status=0;
                    jLabel.setBackground(Color.white);
                    int month = Integer.valueOf(jLabel.getText());
                    focusDate=focusDate.withMonth(month).withDayOfMonth(1);
                    //展示日期
                    refreshDayJPanel();
                    JPanelByCalendar.this.remove(1);
                    JPanelByCalendar.this.add(dayJPanel,1);
                    JPanelByCalendar.this.repaint();
                }
            });
            monthJPanel.add(jLabel);
            monthJLabel.add(jLabel);
        }
        //初始化日期
        dayJPanel=new JPanel();
        dayJPanel.setLayout(new GridLayout(7,7));
        dayJPanel.setBounds(0,50,300,212);
        dayJPanel.setBorder(BorderFactory.createLineBorder(Color.gray,1));
        for (int i = 0; i < 49; i++) {
            JLabel jLabel = new JLabel();
            jLabel.setOpaque(true);
            jLabel.setBackground(Color.white);
            jLabel.setHorizontalAlignment(JLabel.CENTER);
            if(i<7){
                jLabel.setText(weekName[i]);
            }else{
                jLabel.addMouseListener(new MouseUpListener(jLabel){
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        if(jLabel.getText()!=null&&jLabel.getText().length()>0){
                            focusDayJLabel.setBorder(null);
                            focusDate=focusDate.withDayOfMonth(Integer.valueOf(jLabel.getText()));
                            jLabel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
                            focusDayJLabel=jLabel;
                        }
                    }
                });
            }
            dayJLabel.add(jLabel);
            dayJPanel.add(jLabel);
        }
        refreshDayJPanel();
        this.add(dayJPanel,1);
    }

    //刷新日期
    void refreshDayJPanel(){
        //初始化
        for (int i = 0; i < 49; i++) {
            if(i<7)continue;
            JLabel jLabel = dayJLabel.get(i);
            jLabel.setBorder(null);
            jLabel.setForeground(null);
            jLabel.setText("");
        }
        //获取当月数据
        LocalDate localDate = focusDate.withDayOfMonth(1);
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        viewJLabel.setText(String.format("\t%s年%s月",year,month));
        Boolean nowFlag=false;
        if(year== nowDate.getYear()&&month==nowDate.getMonthValue()){
            nowFlag=true;
        }
        int week = localDate.getDayOfWeek().getValue();
        int days = localDate.lengthOfMonth();
        int focusDay=focusDate.getDayOfMonth();
        int start=week+6;
        //循环写入
        for (int i = 0;i<days;i++){
            JLabel jLabel = dayJLabel.get(start + i);
            jLabel.setText(String.valueOf(i+1));
            if(focusDay==i+1){
                focusDayJLabel=jLabel;
                jLabel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
            }
            if(nowFlag&&nowDate.getDayOfMonth()==i+1){
                jLabel.setForeground(Color.BLUE);
            }
        }
    }

    //刷新月份
    void refreshMonthJPanel(){
        int year = focusDate.getYear();
        viewJLabel.setText(String.format("\t%s年",year));
        //设置当前月高亮显示
        if(year== nowDate.getYear()) {
            nowMonthJLabel = monthJLabel.get(nowDate.getMonth().getValue() - 1);
            nowMonthJLabel.setForeground(Color.BLUE);
        }else{
            if(nowMonthJLabel!=null)nowMonthJLabel.setForeground(null);
        }
    }

    //刷新年份
    void refreshYearJPanel(){
        yearJLabel.forEach(jLabel -> {
            jLabel.setText("");
            jLabel.setForeground(null);
        });
        int year = focusDate.getYear();
        int nowYear=nowDate.getYear();
        viewJLabel.setText(String.format("\t%s年-%s年",year,year+15));
        for (int i = 0; i <16; i++) {
            JLabel jLabel = yearJLabel.get(i);
            jLabel.setText(String.valueOf(year+i));
            if(nowYear==year+i){
                jLabel.setForeground(Color.BLUE);
            }
        }
    }

    public LocalDate getFocusDate() {
        return focusDate;
    }

    public static void main(String[] args) {
        Toolkit kit=Toolkit.getDefaultToolkit();
        Dimension sc=kit.getScreenSize();
        JFrame jFrame=new JFrame();
        int width=sc.width;
        int height=sc.height;
        jFrame.setBounds((width-313)/2,(height-300)/2,313,300);
        JPanel calendar = new JPanelByCalendar();
        jFrame.setContentPane(calendar);
        jFrame.setVisible(true);
    }
    abstract class MouseUpListener extends MouseAdapter{
        private JLabel jLabel;

        private Integer type=-1;

        public MouseUpListener(JLabel jLabel) {
            this.jLabel = jLabel;
        }

        public MouseUpListener(JLabel jLabel,Integer type) {
            this.jLabel = jLabel;
            this.type=type;
        }

        @Override
        public void mouseEntered(MouseEvent e) {
            jLabel.setBackground(Color.lightGray);
        }

        @Override
        public void mouseExited(MouseEvent e) {
            if(type==0){
                jLabel.setBackground(null);
            }else {
                jLabel.setBackground(Color.white);
            }
        }
    }
}

说明

该代码使用JPanel实现,选择年份,月份,日期

效果图

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值