/* * JMonthChooser.java - A bean for choosing a month * Copyright (C) 2004 Kai Toedter * kai@toedter.com * www.toedter.com * * This program 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 * of the License, or (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package com.toedter.calendar; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.Locale; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * JMonthChooser is a bean for choosing a month. * * @author Kai Toedter * @version $LastChangedRevision: 100 $ * @version $LastChangedDate: 2006-06-04 14:36:06 +0200 (So, 04 Jun 2006) $ */ public class JMonthChooser extends JPanel implements ItemListener, ChangeListener { private static final long serialVersionUID = -2028361332231218527L; /** true, if the month chooser has a spinner component */ protected boolean hasSpinner; private Locale locale; private int month; private int oldSpinnerValue = 0; // needed for comparison private JDayChooser dayChooser; private JYearChooser yearChooser; private JComboBox comboBox; private JSpinner spinner; private String[] monthNames = new String[] {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; private boolean initialized; private boolean localInitialize; /** * Default JMonthChooser constructor. */ public JMonthChooser() { this (true); } /** * JMonthChooser constructor with month spinner parameter. * * @param hasSpinner * true, if the month chooser should have a spinner component */ public JMonthChooser(boolean hasSpinner) { super (); setName ("JMonthChooser"); this.hasSpinner = hasSpinner; setLayout (new BorderLayout ()); comboBox = new JComboBox (); comboBox.addItemListener (this); comboBox.setBackground (new Color (246, 245, 245)); // comboBox.addPopupMenuListener(this); locale = Locale.getDefault (); initNames (); if (hasSpinner) { spinner = new JSpinner () { private static final long serialVersionUID = 1L; private JTextField textField = new JTextField (); public Dimension getPreferredSize() { Dimension size = super.getPreferredSize (); return new Dimension (size.width, textField.getPreferredSize ().height); } }; spinner.addChangeListener (this); spinner.setEditor (comboBox); comboBox.setBorder (new EmptyBorder (0, 0, 0, 0)); updateUI (); add (spinner, BorderLayout.WEST); } else { add (comboBox, BorderLayout.WEST); } setOpaque (false); initialized = true; setMonth (Calendar.getInstance ().get (Calendar.MONTH), true); } /** * Set the month names with the given month names list. * * @param monthNames The new month names to be set. */ public void setMonthNames(String[] monthNames) { this.monthNames = monthNames; initNames (); } /** * Initializes the locale specific month names. */ public void initNames() { localInitialize = true; if (comboBox.getItemCount () == 12) { comboBox.removeAllItems (); } for (int i = 0; i < 12; i++) { comboBox.addItem (monthNames[i]); } localInitialize = false; comboBox.setSelectedIndex (month); } /** * Is invoked if the state of the spnner changes. * * @param e * the change event. */ public void stateChanged(ChangeEvent e) { SpinnerNumberModel model = (SpinnerNumberModel) ((JSpinner) e.getSource ()).getModel (); int value = model.getNumber ().intValue (); boolean increase = (value > oldSpinnerValue) ? true : false; oldSpinnerValue = value; int month = getMonth (); if (increase) { month += 1; if (month == 12) { month = 0; if (yearChooser != null) { int year = yearChooser.getYear (); year += 1; yearChooser.setYear (year); } } } else { month -= 1; if (month == -1) { month = 11; if (yearChooser != null) { int year = yearChooser.getYear (); year -= 1; yearChooser.setYear (year); } } } setMonth (month, true); } /** * The ItemListener for the months. * * @param e * the item event */ public void itemStateChanged(ItemEvent e) { if (e.getStateChange () == ItemEvent.SELECTED) { int index = comboBox.getSelectedIndex (); if ((index >= 0) && (index != month)) { setMonth (index, false); } } } /** * Sets the month attribute of the JMonthChooser object. Fires a property * change "month". * * @param newMonth * the new month value * @param select * true, if the month should be selcted in the combo box. */ private void setMonth(int newMonth, boolean select) { if (!initialized || localInitialize) { return; } int oldMonth = month; month = newMonth; if (select) { comboBox.setSelectedIndex (month); } if (dayChooser != null) { dayChooser.setMonth (month); } firePropertyChange ("month", oldMonth, month); } /** * Sets the month. This is a bound property. Value are valid between 0 * (January) and 11 (December). A value < 0 will be treated as 0, a value > * 11 will be treated as 11. * * @param newMonth * the new month value * * @see #getMonth */ public void setMonth(int newMonth) { if (newMonth < 0) { yearChooser.setYear (yearChooser.getYear () - 1); setMonth (11, true); } else if (newMonth > 11) { yearChooser.setYear (yearChooser.getYear () + 1); setMonth (0, true); } else { setMonth (newMonth, true); } } /** * Returns the month. * * @return the month value */ public int getMonth() { return month; } /** * Convenience method set a day chooser. * * @param dayChooser * the day chooser */ public void setDayChooser(JDayChooser dayChooser) { this.dayChooser = dayChooser; } /** * Convenience method set a year chooser. If set, the spin for the month * buttons will spin the year as well * * @param yearChooser * the new yearChooser value */ public void setYearChooser(JYearChooser yearChooser) { this.yearChooser = yearChooser; } /** * Returns the locale. * * @return the locale value * * @see #setLocale */ public Locale getLocale() { return locale; } /** * Set the locale and initializes the new month names. * * @param l * the new locale value * * @see #getLocale */ public void setLocale(Locale l) { if (!initialized) { super.setLocale (l); } else { locale = l; initNames (); } } /** * Enable or disable the JMonthChooser. * * @param enabled * the new enabled value */ public void setEnabled(boolean enabled) { super.setEnabled (enabled); comboBox.setEnabled (enabled); if (spinner != null) { spinner.setEnabled (enabled); } } /** * Returns the month chooser's comboBox text area (which allow the focus to * be set to it). * * @return the combo box */ public JComboBox getComboBoxObj() { return comboBox; } /** * Returns the month chooser's comboBox text area (which allow the focus to * be set to it). * * @return the combo box */ public Component getComboBox() { return comboBox; } /** * Returns the month chooser's comboBox bar (which allow the focus to be set * to it). * * @return Component the spinner or null, if the month chooser has no * spinner */ public Component getSpinner() { // Returns <null> if there is no spinner. return spinner; } /** * Returns the type of spinner the month chooser is using. * * @return true, if the month chooser has a spinner */ public boolean hasSpinner() { return hasSpinner; } /** * Sets the font for this component. * * @param font the desired <code>Font</code> for this component */ public void setFont(Font font) { if (comboBox != null) { comboBox.setFont (font); } super.setFont (font); } /** * Updates the UI. * * @see javax.swing.JPanel#updateUI() */ public void updateUI() { final JSpinner testSpinner = new JSpinner (); if (spinner != null) { if ("Windows".equals (UIManager.getLookAndFeel ().getID ())) { spinner.setBorder (testSpinner.getBorder ()); } else { spinner.setBorder (new EmptyBorder (0, 0, 0, 0)); } } } }