1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package fr.ifremer.quadrige3.ui.swing.component.date;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 import javax.swing.event.ChangeEvent;
55 import javax.swing.event.ChangeListener;
56 import java.beans.PropertyChangeEvent;
57 import java.beans.PropertyChangeListener;
58 import java.util.Calendar;
59 import java.util.Date;
60 import java.util.HashSet;
61 import java.util.Set;
62
63
64
65
66
67
68
69 public class DateModel {
70
71
72 public static final String PROPERTY_YEAR = "year";
73
74 public static final String PROPERTY_MONTH = "month";
75
76 public static final String PROPERTY_DAY = "day";
77
78 public static final String PROPERTY_VALUE = "value";
79
80 public static final String PROPERTY_SELECTED = "selected";
81
82 private boolean modelAdjusting;
83 private boolean selected;
84 private Date date;
85 private Calendar calendarValue;
86 private final Set<ChangeListener> changeListeners;
87 private final Set<PropertyChangeListener> propertyChangeListeners;
88
89
90
91
92
93
94 public DateModel(Date dateValue) {
95 this();
96 setDate(dateValue);
97 }
98
99
100
101
102
103
104 public DateModel(Calendar calendarValue) {
105 this();
106 setDate(fromCalendar(calendarValue));
107 }
108
109
110
111
112 public DateModel() {
113 changeListeners = new HashSet<>();
114 propertyChangeListeners = new HashSet<>();
115 selected = false;
116 calendarValue = Calendar.getInstance();
117 }
118
119
120
121
122
123
124 public synchronized void addChangeListener(ChangeListener changeListener) {
125 changeListeners.add(changeListener);
126 }
127
128
129
130
131
132
133 public synchronized void removeChangeListener(ChangeListener changeListener) {
134 changeListeners.remove(changeListener);
135 }
136
137
138
139
140 protected synchronized void fireChangeEvent() {
141 if (modelAdjusting) {
142 return;
143 }
144 modelAdjusting = true;
145 for (ChangeListener changeListener : changeListeners) {
146 changeListener.stateChanged(new ChangeEvent(this));
147 }
148 modelAdjusting = false;
149 }
150
151
152
153
154
155
156 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
157 propertyChangeListeners.add(listener);
158 }
159
160
161
162
163
164
165 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
166 propertyChangeListeners.remove(listener);
167 }
168
169
170
171
172
173
174
175
176 protected synchronized void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
177 if (oldValue != null && newValue != null && oldValue.equals(newValue)) {
178 return;
179 }
180
181 for (PropertyChangeListener listener : propertyChangeListeners) {
182 listener.propertyChange(new PropertyChangeEvent(this, propertyName, oldValue, newValue));
183 }
184 }
185
186
187
188
189
190
191 public int getDay() {
192 return calendarValue.get(Calendar.DATE);
193 }
194
195
196
197
198
199
200 public int getMonth() {
201 return calendarValue.get(Calendar.MONTH);
202 }
203
204
205
206
207
208
209 public int getYear() {
210 return calendarValue.get(Calendar.YEAR);
211 }
212
213
214
215
216
217
218 public Date getDate() {
219 if (!selected) {
220 return null;
221 }
222 return date;
223 }
224
225
226
227
228
229
230 public void setDay(int day) {
231 int oldDayValue = this.calendarValue.get(Calendar.DATE);
232 calendarValue.set(Calendar.DATE, day);
233 fireChangeEvent();
234 firePropertyChange(PROPERTY_DAY, oldDayValue, this.calendarValue.get(Calendar.DATE));
235 updateDateFromCalendar();
236 }
237
238
239
240
241
242
243 public void addDay(int add) {
244 int oldDayValue = this.calendarValue.get(Calendar.DATE);
245 calendarValue.add(Calendar.DATE, add);
246 fireChangeEvent();
247 firePropertyChange(PROPERTY_DAY, oldDayValue, this.calendarValue.get(Calendar.DATE));
248 }
249
250
251
252
253
254
255 public void setMonth(int month) {
256 int oldYearValue = this.calendarValue.get(Calendar.YEAR);
257 int oldMonthValue = this.calendarValue.get(Calendar.MONTH);
258 int oldDayValue = this.calendarValue.get(Calendar.DAY_OF_MONTH);
259
260 Calendar newVal = Calendar.getInstance();
261 newVal.set(Calendar.DAY_OF_MONTH, 1);
262 newVal.set(Calendar.MONTH, month);
263 newVal.set(Calendar.YEAR, oldYearValue);
264
265 if (newVal.getActualMaximum(Calendar.DAY_OF_MONTH) <= oldDayValue) {
266 newVal.set(Calendar.DAY_OF_MONTH,
267 newVal.getActualMaximum(Calendar.DAY_OF_MONTH));
268 } else {
269 newVal.set(Calendar.DAY_OF_MONTH, oldDayValue);
270 }
271
272 calendarValue.set(Calendar.MONTH, newVal.get(Calendar.MONTH));
273 calendarValue.set(Calendar.DAY_OF_MONTH, newVal.get(Calendar.DAY_OF_MONTH));
274
275 fireChangeEvent();
276 firePropertyChange(PROPERTY_MONTH, oldMonthValue, this.calendarValue.get(Calendar.MONTH));
277
278 if (this.calendarValue.get(Calendar.DAY_OF_MONTH) != oldDayValue) {
279 firePropertyChange(PROPERTY_DAY, oldDayValue,
280 this.calendarValue.get(Calendar.DAY_OF_MONTH));
281 }
282 }
283
284
285
286
287
288
289 public void addMonth(int add) {
290 int oldMonthValue = this.calendarValue.get(Calendar.MONTH);
291 calendarValue.add(Calendar.MONTH, add);
292 fireChangeEvent();
293 firePropertyChange(PROPERTY_MONTH, oldMonthValue, this.calendarValue.get(Calendar.MONTH));
294 }
295
296
297
298
299
300
301 public void setYear(int year) {
302 int oldYearValue = this.calendarValue.get(Calendar.YEAR);
303 int oldMonthValue = this.calendarValue.get(Calendar.MONTH);
304 int oldDayValue = this.calendarValue.get(Calendar.DAY_OF_MONTH);
305
306 Calendar newVal = Calendar.getInstance();
307 newVal.set(Calendar.DAY_OF_MONTH, 1);
308 newVal.set(Calendar.MONTH, oldMonthValue);
309 newVal.set(Calendar.YEAR, year);
310
311 if (newVal.getActualMaximum(Calendar.DAY_OF_MONTH) <= oldDayValue) {
312 newVal.set(Calendar.DAY_OF_MONTH,
313 newVal.getActualMaximum(Calendar.DAY_OF_MONTH));
314 } else {
315 newVal.set(Calendar.DAY_OF_MONTH, oldDayValue);
316 }
317
318 calendarValue.set(Calendar.YEAR, newVal.get(Calendar.YEAR));
319 calendarValue.set(Calendar.DAY_OF_MONTH, newVal.get(Calendar.DAY_OF_MONTH));
320
321 fireChangeEvent();
322 firePropertyChange(PROPERTY_YEAR, oldYearValue, this.calendarValue.get(Calendar.YEAR));
323
324 if (this.calendarValue.get(Calendar.DAY_OF_MONTH) != oldDayValue) {
325 firePropertyChange(PROPERTY_DAY, oldDayValue,
326 this.calendarValue.get(Calendar.DAY_OF_MONTH));
327 }
328 }
329
330
331
332
333
334
335 public void addYear(int add) {
336 int oldYearValue = this.calendarValue.get(Calendar.YEAR);
337 calendarValue.add(Calendar.YEAR, add);
338 fireChangeEvent();
339 firePropertyChange(PROPERTY_YEAR, oldYearValue, this.calendarValue.get(Calendar.YEAR));
340 }
341
342
343
344
345
346
347 public void setDate(Date value) {
348 int oldYearValue = this.calendarValue.get(Calendar.YEAR);
349 int oldMonthValue = this.calendarValue.get(Calendar.MONTH);
350 int oldDayValue = this.calendarValue.get(Calendar.DATE);
351 boolean oldSelectedValue = isSelected();
352
353 selected = value != null;
354
355 if (value == null) {
356 value = new Date();
357 }
358
359 this.calendarValue = toCalendar(value);
360 setToMidnight();
361
362 fireChangeEvent();
363 firePropertyChange(PROPERTY_YEAR, oldYearValue, this.calendarValue.get(Calendar.YEAR));
364 firePropertyChange(PROPERTY_MONTH, oldMonthValue, this.calendarValue.get(Calendar.MONTH));
365 firePropertyChange(PROPERTY_DAY, oldDayValue, this.calendarValue.get(Calendar.DATE));
366 updateDateFromCalendar();
367 firePropertyChange(PROPERTY_SELECTED, oldSelectedValue, this.selected);
368 }
369
370
371
372
373
374
375
376
377 public void setDate(int year, int month, int day) {
378 int oldYearValue = this.calendarValue.get(Calendar.YEAR);
379 int oldMonthValue = this.calendarValue.get(Calendar.MONTH);
380 int oldDayValue = this.calendarValue.get(Calendar.DATE);
381 calendarValue.set(year, month, day);
382 fireChangeEvent();
383 firePropertyChange(PROPERTY_YEAR, oldYearValue, this.calendarValue.get(Calendar.YEAR));
384 firePropertyChange(PROPERTY_MONTH, oldMonthValue, this.calendarValue.get(Calendar.MONTH));
385 firePropertyChange(PROPERTY_DAY, oldDayValue, this.calendarValue.get(Calendar.DATE));
386 updateDateFromCalendar();
387 }
388
389 private void updateDateFromCalendar() {
390 date = fromCalendar(calendarValue);
391 firePropertyChange(PROPERTY_VALUE, null, date);
392 }
393
394
395
396
397
398
399 public boolean isSelected() {
400 return selected;
401 }
402
403
404
405
406
407
408 public void setSelected(boolean selected) {
409 boolean oldSelectedValue = isSelected();
410 this.selected = selected;
411 fireChangeEvent();
412 updateDateFromCalendar();
413 firePropertyChange(PROPERTY_SELECTED, oldSelectedValue, this.selected);
414 }
415
416 private void setToMidnight() {
417 calendarValue.set(Calendar.HOUR_OF_DAY, 0);
418 calendarValue.set(Calendar.MINUTE, 0);
419 calendarValue.set(Calendar.SECOND, 0);
420 calendarValue.set(Calendar.MILLISECOND, 0);
421 }
422
423 private Calendar toCalendar(Date from) {
424 Calendar to = Calendar.getInstance();
425 to.setTime(from);
426 return to;
427 }
428
429 private Date fromCalendar(Calendar from) {
430 return new Date(from.getTimeInMillis());
431 }
432
433 }