JAVA SWING 日期选择控件(目前支持JLable和JTextField)

  1. package com.monitor.date;  
  2.   
  3. import java.awt.BasicStroke;  
  4. import java.awt.BorderLayout;  
  5. import java.awt.Color;  
  6. import java.awt.Component;  
  7. import java.awt.Cursor;  
  8. import java.awt.Dimension;  
  9. import java.awt.Font;  
  10. import java.awt.Graphics;  
  11. import java.awt.Graphics2D;  
  12. import java.awt.GridLayout;  
  13. import java.awt.Point;  
  14. import java.awt.Polygon;  
  15. import java.awt.Stroke;  
  16. import java.awt.Toolkit;  
  17. import java.awt.event.FocusEvent;  
  18. import java.awt.event.FocusListener;  
  19. import java.awt.event.MouseAdapter;  
  20. import java.awt.event.MouseEvent;  
  21. import java.awt.event.MouseListener;  
  22. import java.awt.event.MouseMotionListener;  
  23. import java.text.SimpleDateFormat;  
  24. import java.util.ArrayList;  
  25. import java.util.Calendar;  
  26. import java.util.Comparator;  
  27. import java.util.Date;  
  28. import java.util.List;  
  29.    
  30. import javax.swing.BorderFactory;  
  31. import javax.swing.JComponent;  
  32. import javax.swing.JFrame;  
  33. import javax.swing.JLabel;  
  34. import javax.swing.JPanel;  
  35. import javax.swing.JTextField;  
  36. import javax.swing.Popup;  
  37. import javax.swing.PopupFactory;  
  38. import javax.swing.SwingUtilities;  
  39. import javax.swing.event.AncestorEvent;  
  40. import javax.swing.event.AncestorListener;  
  41.    
  42. /**  
  43.  * 日期选择器,可以指定日期的显示格式  
  44.  */  
  45. public class DateChooser extends JPanel {  
  46.    
  47.     private static final long serialVersionUID = 4529266044762990227L;  
  48.    
  49.     private Date initDate;  
  50.     private Calendar now = Calendar.getInstance();  
  51.     private Calendar select;  
  52.     private JPanel monthPanel;//月历    
  53.     private JP1 jp1;//四块面板,组成    
  54.     private JP2 jp2;  
  55.     private JP3 jp3;  
  56.     private JP4 jp4;  
  57.     private Font font = new Font(“宋体”, Font.PLAIN, 12);  
  58.     private final LabelManager lm = new LabelManager();  
  59.     private SimpleDateFormat sdf;  
  60.     private boolean isShow = false;  
  61.     private Popup pop;  
  62.    
  63.     private JComponent showDate;  
  64.    
  65.     public static DateChooser getInstance() {  
  66.         return new DateChooser();  
  67.     }  
  68.    
  69.     public static DateChooser getInstance(Date date) {  
  70.         return new DateChooser(date);  
  71.     }  
  72.    
  73.     public static DateChooser getInstance(String format) {  
  74.         return new DateChooser(format);  
  75.     }  
  76.    
  77.     public static DateChooser getInstance(Date date, String format) {  
  78.         return new DateChooser(date, format);  
  79.     }  
  80.    
  81.     /**  
  82.      * Creates a new instance of DateChooser  
  83.      */  
  84.     private DateChooser() {  
  85.         this(new Date());  
  86.     }  
  87.    
  88.     private DateChooser(Date date) {  
  89.         this(date, “yyyy年MM月dd日”);  
  90.     }  
  91.    
  92.     private DateChooser(String format) {  
  93.         this(new Date(), format);  
  94.     }  
  95.    
  96.     private DateChooser(Date date, String format) {  
  97.         initDate = date;  
  98.         sdf = new SimpleDateFormat(format);  
  99.         select = Calendar.getInstance();  
  100.         select.setTime(initDate);  
  101.         initPanel();  
  102.     }  
  103.    
  104.     /**  
  105.      * 是否允许用户选择  
  106.      */  
  107.     public void setEnabled(boolean b) {  
  108.         super.setEnabled(b);  
  109.         showDate.setEnabled(b);  
  110.     }  
  111.    
  112.     /**  
  113.      *得到当前选择框的日期  
  114.      */  
  115.     public Date getDate() {  
  116.         return select.getTime();  
  117.     }  
  118.    
  119.     public String getStrDate() {  
  120.         return sdf.format(select.getTime());  
  121.     }  
  122.    
  123.     public String getStrDate(String format) {  
  124.         sdf = new SimpleDateFormat(format);  
  125.         return sdf.format(select.getTime());  
  126.     }  
  127.    
  128.     //根据初始化的日期,初始化面板    
  129.     private void initPanel() {  
  130.         monthPanel = new JPanel(new BorderLayout());  
  131.         monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));  
  132.         JPanel up = new JPanel(new BorderLayout());  
  133.         up.add(jp1 = new JP1(), BorderLayout.NORTH);  
  134.         up.add(jp2 = new JP2(), BorderLayout.CENTER);  
  135.         monthPanel.add(jp3 = new JP3(), BorderLayout.CENTER);  
  136.         monthPanel.add(up, BorderLayout.NORTH);  
  137.         monthPanel.add(jp4 = new JP4(), BorderLayout.SOUTH);  
  138.         this.addAncestorListener(new AncestorListener() {  
  139.             public void ancestorAdded(AncestorEvent event) {  
  140.    
  141.             }  
  142.    
  143.             public void ancestorRemoved(AncestorEvent event) {  
  144.    
  145.             }  
  146.    
  147.             //只要祖先组件一移动,马上就让popup消失    
  148.             public void ancestorMoved(AncestorEvent event) {  
  149.                 hidePanel();  
  150.             }  
  151.         });  
  152.     }  
  153.    
  154.     public void register(final JComponent showDate) {  
  155.         this.showDate = showDate;  
  156.    
  157.         showDate.setRequestFocusEnabled(true);  
  158.         showDate.addMouseListener(new MouseAdapter() {  
  159.             public void mousePressed(MouseEvent me) {  
  160.                 showDate.requestFocusInWindow();  
  161.             }  
  162.         });  
  163.         this.setBackground(Color.WHITE);  
  164.         this.add(showDate, BorderLayout.CENTER);  
  165.         this.setPreferredSize(new Dimension(9025));  
  166.         this.setBorder(BorderFactory.createLineBorder(Color.GRAY));  
  167.         showDate.addMouseListener(new MouseAdapter() {  
  168.             public void mouseEntered(MouseEvent me) {  
  169.                 if (showDate.isEnabled()) {  
  170.                     showDate.setCursor(new Cursor(Cursor.HAND_CURSOR));  
  171.                     showDate.setForeground(Color.RED);  
  172.                 }  
  173.             }  
  174.    
  175.             public void mouseExited(MouseEvent me) {  
  176.                 if (showDate.isEnabled()) {  
  177.                     showDate.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
  178.                     showDate.setForeground(Color.BLACK);  
  179.                 }  
  180.             }  
  181.    
  182.             public void mousePressed(MouseEvent me) {  
  183.                 if (showDate.isEnabled()) {  
  184.                     showDate.setForeground(Color.CYAN);  
  185.                     if (isShow) {  
  186.                         hidePanel();  
  187.                     } else {  
  188.                         showPanel(showDate);  
  189.                     }  
  190.                 }  
  191.             }  
  192.    
  193.             public void mouseReleased(MouseEvent me) {  
  194.                 if (showDate.isEnabled()) {  
  195.                     showDate.setForeground(Color.BLACK);  
  196.                 }  
  197.             }  
  198.         });  
  199.         showDate.addFocusListener(new FocusListener() {  
  200.             public void focusLost(FocusEvent e) {  
  201.                 hidePanel();  
  202.             }  
  203.    
  204.             public void focusGained(FocusEvent e) {  
  205.    
  206.             }  
  207.         });  
  208.     }  
  209.    
  210.     //根据新的日期刷新    
  211.     private void refresh() {  
  212.         jp1.updateDate();  
  213.         jp2.updateDate();  
  214.         jp3.updateDate();  
  215.         jp4.updateDate();  
  216.         SwingUtilities.updateComponentTreeUI(this);  
  217.     }  
  218.    
  219.     //提交日期    
  220.     private void commit() {  
  221.         //TODO add other components here  
  222.         if (showDate instanceof JTextField) {  
  223.             ((JTextField) showDate).setText(sdf.format(select.getTime()));  
  224.         }else if (showDate instanceof JLabel) {  
  225.             ((JLabel) showDate).setText(sdf.format(select.getTime()));  
  226.         }  
  227.    
  228.         hidePanel();  
  229.     }  
  230.    
  231.     //隐藏日期选择面板    
  232.     private void hidePanel() {  
  233.         if (pop != null) {  
  234.             isShow = false;  
  235.             pop.hide();  
  236.             pop = null;  
  237.         }  
  238.     }  
  239.    
  240.     //显示日期选择面板    
  241.     private void showPanel(Component owner) {  
  242.         if (pop != null) {  
  243.             pop.hide();  
  244.         }  
  245.         Point show = new Point(0, showDate.getHeight());  
  246.         SwingUtilities.convertPointToScreen(show, showDate);  
  247.         Dimension size = Toolkit.getDefaultToolkit().getScreenSize();  
  248.         int x = show.x;  
  249.         int y = show.y;  
  250.         if (x < 0) {  
  251.             x = 0;  
  252.         }  
  253.         if (x > size.width - 295) {  
  254.             x = size.width - 295;  
  255.         }  
  256.         if (y < size.height - 170) {  
  257.         } else {  
  258.             y -= 188;  
  259.         }  
  260.         pop = PopupFactory.getSharedInstance().getPopup(owner, monthPanel, x, y);  
  261.         pop.show();  
  262.         isShow = true;  
  263.     }  
  264.    
  265.     /**  
  266.      * 最上面的面板用来显示月份的增减  
  267.      */  
  268.     private class JP1 extends JPanel {  
  269.         private static final long serialVersionUID = -5638853772805561174L;  
  270.         JLabel yearleft, yearright, monthleft, monthright, center, centercontainer;  
  271.    
  272.         public JP1() {  
  273.             super(new BorderLayout());  
  274.             this.setBackground(new Color(160185215));  
  275.             initJP1();  
  276.         }  
  277.    
  278.         private void initJP1() {  
  279.             yearleft = new JLabel(“  <<”, JLabel.CENTER);  
  280.             yearleft.setToolTipText(”上一年”);  
  281.             yearright = new JLabel(“>>  ”, JLabel.CENTER);  
  282.             yearright.setToolTipText(”下一年”);  
  283.             yearleft.setBorder(BorderFactory.createEmptyBorder(2000));  
  284.             yearright.setBorder(BorderFactory.createEmptyBorder(2000));  
  285.    
  286.             monthleft = new JLabel(“  <”, JLabel.RIGHT);  
  287.             monthleft.setToolTipText(”上一月”);  
  288.             monthright = new JLabel(“>  ”, JLabel.LEFT);  
  289.             monthright.setToolTipText(”下一月”);  
  290.             monthleft.setBorder(BorderFactory.createEmptyBorder(23000));  
  291.             monthright.setBorder(BorderFactory.createEmptyBorder(20030));  
  292.    
  293.             centercontainer = new JLabel(“”, JLabel.CENTER);  
  294.             centercontainer.setLayout(new BorderLayout());  
  295.             center = new JLabel(“”, JLabel.CENTER);  
  296.    
  297.             centercontainer.add(monthleft, BorderLayout.WEST);  
  298.             centercontainer.add(center, BorderLayout.CENTER);  
  299.             centercontainer.add(monthright, BorderLayout.EAST);  
  300.    
  301.             this.add(yearleft, BorderLayout.WEST);  
  302.             this.add(centercontainer, BorderLayout.CENTER);  
  303.             this.add(yearright, BorderLayout.EAST);  
  304.             this.setPreferredSize(new Dimension(29525));  
  305.    
  306.             updateDate();  
  307.    
  308.             yearleft.addMouseListener(new MouseAdapter() {  
  309.                 public void mouseEntered(MouseEvent me) {  
  310.                     yearleft.setCursor(new Cursor(Cursor.HAND_CURSOR));  
  311.                     yearleft.setForeground(Color.RED);  
  312.                 }  
  313.    
  314.                 public void mouseExited(MouseEvent me) {  
  315.                     yearleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
  316.                     yearleft.setForeground(Color.BLACK);  
  317.                 }  
  318.    
  319.                 public void mousePressed(MouseEvent me) {  
  320.                     select.add(Calendar.YEAR, -1);  
  321.                     yearleft.setForeground(Color.WHITE);  
  322.                     refresh();  
  323.                 }  
  324.    
  325.                 public void mouseReleased(MouseEvent me) {  
  326.                     yearleft.setForeground(Color.BLACK);  
  327.                 }  
  328.             });  
  329.             yearright.addMouseListener(new MouseAdapter() {  
  330.                 public void mouseEntered(MouseEvent me) {  
  331.                     yearright.setCursor(new Cursor(Cursor.HAND_CURSOR));  
  332.                     yearright.setForeground(Color.RED);  
  333.                 }  
  334.    
  335.                 public void mouseExited(MouseEvent me) {  
  336.                     yearright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
  337.                     yearright.setForeground(Color.BLACK);  
  338.                 }  
  339.    
  340.                 public void mousePressed(MouseEvent me) {  
  341.                     select.add(Calendar.YEAR, 1);  
  342.                     yearright.setForeground(Color.WHITE);  
  343.                     refresh();  
  344.                 }  
  345.    
  346.                 public void mouseReleased(MouseEvent me) {  
  347.                     yearright.setForeground(Color.BLACK);  
  348.                 }  
  349.             });  
  350.             monthleft.addMouseListener(new MouseAdapter() {  
  351.                 public void mouseEntered(MouseEvent me) {  
  352.                     monthleft.setCursor(new Cursor(Cursor.HAND_CURSOR));  
  353.                     monthleft.setForeground(Color.RED);  
  354.                 }  
  355.    
  356.                 public void mouseExited(MouseEvent me) {  
  357.                     monthleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
  358.                     monthleft.setForeground(Color.BLACK);  
  359.                 }  
  360.    
  361.                 public void mousePressed(MouseEvent me) {  
  362.                     select.add(Calendar.MONTH, -1);  
  363.                     monthleft.setForeground(Color.WHITE);  
  364.                     refresh();  
  365.                 }  
  366.    
  367.                 public void mouseReleased(MouseEvent me) {  
  368.                     monthleft.setForeground(Color.BLACK);  
  369.                 }  
  370.             });  
  371.             monthright.addMouseListener(new MouseAdapter() {  
  372.                 public void mouseEntered(MouseEvent me) {  
  373.                     monthright.setCursor(new Cursor(Cursor.HAND_CURSOR));  
  374.                     monthright.setForeground(Color.RED);  
  375.                 }  
  376.    
  377.                 public void mouseExited(MouseEvent me) {  
  378.                     monthright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
  379.                     monthright.setForeground(Color.BLACK);  
  380.                 }  
  381.    
  382.                 public void mousePressed(MouseEvent me) {  
  383.                     select.add(Calendar.MONTH, 1);  
  384.                     monthright.setForeground(Color.WHITE);  
  385.                     refresh();  
  386.                 }  
  387.    
  388.                 public void mouseReleased(MouseEvent me) {  
  389.                     monthright.setForeground(Color.BLACK);  
  390.                 }  
  391.             });  
  392.         }  
  393.    
  394.         private void updateDate() {  
  395.             center.setText(select.get(Calendar.YEAR) + ”年” + (select.get(Calendar.MONTH) + 1) + “月”);  
  396.         }  
  397.     }  
  398.    
  399.     private class JP2 extends JPanel {  
  400.         private static final long serialVersionUID = -8176264838786175724L;  
  401.    
  402.         public JP2() {  
  403.             this.setPreferredSize(new Dimension(29520));  
  404.         }  
  405.    
  406.         protected void paintComponent(Graphics g) {  
  407.             g.setFont(font);  
  408.             g.drawString(”星期日 星期一 星期二 星期三 星期四 星期五 星期六”510);  
  409.             g.drawLine(015, getWidth(), 15);  
  410.         }  
  411.    
  412.         private void updateDate() {  
  413.    
  414.         }  
  415.     }  
  416.    
  417.     private class JP3 extends JPanel {  
  418.         private static final long serialVersionUID = 43157272447522985L;  
  419.    
  420.         public JP3() {  
  421.             super(new GridLayout(67));  
  422.             this.setPreferredSize(new Dimension(295100));  
  423.             initJP3();  
  424.         }  
  425.    
  426.         private void initJP3() {  
  427.             updateDate();  
  428.         }  
  429.    
  430.         public void updateDate() {  
  431.             this.removeAll();  
  432.             lm.clear();  
  433.             Date temp = select.getTime();  
  434.             Calendar select = Calendar.getInstance();  
  435.             select.setTime(temp);  
  436.             select.set(Calendar.DAY_OF_MONTH, 1);  
  437.             int index = select.get(Calendar.DAY_OF_WEEK);  
  438.             int sum = (index == 1 ? 8 : index);  
  439.             select.add(Calendar.DAY_OF_MONTH, 0 - sum);  
  440.             for (int i = 0; i < 42; i++) {  
  441.                 select.add(Calendar.DAY_OF_MONTH, 1);  
  442.                 lm.addLabel(new MyLabel(select.get(Calendar.YEAR), select.get(Calendar.MONTH), select.get(Calendar.DAY_OF_MONTH)));  
  443.             }  
  444.             for (MyLabel my : lm.getLabels()) {  
  445.                 this.add(my);  
  446.             }  
  447.             select.setTime(temp);  
  448.         }  
  449.     }  
  450.    
  451.     private class MyLabel extends JLabel implements Comparator<MyLabel>, MouseListener, MouseMotionListener {  
  452.         private static final long serialVersionUID = 3668734399227577214L;  
  453.         private int year, month, day;  
  454.         private boolean isSelected;  
  455.    
  456.         public MyLabel(int year, int month, int day) {  
  457.             super(“” + day, JLabel.CENTER);  
  458.             this.year = year;  
  459.             this.day = day;  
  460.             this.month = month;  
  461.             this.addMouseListener(this);  
  462.             this.addMouseMotionListener(this);  
  463.             this.setFont(font);  
  464.             if (month == select.get(Calendar.MONTH)) {  
  465.                 this.setForeground(Color.BLACK);  
  466.             } else {  
  467.                 this.setForeground(Color.LIGHT_GRAY);  
  468.             }  
  469.             if (day == select.get(Calendar.DAY_OF_MONTH)) {  
  470.                 this.setBackground(new Color(160185215));  
  471.             } else {  
  472.                 this.setBackground(Color.WHITE);  
  473.             }  
  474.         }  
  475.    
  476.         public boolean getIsSelected() {  
  477.             return isSelected;  
  478.         }  
  479.    
  480.         public void setSelected(boolean b, boolean isDrag) {  
  481.             isSelected = b;  
  482.             if (b && !isDrag) {  
  483.                 int temp = select.get(Calendar.MONTH);  
  484.                 select.set(year, month, day);  
  485.                 if (temp == month) {  
  486.                     SwingUtilities.updateComponentTreeUI(jp3);  
  487.                 } else {  
  488.                     refresh();  
  489.                 }  
  490.             }  
  491.             this.repaint();  
  492.         }  
  493.    
  494.         protected void paintComponent(Graphics g) {  
  495.             if (day == select.get(Calendar.DAY_OF_MONTH) && month == select.get(Calendar.MONTH)) {  
  496.                 //如果当前日期是选择日期,则高亮显示    
  497.                 g.setColor(new Color(160185215));  
  498.                 g.fillRect(00, getWidth(), getHeight());  
  499.             }  
  500.             if (year == now.get(Calendar.YEAR) && month == now.get(Calendar.MONTH) && day == now.get(Calendar.DAY_OF_MONTH)) {  
  501.                 //如果日期和当前日期一样,则用红框    
  502.                 Graphics2D gd = (Graphics2D) g;  
  503.                 gd.setColor(Color.RED);  
  504.                 Polygon p = new Polygon();  
  505.                 p.addPoint(00);  
  506.                 p.addPoint(getWidth() - 10);  
  507.                 p.addPoint(getWidth() - 1, getHeight() - 1);  
  508.                 p.addPoint(0, getHeight() - 1);  
  509.                 gd.drawPolygon(p);  
  510.             }  
  511.             if (isSelected) {//如果被选中了就画出一个虚线框出来    
  512.                 Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 1.0f, new float[] { 2.0f, 2.0f }, 1.0f);  
  513.                 Graphics2D gd = (Graphics2D) g;  
  514.                 gd.setStroke(s);  
  515.                 gd.setColor(Color.BLACK);  
  516.                 Polygon p = new Polygon();  
  517.                 p.addPoint(00);  
  518.                 p.addPoint(getWidth() - 10);  
  519.                 p.addPoint(getWidth() - 1, getHeight() - 1);  
  520.                 p.addPoint(0, getHeight() - 1);  
  521.                 gd.drawPolygon(p);  
  522.             }  
  523.             super.paintComponent(g);  
  524.         }  
  525.    
  526.         public boolean contains(Point p) {  
  527.             return this.getBounds().contains(p);  
  528.         }  
  529.    
  530.         private void update() {  
  531.             repaint();  
  532.         }  
  533.    
  534.         public void mouseClicked(MouseEvent e) {  
  535.         }  
  536.    
  537.         public void mousePressed(MouseEvent e) {  
  538.             isSelected = true;  
  539.             update();  
  540.         }  
  541.    
  542.         public void mouseReleased(MouseEvent e) {  
  543.             Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);  
  544.             lm.setSelect(p, false);  
  545.             commit();  
  546.         }  
  547.    
  548.         public void mouseEntered(MouseEvent e) {  
  549.         }  
  550.    
  551.         public void mouseExited(MouseEvent e) {  
  552.         }  
  553.    
  554.         public void mouseDragged(MouseEvent e) {  
  555.             Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);  
  556.             lm.setSelect(p, true);  
  557.         }  
  558.    
  559.         public void mouseMoved(MouseEvent e) {  
  560.         }  
  561.    
  562.         public int compare(MyLabel o1, MyLabel o2) {  
  563.             Calendar c1 = Calendar.getInstance();  
  564.             c1.set(o1.year, o2.month, o1.day);  
  565.             Calendar c2 = Calendar.getInstance();  
  566.             c2.set(o2.year, o2.month, o2.day);  
  567.             return c1.compareTo(c2);  
  568.         }  
  569.     }  
  570.    
  571.     private class LabelManager {  
  572.         private List<MyLabel> list;  
  573.    
  574.         public LabelManager() {  
  575.             list = new ArrayList<MyLabel>();  
  576.         }  
  577.    
  578.         public List<MyLabel> getLabels() {  
  579.             return list;  
  580.         }  
  581.    
  582.         public void addLabel(MyLabel my) {  
  583.             list.add(my);  
  584.         }  
  585.    
  586.         public void clear() {  
  587.             list.clear();  
  588.         }  
  589.    
  590.         @SuppressWarnings(“unused”)  
  591.         public void setSelect(MyLabel my, boolean b) {  
  592.             for (MyLabel m : list) {  
  593.                 if (m.equals(my)) {  
  594.                     m.setSelected(true, b);  
  595.                 } else {  
  596.                     m.setSelected(false, b);  
  597.                 }  
  598.             }  
  599.         }  
  600.    
  601.         public void setSelect(Point p, boolean b) {  
  602.             //如果是拖动,则要优化一下,以提高效率    
  603.             if (b) {  
  604.                 //表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和    
  605.                 //将要显示的标签找到了就可以了    
  606.                 boolean findPrevious = false, findNext = false;  
  607.                 for (MyLabel m : list) {  
  608.                     if (m.contains(p)) {  
  609.                         findNext = true;  
  610.                         if (m.getIsSelected()) {  
  611.                             findPrevious = true;  
  612.                         } else {  
  613.                             m.setSelected(true, b);  
  614.                         }  
  615.                     } else if (m.getIsSelected()) {  
  616.                         findPrevious = true;  
  617.                         m.setSelected(false, b);  
  618.                     }  
  619.                     if (findPrevious && findNext) {  
  620.                         return;  
  621.                     }  
  622.                 }  
  623.             } else {  
  624.                 MyLabel temp = null;  
  625.                 for (MyLabel m : list) {  
  626.                     if (m.contains(p)) {  
  627.                         temp = m;  
  628.                     } else if (m.getIsSelected()) {  
  629.                         m.setSelected(false, b);  
  630.                     }  
  631.                 }  
  632.                 if (temp != null) {  
  633.                     temp.setSelected(true, b);  
  634.                 }  
  635.             }  
  636.         }  
  637.    
  638.     }  
  639.    
  640.     private class JP4 extends JPanel {  
  641.         private static final long serialVersionUID = -6391305687575714469L;  
  642.    
  643.         public JP4() {  
  644.             super(new BorderLayout());  
  645.             this.setPreferredSize(new Dimension(29520));  
  646.             this.setBackground(new Color(160185215));  
  647.             SimpleDateFormat sdf = new SimpleDateFormat(“yyyy年MM月dd日”);  
  648.             final JLabel jl = new JLabel(“今天: ” + sdf.format(new Date()));  
  649.             jl.setToolTipText(”点击选择今天日期”);  
  650.             this.add(jl, BorderLayout.CENTER);  
  651.             jl.addMouseListener(new MouseAdapter() {  
  652.                 public void mouseEntered(MouseEvent me) {  
  653.                     jl.setCursor(new Cursor(Cursor.HAND_CURSOR));  
  654.                     jl.setForeground(Color.RED);  
  655.                 }  
  656.    
  657.                 public void mouseExited(MouseEvent me) {  
  658.                     jl.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
  659.                     jl.setForeground(Color.BLACK);  
  660.                 }  
  661.    
  662.                 public void mousePressed(MouseEvent me) {  
  663.                     jl.setForeground(Color.WHITE);  
  664.                     select.setTime(new Date());  
  665.                     refresh();  
  666.                     commit();  
  667.                 }  
  668.    
  669.                 public void mouseReleased(MouseEvent me) {  
  670.                     jl.setForeground(Color.BLACK);  
  671.                 }  
  672.             });  
  673.         }  
  674.    
  675.         private void updateDate() {  
  676.    
  677.         }  
  678.     }  
  679.    
  680.     public static void main(String[] args) {  
  681.         DateChooser dateChooser1 = DateChooser.getInstance(”yyyy-MM-dd”);  
  682.         DateChooser dateChooser2 = DateChooser.getInstance(”yyyy-MM-dd”);  
  683.         JTextField showDate1 = new JTextField(“单击选择日期”);  
  684.         JLabel showDate2 = new JLabel(“单击选择日期”);  
  685.    
  686.         dateChooser1.register(showDate1);  
  687.         dateChooser2.register(showDate2);  
  688.    
  689.         JFrame jf = new JFrame(“测试日期选择器”);  
  690.         jf.add(showDate1, BorderLayout.NORTH);  
  691.         jf.add(showDate2, BorderLayout.SOUTH);  
  692.         jf.pack();  
  693.         jf.setLocationRelativeTo(null);  
  694.         jf.setVisible(true);  
  695.         jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  696.     }  
  697. }  
