001 /* 002 * $Id: JMonthChooser.java,v 1.3 2012/02/19 17:35:46 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2012 007 * Space Science and Engineering Center (SSEC) 008 * University of Wisconsin - Madison 009 * 1225 W. Dayton Street, Madison, WI 53706, USA 010 * https://www.ssec.wisc.edu/mcidas 011 * 012 * All Rights Reserved 013 * 014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 015 * some McIDAS-V source code is based on IDV and VisAD source code. 016 * 017 * McIDAS-V is free software; you can redistribute it and/or modify 018 * it under the terms of the GNU Lesser Public License as published by 019 * the Free Software Foundation; either version 3 of the License, or 020 * (at your option) any later version. 021 * 022 * McIDAS-V is distributed in the hope that it will be useful, 023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 025 * GNU Lesser Public License for more details. 026 * 027 * You should have received a copy of the GNU Lesser Public License 028 * along with this program. If not, see http://www.gnu.org/licenses. 029 */ 030 package edu.wisc.ssec.mcidasv.data.dateChooser; 031 032 import java.awt.BorderLayout; 033 import java.awt.Component; 034 import java.awt.Dimension; 035 import java.awt.Font; 036 import java.awt.event.ItemEvent; 037 import java.awt.event.ItemListener; 038 import java.text.DateFormatSymbols; 039 import java.util.Calendar; 040 import java.util.Locale; 041 042 import javax.swing.JComboBox; 043 import javax.swing.JFrame; 044 import javax.swing.JPanel; 045 import javax.swing.JSpinner; 046 import javax.swing.JTextField; 047 import javax.swing.SpinnerNumberModel; 048 import javax.swing.UIManager; 049 import javax.swing.border.EmptyBorder; 050 import javax.swing.event.ChangeEvent; 051 import javax.swing.event.ChangeListener; 052 053 /** 054 * JMonthChooser is a bean for choosing a month. 055 * 056 * @author Kai Toedter 057 * @version $LastChangedRevision: 100 $ 058 * @version $LastChangedDate: 2006-06-04 14:36:06 +0200 (So, 04 Jun 2006) $ 059 */ 060 public class JMonthChooser extends JPanel implements ItemListener, 061 ChangeListener { 062 private static final long serialVersionUID = -2028361332231218527L; 063 064 /** true, if the month chooser has a spinner component */ 065 protected boolean hasSpinner; 066 067 private Locale locale; 068 069 private int month; 070 071 private int oldSpinnerValue = 0; 072 073 // needed for comparison 074 private JDayChooser dayChooser; 075 076 private JYearChooser yearChooser; 077 078 private JComboBox comboBox; 079 080 private JSpinner spinner; 081 082 private boolean initialized; 083 084 private boolean localInitialize; 085 086 /** 087 * Default JMonthChooser constructor. 088 */ 089 public JMonthChooser() { 090 this(true); 091 } 092 093 /** 094 * JMonthChooser constructor with month spinner parameter. 095 * 096 * @param hasSpinner 097 * true, if the month chooser should have a spinner component 098 */ 099 public JMonthChooser(boolean hasSpinner) { 100 super(); 101 setName("JMonthChooser"); 102 this.hasSpinner = hasSpinner; 103 104 setLayout(new BorderLayout()); 105 106 comboBox = new JComboBox(); 107 comboBox.addItemListener(this); 108 109 // comboBox.addPopupMenuListener(this); 110 locale = Locale.getDefault(); 111 initNames(); 112 113 if (hasSpinner) { 114 spinner = new JSpinner() { 115 private static final long serialVersionUID = 1L; 116 117 private JTextField textField = new JTextField(); 118 119 public Dimension getPreferredSize() { 120 Dimension size = super.getPreferredSize(); 121 return new Dimension(size.width, textField 122 .getPreferredSize().height); 123 } 124 }; 125 spinner.addChangeListener(this); 126 spinner.setEditor(comboBox); 127 comboBox.setBorder(new EmptyBorder(0, 0, 0, 0)); 128 updateUI(); 129 130 add(spinner, BorderLayout.WEST); 131 } else { 132 add(comboBox, BorderLayout.WEST); 133 } 134 135 initialized = true; 136 setMonth(Calendar.getInstance().get(Calendar.MONTH)); 137 } 138 139 /** 140 * Initializes the locale specific month names. 141 */ 142 public void initNames() { 143 localInitialize = true; 144 145 DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale); 146 String[] monthNames = dateFormatSymbols.getMonths(); 147 148 if (comboBox.getItemCount() == 12) { 149 comboBox.removeAllItems(); 150 } 151 152 for (int i = 0; i < 12; i++) { 153 comboBox.addItem(monthNames[i]); 154 } 155 156 localInitialize = false; 157 comboBox.setSelectedIndex(month); 158 } 159 160 /** 161 * Is invoked if the state of the spnner changes. 162 * 163 * @param e 164 * the change event. 165 */ 166 public void stateChanged(ChangeEvent e) { 167 SpinnerNumberModel model = (SpinnerNumberModel) ((JSpinner) e 168 .getSource()).getModel(); 169 int value = model.getNumber().intValue(); 170 boolean increase = (value > oldSpinnerValue) ? true : false; 171 oldSpinnerValue = value; 172 173 int month = getMonth(); 174 175 if (increase) { 176 month += 1; 177 178 if (month == 12) { 179 month = 0; 180 181 if (yearChooser != null) { 182 int year = yearChooser.getYear(); 183 year += 1; 184 yearChooser.setYear(year); 185 } 186 } 187 } else { 188 month -= 1; 189 190 if (month == -1) { 191 month = 11; 192 193 if (yearChooser != null) { 194 int year = yearChooser.getYear(); 195 year -= 1; 196 yearChooser.setYear(year); 197 } 198 } 199 } 200 201 setMonth(month); 202 } 203 204 /** 205 * The ItemListener for the months. 206 * 207 * @param e 208 * the item event 209 */ 210 public void itemStateChanged(ItemEvent e) { 211 if (e.getStateChange() == ItemEvent.SELECTED) { 212 int index = comboBox.getSelectedIndex(); 213 214 if ((index >= 0) && (index != month)) { 215 setMonth(index, false); 216 } 217 } 218 } 219 220 /** 221 * Sets the month attribute of the JMonthChooser object. Fires a property 222 * change "month". 223 * 224 * @param newMonth 225 * the new month value 226 * @param select 227 * true, if the month should be selcted in the combo box. 228 */ 229 private void setMonth(int newMonth, boolean select) { 230 if (!initialized || localInitialize) { 231 return; 232 } 233 234 int oldMonth = month; 235 month = newMonth; 236 237 if (select) { 238 comboBox.setSelectedIndex(month); 239 } 240 241 if (dayChooser != null) { 242 dayChooser.setMonth(month); 243 } 244 245 firePropertyChange("month", oldMonth, month); 246 } 247 248 /** 249 * Sets the month. This is a bound property. Valuse are valid between 0 250 * (January) and 11 (December). A value < 0 will be treated as 0, a value > 251 * 11 will be treated as 11. 252 * 253 * @param newMonth 254 * the new month value 255 * 256 * @see #getMonth 257 */ 258 public void setMonth(int newMonth) { 259 if (newMonth < 0 || newMonth == Integer.MIN_VALUE) { 260 setMonth(0, true); 261 } else if (newMonth > 11) { 262 setMonth(11, true); 263 } else { 264 setMonth(newMonth, true); 265 } 266 } 267 268 /** 269 * Returns the month. 270 * 271 * @return the month value 272 */ 273 public int getMonth() { 274 return month; 275 } 276 277 /** 278 * Convenience method set a day chooser. 279 * 280 * @param dayChooser 281 * the day chooser 282 */ 283 public void setDayChooser(JDayChooser dayChooser) { 284 this.dayChooser = dayChooser; 285 } 286 287 /** 288 * Convenience method set a year chooser. If set, the spin for the month 289 * buttons will spin the year as well 290 * 291 * @param yearChooser 292 * the new yearChooser value 293 */ 294 public void setYearChooser(JYearChooser yearChooser) { 295 this.yearChooser = yearChooser; 296 } 297 298 /** 299 * Returns the locale. 300 * 301 * @return the locale value 302 * 303 * @see #setLocale 304 */ 305 public Locale getLocale() { 306 return locale; 307 } 308 309 /** 310 * Set the locale and initializes the new month names. 311 * 312 * @param l 313 * the new locale value 314 * 315 * @see #getLocale 316 */ 317 public void setLocale(Locale l) { 318 if (!initialized) { 319 super.setLocale(l); 320 } else { 321 locale = l; 322 initNames(); 323 } 324 } 325 326 /** 327 * Enable or disable the JMonthChooser. 328 * 329 * @param enabled 330 * the new enabled value 331 */ 332 public void setEnabled(boolean enabled) { 333 super.setEnabled(enabled); 334 comboBox.setEnabled(enabled); 335 336 if (spinner != null) { 337 spinner.setEnabled(enabled); 338 } 339 } 340 341 /** 342 * Returns the month chooser's comboBox text area (which allow the focus to 343 * be set to it). 344 * 345 * @return the combo box 346 */ 347 public Component getComboBox() { 348 return this.comboBox; 349 } 350 351 /** 352 * Returns the month chooser's comboBox bar (which allow the focus to be set 353 * to it). 354 * 355 * @return Component the spinner or null, if the month chooser has no 356 * spinner 357 */ 358 public Component getSpinner() { 359 // Returns <null> if there is no spinner. 360 return spinner; 361 } 362 363 /** 364 * Returns the type of spinner the month chooser is using. 365 * 366 * @return true, if the month chooser has a spinner 367 */ 368 public boolean hasSpinner() { 369 return hasSpinner; 370 } 371 372 /** 373 * Sets the font for this component. 374 * 375 * @param font the desired <code>Font</code> for this component 376 */ 377 public void setFont(Font font) { 378 if (comboBox != null) { 379 comboBox.setFont(font); 380 } 381 super.setFont(font); 382 } 383 384 /** 385 * Updates the UI. 386 * 387 * @see javax.swing.JPanel#updateUI() 388 */ 389 public void updateUI() { 390 final JSpinner testSpinner = new JSpinner(); 391 if (spinner != null) { 392 if ("Windows".equals(UIManager.getLookAndFeel().getID())) { 393 spinner.setBorder(testSpinner.getBorder()); 394 } else { 395 spinner.setBorder(new EmptyBorder(0, 0, 0, 0)); 396 } 397 } 398 } 399 400 /** 401 * Creates a JFrame with a JMonthChooser inside and can be used for testing. 402 * 403 * @param s 404 * The command line arguments 405 */ 406 public static void main(String[] s) { 407 JFrame frame = new JFrame("MonthChooser"); 408 frame.getContentPane().add(new JMonthChooser()); 409 frame.pack(); 410 frame.setVisible(true); 411 } 412 }