Swing 自定义日期选择器

Easter79
• 阅读 586

1. 如何对事件进行管理,可以查看这个 http://my.oschina.net/abian/blog/497296

截图:

Swing 自定义日期选择器

package unit;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.EventListener;
import java.util.GregorianCalendar;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.event.EventListenerList;

/**
 * 日期选择器 采用触发事件的方式,这样的话,就可以将DateChooser添加到任何组件之上,
 * 任何组件都可以捕获日期选择的事件,然后进行相应处理
 * 
 * @author changwen
 * @date Aug 26, 2015
 */

@SuppressWarnings("all")
public class DateChooser extends JPanel {

    protected Color weekBackgroundColor = new Color(189, 235, 238);
    protected Color weekendBtnFontColor = new Color(240, 64, 64); // color
    protected Color selectedColor = weekBackgroundColor;
    protected Font labelFont = new Font("Arial", Font.PLAIN, 10);
    protected Color defaultBtnFontColor = Color.BLACK;
    protected Color defaultBtnBackgroundColor = Color.WHITE;
    private Calendar cal = null;
    private Calendar todayCal = null;
    private int year;
    private int month;
    private int day;
    private JPanel controllPanel = null;
    private JPanel dateContainerPanel = null;
    private JLabel todayLabel = null;
    protected DateButton[][] buttonDays = null;
    public JComboBox monthChoice;
    public JComboBox yearChoice;
    protected String[] weekTitle = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    protected int[] months = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    private EventListenerList actionListenerList = new EventListenerList();

    public DateChooser() {
        buttonDays = new DateButton[6][7];
        cal = Calendar.getInstance();
        todayCal = Calendar.getInstance();
        this.year = cal.get(Calendar.YEAR);
        this.month = cal.get(Calendar.MONTH);
        this.day = cal.get(Calendar.DATE);
        JPanel oprPanel = createControlPanel();
        this.setLayout(new BorderLayout(0, 0));
        dateContainerPanel = new JPanel();
        createDayPanel(cal);
        setActiveDay(day);
        this.add(oprPanel, BorderLayout.NORTH);
        this.add(dateContainerPanel, BorderLayout.CENTER);

    }

