/* * 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 accessories.plugins.time; import java.awt.BorderLayout; 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 { public static final String MONTH_PROPERTY = "month"; 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 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.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); } initialized = true; setMonth(Calendar.getInstance().get(Calendar.MONTH)); } /** * Initializes the locale specific month names. */ public void initNames() { localInitialize = true; DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale); String[] monthNames = dateFormatSymbols.getMonths(); 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); } /** * 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_PROPERTY, oldMonth, month); } /** * Sets the month. This is a bound property. Valuse 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 || newMonth == Integer.MIN_VALUE) { setMonth(0, true); } else if (newMonth > 11) { setMonth(11, 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 Component getComboBox() { return this.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)); } } } /** * Creates a JFrame with a JMonthChooser inside and can be used for testing. * * @param s * The command line arguments */ public static void main(String[] s) { JFrame frame = new JFrame("MonthChooser"); frame.getContentPane().add(new JMonthChooser()); frame.pack(); frame.setVisible(true); } }