日历选择器

package fm5.console.util;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerDateModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
* 日期时间选择对话框,模仿Windows日期和时间属性对话框
*
*
*/
public class DateChooserJDialog extends JDialog implements ChangeListener,
        ItemListener {

    private JComboBox month = new JComboBox(new String[]{"一月", "二月", "三月",
                "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"});
    private JSpinner year = new JSpinner(new SpinnerNumberModel(1, 1, 9999, 1));
    private DateGrid dateGrid = new DateGrid();
    private JSpinner time = new JSpinner(new SpinnerDateModel());
    private JButton ok = new JButton("确认");
    private JButton cancle = new JButton("取消");
    private JPanel buttonPanel = new JPanel();
    private JPanel datePanel = new JPanel();
    private String ymdt = "";
    private String date = "";
    private String timeStamp = "";

    /**
     * Description:初始时间设置面板
     *
     * @param initialDate 日历操作句柄
     * @param     taskConfigFrame 任务设置界面句柄 final TaskConfigFrame taskConfigFrame
     */
    public DateChooserJDialog() {
        Calendar initialDate = new GregorianCalendar();
        JPanel cp = new JPanel();
        cp.setLayout(new BorderLayout());
        cp.setBackground(Color.white);
        cp.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
        datePanel.setLayout(new GridLayout(1, 2, 5, 10));
        JPanel p1 = new JPanel();
        p1.setBackground(Color.white);
        p1.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("日期"), BorderFactory.createEmptyBorder(5,
                5, 10, 5)));
        p1.setLayout(new BorderLayout(10, 10));
        JPanel p11 = new JPanel(new GridLayout(1, 2, 10, 10));
        p11.setBackground(Color.white);
        p11.add(month);
        month.addItemListener(this);
        month.setPreferredSize(new Dimension(0, 20));
        p11.add(year);
        year.setEditor(new JSpinner.NumberEditor(year, "0"));
        year.addChangeListener(this);
        year.setPreferredSize(new Dimension(0, 20));
        p1.add(p11, BorderLayout.NORTH);
        p1.add(dateGrid);
        datePanel.add(p1);
        JPanel p2 = new JPanel(new BorderLayout(10, 10));
        p2.setBackground(Color.white);
        p2.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("时间"), BorderFactory.createEmptyBorder(0,
                10, 10, 10)));
        time.setPreferredSize(new Dimension(0, 20));
        JSpinner.DateEditor editor = new JSpinner.DateEditor(time, "HH:mm:ss");
        editor.getTextField().setHorizontalAlignment(JTextField.RIGHT);
        time.setEditor(editor);
        JPanel p = new JPanel();
        p.setBackground(Color.white);
        time.setPreferredSize(new Dimension(100, 20));
        p.add(time);
        p2.add(p, BorderLayout.SOUTH);
        p2.add(new Clock(time));
        datePanel.add(p2);
        setCalendar(initialDate);
        setPreferredSize(new Dimension(369, 200));
        buttonPanel.add(ok);
        buttonPanel.add(cancle);
        cp.add(datePanel, BorderLayout.CENTER);
        cp.add(buttonPanel, BorderLayout.SOUTH);
        ok.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String y = String.valueOf(dateGrid.year);
                String m = String.valueOf(dateGrid.month);
                String d = String.valueOf(dateGrid.day);
                if (dateGrid.month < 10) {
                    m = "0" + dateGrid.month;
                }
                if (dateGrid.day < 10) {
                    d = "0" + dateGrid.day;
                }
                String t = time.getValue().toString().substring(11, 19);
                ymdt = y + "-" + m + "-" + d + " " + t;
                date = y + "-" + m + "-" + d;
                timeStamp = t;
                DateChooserJDialog.this.setVisible(false);

            }
        });
        cancle.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                DateChooserJDialog.this.dispose();
            }
        });
        add(cp, BorderLayout.CENTER);
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize();
        int screenHeight = screenSize.height;
        int screenWidth = screenSize.width;
        this.setTitle("日期和时间设置");
        this.setModal(true);
        this.setLocation(screenWidth / 3, screenHeight / 3);
        this.setSize(400, 280);
        this.setResizable(false);
    }

    public String getDatetime() {
        this.setVisible(true);
        return ymdt;
    }

    public String getTime() {
        this.setVisible(true);
        return timeStamp;
    }

    public String getDate() {
        this.setVisible(true);
        return date;
    }

    /**
     * 设置日期和时间
     *
     * @param calendar 日期和时间
     */
    public void setCalendar(Calendar calendar) {
        if (calendar == null) {
            calendar = new GregorianCalendar();
        }
        month.setSelectedIndex(calendar.get(Calendar.MONTH));
        year.setValue(calendar.get(Calendar.YEAR));
        int year = Integer.parseInt(this.year.getValue().toString());
        int month = this.month.getSelectedIndex() + 1;
        dateGrid.set(year, month);
        dateGrid.setDay(calendar.get(Calendar.DAY_OF_MONTH));
        time.setValue(calendar.getTime());
    }

    /**
     * 获得日期和时间
     *
     * @return 日期和时间
     */
    public Calendar getCalendar() {
        int year = Integer.parseInt(this.year.getValue().toString());
        int month = this.month.getSelectedIndex();
        int day = dateGrid.getDay();
        Calendar c = Calendar.getInstance();
        Date date = (Date) time.getValue();
        c.setTime(date);
        c.set(year, month, day);
        return c;
    }

    public void stateChanged(ChangeEvent e) {
        dateGrid.set(Integer.parseInt(year.getValue().toString()), month.getSelectedIndex() + 1);
    }

    public void itemStateChanged(ItemEvent e) {
        dateGrid.set(Integer.parseInt(year.getValue().toString()), month.getSelectedIndex() + 1);
    }

    private class ActionHandler extends WindowAdapter implements
            ActionListener {

        private DateChooserJDialog dc;

        public ActionHandler(DateChooserJDialog dc) {
            this.dc = dc;
        }

        public void windowClosing(WindowEvent e) {
            actionPerformed(new ActionEvent(this, 0, "取消"));
        }

        public void actionPerformed(ActionEvent e) {
            JDialog dlg = (JDialog) SwingUtilities.windowForComponent(dc);
            dlg.dispose();
            if ("取消".equals(e.getActionCommand())) {
                dc = null;
            }
        }

        public Calendar getCalendar() {
            return dc == null ? null : dc.getCalendar();
        }
    }

    private class DateGrid extends JPanel implements MouseListener {

        JLabel[][] lbs = new JLabel[7][7];
        int year = 1, month = 1, day = 1;

        public DateGrid() {
            super(new GridLayout(7, 7));
            this.setBackground(Color.white);
            Color blue = new Color(140, 150, 255);
            Color white = new Color(220, 220, 255);
            for (int i = 0; i < 7; i++) {
                for (int j = 0; j < 7; j++) {
                    this.add(lbs[i][j] = new JLabel((String) null));
                    lbs[i][j].setOpaque(true);
                    lbs[i][j].setHorizontalAlignment(JLabel.CENTER);
                    lbs[i][j].setBackground(Color.white);
                    if (i > 0) {
                        lbs[i][j].addMouseListener(this);
                    } else {
                        lbs[0][j].setBackground(blue);
                        lbs[0][j].setForeground(white);
                    }
                }
            }
            lbs[0][0].setText("日");
            lbs[0][1].setText("一");
            lbs[0][2].setText("二");
            lbs[0][3].setText("三");
            lbs[0][4].setText("四");
            lbs[0][5].setText("五");
            lbs[0][6].setText("六");
            this.setBorder(BorderFactory.createLoweredBevelBorder());
        }

        public void setDay(int day) {
            if (day < 1) {
                day = 1;
            }
            int days = maxDay(year, month);
            if (day > days) {
                day = days;
            }
            this.day = day;
            int d = 0;
            for (int i = 1; i < 7; i++) {
                for (int j = 0; j < 7; j++) {
                    if (lbs[i][j].getText() != null) {
                        if (++d == day) {
                            lbs[i][j].setBackground(Color.blue);
                            lbs[i][j].setForeground(Color.white);
                            continue;
                        }
                    }
                    lbs[i][j].setBackground(Color.white);
                    lbs[i][j].setForeground(Color.black);
                }
            }
            repaint();
        }

        public int getDay() {
            return day;
        }

        public void set(int year, int month) {
            if (year < 1) {
                year = 1;
            } else if (year > 9999) {
                year = 9999;
            }
            if (month < 1) {
                month = 1;
            } else if (month > 12) {
                month = 12;
            }

            int pastdays = (year - 1) * 365 + (year - 1) / 4 - (year - 1) / 100;
            pastdays += (month - 1) * 31;
            pastdays -= (month - 1) / 2;
            if (month >= 9 && month % 2 == 1) {
                pastdays += 1;
            }
            if (month > 2) {
                pastdays -= 2;
                if ((year % 4 == 0) && (year % 400 != 0)) {
                    pastdays += 1;
                }
            }
            int dayInWeak = pastdays % 7 - 1;
            if (dayInWeak == -1) {
                dayInWeak = 6;
            }
            // ~
            for (int i = 1; i < 7; i++) {
                for (int j = 0; j < 7; j++) {
                    lbs[i][j].setText(null);
                }
            }
            int days = maxDay(year, month);
            for (int i = 1; i <= days; i++) {
                lbs[1 + (dayInWeak + i - 1) / 7][(dayInWeak + i - 1) % 7].setText(String.valueOf(i));
            }
            this.year = year;
            this.month = month;
            setDay(day);
        }

        private int maxDay(int year, int month) {
            int days = (month % 2 == (month > 7 ? 0 : 1)) ? 31 : 30;
            if (month == 2) {
                days = (year % 4 == 0 && year % 400 != 0) ? 29 : 28;
            }
            return days;
        }

        public void mousePressed(MouseEvent e) {
            Object o = e.getSource();
            JLabel lb = null;
            for (int i = 1; i < 7; i++) {
                for (int j = 0; j < 7; j++) {
                    JLabel b = lbs[i][j];
                    if (b == o && b.getText() != null) {
                        lb = b;
                        break;
                    }
                }
            }
            if (lb == null) {
                return;
            }
            int d = 0;
            for (int i = 1; i < 7; i++) {
                for (int j = 0; j < 7; j++) {
                    if (lbs[i][j].getText() != null) {
                        d++;
                        if (lbs[i][j] == lb) {
                            setDay(d);
                            return;
                        }
                    }
                }
            }
        }

        public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub
        }

        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub
        }

        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub
        }

        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub
        }
    }

    private class Clock extends JComponent implements ChangeListener {

        Calendar c;
        int[] xs = new int[4];
        int[] ys = new int[4];
        final Color handColor = new Color(24, 116, 109);

        public Clock(JSpinner time) {
            time.addChangeListener(this);
            stateChanged(new ChangeEvent(time));
        }

        public void stateChanged(ChangeEvent e) {
            JSpinner sp = (JSpinner) e.getSource();
            Date date = (Date) sp.getValue();
            if (c == null) {
                c = Calendar.getInstance();
            }
            c.setTime(date);
            repaint();
        }

        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            float ox = getWidth() / 2f;
            float oy = getHeight() / 2f;
            final float R = 60f;
            Ellipse2D.Float oval = new Ellipse2D.Float();
            for (int i = 0; i < 360; i += 360 / 12 / 5) {
                float a = i / 360f * (float) Math.PI * 2;
                float dx = (float) Math.sin(a) * R;
                float dy = (float) Math.cos(a) * R;
                g2.setColor(i % (360 / 12) == 0 ? Color.black : Color.lightGray);
                oval.setFrame(ox - dx - 1f, oy - dy - 1f, 2, 2);
                g2.fill(oval);
                if (i % (360 / 12) == 0) {
                    g2.setColor(Color.cyan);
                    oval.setFrame(ox + dx - 2f, oy + dy - 1f, 2, 2);
                    g2.fill(oval);
                }
            }
            int hour = c.get(Calendar.HOUR);
            int minute = c.get(Calendar.MINUTE);
            int second = c.get(Calendar.SECOND);
            float ha = (float) Math.PI * 2 / 12 * (hour + (float) minute / 60);
            float ma = (float) Math.PI * 2 / 60
                    * (minute + (float) second / 60);
            float sa = (float) Math.PI * 2 / 60 * second;
            g2.setColor(Color.lightGray);
            g2.translate(1, 1);
            drawHand(g2, ox, oy, ha, 40);
            g2.translate(1, 1);
            drawHand(g2, ox, oy, ma, 48);
            g2.translate(1, 1);
            drawHand(g2, ox, oy, sa, 50, false);
            g2.translate(-3, -3);
            g2.setColor(handColor);
            drawHand(g2, ox, oy, ha, 40);
            drawHand(g2, ox, oy, ma, 48);
            g2.setColor(Color.black);
            drawHand(g2, ox, oy, sa, 50, false);
        }

        private void drawHand(Graphics2D g2, float ox, float oy, float a,
                float len, boolean w) {
            xs[2] = (int) (ox + (float) Math.sin(a) * len);
            ys[2] = (int) (oy - (float) Math.cos(a) * len);
            xs[0] = (int) (ox + (float) Math.sin(a + Math.PI) * 10);
            ys[0] = (int) (oy - (float) Math.cos(a + Math.PI) * 10);
            if (w) {
                xs[1] = (int) (ox + (float) Math.sin(a + Math.PI / 2) * 3);
                ys[1] = (int) (oy - (float) Math.cos(a + Math.PI / 2) * 3);
                xs[3] = (int) (ox + (float) Math.sin(a + Math.PI * 3 / 2) * 3);
                ys[3] = (int) (oy - (float) Math.cos(a + Math.PI * 3 / 2) * 3);
                g2.fillPolygon(xs, ys, 4);
            } else {
                Line2D.Float line = new Line2D.Float(xs[0], ys[0], xs[2], ys[2]);
                g2.draw(line);
            }
        }

        private void drawHand(Graphics2D g2, float ox, float oy, float a,
                float len) {
            this.drawHand(g2, ox, oy, a, len, true);
        }
    }
}

猜你喜欢

转载自mjz13939958835.iteye.com/blog/1843128