    @SuppressWarnings("all")
    public JPanel createControlPanel() {
        controllPanel = new JPanel();
        controllPanel.setBackground(Color.WHITE);
        Box hBox = Box.createHorizontalBox();
        String strToday = formatDate(todayCal);
        todayLabel = new JLabel(strToday);
        monthChoice = new JComboBox();
        for (int i = 0; i < months.length; i++) {
            monthChoice.addItem(months[i]);
        }

        monthChoice.setSelectedItem(months[month]);
        monthChoice.setPreferredSize(new Dimension(monthChoice.getPreferredSize().width,
                monthChoice.getPreferredSize().height));

        monthChoice.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                int i = monthChoice.getSelectedIndex();
                if (i >= 0) {
                    month = i;
                    Calendar cal = new GregorianCalendar(year, month, 1);
                    year = cal.get(Calendar.YEAR);
                    month = cal.get(Calendar.MONTH);
                    createDayPanel(cal);
                }
            }
        });
        int currentYear = todayCal.get(Calendar.YEAR);
        final int gapYears = 10;
        yearChoice = new JComboBox();
        for (int i = currentYear - gapYears; i < currentYear + gapYears; i++) {
            yearChoice.addItem(i);
        }

        yearChoice.setSelectedIndex(gapYears);
        yearChoice.setPreferredSize(new Dimension(yearChoice.getPreferredSize().width,
                yearChoice.getPreferredSize().height));

        yearChoice.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                System.out.println(yearChoice.getSelectedIndex());
                if (yearChoice.getSelectedIndex() != gapYears) {
                    Integer selYear = (Integer) yearChoice.getSelectedItem();
                    Calendar cal = new GregorianCalendar(year, month, 1);
                    cal.set(Calendar.YEAR, selYear);
                    year = cal.get(Calendar.YEAR);
                    month = cal.get(Calendar.MONTH);
                    createDayPanel(cal);
                }
            }
        });

        hBox.add(todayLabel);
        hBox.add(Box.createHorizontalStrut(5));
        hBox.add(monthChoice);
        hBox.add(Box.createHorizontalStrut(8));
        hBox.add(yearChoice);
        hBox.add(Box.createHorizontalStrut(8));

        controllPanel.add(hBox, BorderLayout.NORTH);
        return controllPanel;

    }

    /**
     * 创建日期组件
     * 
     * @param cal
     *            void
     */
    public void createDayPanel(Calendar cal) {
        dateContainerPanel.removeAll();
        dateContainerPanel.revalidate();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        int weeks = cal.get(Calendar.WEEK_OF_MONTH);

        GridLayout grid = new GridLayout(7, 7, 0, 0);
        dateContainerPanel.setLayout(grid);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int weekday = cal.get(Calendar.DAY_OF_WEEK);
        System.out.println("weekday+" + weekday);
        cal.add(Calendar.DAY_OF_MONTH, 1 - weekday);
        System.out.println("Calendar.DAY_OF_MONTH=" + cal.get(Calendar.DAY_OF_MONTH));

        for (int i = 0; i < 7; i++) {
            JLabel weekLabel = new JLabel(weekTitle[i], SwingConstants.CENTER);
            weekLabel.setFont(labelFont);
            weekLabel.setOpaque(true);
            weekLabel.setBackground(weekBackgroundColor);
            dateContainerPanel.add(weekLabel);
        }
        DayButtonActionListener dayButtonActionListener = new DayButtonActionListener();

        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 7; j++) {
                int curMonth = cal.get(Calendar.MONTH);
                DateButton button = null;
                if (curMonth != month) {
                    button = new DateButton(" ");
                    button.setEnabled(false);
                    button.setBackground(defaultBtnBackgroundColor);
                } else {
                    int currentDay = cal.get(Calendar.DAY_OF_MONTH);
                    button = new DateButton(currentDay + "");
                    button.setHorizontalTextPosition(SwingConstants.RIGHT);
                    button.setFont(labelFont);
                    button.setBackground(defaultBtnBackgroundColor);
                    button.setSelectedBackground(weekBackgroundColor);
                    if (currentDay == todayCal.get(Calendar.DAY_OF_MONTH) && month == todayCal.get(Calendar.MONTH)
                            && year == todayCal.get(Calendar.YEAR)) {
                        button.setBorder(BorderFactory.createLineBorder(weekendBtnFontColor));
                    }
                    if (cal.get(Calendar.MONTH) != month) {
                        button.setForeground(Color.BLUE);
                    }
                    if (j == 0 || j == 6) {
                        button.setForeground(weekendBtnFontColor);
                    } else {
                        button.setForeground(defaultBtnFontColor);
                    }

                }
                button.addActionListener(dayButtonActionListener);
                buttonDays[i][j] = button;
                dateContainerPanel.add(buttonDays[i][j]);
                cal.add(Calendar.DAY_OF_MONTH, 1);
            }
        }

    }

    /**
     * 选中莫一天
     * 
     * @param selectedDay
     *            void
     */
    public void setActiveDay(int selectedDay) {
        clearAllActiveDay();
        if (selectedDay <= 0) {
            day = new GregorianCalendar().get(Calendar.DAY_OF_MONTH);
        } else {
            day = selectedDay;
        }
        int leadGap = new GregorianCalendar(year, month, 1).get(Calendar.DAY_OF_WEEK) - 1;
        JButton selectedButton = buttonDays[(leadGap + selectedDay - 1) / 7][(leadGap + selectedDay - 1) % 7];
        selectedButton.setBackground(weekBackgroundColor);
    }

    /**
     * 清除所有选择的日期
     * 
     */
    public void clearAllActiveDay() {
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 7; j++) {
                JButton button = buttonDays[i][j];
                if (button.getText() != null && button.getText().trim().length() > 0) {
                    button.setBackground(defaultBtnBackgroundColor);
                    button.revalidate();
                }
            }

        }
    }

    /**
     * 获取选中的日期
     * 
     * @return String
     */
    public String getSelectedDate() {
        Calendar cal = new GregorianCalendar(year, month, day);
        return formatDate(cal);
    }

    private String formatDate(Calendar cal) {
        String pattern = "MM-dd-yyyy";
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(cal.getTime());
    }

    class DayButtonActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            JButton button = (JButton) e.getSource();
            if (button.getText() != null && button.getText().trim().length() > 0) {
                day = Integer.parseInt(button.getText());
                setActiveDay(day);
                fireActionPerformed(e);// fire button click event
                /**
                 * 采用触发事件的方式,这样的话,就可以将DateChooser添加到任何组件之上,
                 * 任何组件都可以捕获日期选择的事件,然后进行相应处理
                 */
            }
        }
    }

    public void addActionListener(ActionListener actionListener) {
        actionListenerList.add(ActionListener.class, actionListener);
    }

    public void removeActionListener(ActionListener actionListener) {
        actionListenerList.remove(ActionListener.class, actionListener);
    }

    /**
     * 事件管理,触发事件
     * 
     * @param actionEvent
     *            void
     */
    protected void fireActionPerformed(ActionEvent actionEvent) {
        EventListener listenerList[] = actionListenerList.getListeners(ActionListener.class);
        for (int i = 0, n = listenerList.length; i < n; i++) {
            ((ActionListener) listenerList[i]).actionPerformed(actionEvent);
        }
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("xxxxxx");
        frame.setSize(400, 300);

        final DateChooser datePicker = new DateChooser();
        datePicker.addActionListener(new ActionListener() {// 事件捕获

                    public void actionPerformed(ActionEvent e) {
                        System.out.println(datePicker.getSelectedDate());

                    }
                });
        frame.getContentPane().add(datePicker);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }

}

