Source Code Cross Referenced for SpinnerDateModel.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package javax.swing;
027
028        import java.util.*;
029        import java.io.Serializable;
030
031        /**
032         * A <code>SpinnerModel</code> for sequences of <code>Date</code>s. 
033         * The upper and lower bounds of the sequence are defined by properties called 
034         * <code>start</code> and <code>end</code> and the size
035         * of the increase or decrease computed by the <code>nextValue</code>
036         * and <code>previousValue</code> methods is defined by a property
037         * called <code>calendarField</code>.  The <code>start</code> 
038         * and <code>end</code> properties can be <code>null</code> to
039         * indicate that the sequence has no lower or upper limit.  
040         * <p>
041         * The value of the <code>calendarField</code> property must be one of the
042         * <code>java.util.Calendar</code> constants that specify a field
043         * within a <code>Calendar</code>.  The <code>getNextValue</code> 
044         * and <code>getPreviousValue</code> 
045         * methods change the date forward or backwards by this amount.  
046         * For example, if <code>calendarField</code> is <code>Calendar.DAY_OF_WEEK</code>,
047         * then <code>nextValue</code> produces a <code>Date</code> that's 24
048         * hours after the current <code>value</code>, and <code>previousValue</code>
049         * produces a <code>Date</code> that's 24 hours earlier.
050         * <p>
051         * The legal values for <code>calendarField</code> are:
052         * <ul>
053         *   <li><code>Calendar.ERA</code>
054         *   <li><code>Calendar.YEAR</code>
055         *   <li><code>Calendar.MONTH</code>
056         *   <li><code>Calendar.WEEK_OF_YEAR</code>
057         *   <li><code>Calendar.WEEK_OF_MONTH</code>
058         *   <li><code>Calendar.DAY_OF_MONTH</code>
059         *   <li><code>Calendar.DAY_OF_YEAR</code>
060         *   <li><code>Calendar.DAY_OF_WEEK</code>
061         *   <li><code>Calendar.DAY_OF_WEEK_IN_MONTH</code>
062         *   <li><code>Calendar.AM_PM</code>
063         *   <li><code>Calendar.HOUR</code>
064         *   <li><code>Calendar.HOUR_OF_DAY</code>
065         *   <li><code>Calendar.MINUTE</code>
066         *   <li><code>Calendar.SECOND</code>
067         *   <li><code>Calendar.MILLISECOND</code>
068         * </ul>
069         * However some UIs may set the calendarField before commiting the edit
070         * to spin the field under the cursor. If you only want one field to
071         * spin you can subclass and ignore the setCalendarField calls.
072         * <p>
073         * This model inherits a <code>ChangeListener</code>.  The
074         * <code>ChangeListeners</code> are notified whenever the models
075         * <code>value</code>, <code>calendarField</code>, 
076         * <code>start</code>, or <code>end</code> properties changes.
077         * 
078         * @see JSpinner
079         * @see SpinnerModel
080         * @see AbstractSpinnerModel
081         * @see SpinnerListModel
082         * @see SpinnerNumberModel
083         * @see Calendar#add
084         *
085         * @version 1.19 05/05/07
086         * @author Hans Muller
087         * @since 1.4
088         */
089        public class SpinnerDateModel extends AbstractSpinnerModel implements 
090                Serializable {
091            private Comparable start, end;
092            private Calendar value;
093            private int calendarField;
094
095            private boolean calendarFieldOK(int calendarField) {
096                switch (calendarField) {
097                case Calendar.ERA:
098                case Calendar.YEAR:
099                case Calendar.MONTH:
100                case Calendar.WEEK_OF_YEAR:
101                case Calendar.WEEK_OF_MONTH:
102                case Calendar.DAY_OF_MONTH:
103                case Calendar.DAY_OF_YEAR:
104                case Calendar.DAY_OF_WEEK:
105                case Calendar.DAY_OF_WEEK_IN_MONTH:
106                case Calendar.AM_PM:
107                case Calendar.HOUR:
108                case Calendar.HOUR_OF_DAY:
109                case Calendar.MINUTE:
110                case Calendar.SECOND:
111                case Calendar.MILLISECOND:
112                    return true;
113                default:
114                    return false;
115                }
116            }
117
118            /**
119             * Creates a <code>SpinnerDateModel</code> that represents a sequence of dates
120             * between <code>start</code> and <code>end</code>.  The 
121             * <code>nextValue</code> and <code>previousValue</code> methods 
122             * compute elements of the sequence by advancing or reversing
123             * the current date <code>value</code> by the 
124             * <code>calendarField</code> time unit.  For a precise description
125             * of what it means to increment or decrement a <code>Calendar</code>
126             * <code>field</code>, see the <code>add</code> method in 
127             * <code>java.util.Calendar</code>.
128             * <p>
129             * The <code>start</code> and <code>end</code> parameters can be
130             * <code>null</code> to indicate that the range doesn't have an
131             * upper or lower bound.  If <code>value</code> or
132             * <code>calendarField</code> is <code>null</code>, or if both 
133             * <code>start</code> and <code>end</code> are specified and 
134             * <code>mininum &gt; maximum</code> then an
135             * <code>IllegalArgumentException</code> is thrown.
136             * Similarly if <code>(minimum &lt;= value &lt;= maximum)</code> is false,
137             * an IllegalArgumentException is thrown.
138             * 
139             * @param value the current (non <code>null</code>) value of the model
140             * @param start the first date in the sequence or <code>null</code>
141             * @param end the last date in the sequence or <code>null</code>
142             * @param calendarField one of 
143             *   <ul>
144             *    <li><code>Calendar.ERA</code>
145             *    <li><code>Calendar.YEAR</code>
146             *    <li><code>Calendar.MONTH</code>
147             *    <li><code>Calendar.WEEK_OF_YEAR</code>
148             *    <li><code>Calendar.WEEK_OF_MONTH</code>
149             *    <li><code>Calendar.DAY_OF_MONTH</code>
150             *    <li><code>Calendar.DAY_OF_YEAR</code>
151             *    <li><code>Calendar.DAY_OF_WEEK</code>
152             *    <li><code>Calendar.DAY_OF_WEEK_IN_MONTH</code>
153             *    <li><code>Calendar.AM_PM</code>
154             *    <li><code>Calendar.HOUR</code>
155             *    <li><code>Calendar.HOUR_OF_DAY</code>
156             *    <li><code>Calendar.MINUTE</code>
157             *    <li><code>Calendar.SECOND</code>
158             *    <li><code>Calendar.MILLISECOND</code>
159             *   </ul>
160             * 
161             * @throws IllegalArgumentException if <code>value</code> or
162             *    <code>calendarField</code> are <code>null</code>,
163             *    if <code>calendarField</code> isn't valid,
164             *    or if the following expression is 
165             *    false: <code>(start &lt;= value &lt;= end)</code>.
166             * 
167             * @see Calendar#add
168             * @see #setValue
169             * @see #setStart
170             * @see #setEnd
171             * @see #setCalendarField
172             */
173            public SpinnerDateModel(Date value, Comparable start,
174                    Comparable end, int calendarField) {
175                if (value == null) {
176                    throw new IllegalArgumentException("value is null");
177                }
178                if (!calendarFieldOK(calendarField)) {
179                    throw new IllegalArgumentException("invalid calendarField");
180                }
181                if (!(((start == null) || (start.compareTo(value) <= 0)) && ((end == null) || (end
182                        .compareTo(value) >= 0)))) {
183                    throw new IllegalArgumentException(
184                            "(start <= value <= end) is false");
185                }
186                this .value = Calendar.getInstance();
187                this .start = start;
188                this .end = end;
189                this .calendarField = calendarField;
190
191                this .value.setTime(value);
192            }
193
194            /**
195             * Constructs a <code>SpinnerDateModel</code> whose initial
196             * <code>value</code> is the current date, <code>calendarField</code>
197             * is equal to <code>Calendar.DAY_OF_MONTH</code>, and for which 
198             * there are no <code>start</code>/<code>end</code> limits.
199             */
200            public SpinnerDateModel() {
201                this (new Date(), null, null, Calendar.DAY_OF_MONTH);
202            }
203
204            /**
205             * Changes the lower limit for Dates in this sequence. 
206             * If <code>start</code> is <code>null</code>,
207             * then there is no lower limit.  No bounds checking is done here: 
208             * the new start value may invalidate the
209             * <code>(start &lt;= value &lt;= end)</code>
210             * invariant enforced by the constructors.  This is to simplify updating
211             * the model.  Naturally one should ensure that the invariant is true
212             * before calling the <code>nextValue</code>, <code>previousValue</code>,
213             * or <code>setValue</code> methods.
214             * <p>
215             * Typically this property is a <code>Date</code> however it's possible to use 
216             * a <code>Comparable</code> with a <code>compareTo</code> method for Dates.  
217             * For example <code>start</code> might be an instance of a class like this:
218             * <pre>
219             * MyStartDate implements Comparable { 
220             *     long t = 12345;
221             *     public int compareTo(Date d) {
222             *            return (t < d.getTime() ? -1 : (t == d.getTime() ? 0 : 1));
223             *     }
224             *     public int compareTo(Object o) {
225             *            return compareTo((Date)o);
226             *     }
227             * }
228             * </pre>
229             * Note that the above example will throw a <code>ClassCastException</code>
230             * if the <code>Object</code> passed to <code>compareTo(Object)</code>
231             * is not a <code>Date</code>.
232             * <p>
233             * This method fires a <code>ChangeEvent</code> if the
234             * <code>start</code> has changed.
235             * 
236             * @param start defines the first date in the sequence
237             * @see #getStart
238             * @see #setEnd
239             * @see #addChangeListener
240             */
241            public void setStart(Comparable start) {
242                if ((start == null) ? (this .start != null) : !start
243                        .equals(this .start)) {
244                    this .start = start;
245                    fireStateChanged();
246                }
247            }
248
249            /**
250             * Returns the first <code>Date</code> in the sequence.
251             * 
252             * @return the value of the <code>start</code> property
253             * @see #setStart
254             */
255            public Comparable getStart() {
256                return start;
257            }
258
259            /** 
260             * Changes the upper limit for <code>Date</code>s in this sequence. 
261             * If <code>start</code> is <code>null</code>, then there is no upper
262             * limit.  No bounds checking is done here: the new 
263             * start value may invalidate the <code>(start &lt;= value &lt;= end)</code>
264             * invariant enforced by the constructors.  This is to simplify updating
265             * the model.  Naturally, one should ensure that the invariant is true
266             * before calling the <code>nextValue</code>, <code>previousValue</code>, 
267             * or <code>setValue</code> methods.
268             * <p>
269             * Typically this property is a <code>Date</code> however it's possible to use 
270             * <code>Comparable</code> with a <code>compareTo</code> method for 
271             * <code>Date</code>s.  See <code>setStart</code> for an example.
272             * <p>
273             * This method fires a <code>ChangeEvent</code> if the <code>end</code>
274             * has changed.
275             * 
276             * @param end defines the last date in the sequence
277             * @see #getEnd
278             * @see #setStart
279             * @see #addChangeListener
280             */
281            public void setEnd(Comparable end) {
282                if ((end == null) ? (this .end != null) : !end.equals(this .end)) {
283                    this .end = end;
284                    fireStateChanged();
285                }
286            }
287
288            /**
289             * Returns the last <code>Date</code> in the sequence.
290             * 
291             * @return the value of the <code>end</code> property
292             * @see #setEnd
293             */
294            public Comparable getEnd() {
295                return end;
296            }
297
298            /**
299             * Changes the size of the date value change computed
300             * by the <code>nextValue</code> and <code>previousValue</code> methods.
301             * The <code>calendarField</code> parameter must be one of the 
302             * <code>Calendar</code> field constants like <code>Calendar.MONTH</code> 
303             * or <code>Calendar.MINUTE</code>.
304             * The <code>nextValue</code> and <code>previousValue</code> methods
305             * simply move the specified <code>Calendar</code> field forward or backward 
306             * by one unit with the <code>Calendar.add</code> method.
307             * You should use this method with care as some UIs may set the
308             * calendarField before commiting the edit to spin the field under
309             * the cursor. If you only want one field to spin you can subclass
310             * and ignore the setCalendarField calls.
311             * 
312             * @param calendarField one of 
313             *  <ul>
314             *    <li><code>Calendar.ERA</code>
315             *    <li><code>Calendar.YEAR</code>
316             *    <li><code>Calendar.MONTH</code>
317             *    <li><code>Calendar.WEEK_OF_YEAR</code>
318             *    <li><code>Calendar.WEEK_OF_MONTH</code>
319             *    <li><code>Calendar.DAY_OF_MONTH</code>
320             *    <li><code>Calendar.DAY_OF_YEAR</code>
321             *    <li><code>Calendar.DAY_OF_WEEK</code>
322             *    <li><code>Calendar.DAY_OF_WEEK_IN_MONTH</code>
323             *    <li><code>Calendar.AM_PM</code>
324             *    <li><code>Calendar.HOUR</code>
325             *    <li><code>Calendar.HOUR_OF_DAY</code>
326             *    <li><code>Calendar.MINUTE</code>
327             *    <li><code>Calendar.SECOND</code>
328             *    <li><code>Calendar.MILLISECOND</code>
329             *  </ul>
330             * <p>
331             * This method fires a <code>ChangeEvent</code> if the
332             * <code>calendarField</code> has changed.
333             * 
334             * @see #getCalendarField
335             * @see #getNextValue
336             * @see #getPreviousValue
337             * @see Calendar#add
338             * @see #addChangeListener
339             */
340            public void setCalendarField(int calendarField) {
341                if (!calendarFieldOK(calendarField)) {
342                    throw new IllegalArgumentException("invalid calendarField");
343                }
344                if (calendarField != this .calendarField) {
345                    this .calendarField = calendarField;
346                    fireStateChanged();
347                }
348            }
349
350            /**
351             * Returns the <code>Calendar</code> field that is added to or subtracted from
352             * by the <code>nextValue</code> and <code>previousValue</code> methods.
353             * 
354             * @return the value of the <code>calendarField</code> property
355             * @see #setCalendarField
356             */
357            public int getCalendarField() {
358                return calendarField;
359            }
360
361            /**
362             * Returns the next <code>Date</code> in the sequence, or <code>null</code> if 
363             * the next date is after <code>end</code>.
364             * 
365             * @return the next <code>Date</code> in the sequence, or <code>null</code> if 
366             *     the next date is after <code>end</code>.
367             * 
368             * @see SpinnerModel#getNextValue
369             * @see #getPreviousValue
370             * @see #setCalendarField
371             */
372            public Object getNextValue() {
373                Calendar cal = Calendar.getInstance();
374                cal.setTime(value.getTime());
375                cal.add(calendarField, 1);
376                Date next = cal.getTime();
377                return ((end == null) || (end.compareTo(next) >= 0)) ? next
378                        : null;
379            }
380
381            /**
382             * Returns the previous <code>Date</code> in the sequence, or <code>null</code>
383             * if the previous date is before <code>start</code>.
384             * 
385             * @return the previous <code>Date</code> in the sequence, or
386             *     <code>null</code> if the previous date
387             *     is before <code>start</code>
388             * 
389             * @see SpinnerModel#getPreviousValue
390             * @see #getNextValue
391             * @see #setCalendarField
392             */
393            public Object getPreviousValue() {
394                Calendar cal = Calendar.getInstance();
395                cal.setTime(value.getTime());
396                cal.add(calendarField, -1);
397                Date prev = cal.getTime();
398                return ((start == null) || (start.compareTo(prev) <= 0)) ? prev
399                        : null;
400            }
401
402            /**
403             * Returns the current element in this sequence of <code>Date</code>s.
404             * This method is equivalent to <code>(Date)getValue</code>.
405             *
406             * @return the <code>value</code> property
407             * @see #setValue
408             */
409            public Date getDate() {
410                return value.getTime();
411            }
412
413            /**
414             * Returns the current element in this sequence of <code>Date</code>s.
415             * 
416             * @return the <code>value</code> property
417             * @see #setValue
418             * @see #getDate
419             */
420            public Object getValue() {
421                return value.getTime();
422            }
423
424            /**
425             * Sets the current <code>Date</code> for this sequence.  
426             * If <code>value</code> is <code>null</code>,
427             * an <code>IllegalArgumentException</code> is thrown.  No bounds 
428             * checking is done here: 
429             * the new value may invalidate the <code>(start &lt= value &lt end)</code>
430             * invariant enforced by the constructors.  Naturally, one should ensure 
431             * that the <code>(start &lt;= value &lt;= maximum)</code> invariant is true
432             * before calling the <code>nextValue</code>, <code>previousValue</code>,
433             * or <code>setValue</code> methods.  
434             * <p>
435             * This method fires a <code>ChangeEvent</code> if the
436             * <code>value</code> has changed.
437             * 
438             * @param value the current (non <code>null</code>)
439             *    <code>Date</code> for this sequence
440             * @throws IllegalArgumentException if value is <code>null</code>
441             *    or not a <code>Date</code>
442             * @see #getDate
443             * @see #getValue
444             * @see #addChangeListener
445             */
446            public void setValue(Object value) {
447                if ((value == null) || !(value instanceof  Date)) {
448                    throw new IllegalArgumentException("illegal value");
449                }
450                if (!value.equals(this .value.getTime())) {
451                    this .value.setTime((Date) value);
452                    fireStateChanged();
453                }
454            }
455        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.