blob: 9bf8b50227e71d7a1440b9866f5f98bf261c6afb [file] [log] [blame]
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
* Copyright (C) 1997-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.demo.calendar;
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;
import javax.swing.JTextField;
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.text.SimpleDateFormat;
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.TimeZone;
/**
* CalendarCalc demonstrates how Date/Time formatter works.
*/
public class CalendarCalc extends DemoApplet
{
/**
* For serialization
*/
private static final long serialVersionUID = 4540103433916539296L;
/**
* The main function which defines the behavior of the MultiCalendarDemo
* applet when an applet is started.
*/
public static void main(String argv[]) {
new CalendarCalc().showDemo();
}
/**
* This creates a CalendarCalcFrame for the demo applet.
*/
public Frame createDemoFrame(DemoApplet applet) {
return new CalendarCalcFrame(applet);
}
}
/**
* A Frame is a top-level window with a title. The default layout for a frame
* is BorderLayout. The CalendarCalcFrame class defines the window layout of
* MultiCalendarDemo.
*/
class CalendarCalcFrame extends Frame implements ActionListener
{
/**
* For serialization
*/
private static final long serialVersionUID = 8901485296258761846L;
static final Locale[] locales = DemoUtility.getG7Locales();
private DemoApplet applet;
private long time = System.currentTimeMillis();
private static final RollAddField kRollAddFields[] = {
new RollAddField(Calendar.YEAR, "Year" ),
new RollAddField(Calendar.MONTH, "Month" ),
new RollAddField(Calendar.WEEK_OF_MONTH, "Week of Month" ),
new RollAddField(Calendar.WEEK_OF_YEAR, "Week of Year" ),
new RollAddField(Calendar.DAY_OF_MONTH, "Day of Month" ),
new RollAddField(Calendar.DAY_OF_WEEK, "Day of Week" ),
new RollAddField(Calendar.DAY_OF_WEEK_IN_MONTH, "Day of Week in Month" ),
new RollAddField(Calendar.DAY_OF_YEAR, "Day of Year" ),
new RollAddField(Calendar.AM_PM, "AM/PM" ),
new RollAddField(Calendar.HOUR_OF_DAY, "Hour of day" ),
new RollAddField(Calendar.HOUR, "Hour" ),
new RollAddField(Calendar.MINUTE, "Minute" ),
new RollAddField(Calendar.SECOND, "Second" ),
};
/**
* Constructs a new CalendarCalcFrame that is initially invisible.
*/
public CalendarCalcFrame(DemoApplet applet)
{
super("Multiple Calendar Demo");
this.applet = applet;
init();
start();
}
/**
* 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()
{
buildGUI();
patternText.setText( calendars[0].toPattern() );
// Force an update of the display
cityChanged();
millisFormat();
enableEvents(KeyEvent.KEY_RELEASED);
enableEvents(WindowEvent.WINDOW_CLOSING);
}
//------------------------------------------------------------
// package private
//------------------------------------------------------------
void addWithFont(Container container, Component foo, Font font) {
if (font != null)
foo.setFont(font);
container.add(foo);
}
/**
* Called to start the applet. You never need to call this method
* directly, it is called when the applet's document is visited.
*/
public void start()
{
// do nothing
}
TextField patternText;
Choice dateMenu;
Choice localeMenu;
Button up;
Button down;
Checkbox getRoll;
Checkbox getAdd;
public void buildGUI()
{
setBackground(DemoUtility.bgColor);
setLayout(new FlowLayout()); // shouldn't be necessary, but it is.
// TITLE
Label label1=new Label("Calendar Converter", Label.CENTER);
label1.setFont(DemoUtility.titleFont);
add(label1);
add(DemoUtility.createSpacer());
// IO Panel
Panel topPanel = new Panel();
topPanel.setLayout(new FlowLayout());
CheckboxGroup group1= new CheckboxGroup();
// Set up the controls for each calendar we're demonstrating
for (int i = 0; i < calendars.length; i++)
{
Label label = new Label(calendars[i].name, Label.RIGHT);
label.setFont(DemoUtility.labelFont);
topPanel.add(label);
topPanel.add(calendars[i].text);
final int j = i;
calendars[i].text.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
textChanged(j);
}
} );
calendars[i].rollAdd.setCheckboxGroup(group1);
topPanel.add(calendars[i].rollAdd);
}
calendars[0].rollAdd.setState(true); // Make the first one selected
Label label4=new Label("Pattern", Label.RIGHT);
label4.setFont(DemoUtility.labelFont);
topPanel.add(label4);
patternText=new TextField(FIELD_COLUMNS);
patternText.setFont(DemoUtility.editFont);
topPanel.add(patternText);
topPanel.add(new Label(""));
DemoUtility.fixGrid(topPanel,3);
add(topPanel);
add(DemoUtility.createSpacer());
// ROLL / ADD
Panel rollAddPanel=new Panel();
{
rollAddPanel.setLayout(new FlowLayout());
Panel rollAddBoxes = new Panel();
{
rollAddBoxes.setLayout(new GridLayout(2,1));
CheckboxGroup group2= new CheckboxGroup();
getRoll = new Checkbox("Roll",group2, false);
getAdd = new Checkbox("Add",group2, true);
rollAddBoxes.add(getRoll);
rollAddBoxes.add(getAdd);
}
Label dateLabel=new Label("Date Fields");
dateLabel.setFont(DemoUtility.labelFont);
dateMenu= new Choice();
dateMenu.setBackground(DemoUtility.choiceColor);
for (int i = 0; i < kRollAddFields.length; i++) {
dateMenu.addItem(kRollAddFields[i].name);
if (kRollAddFields[i].field == Calendar.MONTH) {
dateMenu.select(i);
}
}
Panel upDown = new Panel();
{
upDown.setLayout(new GridLayout(2,1));
// *** If the images are not found, we use the label.
up = new Button("^");
down = new Button("v");
up.setBackground(DemoUtility.bgColor);
down.setBackground(DemoUtility.bgColor);
upDown.add(up);
upDown.add(down);
up.addActionListener(this);
down.addActionListener(this);
}
rollAddPanel.add(dateLabel);
rollAddPanel.add(dateMenu);
rollAddPanel.add(rollAddBoxes);
rollAddPanel.add(upDown);
}
Panel localePanel = new Panel();
{
// Make the locale popup menus
localeMenu= 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()))
{
localeMenu.addItem( locales[i].getDisplayName() );
} else {
localeMenu.addItem( locales[i].getDisplayLanguage());
}
thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale);
if (thisMatch >= bestMatch) {
bestMatch = thisMatch;
selectMe = i;
}
}
localeMenu.setBackground(DemoUtility.choiceColor);
localeMenu.select(selectMe);
Label localeLabel =new Label("Display Locale");
localeLabel.setFont(DemoUtility.labelFont);
localePanel.add(localeLabel);
localePanel.add(localeMenu);
DemoUtility.fixGrid(localePanel,2);
localeMenu.addItemListener( new ItemListener() {
public void itemStateChanged(ItemEvent e) {
Locale loc = locales[localeMenu.getSelectedIndex()];
System.out.println("Change locale to " + loc.getDisplayName());
for (int i = 0; i < calendars.length; i++) {
calendars[i].setLocale(loc);
}
millisFormat();
}
} );
}
add(rollAddPanel);
add(DemoUtility.createSpacer());
add(localePanel);
add(DemoUtility.createSpacer());
// COPYRIGHT
Panel copyrightPanel = new Panel();
addWithFont (copyrightPanel,new Label(DemoUtility.copyright1, Label.LEFT),
DemoUtility.creditFont);
DemoUtility.fixGrid(copyrightPanel,1);
add(copyrightPanel);
}
/**
* This function is called when users change the pattern text.
*/
public void setFormatFromPattern() {
String timePattern = patternText.getText();
for (int i = 0; i < calendars.length; i++) {
calendars[i].applyPattern(timePattern);
}
millisFormat();
}
/**
* This function is called when it is necessary to parse the time
* string in one of the formatted date fields
*/
public void textChanged(int index) {
String rightString = calendars[index].text.getText();
ParsePosition status = new ParsePosition(0);
if (rightString.length() == 0)
{
errorText("Error: no input to parse!");
return;
}
try {
Date date = calendars[index].format.parse(rightString, status);
time = date.getTime();
}
catch (Exception e) {
for (int i = 0; i < calendars.length; i++) {
if (i != index) {
calendars[i].text.setText("ERROR");
}
}
errorText("Exception: " + e.getClass().toString() + " parsing: "+rightString);
return;
}
int start = calendars[index].text.getSelectionStart();
int end = calendars[index].text.getSelectionEnd();
millisFormat();
calendars[index].text.select(start,end);
}
/**
* This function is called when it is necessary to format the time
* in the "Millis" text field.
*/
public void millisFormat() {
String out = "";
for (int i = 0; i < calendars.length; i++) {
try {
out = calendars[i].format.format(new Date(time));
calendars[i].text.setText(out);
}
catch (Exception e) {
calendars[i].text.setText("ERROR");
errorText("Exception: " + e.getClass().toString() + " formatting "
+ calendars[i].name + " " + time);
}
}
}
/**
* This function is called when users change the pattern text.
*/
public void patternTextChanged() {
setFormatFromPattern();
}
/**
* This function is called when users select a new representative city.
*/
public void cityChanged() {
TimeZone timeZone = TimeZone.getDefault();
for (int i = 0; i < calendars.length; i++) {
calendars[i].format.setTimeZone(timeZone);
}
millisFormat();
}
/**
* This function is called when users select a new time field
* to add or roll its value.
*/
public void dateFieldChanged(boolean isUp) {
int field = kRollAddFields[dateMenu.getSelectedIndex()].field;
for (int i = 0; i < calendars.length; i++)
{
if (calendars[i].rollAdd.getState())
{
Calendar c = calendars[i].calendar;
c.setTime(new Date(time));
if (getAdd.getState()) {
c.add(field, isUp ? 1 : -1);
} else {
c.roll(field, isUp);
}
time = c.getTime().getTime();
millisFormat();
break;
}
}
}
/**
* Print out the error message while debugging this program.
*/
public void errorText(String s)
{
if (true) {
System.out.println(s);
}
}
/**
* Called if an action occurs in the CalendarCalcFrame object.
*/
public void actionPerformed(ActionEvent evt)
{
// *** Button events are handled here.
Object obj = evt.getSource();
System.out.println("action " + obj);
if (obj instanceof Button) {
if (evt.getSource() == up) {
dateFieldChanged(false);
} else
if (evt.getSource() == down) {
dateFieldChanged(true);
}
}
}
/**
* Handles the event. Returns true if the event is handled and should not
* be passed to the parent of this component. The default event handler
* calls some helper methods to make life easier on the programmer.
*/
protected void processKeyEvent(KeyEvent evt)
{
System.out.println("key " + evt);
if (evt.getID() == KeyEvent.KEY_RELEASED) {
if (evt.getSource() == patternText) {
patternTextChanged();
}
else {
for (int i = 0; i < calendars.length; i++) {
if (evt.getSource() == calendars[i].text) {
textChanged(i);
}
}
}
}
}
protected void processWindowEvent(WindowEvent evt)
{
System.out.println("window " + evt);
if (evt.getID() == WindowEvent.WINDOW_CLOSING &&
evt.getSource() == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else System.exit(0);
}
}
/*
protected void processEvent(AWTEvent evt)
{
if (evt.getID() == AWTEvent. Event.ACTION_EVENT && evt.target == up) {
dateFieldChanged(true);
return true;
}
else if (evt.id == Event.ACTION_EVENT && evt.target == down) {
dateFieldChanged(false);
return true;
}
}
*/
private static final int FIELD_COLUMNS = 35;
class CalendarRec {
public CalendarRec(String nameStr, Calendar cal)
{
name = nameStr;
calendar = cal;
rollAdd = new Checkbox();
text = new JTextField("",FIELD_COLUMNS);
text.setFont(DemoUtility.editFont);
format = DateFormat.getDateInstance(cal, DateFormat.FULL,
Locale.getDefault());
//format.applyPattern(DEFAULT_FORMAT);
}
public void setLocale(Locale loc) {
String pattern = toPattern();
format = DateFormat.getDateInstance(calendar, DateFormat.FULL,
loc);
applyPattern(pattern);
}
public void applyPattern(String pattern) {
if (format instanceof SimpleDateFormat) {
((SimpleDateFormat)format).applyPattern(pattern);
//hey {al} -
// } else if (format instanceof java.text.SimpleDateFormat) {
// ((java.text.SimpleDateFormat)format).applyPattern(pattern);
}
}
private String toPattern() {
if (format instanceof SimpleDateFormat) {
return ((SimpleDateFormat)format).toPattern();
//hey {al} -
// } else if (format instanceof java.text.SimpleDateFormat) {
// return ((java.text.SimpleDateFormat)format).toPattern();
}
return "";
}
Calendar calendar;
DateFormat format;
String name;
JTextField text;
Checkbox rollAdd;
}
private final CalendarRec[] calendars = {
new CalendarRec("Gregorian", new GregorianCalendar()),
new CalendarRec("Hebrew", new HebrewCalendar()),
new CalendarRec("Islamic (civil)", makeIslamic(true)),
new CalendarRec("Islamic (true)", makeIslamic(false)),
new CalendarRec("Buddhist", new BuddhistCalendar()),
new CalendarRec("Japanese", new JapaneseCalendar()),
// new CalendarRec("Chinese", new ChineseCalendar()),
};
static private final Calendar makeIslamic(boolean civil) {
IslamicCalendar cal = new IslamicCalendar();
cal.setCivil(civil);
return cal;
}
}
class RollAddField {
RollAddField(int field, String name) {
this.field = field;
this.name = name;
}
int field;
String name;
}