//-------自定义按钮--------------
package unit;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;

public class DateButton extends JButton {
    private static final long serialVersionUID = 1L;
    protected Color normalBackground;
    protected Color selectedBackground;
    public DateButton() {
        initAttributes();
    }

    public DateButton(Icon icon) {
        super(icon);
        initAttributes();
    }

    public DateButton(String text, Icon icon) {
        super(text, icon);
        initAttributes();
    }

    public DateButton(String text) {
        super(text);
        initAttributes();
    }

    public DateButton(Action a) {
        super(a);
        initAttributes();
    }

    public void initAttributes() {
        setRolloverEnabled(true);
        setBorder(BorderFactory.createEmptyBorder());
        setContentAreaFilled(false);
        setFocusPainted(false);
        setNormalBackground(new Color(216, 216, 216));
        setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    }

    @Override
    public void paint(Graphics g) {
        
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        Paint oldPaint = g2d.getPaint();
        
        if ((getModel().isSelected() || getModel().isPressed()) && selectedBackground != null) {
            g2d.setPaint(selectedBackground);
            g2d.fillRect(0, 0, getWidth(), getHeight());
        } else if (getNormalBackground() != null) {
            g2d.setPaint(getNormalBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }
        g2d.setPaint(oldPaint);
        super.paint(g2d);

    }

    public void clearDefaultAttribute() {
        setNormalBackground(null);
    }

    @Override
    public void setBackground(Color bg) {
        super.setBackground(bg);
        normalBackground = bg;
    }

    public Color getNormalBackground() {
        return normalBackground;
    }

    public void setNormalBackground(Color normalBackground) {
        super.setBackground(normalBackground);
        this.normalBackground = normalBackground;
    }

    

    public void setSelectedBackground(Color selectedBackground) {
        this.selectedBackground = selectedBackground;
    }

}

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
AndroidStudio封装SDK的那些事
<divclass"markdown\_views"<!flowchart箭头图标勿删<svgxmlns"http://www.w3.org/2000/svg"style"display:none;"<pathstrokelinecap"round"d"M5,00,2.55,5z"id"raphael
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k