2362N/A * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * A <code>SpinnerModel</code> for sequences of <code>Date</code>s. 0N/A * The upper and lower bounds of the sequence are defined by properties called 0N/A * <code>start</code> and <code>end</code> and the size 0N/A * of the increase or decrease computed by the <code>nextValue</code> 0N/A * and <code>previousValue</code> methods is defined by a property 0N/A * called <code>calendarField</code>. The <code>start</code> 0N/A * and <code>end</code> properties can be <code>null</code> to 0N/A * indicate that the sequence has no lower or upper limit. 0N/A * The value of the <code>calendarField</code> property must be one of the 0N/A * <code>java.util.Calendar</code> constants that specify a field 0N/A * within a <code>Calendar</code>. The <code>getNextValue</code> 0N/A * and <code>getPreviousValue</code> 0N/A * methods change the date forward or backwards by this amount. 0N/A * For example, if <code>calendarField</code> is <code>Calendar.DAY_OF_WEEK</code>, 0N/A * then <code>nextValue</code> produces a <code>Date</code> that's 24 0N/A * hours after the current <code>value</code>, and <code>previousValue</code> 0N/A * produces a <code>Date</code> that's 24 hours earlier. 0N/A * The legal values for <code>calendarField</code> are: 0N/A * <li><code>Calendar.ERA</code> 0N/A * <li><code>Calendar.YEAR</code> 0N/A * <li><code>Calendar.MONTH</code> 0N/A * <li><code>Calendar.WEEK_OF_YEAR</code> 0N/A * <li><code>Calendar.WEEK_OF_MONTH</code> 0N/A * <li><code>Calendar.DAY_OF_MONTH</code> 0N/A * <li><code>Calendar.DAY_OF_YEAR</code> 0N/A * <li><code>Calendar.DAY_OF_WEEK</code> 0N/A * <li><code>Calendar.DAY_OF_WEEK_IN_MONTH</code> 0N/A * <li><code>Calendar.AM_PM</code> 0N/A * <li><code>Calendar.HOUR</code> 0N/A * <li><code>Calendar.HOUR_OF_DAY</code> 0N/A * <li><code>Calendar.MINUTE</code> 0N/A * <li><code>Calendar.SECOND</code> 0N/A * <li><code>Calendar.MILLISECOND</code> 0N/A * However some UIs may set the calendarField before commiting the edit 0N/A * to spin the field under the cursor. If you only want one field to 0N/A * spin you can subclass and ignore the setCalendarField calls. 0N/A * This model inherits a <code>ChangeListener</code>. The 0N/A * <code>ChangeListeners</code> are notified whenever the models 0N/A * <code>value</code>, <code>calendarField</code>, 0N/A * <code>start</code>, or <code>end</code> properties changes. 0N/A * @see AbstractSpinnerModel 0N/A * @see SpinnerListModel 0N/A * @see SpinnerNumberModel 0N/A * @author Hans Muller 0N/A * Creates a <code>SpinnerDateModel</code> that represents a sequence of dates 0N/A * between <code>start</code> and <code>end</code>. The 0N/A * <code>nextValue</code> and <code>previousValue</code> methods 0N/A * compute elements of the sequence by advancing or reversing 0N/A * the current date <code>value</code> by the 0N/A * <code>calendarField</code> time unit. For a precise description 0N/A * of what it means to increment or decrement a <code>Calendar</code> 0N/A * <code>field</code>, see the <code>add</code> method in 0N/A * <code>java.util.Calendar</code>. 0N/A * The <code>start</code> and <code>end</code> parameters can be 0N/A * <code>null</code> to indicate that the range doesn't have an 0N/A * upper or lower bound. If <code>value</code> or 0N/A * <code>calendarField</code> is <code>null</code>, or if both 0N/A * <code>start</code> and <code>end</code> are specified and 0N/A * <code>mininum > maximum</code> then an 0N/A * <code>IllegalArgumentException</code> is thrown. 0N/A * Similarly if <code>(minimum <= value <= maximum)</code> is false, 0N/A * an IllegalArgumentException is thrown. 0N/A * @param value the current (non <code>null</code>) value of the model 0N/A * @param start the first date in the sequence or <code>null</code> 0N/A * @param end the last date in the sequence or <code>null</code> 0N/A * @param calendarField one of 0N/A * <li><code>Calendar.ERA</code> 0N/A * <li><code>Calendar.YEAR</code> 0N/A * <li><code>Calendar.MONTH</code> 0N/A * <li><code>Calendar.WEEK_OF_YEAR</code> 0N/A * <li><code>Calendar.WEEK_OF_MONTH</code> 0N/A * <li><code>Calendar.DAY_OF_MONTH</code> 0N/A * <li><code>Calendar.DAY_OF_YEAR</code> 0N/A * <li><code>Calendar.DAY_OF_WEEK</code> 0N/A * <li><code>Calendar.DAY_OF_WEEK_IN_MONTH</code> 0N/A * <li><code>Calendar.AM_PM</code> 0N/A * <li><code>Calendar.HOUR</code> 0N/A * <li><code>Calendar.HOUR_OF_DAY</code> 0N/A * <li><code>Calendar.MINUTE</code> 0N/A * <li><code>Calendar.SECOND</code> 0N/A * <li><code>Calendar.MILLISECOND</code> 0N/A * @throws IllegalArgumentException if <code>value</code> or 0N/A * <code>calendarField</code> are <code>null</code>, 0N/A * if <code>calendarField</code> isn't valid, 0N/A * or if the following expression is 0N/A * false: <code>(start <= value <= end)</code>. 0N/A * @see #setCalendarField 0N/A * Constructs a <code>SpinnerDateModel</code> whose initial 0N/A * <code>value</code> is the current date, <code>calendarField</code> 0N/A * is equal to <code>Calendar.DAY_OF_MONTH</code>, and for which 0N/A * there are no <code>start</code>/<code>end</code> limits. 0N/A * Changes the lower limit for Dates in this sequence. 0N/A * If <code>start</code> is <code>null</code>, 0N/A * then there is no lower limit. No bounds checking is done here: 0N/A * the new start value may invalidate the 0N/A * <code>(start <= value <= end)</code> 0N/A * invariant enforced by the constructors. This is to simplify updating 0N/A * the model. Naturally one should ensure that the invariant is true 0N/A * before calling the <code>nextValue</code>, <code>previousValue</code>, 0N/A * or <code>setValue</code> methods. 0N/A * Typically this property is a <code>Date</code> however it's possible to use 0N/A * a <code>Comparable</code> with a <code>compareTo</code> method for Dates. 0N/A * For example <code>start</code> might be an instance of a class like this: 0N/A * MyStartDate implements Comparable { 0N/A * public int compareTo(Date d) { 0N/A * return (t < d.getTime() ? -1 : (t == d.getTime() ? 0 : 1)); 0N/A * public int compareTo(Object o) { 0N/A * return compareTo((Date)o); 0N/A * Note that the above example will throw a <code>ClassCastException</code> 0N/A * if the <code>Object</code> passed to <code>compareTo(Object)</code> 0N/A * is not a <code>Date</code>. 0N/A * This method fires a <code>ChangeEvent</code> if the 0N/A * <code>start</code> has changed. 0N/A * @param start defines the first date in the sequence 0N/A * @see #addChangeListener 0N/A * Returns the first <code>Date</code> in the sequence. 0N/A * @return the value of the <code>start</code> property 0N/A * Changes the upper limit for <code>Date</code>s in this sequence. 0N/A * If <code>start</code> is <code>null</code>, then there is no upper 0N/A * limit. No bounds checking is done here: the new 0N/A * start value may invalidate the <code>(start <= value <= end)</code> 0N/A * invariant enforced by the constructors. This is to simplify updating 0N/A * the model. Naturally, one should ensure that the invariant is true 0N/A * before calling the <code>nextValue</code>, <code>previousValue</code>, 0N/A * or <code>setValue</code> methods. 0N/A * Typically this property is a <code>Date</code> however it's possible to use 0N/A * <code>Comparable</code> with a <code>compareTo</code> method for 0N/A * <code>Date</code>s. See <code>setStart</code> for an example. 0N/A * This method fires a <code>ChangeEvent</code> if the <code>end</code> 0N/A * @param end defines the last date in the sequence 0N/A * @see #addChangeListener 0N/A * Returns the last <code>Date</code> in the sequence. 0N/A * @return the value of the <code>end</code> property 0N/A * Changes the size of the date value change computed 0N/A * by the <code>nextValue</code> and <code>previousValue</code> methods. 0N/A * The <code>calendarField</code> parameter must be one of the 0N/A * <code>Calendar</code> field constants like <code>Calendar.MONTH</code> 0N/A * or <code>Calendar.MINUTE</code>. 0N/A * The <code>nextValue</code> and <code>previousValue</code> methods 0N/A * simply move the specified <code>Calendar</code> field forward or backward 0N/A * by one unit with the <code>Calendar.add</code> method. 0N/A * You should use this method with care as some UIs may set the 0N/A * calendarField before commiting the edit to spin the field under 0N/A * the cursor. If you only want one field to spin you can subclass 0N/A * and ignore the setCalendarField calls. 0N/A * @param calendarField one of 0N/A * <li><code>Calendar.ERA</code> 0N/A * <li><code>Calendar.YEAR</code> 0N/A * <li><code>Calendar.MONTH</code> 0N/A * <li><code>Calendar.WEEK_OF_YEAR</code> 0N/A * <li><code>Calendar.WEEK_OF_MONTH</code> 0N/A * <li><code>Calendar.DAY_OF_MONTH</code> 0N/A * <li><code>Calendar.DAY_OF_YEAR</code> 0N/A * <li><code>Calendar.DAY_OF_WEEK</code> 0N/A * <li><code>Calendar.DAY_OF_WEEK_IN_MONTH</code> 0N/A * <li><code>Calendar.AM_PM</code> 0N/A * <li><code>Calendar.HOUR</code> 0N/A * <li><code>Calendar.HOUR_OF_DAY</code> 0N/A * <li><code>Calendar.MINUTE</code> 0N/A * <li><code>Calendar.SECOND</code> 0N/A * <li><code>Calendar.MILLISECOND</code> 0N/A * This method fires a <code>ChangeEvent</code> if the 0N/A * <code>calendarField</code> has changed. 0N/A * @see #getCalendarField 0N/A * @see #getNextValue 0N/A * @see #getPreviousValue 0N/A * @see #addChangeListener 0N/A * Returns the <code>Calendar</code> field that is added to or subtracted from 0N/A * by the <code>nextValue</code> and <code>previousValue</code> methods. 0N/A * @return the value of the <code>calendarField</code> property * Returns the next <code>Date</code> in the sequence, or <code>null</code> if * the next date is after <code>end</code>. * @return the next <code>Date</code> in the sequence, or <code>null</code> if * the next date is after <code>end</code>. * @see SpinnerModel#getNextValue * Returns the previous <code>Date</code> in the sequence, or <code>null</code> * if the previous date is before <code>start</code>. * @return the previous <code>Date</code> in the sequence, or * <code>null</code> if the previous date * is before <code>start</code> * @see SpinnerModel#getPreviousValue * Returns the current element in this sequence of <code>Date</code>s. * This method is equivalent to <code>(Date)getValue</code>. * @return the <code>value</code> property * Returns the current element in this sequence of <code>Date</code>s. * @return the <code>value</code> property * Sets the current <code>Date</code> for this sequence. * If <code>value</code> is <code>null</code>, * an <code>IllegalArgumentException</code> is thrown. No bounds * the new value may invalidate the <code>(start <= value < end)</code> * invariant enforced by the constructors. Naturally, one should ensure * that the <code>(start <= value <= maximum)</code> invariant is true * before calling the <code>nextValue</code>, <code>previousValue</code>, * or <code>setValue</code> methods. * This method fires a <code>ChangeEvent</code> if the * <code>value</code> has changed. * @param value the current (non <code>null</code>) * <code>Date</code> for this sequence * @throws IllegalArgumentException if value is <code>null</code> * or not a <code>Date</code> * @see #addChangeListener