Java/Swing Components/Calendar

Материал из Java эксперт
Версия от 18:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

A panel that allows the user to select a date.

  
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * ---------------------
 * DateChooserPanel.java
 * ---------------------
 * (C) Copyright 2000-2004, by Object Refinery Limited.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   -;
 *
 * $Id: DateChooserPanel.java,v 1.11 2007/11/02 17:50:36 taqua Exp $
 *
 * Changes (from 26-Oct-2001)
 * --------------------------
 * 26-Oct-2001 : Changed package to com.jrefinery.ui.* (DG);
 * 08-Dec-2001 : Dropped the getMonths() method (DG);
 * 13-Oct-2002 : Fixed errors reported by Checkstyle (DG);
 * 02-Nov-2005 : Fixed a bug where the current day-of-the-month is past
 *               the end of the newly selected month when the month or year
 *               combo boxes are changed - see bug id 1344319 (DG);
 *
 */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
/**
 * A panel that allows the user to select a date.
 *
 * @author David Gilbert
 */
public class DateChooserPanel extends JPanel implements ActionListener {
    /**
     * The date selected in the panel.
     */
    private Calendar chosenDate;
    /**
     * The color for the selected date.
     */
    private Color chosenDateButtonColor;
    /**
     * The color for dates in the current month.
     */
    private Color chosenMonthButtonColor;
    /**
     * The color for dates that are visible, but not in the current month.
     */
    private Color chosenOtherButtonColor;
    /**
     * The first day-of-the-week.
     */
    private int firstDayOfWeek;
    /**
     * The range used for selecting years.
     */
    private int yearSelectionRange = 20;
    /**
     * The font used to display the date.
     */
    private Font dateFont = new Font("SansSerif", Font.PLAIN, 10);
    /**
     * A combo for selecting the month.
     */
    private JComboBox monthSelector;
    /**
     * A combo for selecting the year.
     */
    private JComboBox yearSelector;
    /**
     * A button for selecting today"s date.
     */
    private JButton todayButton;
    /**
     * An array of buttons used to display the days-of-the-month.
     */
    private JButton[] buttons;
    /**
     * A flag that indicates whether or not we are currently refreshing the 
     * buttons.
     */
    private boolean refreshing = false;
    /**
     * The ordered set of all seven days of a week,
     * beginning with the "firstDayOfWeek".
     */
    private int[] WEEK_DAYS;
    /**
     * Constructs a new date chooser panel, using today"s date as the initial 
     * selection.
     */
    public DateChooserPanel() {
        this(Calendar.getInstance(), false);
    }
    /**
     * Constructs a new date chooser panel.
     *
     * @param calendar     the calendar controlling the date.
     * @param controlPanel a flag that indicates whether or not the "today" 
     *                     button should appear on the panel.
     */
    public DateChooserPanel(final Calendar calendar, 
                            final boolean controlPanel) {
        super(new BorderLayout());
        this.chosenDateButtonColor = UIManager.getColor("textHighlight");
        this.chosenMonthButtonColor = UIManager.getColor("control");
        this.chosenOtherButtonColor = UIManager.getColor("controlShadow");
        // the default date is today...
        this.chosenDate = calendar;
        this.firstDayOfWeek = calendar.getFirstDayOfWeek();
        this.WEEK_DAYS = new int[7];
        for (int i = 0; i < 7; i++) {
            this.WEEK_DAYS[i] = ((this.firstDayOfWeek + i - 1) % 7) + 1;
        }
        add(constructSelectionPanel(), BorderLayout.NORTH);
        add(getCalendarPanel(), BorderLayout.CENTER);
        if (controlPanel) {
            add(constructControlPanel(), BorderLayout.SOUTH);
        }
        setDate(calendar.getTime());
    }
    /**
     * Sets the date chosen in the panel.
     *
     * @param theDate the new date.
     */
    public void setDate(final Date theDate) {
        this.chosenDate.setTime(theDate);
        this.monthSelector.setSelectedIndex(this.chosenDate.get(
                Calendar.MONTH));
        refreshYearSelector();
        refreshButtons();
    }
    /**
     * Returns the date selected in the panel.
     *
     * @return the selected date.
     */
    public Date getDate() {
        return this.chosenDate.getTime();
    }
    /**
     * Handles action-events from the date panel.
     *
     * @param e information about the event that occurred.
     */
    public void actionPerformed(final ActionEvent e) {
        if (e.getActionCommand().equals("monthSelectionChanged")) {
            final JComboBox c = (JComboBox) e.getSource();
            
            // In most cases, changing the month will not change the selected
            // day.  But if the selected day is 29, 30 or 31 and the newly
            // selected month doesn"t have that many days, we revert to the 
            // last day of the newly selected month...
            int dayOfMonth = this.chosenDate.get(Calendar.DAY_OF_MONTH);
            this.chosenDate.set(Calendar.DAY_OF_MONTH, 1);
            this.chosenDate.set(Calendar.MONTH, c.getSelectedIndex());
            int maxDayOfMonth = this.chosenDate.getActualMaximum(
                    Calendar.DAY_OF_MONTH);
            this.chosenDate.set(Calendar.DAY_OF_MONTH, Math.min(dayOfMonth, 
                    maxDayOfMonth));
            refreshButtons();
        }
        else if (e.getActionCommand().equals("yearSelectionChanged")) {
            if (!this.refreshing) {
                final JComboBox c = (JComboBox) e.getSource();
                final Integer y = (Integer) c.getSelectedItem();
                
                // in most cases, changing the year will not change the 
                // selected day.  But if the selected day is Feb 29, and the
                // newly selected year is not a leap year, we revert to 
                // Feb 28...
                int dayOfMonth = this.chosenDate.get(Calendar.DAY_OF_MONTH);
                this.chosenDate.set(Calendar.DAY_OF_MONTH, 1);
                this.chosenDate.set(Calendar.YEAR, y.intValue());
                int maxDayOfMonth = this.chosenDate.getActualMaximum(
                    Calendar.DAY_OF_MONTH);
                this.chosenDate.set(Calendar.DAY_OF_MONTH, Math.min(dayOfMonth, 
                    maxDayOfMonth));
                refreshYearSelector();
                refreshButtons();
            }
        }
        else if (e.getActionCommand().equals("todayButtonClicked")) {
            setDate(new Date());
        }
        else if (e.getActionCommand().equals("dateButtonClicked")) {
            final JButton b = (JButton) e.getSource();
            final int i = Integer.parseInt(b.getName());
            final Calendar cal = getFirstVisibleDate();
            cal.add(Calendar.DATE, i);
            setDate(cal.getTime());
        }
    }
    /**
     * Returns a panel of buttons, each button representing a day in the month.
     * This is a sub-component of the DatePanel.
     *
     * @return the panel.
     */
    private JPanel getCalendarPanel() {
        final JPanel p = new JPanel(new GridLayout(7, 7));
        final DateFormatSymbols dateFormatSymbols = new DateFormatSymbols();
        final String[] weekDays = dateFormatSymbols.getShortWeekdays();
        for (int i = 0; i < this.WEEK_DAYS.length; i++) {
            p.add(new JLabel(weekDays[this.WEEK_DAYS[i]], 
                    SwingConstants.CENTER));
        }
        this.buttons = new JButton[42];
        for (int i = 0; i < 42; i++) {
            final JButton b = new JButton("");
            b.setMargin(new Insets(1, 1, 1, 1));
            b.setName(Integer.toString(i));
            b.setFont(this.dateFont);
            b.setFocusPainted(false);
            b.setActionCommand("dateButtonClicked");
            b.addActionListener(this);
            this.buttons[i] = b;
            p.add(b);
        }
        return p;
    }
    /**
     * Returns the button color according to the specified date.
     *
     * @param theDate the date.
     * @return the color.
     */
    private Color getButtonColor(final Calendar theDate) {
        if (equalDates(theDate, this.chosenDate)) {
            return this.chosenDateButtonColor;
        }
        else if (theDate.get(Calendar.MONTH) == this.chosenDate.get(
                Calendar.MONTH)) {
            return this.chosenMonthButtonColor;
        }
        else {
            return this.chosenOtherButtonColor;
        }
    }
    /**
     * Returns true if the two dates are equal (time of day is ignored).
     *
     * @param c1 the first date.
     * @param c2 the second date.
     * @return boolean.
     */
    private boolean equalDates(final Calendar c1, final Calendar c2) {
        if ((c1.get(Calendar.DATE) == c2.get(Calendar.DATE))
            && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH))
            && (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR))) {
            return true;
        }
        else {
            return false;
        }
    }
    /**
     * Returns the first date that is visible in the grid.  This should always 
     * be in the month preceding the month of the selected date.
     *
     * @return the date.
     */
    private Calendar getFirstVisibleDate() {
        final Calendar c = Calendar.getInstance();
        c.set(this.chosenDate.get(Calendar.YEAR), this.chosenDate.get(
                Calendar.MONTH), 1);
        c.add(Calendar.DATE, -1);
        while (c.get(Calendar.DAY_OF_WEEK) != getFirstDayOfWeek()) {
            c.add(Calendar.DATE, -1);
        }
        return c;
    }
    /**
     * Returns the first day of the week (controls the labels in the date 
     * panel).
     *
     * @return the first day of the week.
     */
    private int getFirstDayOfWeek() {
        return this.firstDayOfWeek;
    }
    /**
     * Update the button labels and colors to reflect date selection.
     */
    private void refreshButtons() {
        final Calendar c = getFirstVisibleDate();
        for (int i = 0; i < 42; i++) {
            final JButton b = this.buttons[i];
            b.setText(Integer.toString(c.get(Calendar.DATE)));
            b.setBackground(getButtonColor(c));
            c.add(Calendar.DATE, 1);
        }
    }
    /**
     * Changes the contents of the year selection JComboBox to reflect the 
     * chosen date and the year range.
     */
    private void refreshYearSelector() {
        if (!this.refreshing) {
            this.refreshing = true;
            this.yearSelector.removeAllItems();
            final Integer[] years = getYears(this.chosenDate.get(
                    Calendar.YEAR));
            for (int i = 0; i < years.length; i++) {
                this.yearSelector.addItem(years[i]);
            }
            this.yearSelector.setSelectedItem(new Integer(this.chosenDate.get(
                    Calendar.YEAR)));
            this.refreshing = false;
        }
    }
    /**
     * Returns a vector of years preceding and following the specified year.  
     * The number of years preceding and following is determined by the 
     * yearSelectionRange attribute.
     *
     * @param chosenYear the selected year.
     * @return a vector of years.
     */
    private Integer[] getYears(final int chosenYear) {
        final int size = this.yearSelectionRange * 2 + 1;
        final int start = chosenYear - this.yearSelectionRange;
        final Integer[] years = new Integer[size];
        for (int i = 0; i < size; i++) {
            years[i] = new Integer(i + start);
        }
        return years;
    }
    /**
     * Constructs a panel containing two JComboBoxes (for the month and year) 
     * and a button (to reset the date to TODAY).
     *
     * @return the panel.
     */
    private JPanel constructSelectionPanel() {
        final JPanel p = new JPanel();
        final int minMonth = this.chosenDate.getMinimum(Calendar.MONTH);
        final int maxMonth = this.chosenDate.getMaximum(Calendar.MONTH);
        final String[] months = new String[maxMonth - minMonth + 1];
        for(int i=0;i<months.length;i++){
          months[i] = ""+i;
        } 
        
        this.monthSelector = new JComboBox(months);
        this.monthSelector.addActionListener(this);
        this.monthSelector.setActionCommand("monthSelectionChanged");
        p.add(this.monthSelector);
        this.yearSelector = new JComboBox(getYears(0));
        this.yearSelector.addActionListener(this);
        this.yearSelector.setActionCommand("yearSelectionChanged");
        p.add(this.yearSelector);
        return p;
    }
    /**
     * Returns a panel that appears at the bottom of the calendar panel - 
     * contains a button for selecting today"s date.
     *
     * @return the panel.
     */
    private JPanel constructControlPanel() {
        final JPanel p = new JPanel();
        p.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
        this.todayButton = new JButton("Today");
        this.todayButton.addActionListener(this);
        this.todayButton.setActionCommand("todayButtonClicked");
        p.add(this.todayButton);
        return p;
    }
    /**
     * Returns the color for the currently selected date.
     *
     * @return a color.
     */
    public Color getChosenDateButtonColor() {
        return this.chosenDateButtonColor;
    }
    /**
     * Redefines the color for the currently selected date.
     *
     * @param chosenDateButtonColor the new color
     */
    public void setChosenDateButtonColor(final Color chosenDateButtonColor) {
        if (chosenDateButtonColor == null) {
            throw new NullPointerException("UIColor must not be null.");
        }
        final Color oldValue = this.chosenDateButtonColor;
        this.chosenDateButtonColor = chosenDateButtonColor;
        refreshButtons();
        firePropertyChange("chosenDateButtonColor", oldValue, 
                chosenDateButtonColor);
    }
    /**
     * Returns the color for the buttons representing the current month.
     *
     * @return the color for the current month.
     */
    public Color getChosenMonthButtonColor() {
        return this.chosenMonthButtonColor;
    }
    /**
     * Defines the color for the buttons representing the current month.
     *
     * @param chosenMonthButtonColor the color for the current month.
     */
    public void setChosenMonthButtonColor(final Color chosenMonthButtonColor) {
        if (chosenMonthButtonColor == null) {
            throw new NullPointerException("UIColor must not be null.");
        }
        final Color oldValue = this.chosenMonthButtonColor;
        this.chosenMonthButtonColor = chosenMonthButtonColor;
        refreshButtons();
        firePropertyChange("chosenMonthButtonColor", oldValue, 
                chosenMonthButtonColor);
    }
    /**
     * Returns the color for the buttons representing the other months.
     *
     * @return a color.
     */
    public Color getChosenOtherButtonColor() {
        return this.chosenOtherButtonColor;
    }
    /**
     * Redefines the color for the buttons representing the other months.
     *
     * @param chosenOtherButtonColor a color.
     */
    public void setChosenOtherButtonColor(final Color chosenOtherButtonColor) {
        if (chosenOtherButtonColor == null) {
            throw new NullPointerException("UIColor must not be null.");
        }
        final Color oldValue = this.chosenOtherButtonColor;
        this.chosenOtherButtonColor = chosenOtherButtonColor;
        refreshButtons();
        firePropertyChange("chosenOtherButtonColor", oldValue, 
                chosenOtherButtonColor);
    }
    /**
     * Returns the range of years available for selection (defaults to 20).
     * 
     * @return The range.
     */
    public int getYearSelectionRange() {
        return this.yearSelectionRange;
    }
    /**
     * Sets the range of years available for selection.
     * 
     * @param yearSelectionRange  the range.
     */
    public void setYearSelectionRange(final int yearSelectionRange) {
        final int oldYearSelectionRange = this.yearSelectionRange;
        this.yearSelectionRange = yearSelectionRange;
        refreshYearSelector();
        firePropertyChange("yearSelectionRange", oldYearSelectionRange, 
                yearSelectionRange);
    }
}





