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 import javax.swing.event.ChangeEvent;
54 import javax.swing.event.ChangeListener;
55 import java.beans.PropertyChangeEvent;
56 import java.beans.PropertyChangeListener;
57 import java.time.LocalDate;
58 import java.util.Date;
59 import java.util.HashSet;
60 import java.util.Set;
61
62
63
64
65
66
67
68 public class LocalDateModel {
69
70
71
72
73 private static final String PROPERTY_YEAR = "year";
74
75
76
77 private static final String PROPERTY_MONTH = "month";
78
79
80
81 private static final String PROPERTY_DAY = "day";
82
83
84
85 static final String PROPERTY_VALUE = "value";
86
87
88
89 private static final String PROPERTY_SELECTED = "selected";
90
91 private boolean modelAdjusting;
92 private boolean selected;
93 private LocalDate date;
94 private final Set<ChangeListener> changeListeners;
95 private final Set<PropertyChangeListener> propertyChangeListeners;
96
97
98
99
100
101
102 LocalDateModel(LocalDate dateValue) {
103 this();
104 setLocalDate(dateValue);
105 }
106
107
108
109
110 LocalDateModel() {
111 changeListeners = new HashSet<>();
112 propertyChangeListeners = new HashSet<>();
113 selected = false;
114 date = LocalDate.now();
115 }
116
117
118
119
120
121
122 synchronized void addChangeListener(ChangeListener changeListener) {
123 changeListeners.add(changeListener);
124 }
125
126
127
128
129
130
131 synchronized void removeChangeListener(ChangeListener changeListener) {
132 changeListeners.remove(changeListener);
133 }
134
135
136
137
138 private synchronized void fireChangeEvent() {
139 if (modelAdjusting) {
140 return;
141 }
142 modelAdjusting = true;
143 for (ChangeListener changeListener : changeListeners) {
144 changeListener.stateChanged(new ChangeEvent(this));
145 }
146 modelAdjusting = false;
147 }
148
149
150
151
152
153
154 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
155 propertyChangeListeners.add(listener);
156 }
157
158
159
160
161
162
163 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
164 propertyChangeListeners.remove(listener);
165 }
166
167
168
169
170
171
172
173
174 protected synchronized void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
175 if (oldValue != null && oldValue.equals(newValue)) {
176 return;
177 }
178
179 for (PropertyChangeListener listener : propertyChangeListeners) {
180 listener.propertyChange(new PropertyChangeEvent(this, propertyName, oldValue, newValue));
181 }
182 }
183
184
185
186
187
188
189 int getDay() {
190 return getSafeLocalDate().getDayOfMonth();
191 }
192
193
194
195
196
197
198 int getMonth() {
199 return getSafeLocalDate().getMonthValue();
200 }
201
202
203
204
205
206
207 public int getYear() {
208 return getSafeLocalDate().getYear();
209 }
210
211
212
213
214
215
216 LocalDate getLocalDate() {
217 if (!selected) {
218 return null;
219 }
220 return date;
221 }
222
223 LocalDate getSafeLocalDate() {
224 return date != null ? date : LocalDate.now();
225 }
226
227
228
229
230
231
232 void setDay(int day) {
233 int oldDayValue = getDay();
234 if (day < 1) {
235 date = getSafeLocalDate().withDayOfMonth(1).minusDays(1 - day);
236 } else if (day > getSafeLocalDate().lengthOfMonth()) {
237 date = getSafeLocalDate().withDayOfMonth(getSafeLocalDate().lengthOfMonth()).plusDays(day - getSafeLocalDate().lengthOfMonth());
238 } else {
239 date = getSafeLocalDate().withDayOfMonth(day);
240 }
241 fireChangeEvent();
242 firePropertyChange(PROPERTY_DAY, oldDayValue, getDay());
243 firePropertyChange(PROPERTY_VALUE, null, date);
244 }
245
246
247
248
249
250
251 public void addDay(int add) {
252 int oldDayValue = getDay();
253 date = getSafeLocalDate().plusDays(add);
254 fireChangeEvent();
255 firePropertyChange(PROPERTY_DAY, oldDayValue, getDay());
256 }
257
258
259
260
261
262
263 void setMonth(int month) {
264 int oldMonthValue = getMonth();
265 int oldDayValue = getDay();
266
267 date = getSafeLocalDate().withMonth(month);
268
269 fireChangeEvent();
270 firePropertyChange(PROPERTY_MONTH, oldMonthValue, getMonth());
271
272 if (getDay() != oldDayValue) {
273 firePropertyChange(PROPERTY_DAY, oldDayValue, getDay());
274 }
275 }
276
277
278
279
280
281
282 void addMonth(int add) {
283 int oldMonthValue = getMonth();
284 date = getSafeLocalDate().plusMonths(add);
285 fireChangeEvent();
286 firePropertyChange(PROPERTY_MONTH, oldMonthValue, getMonth());
287 }
288
289
290
291
292
293
294 public void setYear(int year) {
295 int oldYearValue = getYear();
296 int oldDayValue = getDay();
297
298 date = getSafeLocalDate().withYear(year);
299
300 fireChangeEvent();
301 firePropertyChange(PROPERTY_YEAR, oldYearValue, getYear());
302
303 if (getDay() != oldDayValue) {
304 firePropertyChange(PROPERTY_DAY, oldDayValue, getDay());
305 }
306 }
307
308
309
310
311
312
313 void addYear(int add) {
314 int oldYearValue = getYear();
315 date = getSafeLocalDate().plusYears(add);
316 fireChangeEvent();
317 firePropertyChange(PROPERTY_YEAR, oldYearValue, getYear());
318 }
319
320
321
322
323
324
325 void setLocalDate(LocalDate value) {
326 int oldYearValue = getYear();
327 int oldMonthValue = getMonth();
328 int oldDayValue = getDay();
329 boolean oldSelectedValue = isSelected();
330
331 selected = value != null;
332 date = value != null ? value : LocalDate.now();
333
334 fireChangeEvent();
335 firePropertyChange(PROPERTY_YEAR, oldYearValue, getYear());
336 firePropertyChange(PROPERTY_MONTH, oldMonthValue, getMonth());
337 firePropertyChange(PROPERTY_DAY, oldDayValue, getDay());
338 firePropertyChange(PROPERTY_VALUE, null, date);
339 firePropertyChange(PROPERTY_SELECTED, oldSelectedValue, this.selected);
340 }
341
342
343
344
345
346
347
348
349 public void setLocalDate(int year, int month, int day) {
350 int oldYearValue = getYear();
351 int oldMonthValue = getMonth();
352 int oldDayValue = getDay();
353
354 date = LocalDate.of(year, month, day);
355
356 fireChangeEvent();
357 firePropertyChange(PROPERTY_YEAR, oldYearValue, getYear());
358 firePropertyChange(PROPERTY_MONTH, oldMonthValue, getMonth());
359 firePropertyChange(PROPERTY_DAY, oldDayValue, getDay());
360 firePropertyChange(PROPERTY_VALUE, null, date);
361 }
362
363
364
365
366
367
368 public boolean isSelected() {
369 return selected;
370 }
371
372
373
374
375
376
377 public void setSelected(boolean selected) {
378 boolean oldSelectedValue = isSelected();
379 this.selected = selected;
380 fireChangeEvent();
381 firePropertyChange(PROPERTY_VALUE, null, date);
382 firePropertyChange(PROPERTY_SELECTED, oldSelectedValue, this.selected);
383 }
384
385 }