package com.monitor.date;

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.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingUtilities;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

/** 
 * 日期选择器,可以指定日期的显示格式 
 */
public class DateChooser extends JPanel {

    private static final long serialVersionUID = 4529266044762990227L;

    private Date initDate;
    private Calendar now = Calendar.getInstance();
    private Calendar select;
    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 SimpleDateFormat sdf;
    private boolean isShow = false;
    private Popup pop;

    private JComponent showDate;

    public static DateChooser getInstance() {
        return new DateChooser();
    }

    public static DateChooser getInstance(Date date) {
        return new DateChooser(date);
    }

    public static DateChooser getInstance(String format) {
        return new DateChooser(format);
    }

    public static DateChooser getInstance(Date date, String format) {
        return new DateChooser(date, format);
    }

    /** 
     * Creates a new instance of DateChooser 
     */
    private DateChooser() {
        this(new Date());
    }

    private DateChooser(Date date) {
        this(date, "yyyy年MM月dd日");
    }

    private DateChooser(String format) {
        this(new Date(), format);
    }

    private DateChooser(Date date, String format) {
        initDate = date;
        sdf = new SimpleDateFormat(format);
        select = Calendar.getInstance();
        select.setTime(initDate);
        initPanel();
    }

    /** 
     * 是否允许用户选择 
     */
    public void setEnabled(boolean b) {
        super.setEnabled(b);
        showDate.setEnabled(b);
    }