Bean to display a month calendar in a JPanel

  
/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
 * Bean to display a month calendar in a JPanel. Only works for the Western
 * calendar.
 * 
 * @author Ian F. Darwin, http://www.darwinsys.ru/
 * @version $Id: Cal.java,v 1.5 2004/02/09 03:33:45 ian Exp $
 */
public class Cal extends JPanel {
  /** The currently-interesting year (not modulo 1900!) */
  protected int yy;
  /** Currently-interesting month and day */
  protected int mm, dd;
  /** The buttons to be displayed */
  protected JButton labs[][];
  /** The number of day squares to leave blank at the start of this month */
  protected int leadGap = 0;
  /** A Calendar object used throughout */
  Calendar calendar = new GregorianCalendar();
  /** Today"s year */
  protected final int thisYear = calendar.get(Calendar.YEAR);
  /** Today"s month */
  protected final int thisMonth = calendar.get(Calendar.MONTH);
  /** One of the buttons. We just keep its reference for getBackground(). */
  private JButton b0;
  /** The month choice */
  private JComboBox monthChoice;
  /** The year choice */
  private JComboBox yearChoice;
  /**
   * Construct a Cal, starting with today.
   */
  Cal() {
    super();
    setYYMMDD(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
        calendar.get(Calendar.DAY_OF_MONTH));
    buildGUI();
    recompute();
  }
  /**
   * Construct a Cal, given the leading days and the total days
   * 
   * @exception IllegalArgumentException
   *                If year out of range
   */
  Cal(int year, int month, int today) {
    super();
    setYYMMDD(year, month, today);
    buildGUI();
    recompute();
  }
  private void setYYMMDD(int year, int month, int today) {
    yy = year;
    mm = month;
    dd = today;
  }
  String[] months = { "January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December" };
  /** Build the GUI. Assumes that setYYMMDD has been called. */
  private void buildGUI() {
    getAccessibleContext().setAccessibleDescription(
        "Calendar not accessible yet. Sorry!");
    setBorder(BorderFactory.createEtchedBorder());
    setLayout(new BorderLayout());
    JPanel tp = new JPanel();
    tp.add(monthChoice = new JComboBox());
    for (int i = 0; i < months.length; i++)
      monthChoice.addItem(months[i]);
    monthChoice.setSelectedItem(months[mm]);
    monthChoice.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        int i = monthChoice.getSelectedIndex();
        if (i >= 0) {
          mm = i;
          // System.out.println("Month=" + mm);
          recompute();
        }
      }
    });
    monthChoice.getAccessibleContext().setAccessibleName("Months");
    monthChoice.getAccessibleContext().setAccessibleDescription(
        "Choose a month of the year");
    tp.add(yearChoice = new JComboBox());
    yearChoice.setEditable(true);
    for (int i = yy - 5; i < yy + 5; i++)
      yearChoice.addItem(Integer.toString(i));
    yearChoice.setSelectedItem(Integer.toString(yy));
    yearChoice.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        int i = yearChoice.getSelectedIndex();
        if (i >= 0) {
          yy = Integer.parseInt(yearChoice.getSelectedItem()
              .toString());
          // System.out.println("Year=" + yy);
          recompute();
        }
      }
    });
    add(BorderLayout.CENTER, tp);
    JPanel bp = new JPanel();
    bp.setLayout(new GridLayout(7, 7));
    labs = new JButton[6][7]; // first row is days
    bp.add(b0 = new JButton("S"));
    bp.add(new JButton("M"));
    bp.add(new JButton("T"));
    bp.add(new JButton("W"));
    bp.add(new JButton("R"));
    bp.add(new JButton("F"));
    bp.add(new JButton("S"));
    ActionListener dateSetter = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String num = e.getActionCommand();
        if (!num.equals("")) {
          // set the current day highlighted
          setDayActive(Integer.parseInt(num));
          // When this becomes a Bean, you can
          // fire some kind of DateChanged event here.
          // Also, build a similar daySetter for day-of-week btns.
        }
      }
    };
    // Construct all the buttons, and add them.
    for (int i = 0; i < 6; i++)
      for (int j = 0; j < 7; j++) {
        bp.add(labs[i][j] = new JButton(""));
        labs[i][j].addActionListener(dateSetter);
      }
    add(BorderLayout.SOUTH, bp);
  }
  public final static int dom[] = { 31, 28, 31, 30, /* jan feb mar apr */
  31, 30, 31, 31, /* may jun jul aug */
  30, 31, 30, 31 /* sep oct nov dec */
  };
  /** Compute which days to put where, in the Cal panel */
  protected void recompute() {
    // System.out.println("Cal::recompute: " + yy + ":" + mm + ":" + dd);
    if (mm < 0 || mm > 11)
      throw new IllegalArgumentException("Month " + mm
          + " bad, must be 0-11");
    clearDayActive();
    calendar = new GregorianCalendar(yy, mm, dd);
    // Compute how much to leave before the first.
    // getDay() returns 0 for Sunday, which is just right.
    leadGap = new GregorianCalendar(yy, mm, 1).get(Calendar.DAY_OF_WEEK) - 1;
    // System.out.println("leadGap = " + leadGap);
    int daysInMonth = dom[mm];
    if (isLeap(calendar.get(Calendar.YEAR)) && mm > 1)
      ++daysInMonth;
    // Blank out the labels before 1st day of month
    for (int i = 0; i < leadGap; i++) {
      labs[0][i].setText("");
    }
    // Fill in numbers for the day of month.
    for (int i = 1; i <= daysInMonth; i++) {
      JButton b = labs[(leadGap + i - 1) / 7][(leadGap + i - 1) % 7];
      b.setText(Integer.toString(i));
    }
    // 7 days/week * up to 6 rows
    for (int i = leadGap + 1 + daysInMonth; i < 6 * 7; i++) {
      labs[(i) / 7][(i) % 7].setText("");
    }
    // Shade current day, only if current month
    if (thisYear == yy && mm == thisMonth)
      setDayActive(dd); // shade the box for today
    // Say we need to be drawn on the screen
    repaint();
  }
  /**
   * isLeap() returns true if the given year is a Leap Year.
   * 
   * "a year is a leap year if it is divisible by 4 but not by 100, except
   * that years divisible by 400 *are* leap years." -- Kernighan & Ritchie,
   * _The C Programming Language_, p 37.
   */
  public boolean isLeap(int year) {
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
      return true;
    return false;
  }
  /** Set the year, month, and day */
  public void setDate(int yy, int mm, int dd) {
    // System.out.println("Cal::setDate");
    this.yy = yy;
    this.mm = mm; // starts at 0, like Date
    this.dd = dd;
    recompute();
  }
  /** Unset any previously highlighted day */
  private void clearDayActive() {
    JButton b;
    // First un-shade the previously-selected square, if any
    if (activeDay > 0) {
      b = labs[(leadGap + activeDay - 1) / 7][(leadGap + activeDay - 1) % 7];
      b.setBackground(b0.getBackground());
      b.repaint();
      activeDay = -1;
    }
  }
  private int activeDay = -1;
  /** Set just the day, on the current month */
  public void setDayActive(int newDay) {
    clearDayActive();
    // Set the new one
    if (newDay <= 0)
      dd = new GregorianCalendar().get(Calendar.DAY_OF_MONTH);
    else
      dd = newDay;
    // Now shade the correct square
    Component square = labs[(leadGap + newDay - 1) / 7][(leadGap + newDay - 1) % 7];
    square.setBackground(Color.red);
    square.repaint();
    activeDay = newDay;
  }
  /** For testing, a main program */
  public static void main(String[] av) {
    JFrame f = new JFrame("Cal");
    Container c = f.getContentPane();
    c.setLayout(new FlowLayout());
    // for this test driver, hardcode 1995/02/10.
    c.add(new Cal(1995, 2 - 1, 10));
    // and beside it, the current month.
    c.add(new Cal());
    f.pack();
    f.setVisible(true);
  }
}





