1 /* 2 ******************************************************************************* 3 * Copyright (C) 1997-2008, 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.Button; 11 import java.awt.Checkbox; 12 import java.awt.CheckboxGroup; 13 import java.awt.Choice; 14 import java.awt.Component; 15 import java.awt.Container; 16 import java.awt.FlowLayout; 17 import java.awt.Font; 18 import java.awt.Frame; 19 import java.awt.GridLayout; 20 import java.awt.Label; 21 import java.awt.Panel; 22 import java.awt.TextField; 23 import java.awt.event.ActionEvent; 24 import java.awt.event.ActionListener; 25 import java.awt.event.ItemEvent; 26 import java.awt.event.ItemListener; 27 import java.awt.event.KeyEvent; 28 import java.awt.event.WindowEvent; 29 import java.text.ParsePosition; 30 import java.util.Date; 31 import java.util.Locale; 32 33 import javax.swing.JTextField; 34 35 import com.ibm.icu.dev.demo.impl.DemoApplet; 36 import com.ibm.icu.dev.demo.impl.DemoUtility; 37 import com.ibm.icu.text.DateFormat; 38 import com.ibm.icu.text.SimpleDateFormat; 39 import com.ibm.icu.util.BuddhistCalendar; 40 import com.ibm.icu.util.Calendar; 41 import com.ibm.icu.util.GregorianCalendar; 42 import com.ibm.icu.util.HebrewCalendar; 43 import com.ibm.icu.util.IslamicCalendar; 44 import com.ibm.icu.util.JapaneseCalendar; 45 import com.ibm.icu.util.TimeZone; 46 47 /** 48 * CalendarCalc demonstrates how Date/Time formatter works. 49 */ 50 public class CalendarCalc extends DemoApplet 51 { 52 /** 53 * For serialization 54 */ 55 private static final long serialVersionUID = 4540103433916539296L; 56 57 /** 58 * The main function which defines the behavior of the MultiCalendarDemo 59 * applet when an applet is started. 60 */ main(String argv[])61 public static void main(String argv[]) { 62 new CalendarCalc().showDemo(); 63 } 64 65 /** 66 * This creates a CalendarCalcFrame for the demo applet. 67 */ createDemoFrame(DemoApplet applet)68 public Frame createDemoFrame(DemoApplet applet) { 69 return new CalendarCalcFrame(applet); 70 } 71 } 72 73 /** 74 * A Frame is a top-level window with a title. The default layout for a frame 75 * is BorderLayout. The CalendarCalcFrame class defines the window layout of 76 * MultiCalendarDemo. 77 */ 78 class CalendarCalcFrame extends Frame implements ActionListener 79 { 80 /** 81 * For serialization 82 */ 83 private static final long serialVersionUID = 8901485296258761846L; 84 85 static final Locale[] locales = DemoUtility.getG7Locales(); 86 87 private DemoApplet applet; 88 private long time = System.currentTimeMillis(); 89 90 private static final RollAddField kRollAddFields[] = { 91 new RollAddField(Calendar.YEAR, "Year" ), 92 new RollAddField(Calendar.MONTH, "Month" ), 93 new RollAddField(Calendar.WEEK_OF_MONTH, "Week of Month" ), 94 new RollAddField(Calendar.WEEK_OF_YEAR, "Week of Year" ), 95 new RollAddField(Calendar.DAY_OF_MONTH, "Day of Month" ), 96 new RollAddField(Calendar.DAY_OF_WEEK, "Day of Week" ), 97 new RollAddField(Calendar.DAY_OF_WEEK_IN_MONTH, "Day of Week in Month" ), 98 new RollAddField(Calendar.DAY_OF_YEAR, "Day of Year" ), 99 new RollAddField(Calendar.AM_PM, "AM/PM" ), 100 new RollAddField(Calendar.HOUR_OF_DAY, "Hour of day" ), 101 new RollAddField(Calendar.HOUR, "Hour" ), 102 new RollAddField(Calendar.MINUTE, "Minute" ), 103 new RollAddField(Calendar.SECOND, "Second" ), 104 }; 105 106 /** 107 * Constructs a new CalendarCalcFrame that is initially invisible. 108 */ CalendarCalcFrame(DemoApplet applet)109 public CalendarCalcFrame(DemoApplet applet) 110 { 111 super("Multiple Calendar Demo"); 112 this.applet = applet; 113 init(); 114 start(); 115 } 116 117 /** 118 * Initializes the applet. You never need to call this directly, it 119 * is called automatically by the system once the applet is created. 120 */ init()121 public void init() 122 { 123 buildGUI(); 124 125 patternText.setText( calendars[0].toPattern() ); 126 127 // Force an update of the display 128 cityChanged(); 129 millisFormat(); 130 enableEvents(KeyEvent.KEY_RELEASED); 131 enableEvents(WindowEvent.WINDOW_CLOSING); 132 } 133 134 //------------------------------------------------------------ 135 // package private 136 //------------------------------------------------------------ addWithFont(Container container, Component foo, Font font)137 void addWithFont(Container container, Component foo, Font font) { 138 if (font != null) 139 foo.setFont(font); 140 container.add(foo); 141 } 142 143 /** 144 * Called to start the applet. You never need to call this method 145 * directly, it is called when the applet's document is visited. 146 */ start()147 public void start() 148 { 149 // do nothing 150 } 151 152 TextField patternText; 153 154 Choice dateMenu; 155 Choice localeMenu; 156 157 Button up; 158 Button down; 159 160 Checkbox getRoll; 161 Checkbox getAdd; 162 buildGUI()163 public void buildGUI() 164 { 165 setBackground(DemoUtility.bgColor); 166 setLayout(new FlowLayout()); // shouldn't be necessary, but it is. 167 168 // TITLE 169 Label label1=new Label("Calendar Converter", Label.CENTER); 170 label1.setFont(DemoUtility.titleFont); 171 add(label1); 172 add(DemoUtility.createSpacer()); 173 174 // IO Panel 175 Panel topPanel = new Panel(); 176 topPanel.setLayout(new FlowLayout()); 177 178 CheckboxGroup group1= new CheckboxGroup(); 179 180 // Set up the controls for each calendar we're demonstrating 181 for (int i = 0; i < calendars.length; i++) 182 { 183 Label label = new Label(calendars[i].name, Label.RIGHT); 184 label.setFont(DemoUtility.labelFont); 185 topPanel.add(label); 186 187 topPanel.add(calendars[i].text); 188 189 final int j = i; 190 calendars[i].text.addActionListener( new ActionListener() { 191 public void actionPerformed(ActionEvent e) { 192 textChanged(j); 193 } 194 } ); 195 196 calendars[i].rollAdd.setCheckboxGroup(group1); 197 topPanel.add(calendars[i].rollAdd); 198 } 199 calendars[0].rollAdd.setState(true); // Make the first one selected 200 201 Label label4=new Label("Pattern", Label.RIGHT); 202 label4.setFont(DemoUtility.labelFont); 203 topPanel.add(label4); 204 205 patternText=new TextField(FIELD_COLUMNS); 206 patternText.setFont(DemoUtility.editFont); 207 topPanel.add(patternText); 208 topPanel.add(new Label("")); 209 210 DemoUtility.fixGrid(topPanel,3); 211 add(topPanel); 212 add(DemoUtility.createSpacer()); 213 214 // ROLL / ADD 215 Panel rollAddPanel=new Panel(); 216 { 217 rollAddPanel.setLayout(new FlowLayout()); 218 219 Panel rollAddBoxes = new Panel(); 220 { 221 rollAddBoxes.setLayout(new GridLayout(2,1)); 222 CheckboxGroup group2= new CheckboxGroup(); 223 getRoll = new Checkbox("Roll",group2, false); 224 getAdd = new Checkbox("Add",group2, true); 225 226 rollAddBoxes.add(getRoll); 227 rollAddBoxes.add(getAdd); 228 } 229 230 Label dateLabel=new Label("Date Fields"); 231 dateLabel.setFont(DemoUtility.labelFont); 232 233 dateMenu= new Choice(); 234 dateMenu.setBackground(DemoUtility.choiceColor); 235 for (int i = 0; i < kRollAddFields.length; i++) { 236 dateMenu.addItem(kRollAddFields[i].name); 237 if (kRollAddFields[i].field == Calendar.MONTH) { 238 dateMenu.select(i); 239 } 240 } 241 242 Panel upDown = new Panel(); 243 { 244 upDown.setLayout(new GridLayout(2,1)); 245 246 // *** If the images are not found, we use the label. 247 up = new Button("^"); 248 down = new Button("v"); 249 up.setBackground(DemoUtility.bgColor); 250 down.setBackground(DemoUtility.bgColor); 251 upDown.add(up); 252 upDown.add(down); 253 up.addActionListener(this); 254 down.addActionListener(this); 255 } 256 257 rollAddPanel.add(dateLabel); 258 rollAddPanel.add(dateMenu); 259 rollAddPanel.add(rollAddBoxes); 260 rollAddPanel.add(upDown); 261 262 } 263 Panel localePanel = new Panel(); 264 { 265 // Make the locale popup menus 266 localeMenu= new Choice(); 267 Locale defaultLocale = Locale.getDefault(); 268 int bestMatch = -1, thisMatch = -1; 269 int selectMe = 0; 270 271 for (int i = 0; i < locales.length; i++) { 272 if (i > 0 && locales[i].getLanguage().equals(locales[i-1].getLanguage()) || 273 i < locales.length - 1 && 274 locales[i].getLanguage().equals(locales[i+1].getLanguage())) 275 { 276 localeMenu.addItem( locales[i].getDisplayName() ); 277 } else { 278 localeMenu.addItem( locales[i].getDisplayLanguage()); 279 } 280 281 thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale); 282 283 if (thisMatch >= bestMatch) { 284 bestMatch = thisMatch; 285 selectMe = i; 286 } 287 } 288 289 localeMenu.setBackground(DemoUtility.choiceColor); 290 localeMenu.select(selectMe); 291 292 Label localeLabel =new Label("Display Locale"); 293 localeLabel.setFont(DemoUtility.labelFont); 294 295 localePanel.add(localeLabel); 296 localePanel.add(localeMenu); 297 DemoUtility.fixGrid(localePanel,2); 298 299 localeMenu.addItemListener( new ItemListener() { 300 public void itemStateChanged(ItemEvent e) { 301 Locale loc = locales[localeMenu.getSelectedIndex()]; 302 System.out.println("Change locale to " + loc.getDisplayName()); 303 304 for (int i = 0; i < calendars.length; i++) { 305 calendars[i].setLocale(loc); 306 } 307 millisFormat(); 308 } 309 } ); 310 } 311 add(rollAddPanel); 312 add(DemoUtility.createSpacer()); 313 add(localePanel); 314 add(DemoUtility.createSpacer()); 315 316 // COPYRIGHT 317 Panel copyrightPanel = new Panel(); 318 addWithFont (copyrightPanel,new Label(DemoUtility.copyright1, Label.LEFT), 319 DemoUtility.creditFont); 320 DemoUtility.fixGrid(copyrightPanel,1); 321 add(copyrightPanel); 322 } 323 324 /** 325 * This function is called when users change the pattern text. 326 */ setFormatFromPattern()327 public void setFormatFromPattern() { 328 String timePattern = patternText.getText(); 329 330 for (int i = 0; i < calendars.length; i++) { 331 calendars[i].applyPattern(timePattern); 332 } 333 334 millisFormat(); 335 } 336 337 /** 338 * This function is called when it is necessary to parse the time 339 * string in one of the formatted date fields 340 */ textChanged(int index)341 public void textChanged(int index) { 342 String rightString = calendars[index].text.getText(); 343 344 ParsePosition status = new ParsePosition(0); 345 346 if (rightString.length() == 0) 347 { 348 errorText("Error: no input to parse!"); 349 return; 350 } 351 352 try { 353 Date date = calendars[index].format.parse(rightString, status); 354 time = date.getTime(); 355 } 356 catch (Exception e) { 357 for (int i = 0; i < calendars.length; i++) { 358 if (i != index) { 359 calendars[i].text.setText("ERROR"); 360 } 361 } 362 errorText("Exception: " + e.getClass().toString() + " parsing: "+rightString); 363 return; 364 } 365 366 int start = calendars[index].text.getSelectionStart(); 367 int end = calendars[index].text.getSelectionEnd(); 368 369 millisFormat(); 370 371 calendars[index].text.select(start,end); 372 } 373 374 /** 375 * This function is called when it is necessary to format the time 376 * in the "Millis" text field. 377 */ millisFormat()378 public void millisFormat() { 379 String out = ""; 380 381 for (int i = 0; i < calendars.length; i++) { 382 try { 383 out = calendars[i].format.format(new Date(time)); 384 calendars[i].text.setText(out); 385 } 386 catch (Exception e) { 387 calendars[i].text.setText("ERROR"); 388 errorText("Exception: " + e.getClass().toString() + " formatting " 389 + calendars[i].name + " " + time); 390 } 391 } 392 } 393 394 395 /** 396 * This function is called when users change the pattern text. 397 */ patternTextChanged()398 public void patternTextChanged() { 399 setFormatFromPattern(); 400 } 401 402 /** 403 * This function is called when users select a new representative city. 404 */ cityChanged()405 public void cityChanged() { 406 TimeZone timeZone = TimeZone.getDefault(); 407 408 for (int i = 0; i < calendars.length; i++) { 409 calendars[i].format.setTimeZone(timeZone); 410 } 411 millisFormat(); 412 } 413 414 /** 415 * This function is called when users select a new time field 416 * to add or roll its value. 417 */ dateFieldChanged(boolean isUp)418 public void dateFieldChanged(boolean isUp) { 419 int field = kRollAddFields[dateMenu.getSelectedIndex()].field; 420 421 for (int i = 0; i < calendars.length; i++) 422 { 423 if (calendars[i].rollAdd.getState()) 424 { 425 Calendar c = calendars[i].calendar; 426 c.setTime(new Date(time)); 427 428 if (getAdd.getState()) { 429 c.add(field, isUp ? 1 : -1); 430 } else { 431 c.roll(field, isUp); 432 } 433 434 time = c.getTime().getTime(); 435 millisFormat(); 436 break; 437 } 438 } 439 } 440 441 /** 442 * Print out the error message while debugging this program. 443 */ errorText(String s)444 public void errorText(String s) 445 { 446 if (true) { 447 System.out.println(s); 448 } 449 } 450 451 /** 452 * Called if an action occurs in the CalendarCalcFrame object. 453 */ actionPerformed(ActionEvent evt)454 public void actionPerformed(ActionEvent evt) 455 { 456 // *** Button events are handled here. 457 Object obj = evt.getSource(); 458 System.out.println("action " + obj); 459 if (obj instanceof Button) { 460 if (evt.getSource() == up) { 461 dateFieldChanged(false); 462 } else 463 if (evt.getSource() == down) { 464 dateFieldChanged(true); 465 } 466 } 467 } 468 469 /** 470 * Handles the event. Returns true if the event is handled and should not 471 * be passed to the parent of this component. The default event handler 472 * calls some helper methods to make life easier on the programmer. 473 */ processKeyEvent(KeyEvent evt)474 protected void processKeyEvent(KeyEvent evt) 475 { 476 System.out.println("key " + evt); 477 if (evt.getID() == KeyEvent.KEY_RELEASED) { 478 if (evt.getSource() == patternText) { 479 patternTextChanged(); 480 } 481 else { 482 for (int i = 0; i < calendars.length; i++) { 483 if (evt.getSource() == calendars[i].text) { 484 textChanged(i); 485 } 486 } 487 } 488 } 489 } 490 processWindowEvent(WindowEvent evt)491 protected void processWindowEvent(WindowEvent evt) 492 { 493 System.out.println("window " + evt); 494 if (evt.getID() == WindowEvent.WINDOW_CLOSING && 495 evt.getSource() == this) { 496 this.hide(); 497 this.dispose(); 498 499 if (applet != null) { 500 applet.demoClosed(); 501 } else System.exit(0); 502 } 503 } 504 505 /* 506 protected void processEvent(AWTEvent evt) 507 { 508 if (evt.getID() == AWTEvent. Event.ACTION_EVENT && evt.target == up) { 509 dateFieldChanged(true); 510 return true; 511 } 512 else if (evt.id == Event.ACTION_EVENT && evt.target == down) { 513 dateFieldChanged(false); 514 return true; 515 } 516 } 517 */ 518 519 private static final int FIELD_COLUMNS = 35; 520 521 522 class CalendarRec { CalendarRec(String nameStr, Calendar cal)523 public CalendarRec(String nameStr, Calendar cal) 524 { 525 name = nameStr; 526 calendar = cal; 527 rollAdd = new Checkbox(); 528 529 text = new JTextField("",FIELD_COLUMNS); 530 text.setFont(DemoUtility.editFont); 531 532 format = DateFormat.getDateInstance(cal, DateFormat.FULL, 533 Locale.getDefault()); 534 //format.applyPattern(DEFAULT_FORMAT); 535 } 536 setLocale(Locale loc)537 public void setLocale(Locale loc) { 538 String pattern = toPattern(); 539 540 format = DateFormat.getDateInstance(calendar, DateFormat.FULL, 541 loc); 542 applyPattern(pattern); 543 } 544 applyPattern(String pattern)545 public void applyPattern(String pattern) { 546 if (format instanceof SimpleDateFormat) { 547 ((SimpleDateFormat)format).applyPattern(pattern); 548 //hey {al} - 549 // } else if (format instanceof java.text.SimpleDateFormat) { 550 // ((java.text.SimpleDateFormat)format).applyPattern(pattern); 551 } 552 } 553 toPattern()554 private String toPattern() { 555 if (format instanceof SimpleDateFormat) { 556 return ((SimpleDateFormat)format).toPattern(); 557 //hey {al} - 558 // } else if (format instanceof java.text.SimpleDateFormat) { 559 // return ((java.text.SimpleDateFormat)format).toPattern(); 560 } 561 return ""; 562 } 563 564 Calendar calendar; 565 DateFormat format; 566 String name; 567 JTextField text; 568 Checkbox rollAdd; 569 } 570 571 private final CalendarRec[] calendars = { 572 new CalendarRec("Gregorian", new GregorianCalendar()), 573 new CalendarRec("Hebrew", new HebrewCalendar()), 574 new CalendarRec("Islamic (civil)", makeIslamic(true)), 575 new CalendarRec("Islamic (true)", makeIslamic(false)), 576 new CalendarRec("Buddhist", new BuddhistCalendar()), 577 new CalendarRec("Japanese", new JapaneseCalendar()), 578 // new CalendarRec("Chinese", new ChineseCalendar()), 579 }; 580 makeIslamic(boolean civil)581 static private final Calendar makeIslamic(boolean civil) { 582 IslamicCalendar cal = new IslamicCalendar(); 583 cal.setCivil(civil); 584 return cal; 585 } 586 } 587 588 class RollAddField { RollAddField(int field, String name)589 RollAddField(int field, String name) { 590 this.field = field; 591 this.name = name; 592 } 593 int field; 594 String name; 595 } 596