    /** 
     *得到当前选择框的日期 
     */
    public Date getDate() {
        return select.getTime();
    }

    public String getStrDate() {
        return sdf.format(select.getTime());
    }

    public String getStrDate(String format) {
        sdf = new SimpleDateFormat(format);
        return sdf.format(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();
            }
        });
    }

    public void register(final JComponent showDate) {
        this.showDate = showDate;

        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();
        jp2.updateDate();
        jp3.updateDate();
        jp4.updateDate();
        SwingUtilities.updateComponentTreeUI(this);
    }

    //提交日期  
    private void commit() {
        //TODO add other components here
        if (showDate instanceof JTextField) {
            ((JTextField) showDate).setText(sdf.format(select.getTime()));
        }else if (showDate instanceof JLabel) {
            ((JLabel) showDate).setText(sdf.format(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 {
        private static final long serialVersionUID = -5638853772805561174L;
        JLabel yearleft, yearright, monthleft, monthright, 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));

            monthleft = new JLabel("  <", JLabel.RIGHT);
            monthleft.setToolTipText("上一月");
            monthright = new JLabel(">  ", JLabel.LEFT);
            monthright.setToolTipText("下一月");
            monthleft.setBorder(BorderFactory.createEmptyBorder(2, 30, 0, 0));
            monthright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 30));

            centercontainer = new JLabel("", JLabel.CENTER);
            centercontainer.setLayout(new BorderLayout());
            center = new JLabel("", JLabel.CENTER);

            centercontainer.add(monthleft, BorderLayout.WEST);
            centercontainer.add(center, BorderLayout.CENTER);
            centercontainer.add(monthright, BorderLayout.EAST);

            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);
                }
            });
            monthleft.addMouseListener(new MouseAdapter() {
                public void mouseEntered(MouseEvent me) {
                    monthleft.setCursor(new Cursor(Cursor.HAND_CURSOR));
                    monthleft.setForeground(Color.RED);
                }

                public void mouseExited(MouseEvent me) {
                    monthleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                    monthleft.setForeground(Color.BLACK);
                }

                public void mousePressed(MouseEvent me) {
                    select.add(Calendar.MONTH, -1);
                    monthleft.setForeground(Color.WHITE);
                    refresh();
                }

                public void mouseReleased(MouseEvent me) {
                    monthleft.setForeground(Color.BLACK);
                }
            });
            monthright.addMouseListener(new MouseAdapter() {
                public void mouseEntered(MouseEvent me) {
                    monthright.setCursor(new Cursor(Cursor.HAND_CURSOR));
                    monthright.setForeground(Color.RED);
                }

                public void mouseExited(MouseEvent me) {
                    monthright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                    monthright.setForeground(Color.BLACK);
                }

                public void mousePressed(MouseEvent me) {
                    select.add(Calendar.MONTH, 1);
                    monthright.setForeground(Color.WHITE);
                    refresh();
                }

                public void mouseReleased(MouseEvent me) {
                    monthright.setForeground(Color.BLACK);
                }
            });
        }

        private void updateDate() {
            center.setText(select.get(Calendar.YEAR) + "年" + (select.get(Calendar.MONTH) + 1) + "月");
        }
    }

    private class JP2 extends JPanel {
        private static final long serialVersionUID = -8176264838786175724L;

        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 void updateDate() {

        }
    }

    private class JP3 extends JPanel {
        private static final long serialVersionUID = 43157272447522985L;

        public JP3() {
            super(new GridLayout(6, 7));
            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);
            int index = select.get(Calendar.DAY_OF_WEEK);
            int sum = (index == 1 ? 8 : index);
            select.add(Calendar.DAY_OF_MONTH, 0 - sum);
            for (int i = 0; i < 42; i++) {
                select.add(Calendar.DAY_OF_MONTH, 1);
                lm.addLabel(new MyLabel(select.get(Calendar.YEAR), select.get(Calendar.MONTH), select.get(Calendar.DAY_OF_MONTH)));
            }
            for (MyLabel my : lm.getLabels()) {
                this.add(my);
            }
            select.setTime(temp);
        }
    }

    private class MyLabel extends JLabel implements Comparator<MyLabel>, MouseListener, MouseMotionListener {
        private static final long serialVersionUID = 3668734399227577214L;
        private int year, month, day;
        private boolean isSelected;

        public MyLabel(int year, int month, int day) {
            super("" + day, JLabel.CENTER);
            this.year = year;
            this.day = day;
            this.month = month;
            this.addMouseListener(this);
            this.addMouseMotionListener(this);
            this.setFont(font);
            if (month == select.get(Calendar.MONTH)) {
                this.setForeground(Color.BLACK);
            } else {
                this.setForeground(Color.LIGHT_GRAY);
            }
            if (day == select.get(Calendar.DAY_OF_MONTH)) {
                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, day);
                if (temp == month) {
                    SwingUtilities.updateComponentTreeUI(jp3);
                } else {
                    refresh();
                }
            }
            this.repaint();
        }

        protected void paintComponent(Graphics g) {
            if (day == select.get(Calendar.DAY_OF_MONTH) && month == select.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) && day == now.get(Calendar.DAY_OF_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, o1.day);
            Calendar c2 = Calendar.getInstance();
            c2.set(o2.year, o2.month, o2.day);
            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();
        }

        @SuppressWarnings("unused")
        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 {
        private static final long serialVersionUID = -6391305687575714469L;

        public JP4() {
            super(new BorderLayout());
            this.setPreferredSize(new Dimension(295, 20));
            this.setBackground(new Color(160, 185, 215));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            final JLabel jl = new JLabel("今天: " + sdf.format(new Date()));
            jl.setToolTipText("点击选择今天日期");
            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);
                }
            });
        }

        private void updateDate() {

        }
    }

    public static void main(String[] args) {
        DateChooser dateChooser1 = DateChooser.getInstance("yyyy-MM-dd");
        DateChooser dateChooser2 = DateChooser.getInstance("yyyy-MM-dd");
        JTextField showDate1 = new JTextField("单击选择日期");
        JLabel showDate2 = new JLabel("单击选择日期");

        dateChooser1.register(showDate1);
        dateChooser2.register(showDate2);

        JFrame jf = new JFrame("测试日期选择器");
        jf.add(showDate1, BorderLayout.NORTH);
        jf.add(showDate2, BorderLayout.SOUTH);
        jf.pack();
        jf.setLocationRelativeTo(null);
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

                </div>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值