]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/demos/src/com/ibm/icu/dev/demo/calendar/CalendarPanel.java
Clean up imports.
[Dictionary.git] / jars / icu4j-52_1 / demos / src / com / ibm / icu / dev / demo / calendar / CalendarPanel.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 1997-2007, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7
8 package com.ibm.icu.dev.demo.calendar;
9
10 import java.awt.Canvas;
11 import java.awt.Color;
12 import java.awt.Dimension;
13 import java.awt.FontMetrics;
14 import java.awt.Graphics;
15 import java.awt.Point;
16 import java.util.Date;
17 import java.util.Locale;
18
19 import com.ibm.icu.dev.demo.impl.DemoUtility;
20 import com.ibm.icu.text.DateFormatSymbols;
21 import com.ibm.icu.util.Calendar;
22 import com.ibm.icu.util.SimpleTimeZone;
23
24 class CalendarPanel extends Canvas {
25
26     /**
27      * For serialization
28      */
29     private static final long serialVersionUID = 625400018027387141L;
30
31     public CalendarPanel( Locale locale ) {
32         setLocale(locale);
33     }
34
35     public void setLocale(Locale locale) {
36         if (fDisplayLocale == null || !fDisplayLocale.equals(locale)) {
37             fDisplayLocale = locale;
38             dirty = true;
39
40             for (int i = 0; i < fCalendar.length; i++) {
41                 if (fCalendar[i] != null) {
42                     fSymbols[i] = new DateFormatSymbols(fCalendar[i],
43                                                         fDisplayLocale);
44                 }
45             }
46             String lang = locale.getLanguage();
47             leftToRight = !(lang.equals("iw") || lang.equals("ar"));
48
49             repaint();
50         }
51     }
52
53     public void setDate(Date date) {
54         fStartOfMonth = date;
55         dirty = true;
56         repaint();
57     }
58
59     public void add(int field, int delta)
60     {
61         synchronized(fCalendar) {
62             fCalendar[0].setTime(fStartOfMonth);
63             fCalendar[0].add(field, delta);
64             fStartOfMonth = fCalendar[0].getTime();
65         }
66         dirty = true;
67         repaint();
68     }
69
70     public void setColor(int index, Color c) {
71         fColor[index] = c;
72         repaint();
73     }
74
75     public void setCalendar(int index, Calendar c) {
76         Date date = (fCalendar[index] == null) ? new Date()
77                                                : fCalendar[index].getTime();
78
79         fCalendar[index] = c;
80         fCalendar[index].setTime(date);
81
82         fSymbols[index] = new DateFormatSymbols(c, fDisplayLocale);
83         dirty = true;
84         repaint();
85     }
86
87     public Calendar getCalendar(int index) {
88         return fCalendar[index];
89     }
90
91     public Locale getDisplayLocale() {
92         return fDisplayLocale;
93     }
94
95     public Date firstOfMonth() {
96         return fStartOfMonth;
97     }
98
99     private Date startOfMonth(Date dateInMonth)
100     {
101         synchronized(fCalendar) {
102             fCalendar[0].setTime(dateInMonth);
103
104             int era = fCalendar[0].get(Calendar.ERA);
105             int year = fCalendar[0].get(Calendar.YEAR);
106             int month = fCalendar[0].get(Calendar.MONTH);
107
108             fCalendar[0].clear();
109             fCalendar[0].set(Calendar.ERA, era);
110             fCalendar[0].set(Calendar.YEAR, year);
111             fCalendar[0].set(Calendar.MONTH, month);
112             fCalendar[0].set(Calendar.DATE, 1);
113
114             return fCalendar[0].getTime();
115         }
116     }
117
118     private void calculate()
119     {
120         //
121         // As a workaround for JDK 1.1.3 and below, where Calendars and time
122         // zones are a bit goofy, always set my calendar's time zone to UTC.
123         // You would think I would want to do this in the "set" function above,
124         // but if I do that, the program hangs when this class is loaded,
125         // perhaps due to some sort of static initialization ordering problem.
126         // So I do it here instead.
127         //
128         fCalendar[0].setTimeZone(new SimpleTimeZone(0, "UTC"));
129
130         Calendar c = (Calendar)fCalendar[0].clone(); // Temporary copy
131
132         fStartOfMonth = startOfMonth(fStartOfMonth);
133
134         // Stash away a few useful constants for this calendar and display
135         minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
136         daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
137
138         firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
139
140         // Stash away a Date for the start of this month
141
142         // Find the day of week of the first day in this month
143         c.setTime(fStartOfMonth);
144         firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
145         int firstWeek = c.get(Calendar.WEEK_OF_MONTH);
146
147         // Now find the # of days in the month
148         c.roll(Calendar.DATE, false);
149         daysInMonth = c.get(Calendar.DATE);
150
151         // Finally, find the end of the month, i.e. the start of the next one
152         c.roll(Calendar.DATE, true);
153         c.add(Calendar.MONTH, 1);
154         c.getTime();        // JDK 1.1.2 bug workaround
155         c.add(Calendar.SECOND, -1);
156         Date endOfMonth = c.getTime();
157         if(endOfMonth==null){
158          //do nothing
159         }
160         endOfMonth = null;
161         int lastWeek = c.get(Calendar.WEEK_OF_MONTH);
162         
163         // Calculate the number of full or partial weeks in this month.
164         numWeeks = lastWeek - firstWeek + 1;
165
166         dirty = false;
167     }
168
169     static final int XINSET = 4;
170     static final int YINSET = 2;
171
172     /*
173      * Convert from the day number within a month (1-based)
174      * to the cell coordinates on the calendar (0-based)
175      */
176     private void dateToCell(int date, Point pos)
177     {
178         int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
179         if (firstDayInMonth < firstDayOfWeek) {
180             cell += daysInWeek;
181         }
182
183         pos.x = cell % daysInWeek;
184         pos.y = cell / daysInWeek;
185     }
186     //private Point dateToCell(int date) {
187     //    Point p = new Point(0,0);
188     //    dateToCell(date, p);
189     //    return p;
190     //}
191
192     public void paint(Graphics g) {
193
194         if (dirty) {
195             calculate();
196         }
197
198         Point cellPos = new Point(0,0);     // Temporary variable
199         Dimension d = this.getSize();
200
201         g.setColor(Color.lightGray);
202         g.fillRect(0,0,d.width,d.height);
203
204         // Draw the day names at the top
205         g.setColor(Color.black);
206         g.setFont(DemoUtility.labelFont);
207         FontMetrics fm = g.getFontMetrics();
208         int labelHeight = fm.getHeight() + YINSET * 2;
209
210         int v = fm.getAscent() + YINSET;
211         for (int i = 0; i < daysInWeek; i++) {
212             int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
213             String dayName = fSymbols[0].getWeekdays()[dayNum];
214
215
216             double h;
217             if (leftToRight) {
218                 h = d.width*(i + 0.5) / daysInWeek;
219             } else {
220                 h = d.width*(daysInWeek - i - 0.5) / daysInWeek;
221             }
222             h -= fm.stringWidth(dayName) / 2;
223
224             g.drawString(dayName, (int)h, v);
225         }
226
227         double cellHeight = (d.height - labelHeight - 1) / numWeeks;
228         double cellWidth = (double)(d.width - 1) / daysInWeek;
229
230         // Draw a white background in the part of the calendar
231         // that displays this month.
232         // First figure out how much of the first week should be shaded.
233         {
234             g.setColor(Color.white);
235             dateToCell(1, cellPos);
236             int width = (int)(cellPos.x*cellWidth);  // Width of unshaded area
237
238             if (leftToRight) {
239                 g.fillRect((int)(width), labelHeight ,
240                            d.width - width, (int)cellHeight);
241             } else {
242                 g.fillRect(0, labelHeight ,
243                            d.width - width, (int)cellHeight);
244             }
245
246             // All of the intermediate weeks get shaded completely
247             g.fillRect(0, (int)(labelHeight + cellHeight),
248                         d.width, (int)(cellHeight * (numWeeks - 2)));
249
250             // Now figure out the last week.
251             dateToCell(daysInMonth, cellPos);
252             width = (int)((cellPos.x+1)*cellWidth);  // Width of shaded area
253
254             if (leftToRight) {
255                 g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
256                            width, (int)cellHeight);
257             } else {
258                 g.fillRect(d.width - width, (int)(labelHeight + (numWeeks-1) * cellHeight),
259                            width, (int)cellHeight);
260             }
261
262         }
263         // Draw the X/Y grid lines
264         g.setColor(Color.black);
265         for (int i = 0; i <= numWeeks; i++) {
266             int y = (int)(labelHeight + i * cellHeight);
267             g.drawLine(0, y, d.width - 1, y);
268         }
269         for (int i = 0; i <= daysInWeek; i++) {
270             int x = (int)(i * cellWidth);
271             g.drawLine(x, labelHeight, x, d.height - 1);
272         }
273
274         // Now loop through all of the days in the month, figure out where
275         // they go in the grid, and draw the day # for each one
276
277         // Figure out the date of the first cell in the calendar display
278         int cell = (1 + firstDayInMonth - firstDayOfWeek - minDay);
279         if (firstDayInMonth < firstDayOfWeek) {
280             cell += daysInWeek;
281         }
282
283         Calendar c = (Calendar)fCalendar[0].clone();
284         c.setTime(fStartOfMonth);
285         c.add(Calendar.DATE, -cell);
286
287         StringBuffer buffer = new StringBuffer();
288
289         for (int row = 0; row < numWeeks; row++) {
290             for (int col = 0; col < daysInWeek; col++) {
291
292                 g.setFont(DemoUtility.numberFont);
293                 g.setColor(Color.black);
294                 fm = g.getFontMetrics();
295
296                 int cellx;
297                 if (leftToRight) {
298                     cellx = (int)((col) * cellWidth);
299                 } else {
300                     cellx = (int)((daysInWeek - col - 1) * cellWidth);
301                 }
302
303                 int celly = (int)(row * cellHeight + labelHeight);
304
305                 for (int i = 0; i < 2; i++) {
306                     fCalendar[i].setTime(c.getTime());
307
308                     int date = fCalendar[i].get(Calendar.DATE);
309                     buffer.setLength(0);
310                     buffer.append(date);
311                     String dayNum = buffer.toString();
312
313                     int x;
314
315                     if (leftToRight) {
316                         x = cellx + (int)cellWidth - XINSET - fm.stringWidth(dayNum);
317                     } else {
318                         x = cellx + XINSET;
319                     }
320                     int y = celly + + fm.getAscent() + YINSET + i * fm.getHeight();
321
322                     if (fColor[i] != null) {
323                         g.setColor(fColor[i]);
324                     }
325                     g.drawString(dayNum, x, y);
326
327                     if (date == 1 || row == 0 && col == 0) {
328                         g.setFont(DemoUtility.numberFont);
329                         String month = fSymbols[i].getMonths()[
330                                             fCalendar[i].get(Calendar.MONTH)];
331
332                         if (leftToRight) {
333                             x = cellx + XINSET;
334                         } else {
335                             x = cellx + (int)cellWidth - XINSET - fm.stringWidth(month);
336                         }
337                         g.drawString(month, x, y);
338                     }
339                 }
340
341                 c.add(Calendar.DATE, 1);
342             }
343         }
344     }
345
346     // Important state variables
347     private Calendar[]          fCalendar = new Calendar[4];
348     private Color[]             fColor = new Color[4];
349
350     private Locale              fDisplayLocale;
351     private DateFormatSymbols[] fSymbols = new DateFormatSymbols[4];
352
353     private Date                fStartOfMonth = new Date();     // 00:00:00 on first day of month
354
355     // Cached calculations to make drawing faster.
356     private transient int       minDay;           // Minimum legal day #
357     private transient int       daysInWeek;       // # of days in a week
358     private transient int       firstDayOfWeek;   // First day to display in week
359     private transient int       numWeeks;         // # full or partial weeks in month
360     private transient int       daysInMonth;      // # days in this month
361     private transient int       firstDayInMonth;  // Day of week of first day in month
362     private transient boolean   leftToRight;
363
364     private transient boolean dirty = true;
365 }