Calendar in a JWindow

  
/*
Swing Hacks Tips and Tools for Killer GUIs
By Joshua Marinacci, Chris Adamson
First Edition June 2005  
Series: Hacks
ISBN: 0-596-00907-0
Pages: 542
website: http://www.oreilly.ru/catalog/swinghks/
*/
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CalendarHack extends JPanel {
  protected Image background = new ImageIcon("calendar.png").getImage();
  protected Image highlight = new ImageIcon("highlight.png").getImage();
  protected Image day_img = new ImageIcon("day.png").getImage();
  protected SimpleDateFormat month = new SimpleDateFormat("MMMM");
  protected SimpleDateFormat year = new SimpleDateFormat("yyyy");
  protected SimpleDateFormat day = new SimpleDateFormat("d");
  protected Date date = new Date();
  public void setDate(Date date) {
    this.date = date;
  }
  public CalendarHack() {
    this.setPreferredSize(new Dimension(300, 280));
  }
  public void paintComponent(Graphics g) {
    ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    g.drawImage(background, 0, 0, null);
    g.setColor(Color.black);
    g.setFont(new Font("SansSerif", Font.PLAIN, 18));
    g.drawString(month.format(date), 34, 36);
    g.setColor(Color.white);
    g.drawString(year.format(date), 235, 36);
    Calendar today = Calendar.getInstance();
    today.setTime(date);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.DATE, 1);
    cal.add(Calendar.DATE, -cal.get(Calendar.DAY_OF_WEEK) + 1);
    for (int week = 0; week < 6; week++) {
      for (int d = 0; d < 7; d++) {
        Image img = day_img;
        Color col = Color.black;
        // only draw if it"s actually in this month
        if (cal.get(Calendar.MONTH) == today.get(Calendar.MONTH)) {
          if (cal.equals(today)) {
            img = highlight;
            col = Color.white;
          }
          g.drawImage(img, d * 30 + 46, week * 29 + 81, null);
          g.drawString(day.format(cal.getTime()), d * 30 + 46 + 4, week * 29 + 81 + 20);
        }
        cal.add(Calendar.DATE, +1);
      }
    }
  }
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    CalendarHack ch = new CalendarHack();
    ch.setDate(new Date());
    frame.getContentPane().add(ch);
    frame.setUndecorated(true);
    MoveMouseListener mml = new MoveMouseListener(ch);
    ch.addMouseListener(mml);
    ch.addMouseMotionListener(mml);
    frame.pack();
    frame.setVisible(true);
  }
}
class MoveMouseListener implements MouseListener, MouseMotionListener {
  JComponent target;
  Point start_drag;
  Point start_loc;
  public MoveMouseListener(JComponent target) {
    this.target = target;
  }
  public static JFrame getFrame(Container target) {
    if (target instanceof JFrame) {
      return (JFrame) target;
    }
    return getFrame(target.getParent());
  }
  Point getScreenLocation(MouseEvent e) {
    Point cursor = e.getPoint();
    Point target_location = this.target.getLocationOnScreen();
    return new Point((int) (target_location.getX() + cursor.getX()),
        (int) (target_location.getY() + cursor.getY()));
  }
  public void mouseClicked(MouseEvent e) {
  }
  public void mouseEntered(MouseEvent e) {
  }
  public void mouseExited(MouseEvent e) {
  }
  public void mousePressed(MouseEvent e) {
    this.start_drag = this.getScreenLocation(e);
    this.start_loc = this.getFrame(this.target).getLocation();
  }
  public void mouseReleased(MouseEvent e) {
  }
  public void mouseDragged(MouseEvent e) {
    Point current = this.getScreenLocation(e);
    Point offset = new Point((int) current.getX() - (int) start_drag.getX(), (int) current.getY()
        - (int) start_drag.getY());
    JFrame frame = this.getFrame(target);
    Point new_location = new Point((int) (this.start_loc.getX() + offset.getX()),
        (int) (this.start_loc.getY() + offset.getY()));
    frame.setLocation(new_location);
  }
  public void mouseMoved(MouseEvent e) {
  }
}





