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