日历1-DatePanel

/**
 * <p>Copyright: Copyright (c) 2002-2004</p>
 * <p>Company: JavaResearch(http://www.javaresearch.org)</p>
 * <p>最后更新日期:2003年4月25日
 * @author Zhouzhq
 */

package org.jr.swing;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * 日期操作面板,以Windows的通用方式选择和设置日期。
 * @since  0.6
 */
public final class DatePanel
    extends JPanel {
  private static ResourceBundle stringResource = ResourceBundle.getBundle(
      "org.jr.resources.DatePanelResource");

  private Calendar date = Calendar.getInstance();
  ;
  private int returnValue;
  private JLabel selectedDay; //the selected index of days---------------------
  //|
  private JComboBox month = new JComboBox(); //|
  private JSpinner year = new JSpinner(new SpinnerNumberModel(1, 1, 9999, 1)); //|
  private JButton up; //|
  private JButton down; //|
  private JLabel[] days = new JLabel[42]; //<----------------------------------
  private JButton ok = new JButton("OK");
  private JButton cancel = new JButton("Cancel");

  private JPanel panel;

  /**
   * 构造方法,生成面板。
   * @param okListener OK按钮的ActionListener(不可为空)
   * @param cancelListener Cancel按钮的ActionListener
   */
  public DatePanel(ActionListener okListener, ActionListener cancelListener) {
    JSpinner.NumberEditor yearEditor = new JSpinner.NumberEditor(year, "###0");
    year.setEditor(yearEditor);
    JPanel contentPanel = new JPanel();
    contentPanel.setLayout(new BorderLayout());
    panel = new JPanel(new BorderLayout());
    panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.
        createEtchedBorder(),
        stringResource.getString("date")));

    JPanel pn = new JPanel(new GridBagLayout()) {
      public Insets getInsets() {
        return new Insets(0, 0, 3, 0);
      }
    };
    GridBagConstraints gc = new GridBagConstraints();
    initMonth();
    gc.gridx = 0;
    gc.gridy = 0;
    gc.gridwidth = 1;
    gc.gridheight = 1;
    pn.add(month, gc);
    gc.gridx = 1;
    pn.add(Box.createRigidArea(new Dimension(5, 1)), gc);
    initYear();
    gc.gridx = 2;
    gc.weightx = 10;
    gc.fill = GridBagConstraints.HORIZONTAL;
    pn.add(year, gc);

    addDays(); //处历院责显示日期的\uFFFD?

    panel.add(pn, BorderLayout.NORTH);

    MyListener myListener = new MyListener();
    JPanel ps = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    ok.setMargin(new Insets(0, 6, 0, 6));
    ps.add(ok);
    cancel.setMargin(new Insets(0, 6, 0, 6));
    ps.add(cancel);
    ok.addMouseListener(myListener);
    contentPanel.add(ps, BorderLayout.SOUTH);
    contentPanel.add(panel, BorderLayout.CENTER);

    Dimension d = getSize();
    setSize(d.width + 10, d.height);
    initDateDialog();

    if (okListener == null) {
      throw new NullPointerException();
    }
    ok.addActionListener(okListener);
    cancel.addActionListener(cancelListener);
    add(contentPanel);
  }

  private void initYear() {
    year.setBorder(new EtchedBorder());
    year.addChangeListener(new YearListener());
    year.setPreferredSize(new Dimension(85, 22));
    year.setMaximumSize(new Dimension(85, 22));
    year.setMinimumSize(new Dimension(85, 22));
  }

  private void initMonth() {
    month.addItem(stringResource.getString("jan"));
    month.addItem(stringResource.getString("feb"));
    month.addItem(stringResource.getString("mar"));
    month.addItem(stringResource.getString("apr"));
    month.addItem(stringResource.getString("may"));
    month.addItem(stringResource.getString("jun"));
    month.addItem(stringResource.getString("jul"));
    month.addItem(stringResource.getString("aug"));
    month.addItem(stringResource.getString("sep"));
    month.addItem(stringResource.getString("oct"));
    month.addItem(stringResource.getString("nov"));
    month.addItem(stringResource.getString("dec"));

    month.setPreferredSize(new Dimension(90, 22));
    month.setMaximumSize(new Dimension(90, 22));
    month.setMinimumSize(new Dimension(90, 22));
    month.addActionListener(new MonthListener());
  }

  private void addDays() {
    DayListener dayListener = new DayListener();
    for (int i = 0; i < 42; i++) {
      days[i] = new JLabel(" ");
      days[i].setMaximumSize(new Dimension(15, 15));
      days[i].setPreferredSize(new Dimension(15, 15));
      days[i].setBackground(new Color(0, 0, 125));
      days[i].addMouseListener(dayListener);
    }
    JPanel dayPanel = new JPanel(new BorderLayout());
    dayPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));

    JPanel dayPn = new JPanel(new GridLayout(1, 7, 5, 5));
    dayPn.setBackground(new Color(140, 140, 140));
    dayPn.add(new JLabel(stringResource.getString("sun"))).setForeground(new
        Color(222, 222, 222));
    dayPn.add(new JLabel(stringResource.getString("mon"))).setForeground(new
        Color(222, 222, 222));
    dayPn.add(new JLabel(stringResource.getString("tue"))).setForeground(new
        Color(222, 222, 222));
    dayPn.add(new JLabel(stringResource.getString("wed"))).setForeground(new
        Color(222, 222, 222));
    dayPn.add(new JLabel(stringResource.getString("thu"))).setForeground(new
        Color(222, 222, 222));
    dayPn.add(new JLabel(stringResource.getString("fri"))).setForeground(new
        Color(222, 222, 222));
    dayPn.add(new JLabel(stringResource.getString("sat"))).setForeground(new
        Color(222, 222, 222));
    dayPanel.add(dayPn, BorderLayout.NORTH);

    JPanel dayPc = new JPanel(new GridLayout(6, 7, 5, 5));
    dayPc.setBackground(new Color(255, 255, 255));
    for (int i = 0; i < 42; i++) {
      dayPc.add(days[i]);
    }
    dayPanel.add(dayPc, BorderLayout.CENTER);

    panel.add(dayPanel, BorderLayout.CENTER);
  }

  private int daysOfMonth(int year, int month) {
    //得出year年month月共有多少?
    int dayCount = 0; //days of the month
    switch (month) {
      case 0:
      case 2:
      case 4:
      case 6:
      case 7:
      case 9:
      case 11:

        //1,3,5,7,8,10,12月
        dayCount = 31;
        break;
      case 3:
      case 5:
      case 8:
      case 10:

        //4,6,9月
        dayCount = 30;
        break;
      case 1: //February
        Calendar c1 = Calendar.getInstance();
        c1.set(year, 1, 28); //2.28
        int week1 = c1.get(Calendar.DAY_OF_WEEK);
        Calendar c2 = Calendar.getInstance();
        c2.set(year, 2, 1); //3.1
        int week2 = c2.get(Calendar.DAY_OF_WEEK);
        if ( (week2 - week1) == 1 || (week2 - week1) == -6) { //interval one day
          dayCount = 28;
        }
        else {
          dayCount = 29;
        }
        break;
    }
    return dayCount;
  }

  private void initDateDialog() {
    processDays(date);

    int y = date.get(Calendar.YEAR); //?
    int m = date.get(Calendar.MONTH); //月
    year.setValue(new Integer(y));
    month.setSelectedIndex(m);
  }

  private void processDays(Calendar date) {
    int y = date.get(Calendar.YEAR); //?
    int m = date.get(Calendar.MONTH); //月
    int d = date.get(Calendar.DAY_OF_MONTH); //日

    int dayCount = daysOfMonth(y, m);

    for (int i = 0; i < 42; i++) { //clear days[]
      days[i].setText(" ");
    }

    Calendar c = Calendar.getInstance();
    c.set(y, m, 1);
    int week = c.get(Calendar.DAY_OF_WEEK); //得出该月一号是星期几 *星期日~~~星期六值为:1~~7
    for (int i = week - 1, day = 1; day <= dayCount; day++) {
      String s = "" + day;
      if (s.length() == 1) {
        s = " " + s;
      }
      days[i++].setText(s);
    }

    if (selectedDay != null) {
      selectedDay.setOpaque(false); //通?朔椒ㄊ筨ackground可?
      selectedDay.setForeground(new Color(0, 0, 0));
    }
    selectedDay = days[d + week - 2]; //d+week-2是当前日期在days?榈奈恢?
    selectedDay.setOpaque(true); //通?朔椒ㄊ筨ackground可?
    selectedDay.setForeground(new Color(255, 255, 255));
  }

  /**
   * 获得用户指定的Date的对象。
   * @return Date对象
   * @since  0.1
   */
  public Date getDate() {
    return date.getTime();
  }

  /**
   * 获得用户指定的Calendar的克隆对象。
   * @return Calendar对象
   * @since  0.1
   */
  public Calendar getCalendar() {
    return (Calendar) date.clone();
  }

  //====== inner class MyActionListener =====
  /**
   * 内部类,负责在okListener前正确的得到用户选择的日期。
   */
  private class MyListener
      extends MouseAdapter {
    public void mousePressed(MouseEvent e) {
      if (e.getSource() == ok) {
        Calendar c = Calendar.getInstance();
        int y = ( (Integer) year.getValue()).intValue();
        int m = month.getSelectedIndex();
        int d = Integer.parseInt(selectedDay.getText().trim());
        c.set(y, m, d);

        date = c;
      }
    }
  }

  /**
   * 内部类,负责在日期面板的‘天’的处理。
   */
  private class DayListener
      extends MouseAdapter {
    public void mousePressed(MouseEvent e) {
      JLabel label = (JLabel) e.getSource();
      if (label.getText().trim().length() != 0) {
        selectedDay.setForeground(new Color(0, 0, 0));
        selectedDay.setOpaque(false);
        selectedDay = label;
        selectedDay.setForeground(new Color(255, 255, 255));
        selectedDay.setOpaque(true);
      }
    }
  }

  /**
   * 内部类,负责在日期面板的‘月’的处理。
   */
  private class MonthListener
      implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      Calendar c = Calendar.getInstance();
      int y = ( (Integer) year.getValue()).intValue();
      int m = month.getSelectedIndex();
      int dayCount = daysOfMonth(y, m);
      int d = Integer.parseInt(selectedDay.getText().trim());
      if (d > dayCount) {
        d = dayCount;
      }
      c.set(y, m, d);

      processDays(c);
    }
  }

  /**
   * 内部类,负责在日期面板的‘年’的处理。
   */
  private class YearListener
      implements ChangeListener {
    public void stateChanged(ChangeEvent e) {
      Calendar c = Calendar.getInstance();
      int y = ( (Integer) year.getValue()).intValue();
      int m = month.getSelectedIndex();
      int dayCount = daysOfMonth(y, m);
      int d = Integer.parseInt(selectedDay.getText().trim());
      if (d > dayCount) {
        d = dayCount;
      }
      c.set(y, m, d);

      processDays(c);
    }
  }
}

posted on 2005-08-08 11:26  wendy  阅读(410)  评论(0)    收藏  举报

导航