001 /*
002 * $Id: DateSelectionModel.java 3100 2008-10-14 22:33:10Z rah003 $
003 *
004 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021 package org.jdesktop.swingx.calendar;
022
023 import java.util.Calendar;
024 import java.util.Date;
025 import java.util.Locale;
026 import java.util.SortedSet;
027 import java.util.TimeZone;
028
029 import org.jdesktop.swingx.event.DateSelectionListener;
030
031
032 /**
033 * The Model used by calendar components. It controls the Calendar to use and
034 * keeps selection-related state.
035 *
036 * @author Joshua Outwater
037 */
038 public interface DateSelectionModel {
039 public static enum SelectionMode {
040 /**
041 * Mode that allows for selection of a single day.
042 */
043 SINGLE_SELECTION,
044 /**
045 * Mode that allows for selecting of multiple consecutive days.
046 */
047 SINGLE_INTERVAL_SELECTION,
048 /**
049 * Mode that allows for selecting disjoint days.
050 */
051 MULTIPLE_INTERVAL_SELECTION
052 }
053
054 //---------------------- mode
055 /**
056 * Get the selection mode.
057 *
058 * @return return the current selection mode
059 */
060 public SelectionMode getSelectionMode();
061
062 /**
063 * Set the selection mode.
064 *
065 * @param mode new selection mode
066 */
067 public void setSelectionMode(final SelectionMode mode);
068
069
070 //-------------------- calendar
071 /**
072 * Returns a clone of the calendar used by this model. It's date is unspecified.
073 *
074 * @return a clone of the calendar used by this model.
075 */
076 public Calendar getCalendar();
077
078 /**
079 * Gets what the first day of the week is; e.g.,
080 * <code>Calendar.SUNDAY</code> in the U.S., <code>Calendar.MONDAY</code>
081 * in France. This is needed when the model selection mode is
082 * <code>WEEK_INTERVAL_SELECTION</code>.
083 *
084 * PENDING JW: move week-interval selection from JXMonthView into the model.
085 *
086 * @return int The first day of the week.
087 * @see #setFirstDayOfWeek(int)
088 */
089 public int getFirstDayOfWeek();
090
091 /**
092 * Sets what the first day of the week is. E.g.,
093 * <code>Calendar.SUNDAY</code> in US, <code>Calendar.MONDAY</code>
094 * in France. Fires a DateSelectionEvent of type CALENDAR_CHANGED, if the
095 * value is different from the old. <p>
096 *
097 * The default value depends on the Calendar's default.
098 *
099 * PENDING JW: actually, it's a bound property. Use a propertyChangeListener?
100 *
101 * @param firstDayOfWeek The first day of the week.
102 * @see #getFirstDayOfWeek()
103 * @see java.util.Calendar
104 */
105 public void setFirstDayOfWeek(final int firstDayOfWeek);
106
107
108 /**
109 * Gets the minimal number of days in the first week of the year.
110 *
111 * @return int the minimal number of days in the first week of the year.
112 */
113 public int getMinimalDaysInFirstWeek();
114
115 /**
116 * Sets the minimal number of days in the first week of the year.
117 * Fires a DateSelectionEvent of type CALENDAR_CHANGED, if the
118 * value is different from the old.
119 *
120 * The default value depends on the Calendar's default.
121 *
122 * PENDING JW: actually, it's a bound property. Use a propertyChangeListener?
123 *
124 * @param minimalDays the minimal number of days in the first week of the year.
125 * @see #getMinimalDaysInFirstWeek()
126 * @see java.util.Calendar
127 */
128 public void setMinimalDaysInFirstWeek(final int minimalDays);
129
130 /**
131 * Returns the TimeZone of this model.
132 *
133 * @return the TimeZone of this model.
134 * @see #setTimeZone(TimeZone)
135 */
136 public TimeZone getTimeZone();
137
138
139 /**
140 * Sets the TimeZone of this model. Fires a DateSelectionEvent of type
141 * CALENDAR_CHANGED if the new value is different from the old.
142 *
143 * The default value depends on the Calendar's default.
144 *
145 * PENDING JW: actually, it's a bound property. Use a propertyChangeListener?
146 *
147 * @param timeZone the TimeZone to use in this model, must not be null.
148 * @see #getTimeZone()
149 */
150 public void setTimeZone(TimeZone timeZone);
151
152 /**
153 * Returns the Locale of this model's calendar.
154 * @return the Locale of this model's calendar.
155 */
156 public Locale getLocale();
157
158 /**
159 * Sets the Locale of this model's calendar. Fires a DateSelectionEvent of type
160 * CALENDAR_CHANGED if the new value is different from the old. <p>
161 *
162 * The default value is Locale.default(). <p>
163 *
164 * PENDING JW: fall back to JComponent.getDefaultLocale instead? We use this
165 * with components anyway? <p>
166 * PENDING JW: actually, it's a bound property. Use a propertyChangeListener?
167 *
168 * @param locale the Locale to use. If null, the default Locale is used.
169 */
170 public void setLocale(Locale locale);
171
172 //-------------------- selection
173
174 /**
175 * Adds the specified selection interval to the selection model.
176 *
177 * @param startDate interval start date, must not be null
178 * @param endDate interval end date >= start date, must not be null
179 * @throws NullPointerException if any of the dates is null
180 */
181 public void addSelectionInterval(Date startDate, Date endDate);
182
183 /**
184 * Sest the specified selection interval to the selection model.
185 *
186 * @param startDate interval start date, must not be null
187 * @param endDate interval end date >= start date, must not be null
188 * @throws NullPointerException if any of the dates is null
189 */
190 public void setSelectionInterval(Date startDate, Date endDate);
191
192 /**
193 * Removes the specifed selection interval from the selection model. If
194 * the selection is changed by this method, it fires a DateSelectionEvent
195 * of type DATES_REMOVED.
196 *
197 * @param startDate interval start date, must not be null
198 * @param endDate interval end date >= start date, must not be null
199 * @throws NullPointerException if any of the dates is null
200 */
201 public void removeSelectionInterval(Date startDate, Date endDate);
202
203 /**
204 * Clears any selection from the selection model. Fires an Event of
205 * type SELECTION_CLEARED if there had been a selection, does nothing
206 * otherwise.
207 */
208 public void clearSelection();
209
210 /**
211 * Returns the current selection.
212 *
213 * @return sorted set of selected dates, guaranteed to be never null.
214 */
215 public SortedSet<Date> getSelection();
216
217 /**
218 * Returns the earliest date in the selection or null if the selection is empty.
219 *
220 * @return the earliest date in the selection, or null if isSelectionEmpty.
221 *
222 * @see #getLastSelectionDate()
223 * @see #getSelection()
224 * @see #isSelectionEmpty()
225 */
226 public Date getFirstSelectionDate();
227
228 /**
229 * Returns the latest date in the selection or null if the selection is empty.
230 *
231 * @return the lastest date in the selection, or null if isSelectionEmpty.
232 *
233 * @see #getFirstSelectionDate()
234 * @see #getSelection()
235 * @see #isSelectionEmpty()
236 */
237 public Date getLastSelectionDate();
238
239
240 /**
241 * Returns true if the date specified is selected, false otherwise. <p>
242 *
243 * Note: it is up to implementations to define the exact notion of selected.
244 * It does not imply the exact date as given is contained the set returned from
245 * getSelection().
246 *
247 * @param date date to check for selection, must not be null
248 * @return true if the date is selected, false otherwise
249 * @throws NullPointerException if the date is null
250 */
251 public boolean isSelected(final Date date);
252
253 /**
254 * Returns a normalized Date as used by the implementation, if any. F.i.
255 * DaySelectionModel returns the start of the day in the model's calendar.
256 * If no normalization is applied, a clone of the Date itself is returned.
257 * The given Date is never changed.
258 * <p>
259 *
260 * The overall contract:
261 *
262 * <pre><code>
263 * if ((date != null) && isSelectable(date)) {
264 * setSelectionInterval(date, date);
265 * assertEquals(getNormalized(date), getFirstSelectionDate();
266 * }
267 * </code></pre>
268 *
269 *
270 * @return the date as it would be normalized before used in the model,
271 * must not be null.
272 * @throws NullPointerException if given date is null.
273 */
274 public Date getNormalizedDate(Date date);
275
276 /**
277 * Returns true if the selection is empty, false otherwise.
278 *
279 * @return true if the selection is empty, false otherwise
280 */
281 public boolean isSelectionEmpty();
282
283
284 /**
285 * Returns a <code>SortedSet</code> of <code>Date</codes>s that are unselectable.
286 *
287 * @return sorted set of dates
288 */
289 public SortedSet<Date> getUnselectableDates();
290
291 /**
292 * Sets a collection of dates which are not selectable.<p>
293 *
294 * Note: it is up to implementations to define the exact notion of unselectableDate.
295 * It does not imply the only the exact date as given is unselectable, it might
296 * have a period like "all dates on the same day".
297 *
298 * PENDING JW: any collection would do - why insist on a SortedSet?
299 *
300 * @param unselectableDates dates that are unselectable, must not be null and
301 * must not contain null dates.
302 */
303 public void setUnselectableDates(SortedSet<Date> unselectableDates);
304
305 /**
306 * Returns true is the specified date is unselectable.
307 *
308 * @param unselectableDate the date to check for unselectability, must not be null.
309 * @return true is the date is unselectable, false otherwise
310 */
311 public boolean isUnselectableDate(Date unselectableDate);
312
313 /**
314 * Return the upper bound date that is allowed to be selected for this
315 * model.
316 *
317 * @return upper bound date or null if not set
318 */
319 public Date getUpperBound();
320
321 /**
322 * Set the upper bound date that is allowed to be selected for this model.
323 *
324 * @param upperBound upper bound
325 */
326 public void setUpperBound(final Date upperBound);
327
328 /**
329 * Return the lower bound date that is allowed to be selected for this
330 * model.
331 *
332 * @return lower bound date or null if not set
333 */
334 public Date getLowerBound();
335
336 /**
337 * Set the lower bound date that is allowed to be selected for this model.
338 *
339 * @param lowerBound lower bound date or null if not set
340 */
341 public void setLowerBound(final Date lowerBound);
342
343 /**
344 * Set the property to mark upcoming selections as intermediate/
345 * final. This will fire a event of type adjusting_start/stop.
346 *
347 * The default value is false.
348 *
349 * Note: Client code marking as intermediate must take care of
350 * finalizing again.
351 *
352 * @param adjusting a flag to turn the adjusting property on/off.
353 */
354 public void setAdjusting(boolean adjusting);
355
356 /**
357 * Returns the property to decide whether the selection is
358 * intermediate or final.
359 *
360 * @return the adjusting property.
361 */
362 public boolean isAdjusting();
363
364 /**
365 * Add the specified listener to this model.
366 *
367 * @param listener listener to add to this model
368 */
369 public void addDateSelectionListener(DateSelectionListener listener);
370
371 /**
372 * Remove the specified listener to this model.
373 *
374 * @param listener listener to remove from this model
375 */
376 public void removeDateSelectionListener(DateSelectionListener listener);
377
378 }