• Swing 自定义日期控件



    /**
     * 
     * Copyright: Ares.
     * All Rights Reserved. 
     * Company: Insigma HT/上海创图
     *
     * Revision History
     *
     * Date            Programmer              Notes
     * ---------    ---------------------  --------------------------------------------
     * 2013-11-17       Ares                    initial
     * 2014-09-16       Ares                    fix bug @n3k123
     * 
     * 1. you can change date format by parameter.
     * 2. you can change week label content by showTEXT.
     * 3. you can change dayOfWeek order by defaultStartDAY.
     */
    package com.swing.test;
    
    import java.awt.BasicStroke;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Cursor;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.Point;
    import java.awt.Polygon;
    import java.awt.Stroke;
    import java.awt.Toolkit;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    
    import javax.swing.BorderFactory;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.PopupFactory;
    import javax.swing.SwingUtilities;
    import javax.swing.event.AncestorEvent;
    import javax.swing.event.AncestorListener;
    
    /**
     * @author Ares
     * @Describe(Date Chooser class)
     */
    public class Chooser extends JPanel{
    
        private static final long serialVersionUID = -5384012731547358720L;
        
        private Calendar calendar;
        private Calendar now = Calendar.getInstance();
        private JPanel calendarPanel;
        private java.awt.Font font = new java.awt.Font("Times",java.awt.Font.PLAIN,12);
        private java.text.SimpleDateFormat sdf;
        private final LabelManager lm = new LabelManager();
        private javax.swing.Popup pop;
        private TitlePanel titlePanel;
        private BodyPanel bodyPanel;
        private FooterPanel footerPanel;
        
        private JComponent showDate;
        private boolean isShow = false;
        private static final String DEFAULTFORMAT = "yyyy-MM-dd";
        private static final String[] showTEXT = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
        private static WeekLabel[] weekLabels = new WeekLabel[7];
        private static int defaultStartDAY = 0;//0 is from Sun, 1 is from Mon, 2 is from Tue
        private static Color hoverColor = Color.BLUE; // hover color
        
    
        private Chooser(java.util.Date date, String format, int startDAY){
            if(startDAY > -1 && startDAY < 7) defaultStartDAY = startDAY;
            int dayIndex = defaultStartDAY;
            for(int i=0; i<7; i++){
                if(dayIndex > 6) dayIndex = 0;
                weekLabels[i] = new WeekLabel(dayIndex, showTEXT[dayIndex]);
                dayIndex ++ ;
            }
            sdf = new java.text.SimpleDateFormat(format);
            calendar = Calendar.getInstance();
            calendar.setTime(date);
            initCalendarPanel();
        }
        
        public static Chooser getInstance(java.util.Date date, String format){
            return new Chooser(date, format, defaultStartDAY);
        }
    
        public static Chooser getInstance(java.util.Date date){
            return getInstance(date, DEFAULTFORMAT);
        }
        public static Chooser getInstance(String format){
            return getInstance(new java.util.Date(), format);
        }
        public static Chooser getInstance(){
            return getInstance(new java.util.Date(), DEFAULTFORMAT);
        }
        
        private void initCalendarPanel(){
            calendarPanel = new JPanel(new java.awt.BorderLayout());
            calendarPanel.setBorder(javax.swing.BorderFactory.
                                   createLineBorder(new java.awt.Color(0xAA, 0xAA, 0xAA)));
            calendarPanel.add(titlePanel = new TitlePanel(), java.awt.BorderLayout.NORTH);
            calendarPanel.add(bodyPanel = new BodyPanel(), java.awt.BorderLayout.CENTER);
            calendarPanel.add(footerPanel = new FooterPanel(),java.awt.BorderLayout.SOUTH);
            this.addAncestorListener(new AncestorListener() {
                public void ancestorAdded(AncestorEvent event) { }
                public void ancestorRemoved(AncestorEvent event) {hidePanel();}
                //hide pop when move component.  
                public void ancestorMoved(AncestorEvent event) {
                    hidePanel();
                }
            });
        }
        public void register(final JComponent showComponent) {
            this.showDate = showComponent;
            showComponent.setRequestFocusEnabled(true);
            showComponent.addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent me) {
                    showComponent.requestFocusInWindow();
                }
            });
            this.add(showComponent, BorderLayout.CENTER);
            this.setPreferredSize(new Dimension(90, 25));
            this.setBorder(BorderFactory.createLineBorder(Color.GRAY));
            showComponent.addMouseListener(new MouseAdapter() {
                public void mouseEntered(MouseEvent me) {
                    if (showComponent.isEnabled()) {
                        showComponent.setCursor(new Cursor(Cursor.HAND_CURSOR));
                    }
                }
                public void mouseExited(MouseEvent me) {
                    if (showComponent.isEnabled()) {
                        showComponent.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                        showComponent.setForeground(Color.BLACK);
                    }
                }
                public void mousePressed(MouseEvent me) {
                    if (showComponent.isEnabled()) {
                        showComponent.setForeground(hoverColor);
                        if (isShow) {
                            hidePanel();
                        } else {
                            showPanel(showComponent);
                        }
                    }
                }
                public void mouseReleased(MouseEvent me) {
                    if (showComponent.isEnabled()) {
                        showComponent.setForeground(Color.BLACK);
                    }
                }
            });
            showComponent.addFocusListener(new FocusListener() {
                public void focusLost(FocusEvent e) {
                    hidePanel();
                }
                public void focusGained(FocusEvent e) { }
            });
        }
        //hide the main panel.
        private void hidePanel() {
            if (pop != null) {
                isShow = false;
                pop.hide();
                pop = null;
            }
        }
     
        //show the main panel.
        private void showPanel(Component owner) {
            if (pop != null) pop.hide();
            Point show = new Point(0, showDate.getHeight());
            SwingUtilities.convertPointToScreen(show, showDate);
            Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
            int x = show.x;
            int y = show.y;
            if (x < 0) x = 0;
            if (x > size.width - 212) x = size.width - 212;
            if (y > size.height - 167) y -= 165;
            pop = PopupFactory.getSharedInstance().getPopup(owner, calendarPanel, x, y);
            pop.show();
            isShow = true;
        }
        // change text or label's content.
        private void commit() {
            if (showDate instanceof JTextField) {
                ((JTextField) showDate).setText(sdf.format(calendar.getTime()));
            }else if (showDate instanceof JLabel) {
                ((JLabel) showDate).setText(sdf.format(calendar.getTime()));
            }
            hidePanel();
        }
    
        // control panel
        private class TitlePanel extends JPanel {
            
            private static final long serialVersionUID = -2865282186037420798L;
            private JLabel preYear,preMonth,center,nextMonth,nextYear,centercontainer;
            
            public TitlePanel(){
                super(new java.awt.BorderLayout());
                this.setBackground(new java.awt.Color(190, 200, 200));
                initTitlePanel();
            }
            private void initTitlePanel(){
                preYear = new JLabel("<<", JLabel.CENTER);
                preMonth = new JLabel("<", JLabel.CENTER);
                center = new JLabel("", JLabel.CENTER);
                centercontainer = new JLabel("", JLabel.CENTER);
                nextMonth = new JLabel(">", JLabel.CENTER);
                nextYear = new JLabel(">>", JLabel.CENTER);
                
                preYear.setToolTipText("Last Year");
                preMonth.setToolTipText("Last Month");
                nextMonth.setToolTipText("Next Month");
                nextYear.setToolTipText("Next Year");
                
                preYear.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 10, 0, 0));
                preMonth.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 15, 0, 0));
                nextMonth.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 0, 0, 15));
                nextYear.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 0, 0, 10));
                
                centercontainer.setLayout(new java.awt.BorderLayout());
                centercontainer.add(preMonth,java.awt.BorderLayout.WEST);
                centercontainer.add(center,java.awt.BorderLayout.CENTER);
                centercontainer.add(nextMonth,java.awt.BorderLayout.EAST);
                
                this.add(preYear,java.awt.BorderLayout.WEST);
                this.add(centercontainer,java.awt.BorderLayout.CENTER);
                this.add(nextYear,java.awt.BorderLayout.EAST);
                this.setPreferredSize(new java.awt.Dimension(210, 25));
                
                updateDate();
                
                preYear.addMouseListener(new MyMouseAdapter(preYear, Calendar.YEAR, -1));
                preMonth.addMouseListener(new MyMouseAdapter(preMonth, Calendar.MONTH, -1));
                nextMonth.addMouseListener(new MyMouseAdapter(nextMonth, Calendar.MONTH, 1));
                nextYear.addMouseListener(new MyMouseAdapter(nextYear, Calendar.YEAR, 1));
            }
            
            private void updateDate() {
                center.setText(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH) + 1));
            }
            // listener for control label.
            class MyMouseAdapter extends java.awt.event.MouseAdapter{
                
                JLabel label;
                private int type, value;
                
                public MyMouseAdapter(final JLabel label, final int type, final int value){
                    this.label = label;
                    this.type = type;
                    this.value = value;
                }
                public void mouseEntered(java.awt.event.MouseEvent me) {
                    label.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
                    label.setForeground(hoverColor);
                }
                public void mouseExited(java.awt.event.MouseEvent me) {
                    label.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
                    label.setForeground(java.awt.Color.BLACK);
                }
                public void mousePressed(java.awt.event.MouseEvent me) {
                    calendar.add(type, value);
                    label.setForeground(java.awt.Color.WHITE);
                    refresh();
                }
                public void mouseReleased(java.awt.event.MouseEvent me) {
                    label.setForeground(java.awt.Color.BLACK);
                }
            }
        }
        // body panel, include week labels and day labels.
        private class BodyPanel extends JPanel {
            
            private static final long serialVersionUID = 5677718768457235447L;
            
            public BodyPanel(){
                super(new GridLayout(7, 7));
                this.setPreferredSize(new java.awt.Dimension(210, 140));
                initMonthPanel();
            }
            private void initMonthPanel(){
                updateDate();
            }
            public void updateDate() {
                this.removeAll();
                lm.clear();
                java.util.Date temp = calendar.getTime();
                Calendar cal = Calendar.getInstance();
                cal.setTime(temp);
                cal.set(Calendar.DAY_OF_MONTH, 1);
                
                int index = cal.get(Calendar.DAY_OF_WEEK);
                // 从当月1号前移,一直移动到面板显示的第一天的前一天;当-index + defaultStartDAY为正数时
                //,为避免面板从当月1号之后开始显示,需要前移一周,确保当月显示完全
                if(index > defaultStartDAY) cal.add(Calendar.DAY_OF_MONTH, -index + defaultStartDAY);
                else cal.add(Calendar.DAY_OF_MONTH, -index + defaultStartDAY - 7);
                
                for (WeekLabel weekLabel : weekLabels) {
                    this.add(weekLabel);
                }
                for (int i = 0; i < 42; i++) {
                    cal.add(Calendar.DAY_OF_MONTH, 1);
                    lm.addLabel(new DayLabel(cal));
                }
                for (DayLabel my : lm.getLabels()) {
                    this.add(my);
                }
            }
        }
        
        private class FooterPanel extends JPanel {
            
            private static final long serialVersionUID = 8135037333899746736L;
            private JLabel dateLabel;
            
            public FooterPanel(){
                super(new BorderLayout());
                initFooterPanel();
            }
            private void initFooterPanel(){
                dateLabel = new JLabel("Today is : "+sdf.format(new java.util.Date()));
                dateLabel.addMouseListener(new MouseListener() {
                    
                    @Override
                    public void mouseReleased(MouseEvent e) {}
                    @Override
                    public void mousePressed(MouseEvent e) {
                        calendar.setTime(new Date());
                        refresh();
                        commit();
                    }
                    @Override
                    public void mouseExited(MouseEvent e) {
                        dateLabel.setForeground(Color.BLACK);
                    }
                    @Override
                    public void mouseEntered(MouseEvent e) {
                        dateLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
                        dateLabel.setForeground(hoverColor);
                    }
                    @Override
                    public void mouseClicked(MouseEvent e) {}
                });
                this.add(dateLabel);
            }
            public void updateDate(){};
        }
        //refresh all panel
        private void refresh() {
            titlePanel.updateDate();
            bodyPanel.updateDate();
            footerPanel.updateDate();
            SwingUtilities.updateComponentTreeUI(this);
        }
        
        private class WeekLabel extends JLabel {
            
            private static final long serialVersionUID = -8053965084432740110L;
            private String name;
            
            public WeekLabel(int index, String name){
                super(name, JLabel.CENTER);
                this.name = name;
            }
            public String toString(){
                return name;
            }
        }
        
        private class DayLabel extends JLabel implements java.util.Comparator,
                                      java.awt.event.MouseListener, java.awt.event.MouseMotionListener {
    
            private static final long serialVersionUID = -6002103678554799020L;
            private boolean isSelected;
            private int year, month, day;
            
            public DayLabel(Calendar cal){
                super(""+cal.get(Calendar.DAY_OF_MONTH), JLabel.CENTER);
                this.year = cal.get(Calendar.YEAR);
                this.month = cal.get(Calendar.MONTH);
                this.day = cal.get(Calendar.DAY_OF_MONTH);
                
                this.setFont(font);
                this.addMouseListener(this);
                this.addMouseMotionListener(this);
                if(month == calendar.get(Calendar.MONTH)) this.setForeground(java.awt.Color.BLACK);
                else this.setForeground(java.awt.Color.LIGHT_GRAY);
                
            }
            public boolean getIsSelected() {
                return isSelected;
            }
            public void setSelected(boolean b, boolean isDrag) {
                isSelected = b;
                if (b && !isDrag) {
                    int temp = calendar.get(Calendar.MONTH);
                    calendar.set(year, month, day);
                    if (temp == month) {
                        SwingUtilities.updateComponentTreeUI(bodyPanel);
                    } else {
                        refresh();
                    }
                    this.repaint();
                }
            }
            
            @Override
            protected void paintComponent(Graphics g) {
                //set curr select day's background
                if(day == calendar.get(Calendar.DAY_OF_MONTH) && month == calendar.get(Calendar.MONTH)){
                    g.setColor(new java.awt.Color(0xBB, 0xBF, 0xDA));
                    g.fillRect(0, 0, getWidth(), getHeight());
                }
                //set current day's border
                if(year == now.get(Calendar.YEAR) && month ==
                                          now.get(Calendar.MONTH) && day == now.get(Calendar.DAY_OF_MONTH)){
                    Graphics2D gd = (Graphics2D) g;
                    gd.setColor(new java.awt.Color(0x55, 0x55, 0x88));
                    Polygon p = new Polygon();
                    p.addPoint(0, 0);
                    p.addPoint(getWidth() - 1, 0);
                    p.addPoint(getWidth() - 1, getHeight() - 1);
                    p.addPoint(0, getHeight() - 1);
                    gd.drawPolygon(p);
                }
                if (isSelected){
                    Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, 
                                           BasicStroke.JOIN_BEVEL, 1.0f, new float[] { 2.0f, 2.0f }, 1.0f);
                    Graphics2D gd = (Graphics2D) g;
                    gd.setStroke(s);
                    gd.setColor(Color.BLACK);
                    Polygon p = new Polygon();
                    p.addPoint(0, 0);
                    p.addPoint(getWidth() - 1, 0);
                    p.addPoint(getWidth() - 1, getHeight() - 1);
                    p.addPoint(0, getHeight() - 1);
                    gd.drawPolygon(p);
                }
                super.paintComponent(g);
            }
            public boolean contains(Point p) {
                return this.getBounds().contains(p);
            }
            private void update() {
                repaint();
            }
            @Override
            public void mouseDragged(MouseEvent e) { }
            @Override
            public void mouseMoved(MouseEvent e) { }
            @Override
            public void mouseClicked(MouseEvent e) { }
    
            @Override
            public void mousePressed(MouseEvent e) {
                isSelected = true;
                update();
            }
    
            @Override
            public void mouseReleased(MouseEvent e) {
                Point p = SwingUtilities.convertPoint(this, e.getPoint(), bodyPanel);
                this.setForeground(Color.BLACK);
                lm.setSelect(p, false);
                commit();
            }
            @Override // change color when mouse over.
            public void mouseEntered(MouseEvent e) {
                this.setForeground(hoverColor);
                this.repaint();
            }
            @Override // change color when mouse exit.
            public void mouseExited(MouseEvent e) {
                if(month == calendar.get(Calendar.MONTH)) this.setForeground(java.awt.Color.BLACK);
                else this.setForeground(java.awt.Color.LIGHT_GRAY);
                this.repaint();
            }
            @Override
            public int compare(DayLabel o1, DayLabel o2) {
                Calendar c1 = Calendar.getInstance();
                c1.set(o1.year, o1.month, o1.day);
                Calendar c2 = Calendar.getInstance();
                c2.set(o2.year, o2.month, o2.day);
                return c1.compareTo(c2);
            }
            
        }
        
        private class LabelManager {
            private List list;
            
            public LabelManager(){
                list = new ArrayList();
            }
            
            public List getLabels(){
                return list;
            }
            public void addLabel(DayLabel label){
                list.add(label);
            }
            public void clear() {
                list.clear();
            }
            public void setSelect(Point p, boolean b) {
                //如果是拖动,则要优化一下,以提高效率  
                if (b) {
                    //表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和  
                    //将要显示的标签找到了就可以了  
                    boolean findPrevious = false, findNext = false;
                    for (DayLabel lab : list) {
                        if (lab.contains(p)) {
                            findNext = true;
                            if (lab.getIsSelected()) findPrevious = true;
                            else lab.setSelected(true, b);
                        } else if (lab.getIsSelected()) {
                            findPrevious = true;
                            lab.setSelected(false, b);
                        }
                        if (findPrevious && findNext) return;
                    }
                }else {
                    DayLabel temp = null;
                    for (DayLabel m : list) {
                        if (m.contains(p)) {
                            temp = m;
                        } else if (m.getIsSelected()) {
                            m.setSelected(false, b);
                        }
                    }
                    if (temp != null) temp.setSelected(true, b);
                }
            }
        }
        
        
        /**
         * @param args
         */
        public static void main(String[] args) {
            JFrame jf = new JFrame("Date Picker Test");
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jf.setLayout(null);
            jf.setBounds(400, 200, 600, 400);
            
            Chooser ser = Chooser.getInstance();
            javax.swing.JTextField text = new JTextField();
            text.setBounds(10, 10, 200, 30);
            text.setText("2013-10-11");
            ser.register(text);
            
            Chooser ser2 = Chooser.getInstance("yyyy年MM月dd日");
            JLabel label = new JLabel("please click me.");
            label.setBounds(10, 50, 200, 30);
            ser2.register(label);
            
            jf.add(text);
            jf.add(label);
            jf.setVisible(true);
        }
    }
  • 相关阅读:
    一个最简单的例子学习SAP Cloud for Customer HTML mashup
    SAP C4C Embedded Component最常见的故障原因分析
    使用SAP CRM Mock framework进行单元测试
    ABAP Debugging Script(调试器脚本)使用的一些实际例子
    SAP ABAP字符和字符串变量隐式转换的一些规则
    两种使用代码获得SAP CRM product sales status的办法
    扎根CNCF社区贡献五年是怎样的体验?听听华为云原生开源团队的负责人怎么说
    LiteOS调测利器:backtrace函数原理知多少
    微服务容错时,这些技术你要立刻想到
    Volcano 监控设计解读,一看就懂
  • 原文地址:https://www.cnblogs.com/swbzmx/p/5605852.html
Copyright © 2020-2023  润新知