]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/demos/src/com/ibm/icu/dev/demo/calendar/CalendarFrame.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / demos / src / com / ibm / icu / dev / demo / calendar / CalendarFrame.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 1997-2007, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 package com.ibm.icu.dev.demo.calendar;\r
9 \r
10 import java.awt.BorderLayout;\r
11 import java.awt.Button;\r
12 import java.awt.Choice;\r
13 import java.awt.Color;\r
14 import java.awt.Component;\r
15 import java.awt.Container;\r
16 import java.awt.Dimension;\r
17 import java.awt.FlowLayout;\r
18 import java.awt.Font;\r
19 import java.awt.FontMetrics;\r
20 import java.awt.Frame;\r
21 import java.awt.Graphics;\r
22 import java.awt.GridBagConstraints;\r
23 import java.awt.GridBagLayout;\r
24 import java.awt.Label;\r
25 import java.awt.Panel;\r
26 import java.awt.Rectangle;\r
27 import java.awt.event.ActionEvent;\r
28 import java.awt.event.ActionListener;\r
29 import java.awt.event.ItemEvent;\r
30 import java.awt.event.ItemListener;\r
31 import java.awt.event.WindowAdapter;\r
32 import java.awt.event.WindowEvent;\r
33 import java.util.Date;\r
34 import java.util.Locale;\r
35 \r
36 import com.ibm.icu.dev.demo.impl.DemoApplet;\r
37 import com.ibm.icu.dev.demo.impl.DemoUtility;\r
38 import com.ibm.icu.text.DateFormat;\r
39 import com.ibm.icu.util.BuddhistCalendar;\r
40 import com.ibm.icu.util.Calendar;\r
41 import com.ibm.icu.util.GregorianCalendar;\r
42 import com.ibm.icu.util.HebrewCalendar;\r
43 import com.ibm.icu.util.IslamicCalendar;\r
44 import com.ibm.icu.util.JapaneseCalendar;\r
45 import com.ibm.icu.util.SimpleTimeZone;\r
46 \r
47 /**\r
48  * A Frame is a top-level window with a title. The default layout for a frame\r
49  * is BorderLayout.  The CalendarFrame class defines the window layout of\r
50  * CalendarDemo.\r
51  */\r
52 class CalendarFrame extends Frame\r
53 {\r
54     /**\r
55      * For serialization\r
56      */\r
57     private static final long serialVersionUID = -4289697663503820619L;\r
58 \r
59     private static final boolean DEBUG = false;\r
60 \r
61     private DemoApplet applet;\r
62 \r
63     /**\r
64      * Constructs a new CalendarFrame that is initially invisible.\r
65      */\r
66     public CalendarFrame(DemoApplet myApplet)\r
67     {\r
68         super("Calendar Demo");\r
69         this.applet = myApplet;\r
70         init();\r
71 \r
72         // When the window is closed, we want to shut down the applet or application\r
73         addWindowListener(\r
74             new WindowAdapter() {\r
75                 public void windowClosing(WindowEvent e) {\r
76                     setVisible(false);\r
77                     dispose();\r
78 \r
79                     if (applet != null) {\r
80                         applet.demoClosed();\r
81                     } else System.exit(0);\r
82                 }\r
83             } );\r
84     }\r
85 \r
86     private Choice          displayMenu;\r
87     private Locale[]        locales = DemoUtility.getG7Locales();\r
88 \r
89     private Calendar        calendars[]   = new Calendar[2];\r
90     private Choice          calMenu[]     = new Choice[2];\r
91     private ColoredLabel    monthLabel[]  = new ColoredLabel[2];\r
92     private DateFormat      monthFormat[] = new DateFormat[2];\r
93 \r
94     private Button          prevYear;\r
95     private Button          prevMonth;\r
96     private Button          gotoToday;\r
97     private Button          nextMonth;\r
98     private Button          nextYear;\r
99     private CalendarPanel   calendarPanel;\r
100 \r
101     private static void add(Container container, Component component,\r
102                             GridBagLayout g, GridBagConstraints c,\r
103                             int gridwidth, int weightx)\r
104     {\r
105         c.gridwidth = gridwidth;\r
106         c.weightx = weightx;\r
107         g.setConstraints(component, c);\r
108         container.add(component);\r
109     }\r
110 \r
111     /**\r
112      * Initializes the applet. You never need to call this directly, it\r
113      * is called automatically by the system once the applet is created.\r
114      */\r
115     public void init() {\r
116         setBackground(DemoUtility.bgColor);\r
117         setLayout(new BorderLayout(10,10));\r
118 \r
119         Panel topPanel = new Panel();\r
120         GridBagLayout g = new GridBagLayout();\r
121         topPanel.setLayout(g);\r
122         GridBagConstraints c = new GridBagConstraints();\r
123         c.fill = GridBagConstraints.HORIZONTAL;\r
124 \r
125         // Build the two menus for selecting which calendar is displayed,\r
126         // plus the month/year label for each calendar\r
127         for (int i = 0; i < 2; i++) {\r
128             calMenu[i] = new Choice();\r
129             for (int j = 0; j < CALENDARS.length; j++) {\r
130                 calMenu[i].addItem(CALENDARS[j].name);\r
131             }\r
132             calMenu[i].setBackground(DemoUtility.choiceColor);\r
133             calMenu[i].select(i);\r
134             calMenu[i].addItemListener(new CalMenuListener());\r
135 \r
136             // Label for the current month name\r
137             monthLabel[i] = new ColoredLabel("", COLORS[i]);\r
138             monthLabel[i].setFont(DemoUtility.titleFont);\r
139 \r
140             // And the default calendar to use for this slot\r
141             calendars[i] = CALENDARS[i].calendar;\r
142 \r
143             add(topPanel, calMenu[i], g, c, 5, 0);\r
144             add(topPanel, monthLabel[i], g, c, GridBagConstraints.REMAINDER, 1);\r
145         }\r
146 \r
147         // Now add the next/previous year/month buttons:\r
148         prevYear = new Button("<<");\r
149         prevYear.addActionListener(new AddAction(Calendar.YEAR, -1));\r
150 \r
151         prevMonth = new Button("<");\r
152         prevMonth.addActionListener(new AddAction(Calendar.MONTH, -1));\r
153 \r
154         gotoToday = new Button("Today");\r
155         gotoToday.addActionListener( new ActionListener()\r
156         {\r
157             public void actionPerformed(ActionEvent e) {\r
158                 calendarPanel.setDate( new Date() );\r
159                 updateMonthName();\r
160             }\r
161         } );\r
162 \r
163         nextMonth = new Button(">");\r
164         nextMonth.addActionListener(new AddAction(Calendar.MONTH, 1));\r
165 \r
166         nextYear = new Button(">>");\r
167         nextYear.addActionListener(new AddAction(Calendar.YEAR, 1));\r
168 \r
169         c.fill = GridBagConstraints.NONE;\r
170         add(topPanel, prevYear,  g, c, 1, 0);\r
171         add(topPanel, prevMonth, g, c, 1, 0);\r
172         add(topPanel, gotoToday, g, c, 1, 0);\r
173         add(topPanel, nextMonth, g, c, 1, 0);\r
174         add(topPanel, nextYear,  g, c, 1, 0);\r
175 \r
176         // Now add the menu for selecting the display language\r
177         Panel displayPanel = new Panel();\r
178         {\r
179             displayMenu = new Choice();\r
180             Locale defaultLocale = Locale.getDefault();\r
181             int bestMatch = -1, thisMatch = -1;\r
182             int selectMe = 0;\r
183             \r
184             for (int i = 0; i < locales.length; i++) {\r
185                 if (i > 0 &&\r
186                         locales[i].getLanguage().equals(locales[i-1].getLanguage()) ||\r
187                     i < locales.length - 1 &&\r
188                         locales[i].getLanguage().equals(locales[i+1].getLanguage()))\r
189                 {\r
190                     displayMenu.addItem( locales[i].getDisplayName() );\r
191                 } else {\r
192                     displayMenu.addItem( locales[i].getDisplayLanguage());\r
193                 }\r
194 \r
195                 thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale);\r
196                 \r
197                 if (thisMatch >= bestMatch) {\r
198                     bestMatch = thisMatch;\r
199                     selectMe = i;\r
200                 }\r
201             }\r
202             \r
203             displayMenu.setBackground(DemoUtility.choiceColor);\r
204             displayMenu.select(selectMe);\r
205 \r
206             displayMenu.addItemListener( new ItemListener()\r
207             {\r
208                  public void itemStateChanged(ItemEvent e) {\r
209                     Locale loc = locales[displayMenu.getSelectedIndex()];\r
210                     calendarPanel.setLocale( loc );\r
211                     monthFormat[0] = monthFormat[1] = null;\r
212                     updateMonthName();\r
213                     repaint();\r
214                 }\r
215             } );\r
216 \r
217             Label l1 = new Label("Display Language:", Label.RIGHT);\r
218             l1.setFont(DemoUtility.labelFont);\r
219 \r
220             displayPanel.setLayout(new FlowLayout());\r
221             displayPanel.add(l1);\r
222             displayPanel.add(displayMenu);\r
223 \r
224         }\r
225         c.fill = GridBagConstraints.NONE;\r
226         c.anchor = GridBagConstraints.EAST;\r
227 \r
228         add(topPanel, displayPanel, g, c, GridBagConstraints.REMAINDER, 0);\r
229 \r
230         // The title, buttons, etc. go in a panel at the top of the window\r
231         add("North", topPanel);\r
232 \r
233         // The copyright notice goes at the bottom of the window\r
234         Label copyright = new Label(DemoUtility.copyright1, Label.LEFT);\r
235         copyright.setFont(DemoUtility.creditFont);\r
236         add("South", copyright);\r
237 \r
238         // Now create the big calendar panel and stick it in the middle\r
239         calendarPanel = new CalendarPanel( locales[displayMenu.getSelectedIndex()] );\r
240         add("Center", calendarPanel);\r
241 \r
242         for (int i = 0; i < 2; i++) {\r
243             calendarPanel.setCalendar(i, calendars[i]);\r
244             calendarPanel.setColor(i, COLORS[i]);\r
245         }\r
246 \r
247         updateMonthName();\r
248     }\r
249 \r
250 \r
251     private void updateMonthName()\r
252     {\r
253             for (int i = 0; i < 2; i++) {\r
254                 try {\r
255                     if (monthFormat[i] == null) {     // TODO: optimize\r
256                         DateFormat f = DateFormat.getDateTimeInstance(\r
257                                                 calendars[i], DateFormat.MEDIUM, -1,\r
258                                                 locales[displayMenu.getSelectedIndex()]);\r
259                         if (f instanceof com.ibm.icu.text.SimpleDateFormat) {\r
260                             com.ibm.icu.text.SimpleDateFormat f1 = (com.ibm.icu.text.SimpleDateFormat) f;\r
261                             f1.applyPattern("MMMM, yyyy G");\r
262                             f1.setTimeZone(new SimpleTimeZone(0, "UTC"));\r
263                         }\r
264                         monthFormat[i] = f;\r
265                     }\r
266                 } catch (ClassCastException e) {\r
267                     //hey {lw} - there's something wrong in this routine that cuases exceptions.\r
268                     System.out.println(e);\r
269                 }\r
270 \r
271                 monthLabel[i].setText( monthFormat[i].format( calendarPanel.firstOfMonth() ));\r
272             }\r
273     }\r
274 \r
275     /**\r
276      * CalMenuListener responds to events in the two popup menus that select\r
277      * the calendar systems to be used in the display.  It figures out which\r
278      * of the two menus the event occurred in and updates the corresponding\r
279      * element of the calendars[] array to match the new selection.\r
280      */\r
281     private class CalMenuListener implements ItemListener\r
282     {\r
283          public void itemStateChanged(ItemEvent e)\r
284          {\r
285             for (int i = 0; i < calMenu.length; i++)\r
286             {\r
287                 if (e.getItemSelectable() == calMenu[i])\r
288                 {\r
289                     // We found the menu that the event happened in.\r
290                     // Figure out which new calendar they selected.\r
291                     Calendar newCal = CALENDARS[ calMenu[i].getSelectedIndex() ].calendar;\r
292 \r
293                     if (newCal != calendars[i])\r
294                     {\r
295                         // If any of the other menus are set to the same new calendar\r
296                         // we're about to use for this menu, set them to the current\r
297                         // calendar from *this* menu so we won't have two the same\r
298                         for (int j = 0; j < calendars.length; j++) {\r
299                             if (j != i && calendars[j] == newCal) {\r
300                                 calendars[j] = calendars[i];\r
301                                 calendarPanel.setCalendar(j, calendars[j]);\r
302                                 monthFormat[j] = null;\r
303 \r
304                                 for (int k = 0; k < CALENDARS.length; k++) {\r
305                                     if (calendars[j] == CALENDARS[k].calendar) {\r
306                                         calMenu[j].select(k);\r
307                                         break;\r
308                                     }\r
309                                 }\r
310                             }\r
311                         }\r
312                         // Now update this menu to use the new calendar the user selected\r
313                         calendars[i] = newCal;\r
314                         calendarPanel.setCalendar(i, newCal);\r
315                         monthFormat[i] = null;\r
316 \r
317                         updateMonthName();\r
318                     }\r
319                     break;\r
320                 }\r
321             }\r
322          }\r
323     }\r
324 \r
325     /**\r
326      * AddAction handles the next/previous year/month buttons...\r
327      */\r
328     private class AddAction implements ActionListener {\r
329         AddAction(int field, int amount) {\r
330             this.field = field;\r
331             this.amount = amount;\r
332         }\r
333 \r
334         public void actionPerformed(ActionEvent e) {\r
335             calendarPanel.add(field, amount);\r
336             updateMonthName();\r
337         }\r
338 \r
339         private int field, amount;\r
340     }\r
341 \r
342     /**\r
343      * ColoredLabel is similar to java.awt.Label, with two differences:\r
344      *\r
345      *  - You can set its text color\r
346      *\r
347      *  - It draws text using drawString rather than using a host-specific\r
348      *    "Peer" object like AWT does.  On 1.2, using drawString gives\r
349      *    us Bidi reordering for free.\r
350      */\r
351     static private class ColoredLabel extends Component {\r
352         /**\r
353          * For serialization\r
354          */\r
355         private static final long serialVersionUID = 5004484960341875722L;\r
356         public ColoredLabel(String label) {\r
357             text = label;\r
358         }\r
359 \r
360         public ColoredLabel(String label, Color c) {\r
361             text = label;\r
362             color = c;\r
363         }\r
364 \r
365         public void setText(String label) {\r
366             text = label;\r
367             repaint();\r
368         }\r
369 \r
370         public void setFont(Font f) {\r
371             font = f;\r
372             repaint();\r
373         }\r
374 \r
375         public void paint(Graphics g) {\r
376             FontMetrics fm = g.getFontMetrics(font);\r
377 \r
378             Rectangle bounds = getBounds();\r
379 \r
380             g.setColor(color);\r
381             g.setFont(font);\r
382             g.drawString(text, fm.stringWidth("\u00a0"),\r
383                          bounds.height/2 + fm.getHeight()\r
384                          - fm.getAscent() + fm.getLeading()/2);\r
385         }\r
386 \r
387         public Dimension getPreferredSize() {\r
388             return getMinimumSize();\r
389         }\r
390 \r
391         public Dimension getMinimumSize() {\r
392             FontMetrics fm = getFontMetrics(font);\r
393 \r
394             return new Dimension( fm.stringWidth(text) + 2*fm.stringWidth("\u00a0"),\r
395                                   fm.getHeight() + fm.getLeading()*2);\r
396         }\r
397 \r
398         String text;\r
399         Color color = Color.black;\r
400         Font font = DemoUtility.labelFont;\r
401     }\r
402 \r
403     /**\r
404      * Print out the error message while debugging this program.\r
405      */\r
406     public void errorText(String s)\r
407     {\r
408         if (DEBUG)\r
409         {\r
410             System.out.println(s);\r
411         }\r
412     }\r
413 \r
414     class CalendarRec {\r
415         public CalendarRec(String nameStr, Calendar cal)\r
416         {\r
417             name = nameStr;\r
418             calendar = cal;\r
419         }\r
420 \r
421         Calendar  calendar;\r
422         String              name;\r
423     }\r
424 \r
425     private final CalendarRec[] CALENDARS = {\r
426         new CalendarRec("Gregorian Calendar",       new GregorianCalendar()),\r
427         new CalendarRec("Hebrew Calendar",          new HebrewCalendar()),\r
428         new CalendarRec("Islamic Calendar",         makeIslamic(false)),\r
429         new CalendarRec("Islamic Civil Calendar ",  makeIslamic(true)),\r
430         new CalendarRec("Buddhist Calendar",        new BuddhistCalendar()),\r
431         new CalendarRec("Japanese Calendar",        new JapaneseCalendar()),\r
432     };\r
433 \r
434     static private final Calendar makeIslamic(boolean civil) {\r
435         IslamicCalendar cal = new IslamicCalendar();\r
436         cal.setCivil(civil);\r
437         return cal;\r
438     }\r
439 \r
440     static final Color[] COLORS = { Color.blue, Color.black };\r
441 }\r
442 \r