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