1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components;
21
22 import java.awt.BorderLayout;
23 import java.awt.Font;
24 import java.awt.GridBagConstraints;
25 import java.awt.GridBagLayout;
26 import java.awt.Insets;
27 import java.awt.event.ItemEvent;
28 import java.awt.event.ItemListener;
29 import java.text.DateFormatSymbols;
30 import java.text.SimpleDateFormat;
31 import java.util.Calendar;
32 import java.util.Date;
33 import java.util.GregorianCalendar;
34
35 import javax.swing.DefaultComboBoxModel;
36 import javax.swing.JComboBox;
37 import javax.swing.JComponent;
38 import javax.swing.JDialog;
39 import javax.swing.JLabel;
40 import javax.swing.border.CompoundBorder;
41 import javax.swing.border.EmptyBorder;
42
43 import com.cosylab.gui.components.util.CosyUIElements;
44 import com.cosylab.gui.components.util.FontHelper;
45 import com.cosylab.gui.property.editors.PropertyEditor;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class SimpleDateSelector extends JComponent implements PropertyEditor
66 {
67 private static final long serialVersionUID = 1L;
68 private int numberOfYears = 20;
69 private JLabel dayLabel;
70 private JLabel monthLabel;
71 private JLabel yearLabel;
72 private final Calendar calendar = new GregorianCalendar();
73 int startingYear = 2000;
74 JComboBox daySelector;
75 JComboBox monthSelector;
76 JComboBox yearSelector;
77
78
79
80
81 private final class DateChangeListener implements ItemListener
82 {
83
84
85
86
87
88
89
90 public final void itemStateChanged(ItemEvent e)
91 {
92 if (e.getStateChange() != ItemEvent.SELECTED) {
93 return;
94 }
95
96 final SimpleDateSelector owner = SimpleDateSelector.this;
97 Date old=owner.getDate();
98 if (e.getSource() == owner.daySelector) {
99 owner.setDay(owner.daySelector.getSelectedIndex() + 1);
100 firePropertyChange("date", old, owner.getDate());
101 return;
102 }
103
104 if (e.getSource() == owner.monthSelector) {
105 owner.setMonth(owner.monthSelector.getSelectedIndex());
106 firePropertyChange("date", old, owner.getDate());
107 return;
108 }
109
110 if (e.getSource() == owner.yearSelector) {
111 owner.setYear(owner.yearSelector.getSelectedIndex()
112 + owner.startingYear);
113 firePropertyChange("date", old, owner.getDate());
114 }
115 }
116 }
117
118
119
120
121 public SimpleDateSelector()
122 {
123 this(new Date());
124 }
125
126
127
128
129
130
131 public SimpleDateSelector(Date date)
132 {
133 this(date, new GregorianCalendar().get(Calendar.YEAR) - 10, 25);
134 }
135
136
137
138
139
140
141
142
143 public SimpleDateSelector(Date date, int fromYear, int yearRange)
144 {
145 super();
146
147 createComponents();
148
149 setStartingYear(fromYear);
150 setYearRange(fromYear, yearRange);
151
152 setDate(date);
153 }
154
155
156
157
158
159
160
161 public SimpleDateSelector(int fromYear, int yearRange)
162 {
163 this(new Date(), fromYear, yearRange);
164 }
165
166
167
168
169
170
171
172
173 public SimpleDateSelector(int day, int month, int year)
174 {
175 this(new GregorianCalendar(year, month, day).getTime());
176 }
177
178
179
180
181
182
183
184
185
186
187 public SimpleDateSelector(int day, int month, int year, int fromYear,
188 int yearRange)
189 {
190 this(new GregorianCalendar(year, month, day).getTime(), fromYear,
191 yearRange);
192 }
193
194
195
196
197
198
199 private final void setComponentFont(JComponent c)
200 {
201 c.setFont(FontHelper.getFontWithStyle(Font.PLAIN, c.getFont()));
202 }
203
204
205
206
207 private final void createComponents()
208 {
209 setLayout(new GridBagLayout());
210
211 setBorder(new CompoundBorder(CosyUIElements.getPlainBorder(true),
212 new EmptyBorder(3, 3, 3, 3)));
213
214 dayLabel = new JLabel("Day");
215 setComponentFont(dayLabel);
216 add(dayLabel, createConstraints(0, 0, 0.1,0, 1, 1, 4));
217
218 monthLabel = new JLabel("Month");
219 setComponentFont(monthLabel);
220 add(monthLabel, createConstraints(1, 0, 1.0,0, 1, 1, 4));
221
222 yearLabel = new JLabel("Year");
223 setComponentFont(yearLabel);
224 add(yearLabel, createConstraints(2, 0, 0.1,0, 1, 1, 4));
225
226 daySelector = new JComboBox();
227
228 setComponentFont(daySelector);
229 add(daySelector, createConstraints(0, 1, 0.1,1, 1, 1, 4));
230
231 monthSelector = new JComboBox();
232 setComponentFont(monthSelector);
233 populateMonths();
234 add(monthSelector, createConstraints(1, 1, 1.0,1, 1, 1, 4));
235
236 yearSelector = new JComboBox();
237 setComponentFont(yearSelector);
238 add(yearSelector, createConstraints(2, 1, 0.1,1, 1, 1, 4));
239
240 DateChangeListener dcl = new DateChangeListener();
241
242 daySelector.addItemListener(dcl);
243 monthSelector.addItemListener(dcl);
244 yearSelector.addItemListener(dcl);
245 }
246
247
248
249
250
251
252
253
254
255
256
257
258
259 private final GridBagConstraints createConstraints(int x, int y,
260 double ratio, double weightY, int top, int bottom, int right)
261 {
262 GridBagConstraints constraints = new GridBagConstraints();
263 constraints.gridx = x;
264 constraints.gridy = y;
265 constraints.weightx = ratio;
266 constraints.weighty = weightY;
267 constraints.fill = GridBagConstraints.BOTH;
268 constraints.insets = new Insets(top, 0, bottom, right);
269 constraints.anchor = GridBagConstraints.WEST;
270
271 return constraints;
272 }
273
274
275
276
277
278
279 public Date getDate()
280 {
281 return calendar.getTime();
282 }
283
284
285
286
287
288
289 public int getDay()
290 {
291 return calendar.get(Calendar.DAY_OF_MONTH);
292 }
293
294
295
296
297
298
299 public int getMonth()
300 {
301 return calendar.get(Calendar.MONTH);
302 }
303
304
305
306
307
308
309 public int getYear()
310 {
311 return calendar.get(Calendar.YEAR);
312 }
313
314
315
316
317
318
319 public int getNumberOfYears()
320 {
321 return numberOfYears;
322 }
323
324
325
326
327
328
329
330 public int getStartingYear()
331 {
332 return startingYear;
333 }
334
335
336
337
338
339
340 public void setDate(Date date)
341 {
342 Date old = calendar.getTime();
343
344 calendar.setTime(date);
345 setYear(getYear());
346
347 updateComponents();
348
349 firePropertyChange("date", old, date);
350 }
351
352
353
354
355
356
357
358
359
360 public void setDay(int day)
361 {
362 if (day == getDay()) {
363 return;
364 }
365
366 day = Math.max(day, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
367 day = Math.min(day, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
368
369 int old = getDay();
370
371 calendar.set(Calendar.DAY_OF_MONTH, day);
372
373
374
375 firePropertyChange("day", old, day);
376 }
377
378
379
380
381
382
383 public void setLabelsVisible(boolean visible)
384 {
385 yearLabel.setVisible(visible);
386 monthLabel.setVisible(visible);
387 dayLabel.setVisible(visible);
388 }
389
390
391
392
393
394
395 public void setMonth(int month)
396 {
397 if (month == getMonth()) {
398 return;
399 }
400
401 month = Math.max(month, calendar.getActualMinimum(Calendar.MONTH));
402 month = Math.min(month, calendar.getActualMaximum(Calendar.MONTH));
403
404 int old = getMonth();
405
406 calendar.set(Calendar.MONTH, month);
407
408 updateComponents();
409
410 firePropertyChange("month", old, month);
411 }
412
413
414
415
416
417
418
419
420
421 public void setYear(int year)
422 {
423 if (year == getYear()) {
424 return;
425 }
426
427 year = Math.max(year, startingYear);
428 year = Math.min(year, startingYear + numberOfYears);
429
430 int old = getYear();
431
432 calendar.set(Calendar.YEAR, year);
433
434 updateComponents();
435
436 firePropertyChange("year", old, year);
437 }
438
439
440
441
442
443
444
445 public void setEnabled(boolean how)
446 {
447 super.setEnabled(how);
448 daySelector.setEnabled(how);
449 monthSelector.setEnabled(how);
450 yearSelector.setEnabled(how);
451 }
452
453
454
455
456
457
458
459
460 public void setStartingYear(int from)
461 {
462 setYearRange(from, startingYear);
463 }
464
465
466
467
468
469
470
471 public void setNumberOfYears(int range)
472 {
473 setYearRange(startingYear, range);
474 }
475
476
477
478
479
480
481
482 public void setYearRange(int from, int range)
483 {
484 int old = getYear();
485
486 startingYear = (from < 1) ? 1 : from;
487 numberOfYears = Math.max(1, range);
488
489 populateYearNames();
490
491 setYear(old);
492
493 updateComponents();
494 }
495
496
497
498
499
500 private final void populateDays()
501 {
502 int min = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
503 int max = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
504
505 int nDays = max - min + 1;
506
507 int old = getDay();
508 String[] dayNumbers = new String[nDays];
509
510 for (int i = 0; i < nDays; i++) {
511 dayNumbers[i] = String.valueOf(i + min);
512 }
513
514 daySelector.setModel(new DefaultComboBoxModel(dayNumbers));
515 setDay(old);
516 }
517
518
519
520
521 private final void populateMonths()
522 {
523 final SimpleDateFormat sdf = new SimpleDateFormat("MMMM");
524 final DateFormatSymbols dfs = sdf.getDateFormatSymbols();
525
526 monthSelector.setModel(new DefaultComboBoxModel(dfs.getMonths()));
527
528
529
530
531
532
533
534 while (monthSelector.getModel().getSize() > 12) {
535 monthSelector.removeItemAt(12);
536 }
537
538
539 }
540
541
542
543
544
545 private final void populateYearNames()
546 {
547 String[] yearNames = new String[numberOfYears];
548
549 for (int i = 0; i < yearNames.length; i++) {
550 yearNames[i] = String.valueOf(startingYear + i);
551 }
552
553 yearSelector.setModel(new DefaultComboBoxModel(yearNames));
554 }
555
556
557
558
559 private final void updateComponents()
560 {
561 populateDays();
562
563 daySelector.setSelectedIndex(getDay() - 1);
564 monthSelector.setSelectedIndex(getMonth());
565
566 if (getYear() < startingYear) {
567 setYear(startingYear);
568 }
569
570 yearSelector.setSelectedIndex(getYear() - startingYear);
571 }
572
573
574
575
576 public Object getPropertyValue()
577 {
578 return getDate();
579 }
580
581
582
583
584 public boolean setPropertyValue(Object value)
585 {
586 if (value instanceof Date) {
587 setDate((Date)value);
588
589 return true;
590 }
591
592 return false;
593 }
594
595
596
597
598 public String getDescription()
599 {
600 return null;
601 }
602
603
604
605
606 public void setDescription(String description)
607 {
608 }
609
610 public void setCompactView(boolean compact) {
611 dayLabel.setVisible(!compact);
612 monthLabel.setVisible(!compact);
613 yearLabel.setVisible(!compact);
614 }
615
616
617
618
619
620
621 public static void main(String[] args)
622 {
623 JDialog dialog = new JDialog();
624 dialog.setModal(true);
625 dialog.setSize(300, 100);
626 dialog.getContentPane().setLayout(new BorderLayout());
627
628 SimpleDateSelector dc = new SimpleDateSelector(new Date(), 1995, 100);
629
630 dialog.getContentPane().add(dc, BorderLayout.CENTER);
631
632
633
634
635 dialog.setVisible(true);
636
637 System.exit(0);
638 }
639 }
640
641