Java Date Chooser (ComboBox)

Java Day Chooser

Java Month Chooser

Java Year Chooser

Paint a calendar

   
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JPanel {
  SimpleDateFormat month = new SimpleDateFormat("MMMM");
  SimpleDateFormat year = new SimpleDateFormat("yyyy");
  SimpleDateFormat day = new SimpleDateFormat("d");
  Date date = new Date();
  public void setDate(Date date) {
    this.date = date;
  }
  public void paintComponent(Graphics g) {
    ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    g.fillRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.black);
    g.drawString(month.format(date), 34, 36);
    g.setColor(Color.white);
    g.drawString(year.format(date), 235, 36);
    Calendar today = Calendar.getInstance();
    today.setTime(date);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.DATE, 1);
    cal.add(Calendar.DATE, -cal.get(Calendar.DAY_OF_WEEK) + 1);
    for (int week = 0; week < 6; week++) {
      for (int d = 0; d < 7; d++) {
        Color col = Color.black;
          g.drawString(day.format(cal.getTime()), d * 30 + 46 + 4,
              week * 29 + 81 + 20);
        cal.add(Calendar.DATE, +1);
      }
    }
  }
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setPreferredSize(new Dimension(300, 280));
    Main ch = new Main();
    ch.setDate(new Date());
    frame.getContentPane().add(ch);
    frame.setUndecorated(true);
    frame.pack();
    frame.setVisible(true);
  }
}





Swing Date chooser (Selector)

Swing Date selector (Chooser): darg to choose multiple dates

Swing Date selector (Chooser): highlight

Swing Date selector (Chooser): more months

Swing Date selector (Chooser): toggle selection

Swing Date selector (Chooser) with source code

toedter: Java Calendar