zoukankan      html  css  js  c++  java
  • java.Swing中的月份选择器

    背景:

      最近在做个Java程序,用来做客户端,使用Swing来开发,界面需要选择一个月份,这个时候使用日期选择器就很蹩脚,不太好应用,网上搜了一会儿找不到合适的拿来直接用,所以在其中一个博客上面找到一个DateChooser的类进行修改,用于进行月份选择;修改后可以拿来使用,对于业务的场景使用OK了,后续比如增加月份选择后再选择等操作还没有实现,后续有空再增加,另外还有部分不再使用的代码还没空删除,有需要的可以参照代码,代码如下:

      

    package my.contacteditor;
    
    /**
     * @date 2018-11-21
     */
      
    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.Font;  
    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.awt.event.MouseMotionListener;  
    import java.text.SimpleDateFormat;  
    import java.util.ArrayList;  
    import java.util.Calendar;  
    import java.util.Comparator;  
    import java.util.Date;  
    import java.util.List;  
    import javax.swing.BorderFactory;  
    import javax.swing.JButton;  
    import javax.swing.JFrame;  
    import javax.swing.JLabel;  
    import javax.swing.JPanel;  
    import javax.swing.Popup;  
    import javax.swing.PopupFactory;  
    import javax.swing.SwingConstants;
    import javax.swing.SwingUtilities;  
    import javax.swing.event.AncestorEvent;  
    import javax.swing.event.AncestorListener;  
      
    /** 
     * 月份选择器,选择相应的月份 
     */  
    public class MonthChooser extends JPanel{  
        private static final long serialVersionUID = 4529266044762990227L;  
        
        private Date initDate;  
        private Calendar now=Calendar.getInstance();  
        private Calendar select;  
        private Date selectDate;
        private JPanel monthPanel;//月历  
        private JP1 jp1;//四块面板,组成  
        private JP2 jp2;  
        private JP3 jp3;  
        private JP4 jp4;  
        private Font font=new Font("宋体",Font.PLAIN,12);  
        private final LabelManager lm=new LabelManager();  
        private JLabel showDate; //,toSelect;  
        private SimpleDateFormat sdf;  
        private boolean isShow=false;  
        private Popup pop;  
        
        /** 
         * Creates a new instance of DateChooser 
         */  
        public MonthChooser() {  
            this(new Date());  
        }  
        public MonthChooser(Date date){  
           this(date, "yyyy年MM月");  
        }  
        public MonthChooser(String format){  
            this(new Date(), format);  
        }  
        public MonthChooser(Date date, String format){  
            initDate=date;  
            selectDate = date;
            sdf=new SimpleDateFormat(format);  
            select=Calendar.getInstance();  
            select.setTime(initDate);  
            initPanel();  
            initLabel();  
        }  
        
        public void resetDate() {
            select.setTime(new Date());
            refresh();
        }
          
        /** 
         * 是否允许用户选择 
         */  
        public void setEnabled(boolean b){  
            super.setEnabled(b);  
            showDate.setEnabled(b);  
        }  
          
        /** 
         *得到当前选择框的日期 
         */  
        public Date getDate(){  
            return select.getTime();  
        }  
          
        //根据初始化的日期,初始化面板  
        private void initPanel(){  
            monthPanel=new JPanel(new BorderLayout());  
            monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));  
            JPanel up=new JPanel(new BorderLayout());  
            up.add(jp1=new JP1(),BorderLayout.NORTH);  
            //up.add(jp2=new JP2(),BorderLayout.CENTER);  
            monthPanel.add(jp3=new JP3(),BorderLayout.CENTER);  
            monthPanel.add(up,BorderLayout.NORTH);  
            monthPanel.add(jp4=new JP4(),BorderLayout.SOUTH);  
            this.addAncestorListener(new AncestorListener(){  
                public void ancestorAdded(AncestorEvent event) {  
                      
                }  
                public void ancestorRemoved(AncestorEvent event) {  
                      
                }  
                //只要祖先组件一移动,马上就让popup消失  
                public void ancestorMoved(AncestorEvent event) {  
                    hidePanel();  
                }  
            });  
        }  
        
        //初始化标签  
        private void initLabel(){  
            showDate=new JLabel(sdf.format(initDate));  
            showDate.setRequestFocusEnabled(true);  
            showDate.addMouseListener(new MouseAdapter(){  
                public void mousePressed(MouseEvent me){  
                    showDate.requestFocusInWindow();  
                }  
            });  
            
            this.setBackground(Color.WHITE);  
            this.add(showDate,BorderLayout.CENTER);
            this.setPreferredSize(new Dimension(90,25));  
            this.setBorder(BorderFactory.createLineBorder(Color.GRAY));  
            showDate.addMouseListener(new MouseAdapter(){  
                public void mouseEntered(MouseEvent me){  
                    if(showDate.isEnabled()){  
                        showDate.setCursor(new Cursor(Cursor.HAND_CURSOR));  
                        showDate.setForeground(Color.RED);  
                    }  
                }  
                public void mouseExited(MouseEvent me){  
                    if(showDate.isEnabled()){  
                        showDate.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
                        showDate.setForeground(Color.BLACK);  
                    }  
                }  
                public void mousePressed(MouseEvent me){  
                    if(showDate.isEnabled()){  
                        showDate.setForeground(Color.CYAN);  
                        if(isShow){  
                            hidePanel();  
                        }else{  
                            showPanel(showDate);  
                        }  
                    }  
                }  
                public void mouseReleased(MouseEvent me){  
                    if(showDate.isEnabled()){  
                        showDate.setForeground(Color.BLACK);  
                    }  
                }  
            });  
            showDate.addFocusListener(new FocusListener(){  
                public void focusLost(FocusEvent e){  
                    hidePanel();  
                }  
                public void focusGained(FocusEvent e){  
                      
                }  
            });  
        }  
        
        //根据新的日期刷新  
        private void refresh(){  
            jp1.updateDate();  
            jp3.updateDate();  
            SwingUtilities.updateComponentTreeUI(this);  
        }  
        
        //提交日期  
        private void commit(){  
            System.out.println("选中的日期是:"+sdf.format(select.getTime()));  
            showDate.setText(sdf.format(select.getTime()));  
            selectDate = select.getTime();
            hidePanel();  
        }  
        
        //隐藏日期选择面板  
        private void hidePanel(){  
            if(pop!=null){  
                isShow=false;  
                pop.hide();  
                pop=null;  
            }  
        }  
        
        //显示日期选择面板  
        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-295){  
                x=size.width-295;  
            }  
            if(y<size.height-170){  
            }else{  
                y-=188;  
            }  
            pop=PopupFactory.getSharedInstance().getPopup(owner,monthPanel,x,y);  
            pop.show();  
            isShow=true;  
        }  
        
        /** 
         * 最上面的面板用来显示月份的增减 
         */  
        private class JP1 extends JPanel{  
            JLabel yearleft,yearright,center,centercontainer;  
            public JP1(){  
                super(new BorderLayout());  
                this.setBackground(new Color(160,185,215));  
                initJP1();  
            }  
            private void initJP1(){  
                yearleft=new JLabel("  <<",JLabel.CENTER);  
                yearleft.setToolTipText("上一年");  
                yearright=new JLabel(">>  ",JLabel.CENTER);  
                yearright.setToolTipText("下一年");  
                yearleft.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));  
                yearright.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));  
                  
                centercontainer=new JLabel("", JLabel.CENTER);  
                centercontainer.setLayout(new BorderLayout());  
                center=new JLabel("", JLabel.CENTER);  
       
                centercontainer.add(center,BorderLayout.CENTER);   
                  
                this.add(yearleft,BorderLayout.WEST);  
                this.add(centercontainer,BorderLayout.CENTER);  
                this.add(yearright,BorderLayout.EAST);  
                this.setPreferredSize(new Dimension(295,25));  
                  
                updateDate();  
                  
                yearleft.addMouseListener(new MouseAdapter(){  
                    public void mouseEntered(MouseEvent me){  
                        yearleft.setCursor(new Cursor(Cursor.HAND_CURSOR));  
                        yearleft.setForeground(Color.RED);  
                    }  
                    public void mouseExited(MouseEvent me){  
                        yearleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
                        yearleft.setForeground(Color.BLACK);  
                    }  
                    public void mousePressed(MouseEvent me){  
                        select.add(Calendar.YEAR,-1);  
                        yearleft.setForeground(Color.WHITE);  
                        refresh();  
                    }  
                    public void mouseReleased(MouseEvent me){  
                        yearleft.setForeground(Color.BLACK);  
                    }  
                });  
                yearright.addMouseListener(new MouseAdapter(){  
                    public void mouseEntered(MouseEvent me){  
                        yearright.setCursor(new Cursor(Cursor.HAND_CURSOR));  
                        yearright.setForeground(Color.RED);  
                    }  
                    public void mouseExited(MouseEvent me){  
                        yearright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
                        yearright.setForeground(Color.BLACK);  
                    }  
                    public void mousePressed(MouseEvent me){  
                        select.add(Calendar.YEAR,1);  
                        yearright.setForeground(Color.WHITE);  
                        refresh();  
                    }  
                    public void mouseReleased(MouseEvent me){  
                        yearright.setForeground(Color.BLACK);  
                    }  
                });  
            }  
            private void updateDate(){  
                center.setText(select.get(Calendar.YEAR)+"年");  
            }  
        }  
        
        private class JP2 extends JPanel{  
            public JP2(){  
                this.setPreferredSize(new Dimension(295,20));  
            }  
            protected void paintComponent(Graphics g){  
                g.setFont(font);  
                g.drawString("月份一 月份二 月份三 月份四 月份五 月份六",5,10);  
                g.drawLine(0,15,getWidth(),15);  
            }  
        }  
        
        private class JP3 extends JPanel{  
            public JP3(){  
                super(new GridLayout(3,4));  
                this.setPreferredSize(new Dimension(295,100));  
                initJP3();  
            }  
            private void initJP3(){  
                updateDate();  
            }  
            public void updateDate(){  
                this.removeAll();  
                lm.clear();  
                Date temp=select.getTime();  
                Calendar select=Calendar.getInstance();  
                select.setTime(temp);  
                select.set(Calendar.DAY_OF_MONTH,1);
                Calendar show=Calendar.getInstance();
                show.set(Calendar.DAY_OF_MONTH,1);
                show.set(Calendar.YEAR,select.get(Calendar.YEAR));
                show.set(Calendar.MONTH,0);
                for(int i=0;i<12;i++){  
                    lm.addLabel(new MyLabel(show.get(Calendar.YEAR),  
                            show.get(Calendar.MONTH)));  
                    show.add(Calendar.MONTH,1);
                }  
                for(MyLabel my:lm.getLabels()){  
                    this.add(my);  
                }  
                select.setTime(temp);  
            }  
        }  
        
        private class MyLabel extends JLabel implements Comparator<MyLabel>,  
                MouseListener,MouseMotionListener{  
            private int year,month;  
            private boolean isSelected;  
            public MyLabel(int year,int month){  
                super(""+(month+1)+"月",JLabel.CENTER);  
                this.year=year;  
                this.month=month;  
                this.addMouseListener(this);  
                this.addMouseMotionListener(this);  
                this.setFont(font);  
                if(year==select.get(Calendar.YEAR)){  
                    this.setForeground(Color.BLACK);  
                }else{  
                    this.setForeground(Color.LIGHT_GRAY);  
                }  
                if(month==select.get(Calendar.MONTH) && year == select.get(Calendar.YEAR)){  
                    this.setBackground(new Color(160,185,215));  
                }else{  
                    this.setBackground(Color.WHITE);  
                }  
            }  
            public boolean getIsSelected(){  
                return isSelected;  
            }  
            public void setSelected(boolean b,boolean isDrag){  
                isSelected=b;  
                if(b&&!isDrag){  
                    int temp=select.get(Calendar.MONTH);  
                    select.set(year,month,1);  
                    if(temp==month){  
                        SwingUtilities.updateComponentTreeUI(jp3);  
                    }else{  
                        refresh();  
                    }  
                }  
                this.repaint();  
            }  
            protected void paintComponent(Graphics g){  
                Calendar sd = Calendar.getInstance();
                sd.setTime(selectDate);
                if(year==sd.get(Calendar.YEAR) && month==sd.get(Calendar.MONTH) ){  
                    //如果当前日期是选择日期,则高亮显示  
                    g.setColor(new Color(160,185,215));  
                    g.fillRect(0,0,getWidth(),getHeight());  
                }  
                
                if(year==now.get(Calendar.YEAR)&&  
                        month==now.get(Calendar.MONTH)){  
                    //如果日期和当前日期一样,则用红框  
                    Graphics2D gd=(Graphics2D)g;  
                    gd.setColor(Color.RED);  
                    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();  
            }  
            public void mouseClicked(MouseEvent e) {  
            }  
            public void mousePressed(MouseEvent e) {  
                isSelected=true;  
                update();  
            }  
            public void mouseReleased(MouseEvent e) {  
                Point p=SwingUtilities.convertPoint(this,e.getPoint(),jp3);  
                lm.setSelect(p,false);  
                commit();  
            }  
            public void mouseEntered(MouseEvent e) {  
            }  
              
            public void mouseExited(MouseEvent e) {  
            }  
            public void mouseDragged(MouseEvent e) {  
                Point p=SwingUtilities.convertPoint(this,e.getPoint(),jp3);  
                lm.setSelect(p,true);  
            }  
            public void mouseMoved(MouseEvent e) {  
            }  
            public int compare(MyLabel o1, MyLabel o2) {  
                Calendar c1=Calendar.getInstance();  
                c1.set(o1.year,o2.month,1);  
                Calendar c2=Calendar.getInstance();  
                c2.set(o2.year,o2.month,1);  
                return c1.compareTo(c2);  
            }  
        }  
        
        private class LabelManager{  
            private List<MyLabel> list;  
            public LabelManager(){  
                list=new ArrayList<MyLabel>();  
            }  
            public List<MyLabel> getLabels(){  
                return list;  
            }  
            public void addLabel(MyLabel my){  
                list.add(my);  
            }  
            public void clear(){  
                list.clear();  
            }  
            public void setSelect(MyLabel my, boolean b){  
                for(MyLabel m:list){  
                    if(m.equals(my)){  
                        m.setSelected(true,b);  
                    }else{  
                        m.setSelected(false,b);  
                    }  
                }  
            }  
            public void setSelect(Point p, boolean b){  
                //如果是拖动,则要优化一下,以提高效率  
                if(b){  
                    //表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和  
                    //将要显示的标签找到了就可以了  
                    boolean findPrevious=false,findNext=false;  
                    for(MyLabel m:list){  
                        if(m.contains(p)){  
                            findNext=true;  
                            if(m.getIsSelected()){  
                                findPrevious=true;  
                            }else{  
                                m.setSelected(true,b);  
                            }  
                        }else if(m.getIsSelected()){  
                            findPrevious=true;  
                            m.setSelected(false,b);  
                        }  
                        if(findPrevious&&findNext){  
                            return;  
                        }  
                    }  
                }else{  
                    MyLabel temp=null;  
                    for(MyLabel m:list){  
                        if(m.contains(p)){  
                            temp=m;  
                        }else if(m.getIsSelected()){  
                            m.setSelected(false,b);  
                        }  
                    }  
                    if(temp!=null){  
                        temp.setSelected(true,b);  
                    }  
                }  
            }  
        }  
        
        private class JP4 extends JPanel{  
            public JP4(){  
                super(new BorderLayout());  
                this.setPreferredSize(new Dimension(295,20));  
                this.setBackground(new Color(160,185,215));  
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月");  
                final JLabel jl=new JLabel("本月: "+sdf.format(new Date()));  
                jl.setToolTipText("点击选择本月");
                jl.setHorizontalAlignment(SwingConstants.CENTER);
                this.add(jl,BorderLayout.CENTER);  
                jl.addMouseListener(new MouseAdapter(){  
                    public void mouseEntered(MouseEvent me){  
                        jl.setCursor(new Cursor(Cursor.HAND_CURSOR));  
                        jl.setForeground(Color.RED);  
                    }  
                    public void mouseExited(MouseEvent me){  
                        jl.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
                        jl.setForeground(Color.BLACK);  
                    }  
                    public void mousePressed(MouseEvent me){  
                        jl.setForeground(Color.WHITE);  
                        select.setTime(new Date());  
                        refresh();  
                        commit();  
                    }  
                    public void mouseReleased(MouseEvent me){  
                        jl.setForeground(Color.BLACK);  
                    }  
                });  
            }  
        }  
        
        public static void main(String[] args) {  
            final MonthChooser mp = new MonthChooser("yyyy年MM月");  
            JFrame jf = new JFrame("测试月份选择器");  
            jf.add(mp, BorderLayout.CENTER);  
            jf.add(new JButton("测试用的"),BorderLayout.NORTH);  
            jf.pack();  
            jf.setLocationRelativeTo(null);  
            jf.setVisible(true);  
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        }  
    }  
    

      

  • 相关阅读:
    LeetCode: Search in Rotated Sorted Array
    LeetCode: Search in Rotated Sorted Array II
    LeetCode: Search Insert Position
    LeetCode: Same Tree
    LeetCode: Search a 2D Matrix
    Oracle工具下载地址
    华为创始人任正非简介
    个人开公司的流程,以后用得着!
    如何更改收藏夹的位置,收藏夹的位置
    帮助大家了解到Google关键字排名、价格
  • 原文地址:https://www.cnblogs.com/coldforce/p/9995513.html
Copyright © 2011-2022 走看看