| /* |
| ******************************************************************************* |
| * Copyright (C) 1997-2007, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| */ |
| |
| package com.ibm.icu.dev.demo.calendar; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Button; |
| import java.awt.Choice; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Container; |
| import java.awt.Dimension; |
| import java.awt.FlowLayout; |
| import java.awt.Font; |
| import java.awt.FontMetrics; |
| import java.awt.Frame; |
| import java.awt.Graphics; |
| import java.awt.GridBagConstraints; |
| import java.awt.GridBagLayout; |
| import java.awt.Label; |
| import java.awt.Panel; |
| import java.awt.Rectangle; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.ItemEvent; |
| import java.awt.event.ItemListener; |
| import java.awt.event.WindowAdapter; |
| import java.awt.event.WindowEvent; |
| import java.util.Date; |
| import java.util.Locale; |
| |
| import com.ibm.icu.dev.demo.impl.DemoApplet; |
| import com.ibm.icu.dev.demo.impl.DemoUtility; |
| import com.ibm.icu.text.DateFormat; |
| import com.ibm.icu.util.BuddhistCalendar; |
| import com.ibm.icu.util.Calendar; |
| import com.ibm.icu.util.GregorianCalendar; |
| import com.ibm.icu.util.HebrewCalendar; |
| import com.ibm.icu.util.IslamicCalendar; |
| import com.ibm.icu.util.JapaneseCalendar; |
| import com.ibm.icu.util.SimpleTimeZone; |
| |
| /** |
| * A Frame is a top-level window with a title. The default layout for a frame |
| * is BorderLayout. The CalendarFrame class defines the window layout of |
| * CalendarDemo. |
| */ |
| class CalendarFrame extends Frame |
| { |
| /** |
| * For serialization |
| */ |
| private static final long serialVersionUID = -4289697663503820619L; |
| |
| private static final boolean DEBUG = false; |
| |
| private DemoApplet applet; |
| |
| /** |
| * Constructs a new CalendarFrame that is initially invisible. |
| */ |
| public CalendarFrame(DemoApplet myApplet) |
| { |
| super("Calendar Demo"); |
| this.applet = myApplet; |
| init(); |
| |
| // When the window is closed, we want to shut down the applet or application |
| addWindowListener( |
| new WindowAdapter() { |
| public void windowClosing(WindowEvent e) { |
| setVisible(false); |
| dispose(); |
| |
| if (applet != null) { |
| applet.demoClosed(); |
| } else System.exit(0); |
| } |
| } ); |
| } |
| |
| private Choice displayMenu; |
| private Locale[] locales = DemoUtility.getG7Locales(); |
| |
| private Calendar calendars[] = new Calendar[2]; |
| private Choice calMenu[] = new Choice[2]; |
| private ColoredLabel monthLabel[] = new ColoredLabel[2]; |
| private DateFormat monthFormat[] = new DateFormat[2]; |
| |
| private Button prevYear; |
| private Button prevMonth; |
| private Button gotoToday; |
| private Button nextMonth; |
| private Button nextYear; |
| private CalendarPanel calendarPanel; |
| |
| private static void add(Container container, Component component, |
| GridBagLayout g, GridBagConstraints c, |
| int gridwidth, int weightx) |
| { |
| c.gridwidth = gridwidth; |
| c.weightx = weightx; |
| g.setConstraints(component, c); |
| container.add(component); |
| } |
| |
| /** |
| * Initializes the applet. You never need to call this directly, it |
| * is called automatically by the system once the applet is created. |
| */ |
| public void init() { |
| setBackground(DemoUtility.bgColor); |
| setLayout(new BorderLayout(10,10)); |
| |
| Panel topPanel = new Panel(); |
| GridBagLayout g = new GridBagLayout(); |
| topPanel.setLayout(g); |
| GridBagConstraints c = new GridBagConstraints(); |
| c.fill = GridBagConstraints.HORIZONTAL; |
| |
| // Build the two menus for selecting which calendar is displayed, |
| // plus the month/year label for each calendar |
| for (int i = 0; i < 2; i++) { |
| calMenu[i] = new Choice(); |
| for (int j = 0; j < CALENDARS.length; j++) { |
| calMenu[i].addItem(CALENDARS[j].name); |
| } |
| calMenu[i].setBackground(DemoUtility.choiceColor); |
| calMenu[i].select(i); |
| calMenu[i].addItemListener(new CalMenuListener()); |
| |
| // Label for the current month name |
| monthLabel[i] = new ColoredLabel("", COLORS[i]); |
| monthLabel[i].setFont(DemoUtility.titleFont); |
| |
| // And the default calendar to use for this slot |
| calendars[i] = CALENDARS[i].calendar; |
| |
| add(topPanel, calMenu[i], g, c, 5, 0); |
| add(topPanel, monthLabel[i], g, c, GridBagConstraints.REMAINDER, 1); |
| } |
| |
| // Now add the next/previous year/month buttons: |
| prevYear = new Button("<<"); |
| prevYear.addActionListener(new AddAction(Calendar.YEAR, -1)); |
| |
| prevMonth = new Button("<"); |
| prevMonth.addActionListener(new AddAction(Calendar.MONTH, -1)); |
| |
| gotoToday = new Button("Today"); |
| gotoToday.addActionListener( new ActionListener() |
| { |
| public void actionPerformed(ActionEvent e) { |
| calendarPanel.setDate( new Date() ); |
| updateMonthName(); |
| } |
| } ); |
| |
| nextMonth = new Button(">"); |
| nextMonth.addActionListener(new AddAction(Calendar.MONTH, 1)); |
| |
| nextYear = new Button(">>"); |
| nextYear.addActionListener(new AddAction(Calendar.YEAR, 1)); |
| |
| c.fill = GridBagConstraints.NONE; |
| add(topPanel, prevYear, g, c, 1, 0); |
| add(topPanel, prevMonth, g, c, 1, 0); |
| add(topPanel, gotoToday, g, c, 1, 0); |
| add(topPanel, nextMonth, g, c, 1, 0); |
| add(topPanel, nextYear, g, c, 1, 0); |
| |
| // Now add the menu for selecting the display language |
| Panel displayPanel = new Panel(); |
| { |
| displayMenu = new Choice(); |
| Locale defaultLocale = Locale.getDefault(); |
| int bestMatch = -1, thisMatch = -1; |
| int selectMe = 0; |
| |
| for (int i = 0; i < locales.length; i++) { |
| if (i > 0 && |
| locales[i].getLanguage().equals(locales[i-1].getLanguage()) || |
| i < locales.length - 1 && |
| locales[i].getLanguage().equals(locales[i+1].getLanguage())) |
| { |
| displayMenu.addItem( locales[i].getDisplayName() ); |
| } else { |
| displayMenu.addItem( locales[i].getDisplayLanguage()); |
| } |
| |
| thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale); |
| |
| if (thisMatch >= bestMatch) { |
| bestMatch = thisMatch; |
| selectMe = i; |
| } |
| } |
| |
| displayMenu.setBackground(DemoUtility.choiceColor); |
| displayMenu.select(selectMe); |
| |
| displayMenu.addItemListener( new ItemListener() |
| { |
| public void itemStateChanged(ItemEvent e) { |
| Locale loc = locales[displayMenu.getSelectedIndex()]; |
| calendarPanel.setLocale( loc ); |
| monthFormat[0] = monthFormat[1] = null; |
| updateMonthName(); |
| repaint(); |
| } |
| } ); |
| |
| Label l1 = new Label("Display Language:", Label.RIGHT); |
| l1.setFont(DemoUtility.labelFont); |
| |
| displayPanel.setLayout(new FlowLayout()); |
| displayPanel.add(l1); |
| displayPanel.add(displayMenu); |
| |
| } |
| c.fill = GridBagConstraints.NONE; |
| c.anchor = GridBagConstraints.EAST; |
| |
| add(topPanel, displayPanel, g, c, GridBagConstraints.REMAINDER, 0); |
| |
| // The title, buttons, etc. go in a panel at the top of the window |
| add("North", topPanel); |
| |
| // The copyright notice goes at the bottom of the window |
| Label copyright = new Label(DemoUtility.copyright1, Label.LEFT); |
| copyright.setFont(DemoUtility.creditFont); |
| add("South", copyright); |
| |
| // Now create the big calendar panel and stick it in the middle |
| calendarPanel = new CalendarPanel( locales[displayMenu.getSelectedIndex()] ); |
| add("Center", calendarPanel); |
| |
| for (int i = 0; i < 2; i++) { |
| calendarPanel.setCalendar(i, calendars[i]); |
| calendarPanel.setColor(i, COLORS[i]); |
| } |
| |
| updateMonthName(); |
| } |
| |
| |
| private void updateMonthName() |
| { |
| for (int i = 0; i < 2; i++) { |
| try { |
| if (monthFormat[i] == null) { // TODO: optimize |
| DateFormat f = DateFormat.getDateTimeInstance( |
| calendars[i], DateFormat.MEDIUM, -1, |
| locales[displayMenu.getSelectedIndex()]); |
| if (f instanceof com.ibm.icu.text.SimpleDateFormat) { |
| com.ibm.icu.text.SimpleDateFormat f1 = (com.ibm.icu.text.SimpleDateFormat) f; |
| f1.applyPattern("MMMM, yyyy G"); |
| f1.setTimeZone(new SimpleTimeZone(0, "UTC")); |
| } |
| monthFormat[i] = f; |
| } |
| } catch (ClassCastException e) { |
| //hey {lw} - there's something wrong in this routine that cuases exceptions. |
| System.out.println(e); |
| } |
| |
| monthLabel[i].setText( monthFormat[i].format( calendarPanel.firstOfMonth() )); |
| } |
| } |
| |
| /** |
| * CalMenuListener responds to events in the two popup menus that select |
| * the calendar systems to be used in the display. It figures out which |
| * of the two menus the event occurred in and updates the corresponding |
| * element of the calendars[] array to match the new selection. |
| */ |
| private class CalMenuListener implements ItemListener |
| { |
| public void itemStateChanged(ItemEvent e) |
| { |
| for (int i = 0; i < calMenu.length; i++) |
| { |
| if (e.getItemSelectable() == calMenu[i]) |
| { |
| // We found the menu that the event happened in. |
| // Figure out which new calendar they selected. |
| Calendar newCal = CALENDARS[ calMenu[i].getSelectedIndex() ].calendar; |
| |
| if (newCal != calendars[i]) |
| { |
| // If any of the other menus are set to the same new calendar |
| // we're about to use for this menu, set them to the current |
| // calendar from *this* menu so we won't have two the same |
| for (int j = 0; j < calendars.length; j++) { |
| if (j != i && calendars[j] == newCal) { |
| calendars[j] = calendars[i]; |
| calendarPanel.setCalendar(j, calendars[j]); |
| monthFormat[j] = null; |
| |
| for (int k = 0; k < CALENDARS.length; k++) { |
| if (calendars[j] == CALENDARS[k].calendar) { |
| calMenu[j].select(k); |
| break; |
| } |
| } |
| } |
| } |
| // Now update this menu to use the new calendar the user selected |
| calendars[i] = newCal; |
| calendarPanel.setCalendar(i, newCal); |
| monthFormat[i] = null; |
| |
| updateMonthName(); |
| } |
| break; |
| } |
| } |
| } |
| } |
| |
| /** |
| * AddAction handles the next/previous year/month buttons... |
| */ |
| private class AddAction implements ActionListener { |
| AddAction(int field, int amount) { |
| this.field = field; |
| this.amount = amount; |
| } |
| |
| public void actionPerformed(ActionEvent e) { |
| calendarPanel.add(field, amount); |
| updateMonthName(); |
| } |
| |
| private int field, amount; |
| } |
| |
| /** |
| * ColoredLabel is similar to java.awt.Label, with two differences: |
| * |
| * - You can set its text color |
| * |
| * - It draws text using drawString rather than using a host-specific |
| * "Peer" object like AWT does. On 1.2, using drawString gives |
| * us Bidi reordering for free. |
| */ |
| static private class ColoredLabel extends Component { |
| /** |
| * For serialization |
| */ |
| private static final long serialVersionUID = 5004484960341875722L; |
| public ColoredLabel(String label) { |
| text = label; |
| } |
| |
| public ColoredLabel(String label, Color c) { |
| text = label; |
| color = c; |
| } |
| |
| public void setText(String label) { |
| text = label; |
| repaint(); |
| } |
| |
| public void setFont(Font f) { |
| font = f; |
| repaint(); |
| } |
| |
| public void paint(Graphics g) { |
| FontMetrics fm = g.getFontMetrics(font); |
| |
| Rectangle bounds = getBounds(); |
| |
| g.setColor(color); |
| g.setFont(font); |
| g.drawString(text, fm.stringWidth("\u00a0"), |
| bounds.height/2 + fm.getHeight() |
| - fm.getAscent() + fm.getLeading()/2); |
| } |
| |
| public Dimension getPreferredSize() { |
| return getMinimumSize(); |
| } |
| |
| public Dimension getMinimumSize() { |
| FontMetrics fm = getFontMetrics(font); |
| |
| return new Dimension( fm.stringWidth(text) + 2*fm.stringWidth("\u00a0"), |
| fm.getHeight() + fm.getLeading()*2); |
| } |
| |
| String text; |
| Color color = Color.black; |
| Font font = DemoUtility.labelFont; |
| } |
| |
| /** |
| * Print out the error message while debugging this program. |
| */ |
| public void errorText(String s) |
| { |
| if (DEBUG) |
| { |
| System.out.println(s); |
| } |
| } |
| |
| class CalendarRec { |
| public CalendarRec(String nameStr, Calendar cal) |
| { |
| name = nameStr; |
| calendar = cal; |
| } |
| |
| Calendar calendar; |
| String name; |
| } |
| |
| private final CalendarRec[] CALENDARS = { |
| new CalendarRec("Gregorian Calendar", new GregorianCalendar()), |
| new CalendarRec("Hebrew Calendar", new HebrewCalendar()), |
| new CalendarRec("Islamic Calendar", makeIslamic(false)), |
| new CalendarRec("Islamic Civil Calendar ", makeIslamic(true)), |
| new CalendarRec("Buddhist Calendar", new BuddhistCalendar()), |
| new CalendarRec("Japanese Calendar", new JapaneseCalendar()), |
| }; |
| |
| static private final Calendar makeIslamic(boolean civil) { |
| IslamicCalendar cal = new IslamicCalendar(); |
| cal.setCivil(civil); |
| return cal; |
| } |
| |
| static final Color[] COLORS = { Color.blue, Color.black }; |
| } |
| |