*** empty log message ***

X-SVN-Rev: 742
This commit is contained in:
John Fitzpatrick 2000-02-10 06:25:58 +00:00
parent ad902e7865
commit 4857053b2e
291 changed files with 182388 additions and 0 deletions

3
.gitattributes vendored
View file

@ -77,6 +77,9 @@ icu4c/source/data/brkitr/word_thBE.brk -text
icu4c/source/data/brkitr/word_thLE.brk -text
icu4c/source/test/testdata/en_US.uni -text
icu4c/source/test/testdata/uni-text.txt -text
icu4j/src/com/ibm/demo/rbbi/genesis.dict -text
icu4j/src/com/ibm/icu/dev/data/holidays_jp.ucs -text
icu4j/src/data/holidays_jp.ucs -text
# The following file types are stored in Git-LFS.
*.jar filter=lfs diff=lfs merge=lfs -text

10
icu4j/src/build/defs.mak Executable file
View file

@ -0,0 +1,10 @@
CLASSDIR= $(TOPDIR)/classes
SRCDIR= $(TOPDIR)/src
DOCDIR= $(TOPDIR)/docs
CLASSPATH= $(CLASSDIR);$(TOPDIR)/classes/decimal.jar;$(TOPDIR)/classes/decimal1.jar
PKGPATH= $(PACKAGE:.=\)
TARGDIR= $(CLASSDIR)/$(PKGPATH)
JAVACFLAGS= -target 1.1

57
icu4j/src/build/rules.mak Executable file
View file

@ -0,0 +1,57 @@
default: classes
JAVAC= javac -classpath $(CLASSPATH) -sourcepath $(SRCDIR) -d $(CLASSDIR) $(JAVACFLAGS)
.SUFFIXES: .java .class
!ifdef FILES_JAVA
FILES_java= $(FILES_java:/=\)
!endif
FILES_class= $(FILES_java:.java=.class)
CLASSLIST= classes.list
{$(SRCDIR)\$(PKGPATH)}.java{$(CLASSDIR)\$(PKGPATH)}.class:
@echo $(?) >> $(CLASSLIST)
!ifdef FILES_dict
FILES_dict= $(FILES_dict:/=\)
SRC_FILES_dict= $(FILES_dict:classes=src)
!endif
classes: delete.classlist $(FILES_class) $(FILES_dics)
@if exist $(CLASSLIST) echo Compiling {
@if exist $(CLASSLIST) cat $(CLASSLIST)
if exist $(CLASSLIST) $(JAVAC) @$(CLASSLIST)
rm -f $(CLASSLIST)
!ifdef FILES_dict
cp $(SRC_FILES_dict) $(TARGDIR)
!endif
!ifdef SUBDIRS
@for %%d in ( $(SUBDIRS) ) do cd %d && nmake -nologo classes && cd ..
!endif
dict: $(SRC_FILES_dict)
echo $(FILES_dict)
echo $(SRC_FILES_dict)
cp $(SRC_FILES_dict) $(CLASSDIR)/$(PKGPATH)/
delete.classlist:
@rm -f $(CLASSLIST)
clean:
!ifdef FILES_java
rm -f $(FILES_class)
!endif
!ifdef FILES_dict
rm -f $(FILES_dict)
!endif
!ifdef SUBDIRS
@for %%d in ( $(SUBDIRS) ) do cd %d && nmake -nologo clean && cd ..
!endif
FORCE: ;

View file

@ -0,0 +1,97 @@
/*
* $RCSfile: DemoApplet.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo;
import java.applet.Applet;
import java.util.Locale;
import java.awt.*;
import java.awt.event.*;
public abstract class DemoApplet extends java.applet.Applet {
private Button demoButton;
private Frame demoFrame;
private static int demoFrameCount = 0;
protected abstract Frame createDemoFrame(DemoApplet applet);
protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
return new Dimension(700, 550);
}
//Create a button that will display the demo
public void init()
{
setBackground(Color.white);
demoButton = new Button("Demo");
demoButton.setBackground(Color.yellow);
add( demoButton );
demoButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getID() == ActionEvent.ACTION_PERFORMED) {
demoButton.setLabel("loading");
if (demoFrame == null) {
demoFrame = createDemoFrame(DemoApplet.this);
showDemo();
}
demoButton.setLabel("Demo");
}
}
} );
}
public void showDemo()
{
demoFrame = createDemoFrame(this);
demoFrame.layout();
Dimension d = getDefaultFrameSize(this, demoFrame);
demoFrame.resize(d.width, d.height);
demoFrame.show();
demoFrameOpened();
}
public void demoClosed()
{
demoFrame = null;
demoFrameClosed();
}
protected static void demoFrameOpened() {
demoFrameCount++;
}
protected static void demoFrameClosed() {
if (--demoFrameCount == 0) {
System.exit(0);
}
}
}

View file

@ -0,0 +1,118 @@
/*
* $RCSfile: DemoTextBox.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo;
import java.text.BreakIterator;
import java.awt.*;
public class DemoTextBox {
public DemoTextBox(Graphics g, String text, int width)
{
this.text = text;
this.chars = new char[text.length()];
text.getChars(0, text.length(), chars, 0);
this.width = width;
this.port = g;
this.metrics = g.getFontMetrics();
breakText();
}
public int getHeight() {
return (nbreaks + 1) * metrics.getHeight();
}
public void draw(Graphics g, int x, int y)
{
int index = 0;
y += metrics.getAscent();
for (int i = 0; i < nbreaks; i++)
{
g.drawChars(chars, index, breakPos[i] - index, x, y);
index = breakPos[i];
y += metrics.getHeight();
}
g.drawChars(chars, index, chars.length - index, x, y);
}
private void breakText()
{
if (metrics.charsWidth(chars, 0, chars.length) > width)
{
BreakIterator iter = BreakIterator.getWordInstance();
iter.setText(text);
int start = iter.first();
int end = start;
int pos;
while ( (pos = iter.next()) != BreakIterator.DONE )
{
int w = metrics.charsWidth(chars, start, pos - start);
if (w > width)
{
// We've gone past the maximum width, so break the line
if (end > start) {
// There was at least one break position before this point
breakPos[nbreaks++] = end;
start = end;
end = pos;
} else {
// There weren't any break positions before this one, so
// let this word overflow the margin (yuck)
breakPos[nbreaks++] = pos;
start = end = pos;
}
} else {
// the current position still fits on the line; it's the best
// tentative break position we have so far.
end = pos;
}
}
}
}
private String text;
private char[] chars;
private Graphics port;
private FontMetrics metrics;
private int width;
private int[] breakPos = new int[10]; // TODO: get real
private int nbreaks = 0;
}

View file

@ -0,0 +1,127 @@
/*
* $RCSfile: DemoUtility.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo;
import java.awt.*;
import java.lang.*;
import java.util.*;
public class DemoUtility
{
public static final Font titleFont = new Font("TimesRoman",Font.BOLD,18);
public static final Font labelFont = new Font("TimesRoman",Font.BOLD,14);
public static final Font choiceFont = new Font("Helvetica",Font.BOLD,12);
public static final Font editFont = new Font("Helvetica",Font.PLAIN,14);
public static final Font creditFont = new Font("Helvetica",Font.PLAIN,10);
public static final Font numberFont = new Font("sansserif", Font.PLAIN, 14);
public static final Color bgColor = Color.lightGray;
public static final Color choiceColor = Color.white;
public static final String copyright1 =
"(C) Copyright Taligent, Inc. 1996-1998. Copyright (C) IBM, Inc. 1998 - All Rights Reserved";
public static final String copyright2 =
"Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.";
/**
Provides easy way to use basic functions of GridBagLayout, without
the complications. After building a panel, and inserting all the
* subcomponents, call this to lay it out in the desired number of columns.
*/
public static void fixGrid(Container cont, int columns) {
GridBagLayout gridbag = new GridBagLayout();
cont.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.VERTICAL;
c.weightx = 1.0;
c.insets = new Insets(2,2,2,2);
Component[] components = cont.getComponents();
for (int i = 0; i < components.length; ++i) {
int colNumber = i%columns;
c.gridwidth = 1; // default
if ((i%columns) == columns - 1)
c.gridwidth = GridBagConstraints.REMAINDER; // last in grid
if (components[i] instanceof Label) {
switch (((Label)components[i]).getAlignment()) {
case Label.CENTER: c.anchor = GridBagConstraints.CENTER; break;
case Label.LEFT: c.anchor = GridBagConstraints.WEST; break;
case Label.RIGHT: c.anchor = GridBagConstraints.EAST; break;
}
}
gridbag.setConstraints(components[i], c);
}
}
/**
Provides easy way to change the spacing around an object in a GridBagLayout.
Call AFTER fixGridBag, passing in the container, the component, and the
new insets.
*/
public static void setInsets(Container cont, Component comp, Insets insets) {
GridBagLayout gbl = (GridBagLayout)cont.getLayout();
GridBagConstraints g = gbl.getConstraints(comp);
g.insets = insets;
gbl.setConstraints(comp,g);
}
public static Panel createSpacer() {
Panel spacer = new Panel();
spacer.setLayout(null);
spacer.resize(1000, 1);
return spacer;
}
// to avoid goofy updates and misplaced cursors
public static void setText(TextComponent area, String newText) {
String foo = area.getText();
if (foo.equals(newText)) return;
area.setText(newText);
}
/**
* Get the G7 locale list for demos.
*/
public static Locale[] getG7Locales() {
return localeList;
}
private static Locale[] localeList = {
new Locale("DA", "DK", ""),
new Locale("EN", "US", ""),
new Locale("EN", "GB", ""),
new Locale("EN", "CA", ""),
new Locale("FR", "FR", ""),
new Locale("FR", "CA", ""),
new Locale("DE", "DE", ""),
new Locale("IT", "IT", ""),
//new Locale("JA", "JP", ""),
};
}

Binary file not shown.

View file

@ -0,0 +1,54 @@
/**
* $RCSfile: CalendarApp.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
//import java.text.SimpleDateFormat;
//import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
import com.ibm.text.*;
/**
* CalendarApp demonstrates how Calendar works.
*/
public class CalendarApp extends DemoApplet
{
/**
* The main function which defines the behavior of the CalendarDemo
* applet when an applet is started.
*/
public static void main(String argv[]) {
new CalendarApp().showDemo();
}
/* This creates a CalendarFrame for the demo applet. */
public Frame createDemoFrame(DemoApplet applet) {
return new CalendarFrame(applet);
}
}

View file

@ -0,0 +1,550 @@
/*
* $RCSfile: CalendarCalc.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.util.Date;
import java.awt.*;
import java.awt.event.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParsePosition;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.Locale;
import com.ibm.util.*;
import javax.swing.*;
/**
* CalendarCalc demonstrates how Date/Time formatter works.
*/
public class CalendarCalc extends DemoApplet
{
/**
* 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
{
private static final String creditString = "";
static final Locale[] locales = DemoUtility.getG7Locales();
private static final boolean DEBUG = false;
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].format.toPattern() );
// Force an update of the display
cityChanged();
millisFormat();
}
//------------------------------------------------------------
// 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);
}
rollAddPanel.add(dateLabel);
rollAddPanel.add(dateMenu);
rollAddPanel.add(rollAddBoxes);
rollAddPanel.add(upDown);
}
Panel localePanel = new Panel();
{
// Make the locale popup menus
localeMenu= new Choice();
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());
}
if (locales[i].getLanguage().equals(Locale.getDefault().getLanguage())) {
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);
}
/**
* Called if an action occurs in the CalendarCalcFrame object.
*/
public boolean action(Event evt, Object obj)
{
// *** Button events are handled here.
if (evt.target instanceof Button) {
if (evt.target == up) {
dateFieldChanged(false);
return true;
} else
if (evt.target == down) {
dateFieldChanged(true);
return true;
}
}
return super.action(evt, obj);
}
/**
* 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.
*/
public boolean handleEvent(Event evt)
{
if (evt.id == Event.KEY_RELEASE && evt.target == patternText) {
patternTextChanged();
return true;
}
else if (evt.id == Event.KEY_RELEASE) {
for (int i = 0; i < calendars.length; i++) {
if (evt.target == calendars[i].text) {
textChanged(i);
return true;
}
}
}
else if (evt.id == Event.ACTION_EVENT && evt.target == up) {
dateFieldChanged(true);
return true;
}
else if (evt.id == Event.ACTION_EVENT && evt.target == down) {
dateFieldChanged(false);
return true;
}
else if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else System.exit(0);
return true;
}
return super.handleEvent(evt);
}
/**
* 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 up) {
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, up ? 1 : -1);
} else {
c.roll(field, up);
}
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);
}
}
private static final int FIELD_COLUMNS = 35;
private static final String DEFAULT_FORMAT = "EEEE MMMM d, yyyy G";
class CalendarRec {
public CalendarRec(String nameStr, java.util.Calendar cal)
{
name = nameStr;
calendar = cal;
rollAdd = new Checkbox();
text = new JTextField("",FIELD_COLUMNS);
text.setFont(DemoUtility.editFont);
format = (SimpleDateFormat) IBMCalendar.getDateFormat(cal, DateFormat.FULL,
Locale.getDefault());
//format.applyPattern(DEFAULT_FORMAT);
}
public void setLocale(Locale loc) {
String pattern = format.toPattern();
format = (SimpleDateFormat) IBMCalendar.getDateFormat(calendar, DateFormat.FULL,
loc);
format.applyPattern(pattern);
}
public void applyPattern(String pattern) {
format.applyPattern(pattern);
}
java.util.Calendar calendar;
SimpleDateFormat 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;
};

View file

@ -0,0 +1,407 @@
/**
* $RCSfile: CalendarFrame.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
//import java.text.SimpleDateFormat;
//import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
import com.ibm.text.*;
/**
* 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
{
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();
int selectMe = 1;
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());
}
if (locales[i].getLanguage().equals(Locale.getDefault().getLanguage())) {
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++) {
if (monthFormat[i] == null) { // TODO: optimize
SimpleDateFormat f = (SimpleDateFormat) IBMCalendar.getDateTimeFormat(
calendars[i], DateFormat.MEDIUM, -1,
locales[displayMenu.getSelectedIndex()]);
f.applyPattern("MMMM, yyyy G");
f.setTimeZone(new SimpleTimeZone(0, "UTC"));
monthFormat[i] = f;
}
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 {
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, java.util.Calendar cal)
{
name = nameStr;
calendar = cal;
}
java.util.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 };
}

View file

@ -0,0 +1,368 @@
/**
* $RCSfile: CalendarPanel.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
//import java.text.SimpleDateFormat;
//import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
import com.ibm.text.*;
class CalendarPanel extends Canvas {
public CalendarPanel( Locale locale ) {
setLocale(locale);
}
public void setLocale(Locale locale) {
if (fDisplayLocale == null || !fDisplayLocale.equals(locale)) {
fDisplayLocale = locale;
dirty = true;
for (int i = 0; i < fCalendar.length; i++) {
if (fCalendar[i] != null) {
fSymbols[i] = IBMCalendar.getDateFormatSymbols(fCalendar[i],
fDisplayLocale);
}
}
String lang = locale.getLanguage();
leftToRight = !(lang.equals("iw") || lang.equals("ar"));
repaint();
}
}
public void setDate(Date date) {
fStartOfMonth = date;
dirty = true;
repaint();
}
public void add(int field, int delta)
{
synchronized(fCalendar) {
fCalendar[0].setTime(fStartOfMonth);
fCalendar[0].add(field, delta);
fStartOfMonth = fCalendar[0].getTime();
}
dirty = true;
repaint();
}
public void setColor(int index, Color c) {
fColor[index] = c;
repaint();
}
public void setCalendar(int index, Calendar c) {
Date date = (fCalendar[index] == null) ? new Date()
: fCalendar[index].getTime();
fCalendar[index] = c;
fCalendar[index].setTime(date);
fSymbols[index] = IBMCalendar.getDateFormatSymbols(c, fDisplayLocale);
dirty = true;
repaint();
}
public Calendar getCalendar(int index) {
return fCalendar[index];
}
public Locale getDisplayLocale() {
return fDisplayLocale;
}
public Date firstOfMonth() {
return fStartOfMonth;
}
private Date startOfMonth(Date dateInMonth)
{
synchronized(fCalendar) {
fCalendar[0].setTime(dateInMonth);
int era = fCalendar[0].get(Calendar.ERA);
int year = fCalendar[0].get(Calendar.YEAR);
int month = fCalendar[0].get(Calendar.MONTH);
fCalendar[0].clear();
fCalendar[0].set(Calendar.ERA, era);
fCalendar[0].set(Calendar.YEAR, year);
fCalendar[0].set(Calendar.MONTH, month);
fCalendar[0].set(Calendar.DATE, 1);
return fCalendar[0].getTime();
}
}
private void calculate()
{
//
// As a workaround for JDK 1.1.3 and below, where Calendars and time
// zones are a bit goofy, always set my calendar's time zone to UTC.
// You would think I would want to do this in the "set" function above,
// but if I do that, the program hangs when this class is loaded,
// perhaps due to some sort of static initialization ordering problem.
// So I do it here instead.
//
fCalendar[0].setTimeZone(new SimpleTimeZone(0, "UTC"));
Calendar c = (Calendar)fCalendar[0].clone(); // Temporary copy
fStartOfMonth = startOfMonth(fStartOfMonth);
// Stash away a few useful constants for this calendar and display
minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
// Stash away a Date for the start of this month
// Find the day of week of the first day in this month
c.setTime(fStartOfMonth);
firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
int firstWeek = c.get(Calendar.WEEK_OF_MONTH);
// Now find the # of days in the month
c.roll(Calendar.DATE, false);
daysInMonth = c.get(Calendar.DATE);
// Finally, find the end of the month, i.e. the start of the next one
c.roll(Calendar.DATE, true);
c.add(Calendar.MONTH, 1);
c.getTime(); // JDK 1.1.2 bug workaround
c.add(Calendar.SECOND, -1);
Date endOfMonth = c.getTime();
int lastWeek = c.get(Calendar.WEEK_OF_MONTH);
// Calculate the number of full or partial weeks in this month.
numWeeks = lastWeek - firstWeek + 1;
dirty = false;
}
static final int XINSET = 4;
static final int YINSET = 2;
/*
* Convert from the day number within a month (1-based)
* to the cell coordinates on the calendar (0-based)
*/
private void dateToCell(int date, Point pos)
{
int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
if (firstDayInMonth < firstDayOfWeek) {
cell += daysInWeek;
}
pos.x = cell % daysInWeek;
pos.y = cell / daysInWeek;
}
private Point dateToCell(int date) {
Point p = new Point(0,0);
dateToCell(date, p);
return p;
}
public void paint(Graphics g) {
if (dirty) {
calculate();
}
Point cellPos = new Point(0,0); // Temporary variable
Dimension d = this.getSize();
g.setColor(Color.lightGray);
g.fillRect(0,0,d.width,d.height);
// Draw the day names at the top
g.setColor(Color.black);
g.setFont(DemoUtility.labelFont);
FontMetrics fm = g.getFontMetrics();
int labelHeight = fm.getHeight() + YINSET * 2;
int v = fm.getAscent() + YINSET;
for (int i = 0; i < daysInWeek; i++) {
int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
String dayName = fSymbols[0].getWeekdays()[dayNum];
double h;
if (leftToRight) {
h = d.width*(i + 0.5) / daysInWeek;
} else {
h = d.width*(daysInWeek - i - 0.5) / daysInWeek;
}
h -= fm.stringWidth(dayName) / 2;
g.drawString(dayName, (int)h, v);
}
double cellHeight = (d.height - labelHeight - 1) / numWeeks;
double cellWidth = (double)(d.width - 1) / daysInWeek;
// Draw a white background in the part of the calendar
// that displays this month.
// First figure out how much of the first week should be shaded.
{
g.setColor(Color.white);
dateToCell(1, cellPos);
int width = (int)(cellPos.x*cellWidth); // Width of unshaded area
if (leftToRight) {
g.fillRect((int)(width), labelHeight ,
d.width - width, (int)cellHeight);
} else {
g.fillRect(0, labelHeight ,
d.width - width, (int)cellHeight);
}
// All of the intermediate weeks get shaded completely
g.fillRect(0, (int)(labelHeight + cellHeight),
d.width, (int)(cellHeight * (numWeeks - 2)));
// Now figure out the last week.
dateToCell(daysInMonth, cellPos);
width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area
if (leftToRight) {
g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
width, (int)cellHeight);
} else {
g.fillRect(d.width - width, (int)(labelHeight + (numWeeks-1) * cellHeight),
width, (int)cellHeight);
}
}
// Draw the X/Y grid lines
g.setColor(Color.black);
for (int i = 0; i <= numWeeks; i++) {
int y = (int)(labelHeight + i * cellHeight);
g.drawLine(0, y, d.width - 1, y);
}
for (int i = 0; i <= daysInWeek; i++) {
int x = (int)(i * cellWidth);
g.drawLine(x, labelHeight, x, d.height - 1);
}
// Now loop through all of the days in the month, figure out where
// they go in the grid, and draw the day # for each one
// Figure out the date of the first cell in the calendar display
int cell = (1 + firstDayInMonth - firstDayOfWeek - minDay);
if (firstDayInMonth < firstDayOfWeek) {
cell += daysInWeek;
}
Calendar c = (Calendar)fCalendar[0].clone();
c.setTime(fStartOfMonth);
c.add(Calendar.DATE, -cell);
StringBuffer buffer = new StringBuffer();
for (int row = 0; row < numWeeks; row++) {
for (int col = 0; col < daysInWeek; col++) {
g.setFont(DemoUtility.numberFont);
g.setColor(Color.black);
fm = g.getFontMetrics();
int cellx;
if (leftToRight) {
cellx = (int)((col) * cellWidth);
} else {
cellx = (int)((daysInWeek - col - 1) * cellWidth);
}
int celly = (int)(row * cellHeight + labelHeight);
for (int i = 0; i < 2; i++) {
fCalendar[i].setTime(c.getTime());
int date = fCalendar[i].get(Calendar.DATE);
buffer.setLength(0);
buffer.append(date);
String dayNum = buffer.toString();
int x;
if (leftToRight) {
x = cellx + (int)cellWidth - XINSET - fm.stringWidth(dayNum);
} else {
x = cellx + XINSET;
}
int y = celly + + fm.getAscent() + YINSET + i * fm.getHeight();
if (fColor[i] != null) {
g.setColor(fColor[i]);
}
g.drawString(dayNum, x, y);
if (date == 1 || row == 0 && col == 0) {
g.setFont(DemoUtility.numberFont);
String month = fSymbols[i].getMonths()[
fCalendar[i].get(Calendar.MONTH)];
if (leftToRight) {
x = cellx + XINSET;
} else {
x = cellx + (int)cellWidth - XINSET - fm.stringWidth(month);
}
g.drawString(month, x, y);
}
}
c.add(Calendar.DATE, 1);
}
}
}
// Important state variables
private Calendar[] fCalendar = new Calendar[4];
private Color[] fColor = new Color[4];
private Locale fDisplayLocale;
private DateFormatSymbols[] fSymbols = new DateFormatSymbols[4];
private Date fStartOfMonth = new Date(); // 00:00:00 on first day of month
// Cached calculations to make drawing faster.
private transient int minDay; // Minimum legal day #
private transient int daysInWeek; // # of days in a week
private transient int firstDayOfWeek; // First day to display in week
private transient int numWeeks; // # full or partial weeks in month
private transient int daysInMonth; // # days in this month
private transient int firstDayInMonth; // Day of week of first day in month
private transient boolean leftToRight;
private transient boolean dirty = true;
}

View file

@ -0,0 +1,552 @@
/* ************************************************************* */
/* (C) Copyright Taligent, Inc. 1996-All Rights Reserved. */
/* (C) Copyright IBM Corporation 1996 - 1998 */
/* */
/* Permission is granted to copy, use, modify, and merge this */
/* software into your applications and to permit others to do */
/* any of the foregoing. You must include this permission and */
/* copyright notice in all copies and modified versions of this */
/* software, and include attribution to Taligent in all splash */
/* screens included in any application using this software. */
/* THIS SOFTWARE IS PROVIDED IN ITS 'AS IS' CONDITION. TALIGENT */
/* DISCLAIMS ANY LIABILITY OF ANY KIND FOR DAMAGES WHATSOEVER */
/* RESULTING FROM THE USE OF THIS SOFTWARE. */
/* ************************************************************* */
package com.ibm.demo.holiday;
import com.ibm.demo.*;
import java.awt.*;
/**
* Various graphical borders. The border itself is a Panel so that it can
* contain other Components (i.e. it borders something). You use the
* HolidayBorderPanel like any other Panel: you set the layout that you prefer and
* add Components to it. Beware that a null layout does not obey the insets
* of the panel so if you use null layouts, adjust your measurements to
* handle the border by calling insets().
*
* @author Andy Clark, Taligent Inc.
* @version 1.0
*/
public class HolidayBorderPanel extends Panel {
// Constants
/** Solid border. */
public final static int SOLID = 0;
/** A raised border. */
public final static int RAISED = 1;
/** A lowered border. */
public final static int LOWERED = 2;
/** An etched in border. */
public final static int IN = 3;
/** An etched out border. */
public final static int OUT = 4;
/** Left alignment. */
public final static int LEFT = 0;
/** Center alignment. */
public final static int CENTER = 1;
/** Right alignment. */
public final static int RIGHT = 2;
/** Default style (IN). */
public final static int DEFAULT_STYLE = IN;
/** Default thickness (10). */
public final static int DEFAULT_THICKNESS = 10;
/** Default thickness for solid borders (4). */
public final static int DEFAULT_SOLID_THICKNESS = 4;
/** Default thickness for raised borders (2). */
public final static int DEFAULT_RAISED_THICKNESS = 2;
/** Default thickness for lowered borders (2). */
public final static int DEFAULT_LOWERED_THICKNESS = 2;
/** Default thickness for etched-in borders (10). */
public final static int DEFAULT_IN_THICKNESS = 10;
/** Default thickness for etched-out borders (10). */
public final static int DEFAULT_OUT_THICKNESS = 10;
/** Default gap between border and contained component (5). */
public final static int DEFAULT_GAP = 5;
/** Default color (black). Applies to SOLID and etched borders. */
public final static Color DEFAULT_COLOR = Color.black;
/** Default font (TimesRoman,PLAIN,14). Only applies to etched borders. */
public final static Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14);
/** Default alignment (LEFT). Only applies to etched borders. */
public final static int DEFAULT_ALIGNMENT = LEFT;
// Data
private int style;
private int thickness;
private int gap;
private Color color;
private Font font;
private String text;
private int alignment;
/**
* Constructor. Makes default border.
*/
public HolidayBorderPanel() {
// initialize data
style = DEFAULT_STYLE;
thickness = DEFAULT_THICKNESS;
gap = DEFAULT_GAP;
color = DEFAULT_COLOR;
text = null;
font = DEFAULT_FONT;
alignment = DEFAULT_ALIGNMENT;
}
/**
* Constructor. Makes an etched IN border with given text caption.
*
* @param text Text caption
*/
public HolidayBorderPanel(String text) {
this();
style = IN;
this.text = text;
}
/**
* Constructor. Makes SOLID border with color and thickness given.
*
* @param color The color for the border.
* @param thickness The thickness of the border.
*/
public HolidayBorderPanel(Color color, int thickness) {
this();
style = SOLID;
this.color = color;
this.thickness = thickness;
}
/**
* Constructor. Makes a border of the given style with the default
* thickness for that style.
*
* @param style The style for this border.
*/
public HolidayBorderPanel(int style) {
this();
// set thickness appropriate to this style
int thickness;
switch (style) {
case SOLID: thickness = DEFAULT_SOLID_THICKNESS; break;
case RAISED: thickness = DEFAULT_RAISED_THICKNESS; break;
case LOWERED: thickness = DEFAULT_LOWERED_THICKNESS; break;
case IN: thickness = DEFAULT_IN_THICKNESS; break;
case OUT: thickness = DEFAULT_OUT_THICKNESS; break;
default:
thickness = DEFAULT_THICKNESS;
}
this.style = style;
this.thickness = thickness;
}
/**
* Constructor. Makes border with given style and thickness.
*
* @param style The style for this border.
* @param thickness The thickness for this border.
*/
public HolidayBorderPanel(int style, int thickness) {
this();
this.style = style;
this.thickness = thickness;
}
/**
* Returns the insets of this panel..
*/
public Insets insets() {
int adjustment = 0;
// adjust for text string
if (style == IN || style == OUT) {
if (text != null && text.length() > 0) {
try {
// set font and get info
int height = getGraphics().getFontMetrics(font).getHeight();
if (height > thickness)
adjustment = height - thickness;
}
catch (Exception e) {
// nothing: just in case there is no graphics context
// at the beginning.
}
}
}
// return appropriate insets
int dist = thickness + gap;
return new Insets(dist + adjustment, dist, dist, dist);
}
/**
* Sets the style of the border
*
* @param style The new style.
*/
public HolidayBorderPanel setStyle(int style) {
// set the style and re-layout the panel
this.style = style;
layout();
repaint();
return this;
}
/**
* Gets the style of the border
*/
public int getStyle() {
return style;
}
/**
* Sets the thickness of the border.
*
* @param thickness The new thickness
*/
public HolidayBorderPanel setThickness(int thickness) {
if (thickness > 0) {
this.thickness = thickness;
layout();
repaint();
}
return this;
}
/**
* Gets the thickness of the border.
*/
public int getThickness() {
return thickness;
}
/**
* Sets the gap between the border and the contained Component.
*
* @param gap The new gap, in pixels.
*/
public HolidayBorderPanel setGap(int gap) {
if (gap > -1) {
this.gap = gap;
layout();
repaint();
}
return this;
}
/**
* Gets the gap between the border and the contained Component.
*/
public int getGap() {
return gap;
}
/**
* Sets the current color for SOLID borders and the caption text
* color for etched borders.
*
* @param color The new color.
*/
public HolidayBorderPanel setColor(Color color) {
this.color = color;
if (style == SOLID || style == IN || style == OUT)
repaint();
return this;
}
/**
* Gets the current color for SOLID borders and the caption
* text color for etched borders.
*/
public Color getColor() {
return color;
}
/**
* Sets the font. Only applies to etched borders.
*/
public HolidayBorderPanel setTextFont(Font font) {
// set font
if (font != null) {
this.font = font;
if (style == IN || style == OUT) {
layout();
repaint();
}
}
return this;
}
/**
* Gets the font of the text. Only applies to etched borders.
*/
public Font getTextFont() {
return font;
}
/**
* Sets the text. Only applies to etched borders.
*
* @param text The new text.
*/
public HolidayBorderPanel setText(String text) {
this.text = text;
if (style == IN || style == OUT) {
layout();
repaint();
}
return this;
}
/**
* Gets the text. Only applies to etched borders.
*/
public String getText() {
return text;
}
/**
* Sets the text alignment. Only applies to etched borders.
*
* @param alignment The new alignment.
*/
public HolidayBorderPanel setAlignment(int alignment) {
this.alignment = alignment;
if (style == IN || style == OUT) {
layout();
repaint();
}
return this;
}
/**
* Gets the text alignment.
*/
public int getAlignment() {
return alignment;
}
/**
* Repaints the border.
*
* @param g The graphics context.
*/
public void paint(Graphics g) {
// get current dimensions
Dimension size = size();
int width = size.width;
int height = size.height;
// set colors
Color light = getBackground().brighter().brighter().brighter();
Color dark = getBackground().darker().darker().darker();
// Draw border
switch (style) {
case RAISED: // 3D Border (in or out)
case LOWERED:
Color topleft = null;
Color bottomright = null;
// set colors
if (style == RAISED) {
topleft = light;
bottomright = dark;
}
else {
topleft = dark;
bottomright = light;
}
// draw border
g.setColor(topleft);
for (int i = 0; i < thickness; i++) {
g.drawLine(i, i, width - i - 2, i);
g.drawLine(i, i + 1, i, height - i - 1);
}
g.setColor(bottomright);
for (int i = 0; i < thickness; i++) {
g.drawLine(i + 1, height - i - 1, width - i - 1, height - i - 1);
g.drawLine(width - i - 1, i, width - i - 1, height - i - 2);
}
break;
case IN: // Etched Border (in or out)
case OUT:
int adjust1 = 0;
int adjust2 = 0;
// set font and get info
Font oldfont = g.getFont();
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
int ascent = fm.getAscent();
// set adjustment
if (style == IN)
adjust1 = 1;
else
adjust2 = 1;
// Calculate adjustment for text
int adjustment = 0;
if (text != null && text.length() > 0) {
if (ascent > thickness)
adjustment = (ascent - thickness) / 2;
}
// The adjustment is there so that we always draw the
// light rectangle first. Otherwise, your eye picks up
// the discrepancy where the light rect. passes over
// the darker rect.
int x = thickness / 2;
int y = thickness / 2 + adjustment;
int w = width - thickness - 1;
int h = height - thickness - 1 - adjustment;
// draw rectangles
g.setColor(light);
g.drawRect(x + adjust1, y + adjust1, w, h);
g.setColor(dark);
g.drawRect(x + adjust2, y + adjust2, w, h);
// draw text, if applicable
if (text != null && text.length() > 0) {
// calculate drawing area
int fontheight = fm.getHeight();
int strwidth = fm.stringWidth(text);
int textwidth = width - 2 * (thickness + 5);
if (strwidth > textwidth)
strwidth = textwidth;
// calculate offset for alignment
int offset;
switch (alignment) {
case CENTER:
offset = (width - strwidth) / 2;
break;
case RIGHT:
offset = width - strwidth - thickness - 5;
break;
case LEFT:
default: // assume left alignment if invalid
offset = thickness + 5;
break;
}
// clear drawing area and set clipping region
g.clearRect(offset - 5, 0, strwidth + 10, fontheight);
g.clipRect(offset, 0, strwidth, fontheight);
// draw text
g.setColor(color);
g.drawString(text, offset, ascent);
// restore old clipping area
g.clipRect(0, 0, width, height);
}
g.setFont(oldfont);
break;
case SOLID:
default: // assume SOLID
g.setColor(color);
for (int i = 0; i < thickness; i++)
g.drawRect(i, i, width - 2 * i - 1, height - 2 * i - 1);
}
}
/**
* Returns the settings of this HolidayBorderPanel instance as a string.
*/
public String toString() {
StringBuffer str = new StringBuffer("HolidayBorderPanel[");
// style
str.append("style=");
switch (style) {
case SOLID: str.append("SOLID"); break;
case RAISED: str.append("RAISED"); break;
case LOWERED: str.append("LOWERED"); break;
case IN: str.append("IN"); break;
case OUT: str.append("OUT"); break;
default: str.append("unknown");
}
str.append(",");
// thickness
str.append("thickness=");
str.append(thickness);
str.append(",");
// gap
str.append("gap=");
str.append(gap);
str.append(",");
// color
str.append(color);
str.append(",");
// font
str.append(font);
str.append(",");
// text
str.append("text=");
str.append(text);
str.append(",");
// alignment
str.append("alignment=");
switch (alignment) {
case LEFT: str.append("LEFT"); break;
case CENTER: str.append("CENTER"); break;
case RIGHT: str.append("RIGHT"); break;
default: str.append("unknown");
}
str.append("]");
return str.toString();
}
}

View file

@ -0,0 +1,714 @@
/*
* $RCSfile: HolidayCalendarDemo.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
*/
package com.ibm.demo.holiday;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
/**
* CalendarDemo demonstrates how Calendar works.
*/
public class HolidayCalendarDemo extends DemoApplet
{
/**
* The main function which defines the behavior of the CalendarDemo
* applet when an applet is started.
*/
public static void main(String argv[]) {
new HolidayCalendarDemo().showDemo();
}
/* This creates a CalendarFrame for the demo applet. */
public Frame createDemoFrame(DemoApplet applet) {
return new CalendarFrame(applet);
}
/**
* 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.
*/
private static class CalendarFrame extends Frame
{
private static final String creditString = "";
private static final boolean DEBUG = false;
private Locale curLocale = Locale.US;
private DemoApplet applet;
private static final Locale[] calendars = {
//new Locale("de","AT"),
Locale.CANADA,
Locale.CANADA_FRENCH,
Locale.FRANCE,
Locale.GERMANY,
new Locale("iw","IL"),
new Locale("el","GR"),
//new Locale("es","MX"),
Locale.UK,
Locale.US,
};
private static final Locale[] displays = {
Locale.CANADA,
Locale.UK,
Locale.US,
Locale.FRANCE,
Locale.CANADA_FRENCH,
//new Locale("de","AT"),
Locale.GERMAN,
new Locale("el","GR"),
//new Locale("iw","IL"),
new Locale("es","MX"),
};
/**
* Constructs a new CalendarFrame that is initially invisible.
*/
public CalendarFrame(DemoApplet applet)
{
super("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()
{
// Get G7 locales only for demo purpose. To get all the locales
// supported, switch to calling Calendar.getAvailableLocales().
// commented
locales = displays;
buildGUI();
}
//------------------------------------------------------------
// 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
}
private Choice localeMenu;
private Choice displayMenu;
private Locale[] locales;
private Label monthLabel;
private Button prevYear;
private Button prevMonth;
private Button gotoToday;
private Button nextMonth;
private Button nextYear;
private CalendarPanel calendarPanel;
private static final Locale kFirstLocale = Locale.US;
private static void add(Container container, Component component,
GridBagLayout g, GridBagConstraints c)
{
g.setConstraints(component, c);
container.add(component);
}
public void buildGUI()
{
setBackground(DemoUtility.bgColor);
setLayout(new BorderLayout(10,10));
// Label for the demo's title
Label titleLabel = new Label("Calendar Demo", Label.CENTER);
titleLabel.setFont(DemoUtility.titleFont);
// Label for the current month name
monthLabel = new Label("", Label.LEFT);
monthLabel.setFont(new Font(DemoUtility.titleFont.getName(),
DemoUtility.titleFont.getStyle(),
(DemoUtility.titleFont.getSize() * 3)/2));
// Make the locale popup menus
localeMenu= new Choice();
int selectMe = 0;
for (int i = 0; i < calendars.length; i++) {
if (i > 0 &&
calendars[i].getCountry().equals(calendars[i-1].getCountry()) ||
i < calendars.length - 1 &&
calendars[i].getCountry().equals(calendars[i+1].getCountry()))
{
localeMenu.addItem(calendars[i].getDisplayCountry() + " (" +
calendars[i].getDisplayLanguage() + ")");
} else {
localeMenu.addItem( calendars[i].getDisplayCountry() );
}
if (calendars[i].equals(kFirstLocale)) {
selectMe = i;
}
}
localeMenu.setBackground(DemoUtility.choiceColor);
localeMenu.select(selectMe);
displayMenu = new Choice();
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());
}
}
displayMenu.setBackground(DemoUtility.choiceColor);
displayMenu.select(kFirstLocale.getDisplayName());
// Make all the next/previous/today buttons
prevYear = new Button("<<");
prevMonth = new Button("<");
gotoToday = new Button("Today");
nextMonth = new Button(">");
nextYear = new Button(">>");
// The month name and the control buttons are bunched together
Panel monthPanel = new Panel();
{
GridBagLayout g = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
monthPanel.setLayout(g);
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = GridBagConstraints.REMAINDER;
add(monthPanel, monthLabel, g, c);
c.gridwidth = 1;
add(monthPanel, prevYear, g, c);
add(monthPanel, prevMonth, g, c);
add(monthPanel, gotoToday, g, c);
add(monthPanel, nextMonth, g, c);
c.gridwidth = GridBagConstraints.REMAINDER;
add(monthPanel, nextYear, g, c);
}
// Stick the menu and buttons in a little "control panel"
Panel menuPanel = new Panel();
{
GridBagLayout g = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
menuPanel.setLayout(g);
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = GridBagConstraints.RELATIVE;
Label l1 = new Label("Holidays");
l1.setFont(DemoUtility.labelFont);
add(menuPanel, l1, g, c);
c.gridwidth = GridBagConstraints.REMAINDER;
add(menuPanel, localeMenu, g, c);
c.gridwidth = GridBagConstraints.RELATIVE;
Label l2 = new Label("Display:");
l2.setFont(DemoUtility.labelFont);
add(menuPanel, l2, g, c);
c.gridwidth = GridBagConstraints.REMAINDER;
add(menuPanel, displayMenu, g, c);
}
// The title, buttons, etc. go in a panel at the top of the window
Panel topPanel = new Panel();
{
topPanel.setLayout(new BorderLayout());
//topPanel.add("North", titleLabel);
topPanel.add("Center", monthPanel);
topPanel.add("East", menuPanel);
}
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( kFirstLocale );
add("Center", calendarPanel);
updateMonthName();
}
/**
* Called if an action occurs in the CalendarFrame object.
*/
public boolean action(Event evt, Object obj)
{
// *** Button events are handled here.
boolean handled = false;
if (evt.target instanceof Button) {
if (evt.target == nextMonth) {
calendarPanel.add(Calendar.MONTH, +1);
handled = true;
}
else
if (evt.target == prevMonth) {
calendarPanel.add(Calendar.MONTH, -1);
handled = true;
}
else
if (evt.target == prevYear) {
calendarPanel.add(Calendar.YEAR, -1);
handled = true;
}
else
if (evt.target == nextYear) {
calendarPanel.add(Calendar.YEAR, +1);
handled = true;
}
else
if (evt.target == gotoToday) {
calendarPanel.set( new Date() );
handled = true;
}
if (handled) {
updateMonthName();
}
}
return handled || super.action(evt, obj);
}
private void updateMonthName()
{
SimpleDateFormat f = new SimpleDateFormat("MMMM yyyyy",
calendarPanel.getDisplayLocale());
f.setCalendar(calendarPanel.getCalendar());
f.setTimeZone(new SimpleTimeZone(0, "UTC")); // JDK 1.1.2 workaround
monthLabel.setText( f.format( calendarPanel.firstOfMonth() ));
}
/**
* 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.
*/
public boolean handleEvent(Event evt)
{
if (evt.id == Event.ACTION_EVENT && evt.target == localeMenu) {
calendarPanel.setCalendarLocale(calendars[localeMenu.getSelectedIndex()]);
updateMonthName();
return true;
}
if (evt.id == Event.ACTION_EVENT && evt.target == displayMenu) {
calendarPanel.setDisplayLocale(locales[displayMenu.getSelectedIndex()]);
updateMonthName();
return true;
}
else
if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else {
System.exit(0);
}
return true;
}
return super.handleEvent(evt);
}
/**
* Print out the error message while debugging this program.
*/
public void errorText(String s)
{
if (DEBUG)
{
System.out.println(s);
}
}
}
private static class CalendarPanel extends Canvas {
public CalendarPanel( Locale locale ) {
set(locale, locale, new Date());
}
public void setCalendarLocale(Locale locale) {
set(locale, fDisplayLocale, fCalendar.getTime());
}
public void setDisplayLocale(Locale locale) {
set(fCalendarLocale, locale, fCalendar.getTime());
}
public void set(Date date) {
set(fCalendarLocale, fDisplayLocale, date);
}
public void set(Locale loc, Locale display, Date date)
{
if (fCalendarLocale == null || !loc.equals(fCalendarLocale)) {
fCalendarLocale = loc;
fCalendar = Calendar.getInstance(fCalendarLocale);
fAllHolidays = Holiday.getHolidays(fCalendarLocale);
}
if (fDisplayLocale == null || !display.equals(fDisplayLocale)) {
fDisplayLocale = display;
fSymbols = new DateFormatSymbols(fDisplayLocale);
}
fStartOfMonth = date;
dirty = true;
repaint();
}
public void add(int field, int delta)
{
synchronized(fCalendar) {
fCalendar.setTime(fStartOfMonth);
fCalendar.add(field, delta);
fStartOfMonth = fCalendar.getTime();
}
dirty = true;
repaint();
}
public Calendar getCalendar() {
return fCalendar;
}
public Locale getCalendarLocale() {
return fCalendarLocale;
}
public Locale getDisplayLocale() {
return fDisplayLocale;
}
public Date firstOfMonth() {
return fStartOfMonth;
}
private Date startOfMonth(Date dateInMonth)
{
synchronized(fCalendar) {
fCalendar.setTime(dateInMonth); // TODO: synchronization
int era = fCalendar.get(Calendar.ERA);
int year = fCalendar.get(Calendar.YEAR);
int month = fCalendar.get(Calendar.MONTH);
fCalendar.clear();
fCalendar.set(Calendar.ERA, era);
fCalendar.set(Calendar.YEAR, year);
fCalendar.set(Calendar.MONTH, month);
fCalendar.set(Calendar.DATE, 1);
return fCalendar.getTime();
}
}
private void calculate()
{
//
// As a workaround for JDK 1.1.3 and below, where Calendars and time
// zones are a bit goofy, always set my calendar's time zone to UTC.
// You would think I would want to do this in the "set" function above,
// but if I do that, the program hangs when this class is loaded,
// perhaps due to some sort of static initialization ordering problem.
// So I do it here instead.
//
fCalendar.setTimeZone(new SimpleTimeZone(0, "UTC"));
Calendar c = (Calendar)fCalendar.clone(); // Temporary copy
fStartOfMonth = startOfMonth(fStartOfMonth);
// Stash away a few useful constants for this calendar and display
minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
// Stash away a Date for the start of this month
// Find the day of week of the first day in this month
c.setTime(fStartOfMonth);
firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
// Now find the # of days in the month
c.roll(Calendar.DATE, false);
daysInMonth = c.get(Calendar.DATE);
// Finally, find the end of the month, i.e. the start of the next one
c.roll(Calendar.DATE, true);
c.add(Calendar.MONTH, 1);
c.getTime(); // JDK 1.1.2 bug workaround
c.add(Calendar.SECOND, -1);
Date endOfMonth = c.getTime();
//
// Calculate the number of full or partial weeks in this month.
// To do this I can just reuse the code that calculates which
// calendar cell contains a given date.
//
numWeeks = dateToCell(daysInMonth).y - dateToCell(1).y + 1;
// Remember which holidays fall on which days in this month,
// to save the trouble of having to do it later
fHolidays.setSize(0);
for (int h = 0; h < fAllHolidays.length; h++)
{
Date d = fStartOfMonth;
while ( (d = fAllHolidays[h].firstBetween(d, endOfMonth) ) != null)
{
c.setTime(d);
fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE),
fAllHolidays[h],
fAllHolidays[h].getDisplayName(fDisplayLocale) ));
d.setTime( d.getTime() + 1000 ); // "d++"
}
}
dirty = false;
}
static final int INSET = 2;
/*
* Convert from the day number within a month (1-based)
* to the cell coordinates on the calendar (0-based)
*/
private void dateToCell(int date, Point pos)
{
int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
if (firstDayInMonth < firstDayOfWeek) {
cell += daysInWeek;
}
pos.x = cell % daysInWeek;
pos.y = cell / daysInWeek;
}
private Point dateToCell(int date) {
Point p = new Point(0,0);
dateToCell(date, p);
return p;
}
public void paint(Graphics g) {
if (dirty) {
calculate();
}
Point cellPos = new Point(0,0); // Temporary variable
Dimension d = this.size();
g.setColor(DemoUtility.bgColor);
g.fillRect(0,0,d.width,d.height);
// Draw the day names at the top
g.setColor(Color.black);
g.setFont(DemoUtility.labelFont);
FontMetrics fm = g.getFontMetrics();
int labelHeight = fm.getHeight() + INSET * 2;
int v = fm.getAscent() + INSET;
for (int i = 0; i < daysInWeek; i++) {
int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
String dayName = fSymbols.getWeekdays()[dayNum];
int h = (int) (d.width * (i + 0.5)) / daysInWeek;
h -= fm.stringWidth(dayName) / 2;
g.drawString(dayName, h, v);
}
double cellHeight = (d.height - labelHeight - 1) / numWeeks;
double cellWidth = (double)(d.width - 1) / daysInWeek;
// Draw a white background in the part of the calendar
// that displays this month.
// First figure out how much of the first week should be shaded.
{
g.setColor(Color.white);
dateToCell(1, cellPos);
int width = (int)(cellPos.x*cellWidth); // Width of unshaded area
g.fillRect((int)(width), labelHeight ,
(int)(d.width - width), (int)cellHeight);
// All of the intermediate weeks get shaded completely
g.fillRect(0, (int)(labelHeight + cellHeight),
d.width, (int)(cellHeight * (numWeeks - 2)));
// Now figure out the last week.
dateToCell(daysInMonth, cellPos);
width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area
g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
width, (int)(cellHeight));
}
// Draw the X/Y grid lines
g.setColor(Color.black);
for (int i = 0; i <= numWeeks; i++) {
int y = (int)(labelHeight + i * cellHeight);
g.drawLine(0, y, d.width - 1, y);
}
for (int i = 0; i <= daysInWeek; i++) {
int x = (int)(i * cellWidth);
g.drawLine(x, labelHeight, x, d.height - 1);
}
// Now loop through all of the days in the month, figure out where
// they go in the grid, and draw the day # for each one
Font numberFont = new Font("Helvetica",Font.PLAIN,12);
Font holidayFont = DemoUtility.creditFont;
Calendar c = (Calendar)fCalendar.clone();
c.setTime(fStartOfMonth);
for (int i = 1, h = 0; i <= daysInMonth; i++) {
g.setFont(numberFont);
g.setColor(Color.black);
fm = g.getFontMetrics();
dateToCell(i, cellPos);
int x = (int)((cellPos.x + 1) * cellWidth);
int y = (int)(cellPos.y * cellHeight + labelHeight);
StringBuffer buffer = new StringBuffer();
buffer.append(i);
String dayNum = buffer.toString();
x = x - INSET - fm.stringWidth(dayNum);
y = y + fm.getAscent() + INSET;
g.drawString(dayNum, x, y);
// See if any of the holidays land on this day....
HolidayInfo info = null;
int count = 0;
// Coordinates of lower-left corner of cell.
x = (int)((cellPos.x) * cellWidth);
y = (int)((cellPos.y+1) * cellHeight) + labelHeight;
while (h < fHolidays.size() &&
(info = (HolidayInfo)fHolidays.elementAt(h)).date <= i)
{
if (info.date == i) {
// Draw the holiday here.
g.setFont(numberFont);
g.setColor(Color.red);
DemoTextBox box = new DemoTextBox(g, info.name, (int)(cellWidth - INSET));
box.draw(g, x + INSET, y - INSET - box.getHeight());
y -= (box.getHeight() + INSET);
count++;
}
h++;
}
}
}
// Important state variables
private Locale fCalendarLocale; // Whose calendar
private Calendar fCalendar; // Calendar for calculations
private Locale fDisplayLocale; // How to display it
private DateFormatSymbols fSymbols; // Symbols for drawing
private Date fStartOfMonth; // 00:00:00 on first day of month
// Cached calculations to make drawing faster.
private transient int minDay; // Minimum legal day #
private transient int daysInWeek; // # of days in a week
private transient int firstDayOfWeek; // First day to display in week
private transient int numWeeks; // # full or partial weeks in month
private transient int daysInMonth; // # days in this month
private transient int firstDayInMonth; // Day of week of first day in month
private transient Holiday[] fAllHolidays;
private transient Vector fHolidays = new Vector(5,5);
private transient boolean dirty = true;
}
private static class HolidayInfo {
public HolidayInfo(int date, Holiday holiday, String name) {
this.date = date;
this.holiday = holiday;
this.name = name;
}
public Holiday holiday;
public int date;
public String name;
}
}

View file

@ -0,0 +1,105 @@
/*
* (C) IBM Corp. 1997-1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.text.resources;
import java.util.ListResourceBundle;
/**
* This resource bundle is included for testing and demonstration purposes only.
* It applies the dictionary-based algorithm to English text that has had all the
* spaces removed. Once we have good test cases for Thai, we will replace this
* with good resource data (and a good dictionary file) for Thai
*/
public class BreakIteratorRules_en_US_TEST extends ListResourceBundle {
public Object[][] getContents() {
return contents;
}
static final Object[][] contents = {
// names of classes to instantiate for the different kinds of break
// iterator. Notice we're now using DictionaryBasedBreakIterator
// for word and line breaking.
{ "BreakIteratorClasses",
new String[] { "RuleBasedBreakIterator", // character-break iterator class
"DictionaryBasedBreakIterator", // word-break iterator class
"DictionaryBasedBreakIterator", // line-break iterator class
"RuleBasedBreakIterator" } // sentence-break iterator class
},
// These are the same word-breaking rules as are specified in the default
// resource, except that the Latin letters, apostrophe, and hyphen are
// specified as dictionary characters
{ "WordBreakRules",
"<ignore>=[:Mn::Me::Cf:];"
+ "<dictionary>=[a-zA-z\\'\\-];"
+ "<kanji>=[\u3005\u4e00-\u9fa5\uf900-\ufa2d];"
+ "<kata>=[\u30a1-\u30fa];"
+ "<hira>=[\u3041-\u3094];"
+ "<cjk-diacrit>=[\u3099-\u309c];"
+ "<let>=[:L:^[<kanji><kata><hira><cjk-diacrit><dictionary>]];"
+ "<dgt>=[:N:];"
+ "<mid-word>=[:Pd:\u00ad\u2027\\\"\\\'\\.];"
+ "<mid-num>=[\\\"\\\'\\,\u066b\\.];"
+ "<pre-num>=[:Sc:\\#\\.^\u00a2];"
+ "<post-num>=[\\%\\&\u00a2\u066a\u2030\u2031];"
+ "<ls>=[\n\u000c\u2028\u2029];"
+ "<ws>=[:Zs:\t];"
+ "<word>=(<let><let>*(<mid-word><let><let>*)*|[a-zA-Z][a-z\\'\\-]*);"
+ "<number>=(<dgt><dgt>*(<mid-num><dgt><dgt>*)*);"
+ ".;"
+ "{<word>}(<number><word>)*{<number>{<post-num>}};"
+ "<pre-num>(<number><word>)*{<number>{<post-num>}};"
+ "<ws>*{\r}{<ls>};"
+ "[<kata><cjk-diacrit>]*;"
+ "[<hira><cjk-diacrit>]*;"
+ "<kanji>*;" },
// These are the same line-breaking rules as are specified in the default
// resource, except that the Latin letters, apostrophe, and hyphen are
// specified as dictionary characters
{ "LineBreakRules",
"<ignore>=[:Mn::Me::Cf:];"
+ "<dictionary>=[a-zA-z\\'\\-];"
+ "<break>=[\u0003\t\n\f\u2028\u2029];"
+ "<nbsp>=[\u00a0\u2007\u2011\ufeff];"
+ "<space>=[:Zs::Cc:^[<nbsp><break>\r]];"
+ "<dash>=[:Pd:\u00ad^<nbsp>];"
+ "<pre-word>=[:Sc::Ps:^\u00a2];"
+ "<post-word>=[:Pe:\\!\\%\\.\\,\\:\\;\\?\u00a2\u00b0\u066a\u2030-\u2034\u2103"
+ "\u2105\u2109\u3001\u3002\u3005\u3041\u3043\u3045\u3047\u3049\u3063"
+ "\u3083\u3085\u3087\u308e\u3099-\u309e\u30a1\u30a3\u30a5\u30a7\u30a9"
+ "\u30c3\u30e3\u30e5\u30e7\u30ee\u30f5\u30f6\u30fc-\u30fe\uff01\uff0e"
+ "\uff1f];"
+ "<kanji>=[\u4e00-\u9fa5\uf900-\ufa2d\u3041-\u3094\u30a1-\u30fa^[<post-word><ignore>]];"
+ "<digit>=[:Nd::No:];"
+ "<mid-num>=[\\.\\,];"
+ "<char>=[^[<break><space><dash><kanji><nbsp><ignore><dictionary>\r]];"
+ "<number>=([<pre-word><dash>]*<digit><digit>*(<mid-num><digit><digit>*)*);"
+ "<word-core>=(<char>*|<kanji>|<number>|[a-zA-Z][a-z\\'\\-]*);"
+ "<word-suffix>=((<dash><dash>*|<post-word>*)<space>*);"
+ "<word>=(<pre-word>*<word-core><word-suffix>);"
+ "<word>(<nbsp><nbsp>*<word>)*{\r}{<break>};" },
// these two resources specify the pathnames of the dictionary files to
// use for word breaking and line breaking. Both currently refer to
// a file called english.dict placed in com\ibm\text\resources
// somewhere in the class path. It's important to note that
// english.dict was created for testing purposes only, and doesn't
// come anywhere close to being an exhaustive dictionary of English
// words (basically, it contains all the words in the Declaration of
// Independence, and the Revised Standard Version of the book of Genesis,
// plus a few other words thrown in to show more interesting cases).
{ "WordBreakDictionary", "com\\ibm\\text\\resources\\english.dict" },
{ "LineBreakDictionary", "com\\ibm\\text\\resources\\english.dict" }
};
}

View file

@ -0,0 +1,475 @@
/*
* $RCSfile: DBBIDemo.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo.RuleBasedBreakIterator;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.BorderFactory;
import java.util.*;
import com.ibm.text.BreakIterator;
public class DBBIDemo extends DemoApplet
{
public static void main(String argv[]) {
Locale.setDefault(new Locale("en", "US", "TEST"));
new DBBIDemo().showDemo();
}
public Frame createDemoFrame(DemoApplet applet) {
return new DBBIFrame(applet);
}
}
class DBBIFrame extends Frame
{
private static final String creditString =
"v1.1a9, Demo";
private static final int FIELD_COLUMNS = 45;
private static final Font choiceFont = null;
private static final boolean DEBUG = false;
private DemoApplet applet;
final String right = "-->";
final String left = "<--";
private BreakIterator enum;
JTextArea text;
// TextArea text;
Choice bound;
public DBBIFrame(DemoApplet applet)
{
this.applet = applet;
init();
start();
}
public void run()
{
/*
while (true) {
try {
checkChange();
Thread.sleep(250);
}
catch (InterruptedException e) {
}
catch (Exception e) {
}
catch (Throwable e) {
}
}
*/
}
int s, e;
int ts, te;
public void checkChange()
{
// System.out.println("checkChange...");
if ((text.getSelectionStart() & 0x7FFF) != ts ||
(text.getSelectionEnd() & 0x7FFF) != te) {
int tempS = text.getSelectionStart() & 0x7FFF;
int tempE = text.getSelectionEnd() & 0x7FFF;
// System.out.println(">");
// select(0, 0);
// select(tempS, tempE);
//select(tempS - (ts - s), tempE - (te - e));
// System.out.println("<");
// if (s != ts || e != te) System.out.println(" s("+s+") ts("+ts+") e("+e+") te("+te+")");
// if (tempS != ts || tempE != te) System.out.println(">s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// select(s - (ts - s), e - (te - e));
// if (tempS != ts || tempE != te) System.out.println("s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// System.out.println("lkdslksj");
}
}
public void select(int sIn, int eIn)
{
s = sIn;
e = eIn;
text.select(s, e);
ts = text.getSelectionStart() & 0x7FFF;
te = text.getSelectionEnd() & 0x7FFF;
// if (s != ts || e != te) {
// System.out.println(">s("+s+") ts("+ts+") e("+e+") te("+te+")");
// System.out.println(" "+(ts-s)+","+(te-e));
// }
}
public int getSelectionStart()
{
checkChange();
// return s;
return text.getSelectionStart() & 0x7FFF;
}
public int getSelectionEnd()
{
checkChange();
// return e;
return text.getSelectionEnd() & 0x7FFF;
}
public final synchronized void selectRange(int s, int e)
{
try {
//if (getSelectionStart() != s || getSelectionEnd() != e) {
//text.select(s, e);
select(s,e);
//}
// if (getSelectionStart() != s || getSelectionEnd() != e) {
// System.out.println("AGH! select("+s+","+e+") -> ("+
// getSelectionStart()+","+getSelectionEnd()+")");
// text.select(s - (getSelectionStart() - s), e - (getSelectionEnd() - e));
// }
} catch (Exception exp) {
errorText(exp.toString());
}
}
public void init()
{
buildGUI();
}
public void start()
{
}
void addWithFont(Container container, Component foo, Font font) {
if (font != null)
foo.setFont(font);
container.add(foo);
}
public void buildGUI()
{
setBackground(DemoUtility.bgColor);
setLayout(new BorderLayout());
Panel topPanel = new Panel();
Label titleLabel =
new Label("Text Boundary Demo", Label.CENTER);
titleLabel.setFont(DemoUtility.titleFont);
topPanel.add(titleLabel);
//Label demo=new Label(creditString, Label.CENTER);
//demo.setFont(DemoUtility.creditFont);
//topPanel.add(demo);
Panel choicePanel = new Panel();
Label demo1=new Label("Boundaries", Label.LEFT);
demo1.setFont(DemoUtility.labelFont);
choicePanel.add(demo1);
bound = new Choice();
bound.setBackground(DemoUtility.choiceColor);
bound.addItem("Sentence");
bound.addItem("Line Break");
bound.addItem("Word");
bound.addItem("Char");
if (choiceFont != null)
bound.setFont(choiceFont);
choicePanel.add(bound);
topPanel.add(choicePanel);
DemoUtility.fixGrid(topPanel,1);
add("North", topPanel);
int ROWS = 15;
int COLUMNS = 50;
// text = new TextArea(getInitialText(), ROWS, COLUMNS);
text = new JTextArea(getInitialText(), ROWS, COLUMNS);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setEditable(true);
text.selectAll();
text.setFont(DemoUtility.editFont);
text.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
add("Center", new JScrollPane(text, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
Panel copyrightPanel = new Panel();
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright1, Label.LEFT),DemoUtility.creditFont);
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright2, Label.LEFT),DemoUtility.creditFont);
DemoUtility.fixGrid(copyrightPanel,1);
add("South", copyrightPanel);
//layout();
handleEnumChanged();
// (new Thread(this)).start();
}
public String getInitialText()
{
return
"When,inthecourseofhumanevents,itbecomesnecessaryforonepeopletodissolvethepoliticalbondswhichhave"
+ "connectedthemwithanother,andtoassumeamongthepowersoftheearth,theseparateandequalstationtowhichthelaws"
+ "ofnatureandofnature'sGodentitlethem,adecentrespecttotheopinionsofmankindrequiresthattheyshoulddeclarethe"
+ "causeswhichimpelthemtotheseparation.\n"
+ "Weholdthesetruthstobeself-evident,thatallmenarecreatedequal,thattheyareendowedbytheirCreatorwithcertain"
+ "unalienablerights,thatamongthesearelife,libertyandthepursuitofhappiness.Thattosecuretheserights,governmentsare"
+ "institutedamongmen,derivingtheirjustpowersfromtheconsentofthegoverned.Thatwheneveranyformofgovernment"
+ "becomesdestructivetotheseends,itistherightofthepeopletoalterortoabolishit,andtoinstitutenewgovernment,laying"
+ "itsfoundationonsuchprinciplesandorganizingitspowersinsuchform,astothemshallseemmostlikelytoeffecttheirsafety"
+ "andhappiness.Prudence,indeed,willdictatethatgovernmentslongestablishedshouldnotbechangedforlightandtransient"
+ "causes;andaccordinglyallexperiencehathshownthatmankindaremoredisposedtosuffer,whileevilsaresufferable,than"
+ "torightthemselvesbyabolishingtheformstowhichtheyareaccustomed.Butwhenalongtrainofabusesandusurpations,"
+ "pursuinginvariablythesameobjectevincesadesigntoreducethemunderabsolutedespotism,itistheirright,itistheirduty,"
+ "tothrowoffsuchgovernment,andtoprovidenewguardsfortheirfuturesecurity.--Suchhasbeenthepatientsufferanceof"
+ "thesecolonies;andsuchisnowthenecessitywhichconstrainsthemtoaltertheirformersystemsofgovernment.Thehistory"
+ "ofthepresentKingofGreatBritainisahistoryofrepeatedinjuriesandusurpations,allhavingindirectobjectthe"
+ "establishmentofanabsolutetyrannyoverthesestates.Toprovethis,letfactsbesubmittedtoacandidworld.\n"
+ "Hehasrefusedhisassenttolaws,themostwholesomeandnecessaryforthepublicgood.\n"
+ "Hehasforbiddenhisgovernorstopasslawsofimmediateandpressingimportance,unlesssuspendedintheiroperationtill"
+ "hisassentshouldbeobtained;andwhensosuspended,hehasutterlyneglectedtoattendtothem.\n"
+ "Hehasrefusedtopassotherlawsfortheaccommodationoflargedistrictsofpeople,unlessthosepeoplewouldrelinquish"
+ "therightofrepresentationinthelegislature,arightinestimabletothemandformidabletotyrantsonly.\n"
+ "Hehascalledtogetherlegislativebodiesatplacesunusual,uncomfortable,anddistantfromthedepositoryoftheirpublic"
+ "records,forthesolepurposeoffatiguingthemintocompliancewithhismeasures.\n"
+ "Hehasdissolvedrepresentativehousesrepeatedly,foropposingwithmanlyfirmnesshisinvasionsontherightsofthepeople.\n"
+ "Hehasrefusedforalongtime,aftersuchdissolutions,tocauseotherstobeelected;wherebythelegislativepowers,"
+ "incapableofannihilation,havereturnedtothepeopleatlargefortheirexercise;thestateremaininginthemeantimeexposed"
+ "toallthedangersofinvasionfromwithout,andconvulsionswithin.\n"
+ "Hehasendeavoredtopreventthepopulationofthesestates;forthatpurposeobstructingthelawsfornaturalizationof"
+ "foreigners;refusingtopassotherstoencouragetheirmigrationhither,andraisingtheconditionsofnewappropriationsof"
+ "lands.\n"
+ "Hehasobstructedtheadministrationofjustice,byrefusinghisassenttolawsforestablishingjudiciarypowers.\n"
+ "Hehasmadejudgesdependentonhiswillalone,forthetenureoftheiroffices,andtheamountandpaymentoftheirsalaries.\n"
+ "Hehaserectedamultitudeofnewoffices,andsenthitherswarmsofofficerstoharassourpeople,andeatouttheir"
+ "substance.\n"
+ "Hehaskeptamongus,intimesofpeace,standingarmieswithouttheconsentofourlegislature.\n"
+ "Hehasaffectedtorenderthemilitaryindependentofandsuperiortocivilpower.\n"
+ "Hehascombinedwithotherstosubjectustoajurisdictionforeigntoourconstitution,andunacknowledgedbyourlaws;"
+ "givinghisassenttotheiractsofpretendedlegislation:\n"
+ "Forquarteringlargebodiesofarmedtroopsamongus:\n"
+ "Forprotectingthem,bymocktrial,frompunishmentforanymurderswhichtheyshouldcommitontheinhabitantsofthese"
+ "states:\n"
+ "Forcuttingoffourtradewithallpartsoftheworld:\n"
+ "Forimposingtaxesonuswithoutourconsent:\n"
+ "Fordeprivingusinmanycases,ofthebenefitsoftrialbyjury:\n"
+ "Fortransportingusbeyondseastobetriedforpretendedoffenses:\n"
+ "ForabolishingthefreesystemofEnglishlawsinaneighboringprovince,establishingthereinanarbitrarygovernment,and"
+ "enlargingitsboundariessoastorenderitatonceanexampleandfitinstrumentforintroducingthesameabsoluteruleinthese"
+ "colonies:\n"
+ "Fortakingawayourcharters,abolishingourmostvaluablelaws,andalteringfundamentallytheformsofourgovernments:\n"
+ "Forsuspendingourownlegislatures,anddeclaringthemselvesinvestedwithpowertolegislateforusinallcaseswhatsoever.\n"
+ "Hehasabdicatedgovernmenthere,bydeclaringusoutofhisprotectionandwagingwaragainstus.\n"
+ "Hehasplunderedourseas,ravagedourcoasts,burnedourtowns,anddestroyedthelivesofourpeople.\n"
+ "Heisatthistimetransportinglargearmiesofforeignmercenariestocompletetheworksofdeath,desolationandtyranny,"
+ "alreadybegunwithcircumstancesofcrueltyandperfidyscarcelyparalleledinthemostbarbarousages,andtotalyunworth"
+ "theheadofacivilizednation.\n"
+ "Hehasconstrainedourfellowcitizenstakencaptiveonthehighseastobeararmsagainsttheircountry,tobecomethe"
+ "executionersoftheirfriendsandbrethren,ortofallthemselvesbytheirhands.\n"
+ "Hehasexciteddomesticinsurrectionsamongstus,andhasendeavoredtobringontheinhabitantsofourfrontiers,the"
+ "mercilessIndiansavages,whoseknownruleofwarfare,isundistinguisheddestructionofallages,sexesandconditions.\n"
+ "Ineverystageoftheseoppressionswehavepetitionedforredressinthemosthumbleterms:ourrepeatedpetitionshave"
+ "beenansweredonlybyrepeatedinjury.Aprince,whosecharacteristhusmarkedbyeveryactwhichmaydefineatyrant,is"
+ "unfittobetherulerofafreepeople.\n"
+ "NorhavewebeenwantinginattentiontoourBritishbrethren.Wehavewarnedthemfromtimetotimeofattemptsbytheir"
+ "legislaturetoextendanunwarrantablejurisdictionoverus.Wehaveremindedthemofthecircumstancesofouremigration"
+ "andsettlementhere.Wehaveappealedtotheirnativejusticeandmagnanimity,andwehaveconjuredthembythetiesofour"
+ "commonkindredtodisavowtheseusurpations,which,wouldinevitablyinterruptourconnectionsandcorrespondence.We"
+ "must,therefore,acquiesceinthenecessity,whichdenouncesourseparation,andholdthem,asweholdtherestofmankind,"
+ "enemiesinwar,inpeacefriends.\n"
+ "We,therefore,therepresentativesoftheUnitedStatesofAmerica,inGeneralCongress,assembled,appealingtothe"
+ "SupremeJudgeoftheworldfortherectitudeofourintentions,do,inthename,andbytheauthorityofthegoodpeopleof"
+ "thesecolonies,solemnlypublishanddeclare,thattheseunitedcoloniesare,andofrightoughttobefreeandindependent"
+ "states;thattheyareabsolvedfromallallegiancetotheBritishCrown,andthatallpoliticalconnectionbetweenthemandthe"
+ "stateofGreatBritain,isandoughttobetotallydissolved;andthatasfreeandindependentstates,theyhavefullpowerto"
+ "leveywar,concludepeace,contractalliances,establishcommerce,andtodoallotheractsandthingswhichindependent"
+ "statesmayofrightdo.Andforthesupportofthisdeclaration,withafirmrelianceontheprotectionofDivineProvidence,we"
+ "mutuallypledgetoeachotherourlives,ourfortunesandoursacredhonor.\n";
}
public void handleEnumChanged()
{
String s = bound.getSelectedItem();
if (s.equals("Char")) {
errorText("getCharacterInstance");
enum = BreakIterator.getCharacterInstance();
}
else if (s.equals("Word")) {
errorText("tWordBreak");
enum = BreakIterator.getWordInstance();
}
else if (s.equals("Line Break")) {
errorText("getLineInstance");
enum = BreakIterator.getLineInstance();
}
else /* if (s.equals("Sentence")) */ {
errorText("getSentenceInstance");
enum = BreakIterator.getSentenceInstance();
}
enum.setText(text.getText());
selectRange(0, 0);
//text.select(0,0);
}
public void handleForward()
{
try {
// System.out.println("entering handleForward");
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
// System.out.println("handleForward: oldStart=" + oldStart + ", oldEnd=" + oldEnd);
if (oldEnd < 1) {
selectRange(0, enum.following(0));
}
else {
int s = enum.following(oldEnd-1);
int e = enum.next();
if (e == -1) {
e = s;
}
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" +
s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public void handleBackward()
{
try {
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
if (oldStart < 1) {
selectRange(0, 0);
}
else {
int e = enum.following(oldStart-1);
int s = enum.previous();
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" + s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public boolean action(Event evt, Object obj)
{
if(evt.target instanceof Button && left.equals(obj))
{
handleBackward();
return true;
}
else if(evt.target instanceof Button && right.equals(obj))
{
handleForward();
return true;
}
else if(evt.target instanceof Choice)
{
handleEnumChanged();
return true;
}
return false;
}
public boolean handleEvent(Event evt)
{
if (evt.id == Event.KEY_PRESS || evt.id == Event.KEY_ACTION) {
if (evt.key == Event.RIGHT || (evt.key == 0x0E && evt.controlDown())) {
handleForward();
return true;
}
else if (evt.key == Event.LEFT || (evt.key == 0x10 && evt.controlDown())) {
handleBackward();
return true;
}
}
else
if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else System.exit(0);
return true;
}
return super.handleEvent(evt);
}
public void errorText(String s)
{
if (DEBUG)
System.out.println(s);
}
}

View file

@ -0,0 +1,441 @@
/*
* $RCSfile: TextBoundDemo.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo.RuleBasedBreakIterator;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.BorderFactory;
import java.util.*;
import com.ibm.text.BreakIterator;
public class TextBoundDemo extends DemoApplet
{
public static void main(String argv[]) {
new TextBoundDemo().showDemo();
}
public Frame createDemoFrame(DemoApplet applet) {
return new TextBoundFrame(applet);
}
}
class TextBoundFrame extends Frame
{
private static final String creditString =
"v1.1a9, Demo";
private static final int FIELD_COLUMNS = 45;
private static final Font choiceFont = null;
private static final boolean DEBUG = false;
private DemoApplet applet;
final String right = "-->";
final String left = "<--";
private BreakIterator enum;
JTextArea text;
// TextArea text;
Choice bound;
public TextBoundFrame(DemoApplet applet)
{
this.applet = applet;
init();
start();
}
public void run()
{
/*
while (true) {
try {
checkChange();
Thread.sleep(250);
}
catch (InterruptedException e) {
}
catch (Exception e) {
}
catch (Throwable e) {
}
}
*/
}
int s, e;
int ts, te;
public void checkChange()
{
// System.out.println("checkChange...");
if ((text.getSelectionStart() & 0x7FFF) != ts ||
(text.getSelectionEnd() & 0x7FFF) != te) {
int tempS = text.getSelectionStart() & 0x7FFF;
int tempE = text.getSelectionEnd() & 0x7FFF;
// System.out.println(">");
// select(0, 0);
// select(tempS, tempE);
//select(tempS - (ts - s), tempE - (te - e));
// System.out.println("<");
// if (s != ts || e != te) System.out.println(" s("+s+") ts("+ts+") e("+e+") te("+te+")");
// if (tempS != ts || tempE != te) System.out.println(">s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// select(s - (ts - s), e - (te - e));
// if (tempS != ts || tempE != te) System.out.println("s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// System.out.println("lkdslksj");
}
}
public void select(int sIn, int eIn)
{
s = sIn;
e = eIn;
text.select(s, e);
ts = text.getSelectionStart() & 0x7FFF;
te = text.getSelectionEnd() & 0x7FFF;
// if (s != ts || e != te) {
// System.out.println(">s("+s+") ts("+ts+") e("+e+") te("+te+")");
// System.out.println(" "+(ts-s)+","+(te-e));
// }
}
public int getSelectionStart()
{
checkChange();
// return s;
return text.getSelectionStart() & 0x7FFF;
}
public int getSelectionEnd()
{
checkChange();
// return e;
return text.getSelectionEnd() & 0x7FFF;
}
public final synchronized void selectRange(int s, int e)
{
try {
//if (getSelectionStart() != s || getSelectionEnd() != e) {
//text.select(s, e);
select(s,e);
//}
// if (getSelectionStart() != s || getSelectionEnd() != e) {
// System.out.println("AGH! select("+s+","+e+") -> ("+
// getSelectionStart()+","+getSelectionEnd()+")");
// text.select(s - (getSelectionStart() - s), e - (getSelectionEnd() - e));
// }
} catch (Exception exp) {
errorText(exp.toString());
}
}
public void init()
{
buildGUI();
}
public void start()
{
}
void addWithFont(Container container, Component foo, Font font) {
if (font != null)
foo.setFont(font);
container.add(foo);
}
public void buildGUI()
{
setBackground(DemoUtility.bgColor);
setLayout(new BorderLayout());
Panel topPanel = new Panel();
Label titleLabel =
new Label("Text Boundary Demo", Label.CENTER);
titleLabel.setFont(DemoUtility.titleFont);
topPanel.add(titleLabel);
//Label demo=new Label(creditString, Label.CENTER);
//demo.setFont(DemoUtility.creditFont);
//topPanel.add(demo);
Panel choicePanel = new Panel();
Label demo1=new Label("Boundaries", Label.LEFT);
demo1.setFont(DemoUtility.labelFont);
choicePanel.add(demo1);
bound = new Choice();
bound.setBackground(DemoUtility.choiceColor);
bound.addItem("Sentence");
bound.addItem("Line Break");
bound.addItem("Word");
bound.addItem("Char");
if (choiceFont != null)
bound.setFont(choiceFont);
choicePanel.add(bound);
topPanel.add(choicePanel);
DemoUtility.fixGrid(topPanel,1);
add("North", topPanel);
int ROWS = 15;
int COLUMNS = 50;
// text = new TextArea(getInitialText(), ROWS, COLUMNS);
text = new JTextArea(getInitialText(), ROWS, COLUMNS);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setEditable(true);
text.selectAll();
text.setFont(DemoUtility.editFont);
text.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
add("Center", new JScrollPane(text, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
Panel copyrightPanel = new Panel();
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright1, Label.LEFT),DemoUtility.creditFont);
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright2, Label.LEFT),DemoUtility.creditFont);
DemoUtility.fixGrid(copyrightPanel,1);
add("South", copyrightPanel);
//layout();
handleEnumChanged();
// (new Thread(this)).start();
}
public String getInitialText()
{
return
/*
"\"This is a sentence.\" This is not.\" \"because. And go. " +
"This is a simple 012.566,5 sample sentence. \n"+
"It does not have to make any sense as you can see. \n"+
"Nel mezzo del cammin di nostra vita, mi ritrovai in "+
"una selva oscura. \n"+
"Che la dritta via aveo smarrita. \n"+
"He said, that I said, that you said!! \n"+
"Don't rock the boat.\n\n"+
"Because I am the daddy, that is why. \n"+
"Not on my time (el timo.)! \n"+
"Tab\tTab\rTab\tWow."+
"So what!!\n\n"+
"Is this a question??? " +
"I wonder...Hmm.\n" +
"Harris thumbed down several, including \"Away We Go\" "+
"(which became the huge success Oklahoma!). \n"+
"One species, B. anthracis, is highly virulent.\n"+
"Wolf said about Sounder: \"Beautifully thought-out and "+
"directed.\"\n"+
"Have you ever said, \"This is where I shall live\"? \n"+
"He 1000,233,456.000 answered, \"You may not!\" \n"+
"Another popular saying is: \"How do you do?\". \n"+
"What is the proper use of the abbreviation pp.? \n"+
"Yes, I am 1,23.322% definatelly 12\" tall!!";
*/
"(\"This is a complete sentence.\") This is (\"not.\") also. "
+"An abbreviation in the middle, etc. and one at the end, etc. "+
"This "
+"is a simple sample 012.566,5 sentence. It doesn't "
+"have to make any sense, as you can see. Nel mezzo del c"
+"ammin di nostra vita, mi ritrovai in una selva oscura. Che "
+"la dritta via aveo smarrita. Not on my time (el timo.)! And "
+"tabulated columns: \tCol1\tCol2\t3,456%.\t "
+"Is this a question??? I wonder... Hmm. Harris thumbed "
+"down several, including \"Away We Go\" (which became the "
+"huge success Oklahoma!). One species, B. anthracis, is "
+"highly virulent. Wolf said about Sounder: \"Beautifully "
+"thought-out and directed.\" Have you ever said, \"This is "+
"where I "
+"shall live\"? He said 1000,233,456.000 and answered, \"You "+
"may not!\" "
+"Another popular saying is: \"How do you do?\". What is the "
+"proper use of the abbreviation pp.? Yes, I am 12\' 3\" tall!!";
}
public void handleEnumChanged()
{
String s = bound.getSelectedItem();
if (s.equals("Char")) {
errorText("getCharacterInstance");
enum = BreakIterator.getCharacterInstance();
}
else if (s.equals("Word")) {
errorText("tWordBreak");
enum = BreakIterator.getWordInstance();
}
else if (s.equals("Line Break")) {
errorText("getLineInstance");
enum = BreakIterator.getLineInstance();
}
else /* if (s.equals("Sentence")) */ {
errorText("getSentenceInstance");
enum = BreakIterator.getSentenceInstance();
}
enum.setText(text.getText());
selectRange(0, 0);
//text.select(0,0);
}
public void handleForward()
{
try {
// System.out.println("entering handleForward");
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
// System.out.println("handleForward: oldStart=" + oldStart + ", oldEnd=" + oldEnd);
if (oldEnd < 1) {
selectRange(0, enum.following(0));
}
else {
int s = enum.following(oldEnd-1);
int e = enum.next();
if (e == -1) {
e = s;
}
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" +
s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public void handleBackward()
{
try {
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
if (oldStart < 1) {
selectRange(0, 0);
}
else {
int e = enum.following(oldStart-1);
int s = enum.previous();
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" + s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public boolean action(Event evt, Object obj)
{
if(evt.target instanceof Button && left.equals(obj))
{
handleBackward();
return true;
}
else if(evt.target instanceof Button && right.equals(obj))
{
handleForward();
return true;
}
else if(evt.target instanceof Choice)
{
handleEnumChanged();
return true;
}
return false;
}
public boolean handleEvent(Event evt)
{
if (evt.id == Event.KEY_PRESS || evt.id == Event.KEY_ACTION) {
if (evt.key == Event.RIGHT || (evt.key == 0x0E && evt.controlDown())) {
handleForward();
return true;
}
else if (evt.key == Event.LEFT || (evt.key == 0x10 && evt.controlDown())) {
handleBackward();
return true;
}
}
else
if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else System.exit(0);
return true;
}
return super.handleEvent(evt);
}
public void errorText(String s)
{
if (DEBUG)
System.out.println(s);
}
}

Binary file not shown.

View file

@ -0,0 +1,533 @@
/*
* (C) IBM Corp. 1997-1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.rbnf;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.text.BreakIterator;
import java.text.ParsePosition;
import java.util.Locale;
import com.ibm.text.RuleBasedNumberFormat;
public class RbnfDemo extends DemoApplet {
/**
* Puts a copyright in the .class file
*/
private static final String copyrightNotice
= "Copyright \u00a91997-1998 IBM Corp. All rights reserved.";
/*
* code to run the demo as an application
*/
public static void main(String[] argv) {
new RbnfDemo().showDemo();
}
protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
return new Dimension(430,270);
}
protected Frame createDemoFrame(DemoApplet applet) {
final Frame window = new Frame("Number Spellout Demo");
window.setSize(800, 600);
window.setLayout(new BorderLayout());
Panel mainPanel = new Panel();
mainPanel.setLayout(new GridLayout(1,2));
commentaryField = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
commentaryField.setSize(800, 50);
commentaryField.setText(RbnfSampleRuleSets.sampleRuleSetCommentary[0]);
commentaryField.setEditable(false);
commentaryField.setFont(new Font("Helvetica", Font.PLAIN, 14));
spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.usEnglish, Locale.US);
spelloutFormatter.setLenientParseMode(lenientParse);
populateRuleSetMenu();
numberFormatter = new DecimalFormat("#,##0.##########");
parsePosition = new ParsePosition(0);
theNumber = 0;
numberField = new TextField();
numberField.setFont(new Font("Serif", Font.PLAIN, 24));
textField = new DemoTextFieldHolder();
textField.setFont(new Font("Serif", Font.PLAIN, 24));
rulesField = new DemoTextFieldHolder();
rulesField.setFont(new Font("Serif", Font.PLAIN, 14));
lenientParseButton = new Checkbox("Lenient parse", lenientParse);
numberField.addTextListener(new TextListener() {
public void textValueChanged(TextEvent e) {
if (!numberFieldHasFocus)
return;
String fieldText = ((TextComponent)(e.getSource())).getText();
parsePosition.setIndex(0);
Number temp = numberFormatter.parse(fieldText, parsePosition);
if (temp == null || parsePosition.getIndex() == 0) {
theNumber = 0;
textField.setText("PARSE ERROR");
}
else {
theNumber = temp.doubleValue();
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
}
}
} );
numberField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
numberFieldHasFocus = false;
numberField.setText(numberFormatter.format(theNumber));
}
public void focusGained(FocusEvent e) {
numberFieldHasFocus = true;
numberField.selectAll();
}
} );
textField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '\t') {
String fieldText = ((TextComponent)(e.getSource())).getText();
parsePosition.setIndex(0);
theNumber = spelloutFormatter.parse(fieldText, parsePosition)
.doubleValue();
if (parsePosition.getIndex() == 0) {
theNumber = 0;
numberField.setText("PARSE ERROR");
textField.selectAll();
}
else if (parsePosition.getIndex() < fieldText.length()) {
textField.select(parsePosition.getIndex(), fieldText.length());
numberField.setText(numberFormatter.format(theNumber));
}
else {
textField.selectAll();
numberField.setText(numberFormatter.format(theNumber));
}
e.consume();
}
}
} );
textField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
String fieldText = ((TextComponent)(e.getSource())).getText();
parsePosition.setIndex(0);
theNumber = spelloutFormatter.parse(fieldText, parsePosition)
.doubleValue();
if (parsePosition.getIndex() == 0)
numberField.setText("PARSE ERROR");
else
numberField.setText(numberFormatter.format(theNumber));
textField.setText(textField.getText()); // textField.repaint() didn't work right
}
public void focusGained(FocusEvent e) {
textField.selectAll();
}
} );
rulesField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '\t') {
String fieldText = ((TextComponent)(e.getSource())).getText();
if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
try {
RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
temp.setLenientParseMode(lenientParse);
populateRuleSetMenu();
spelloutFormatter = temp;
customRuleSet = fieldText;
formatterMenu.select("Custom");
commentaryField.setText(RbnfSampleRuleSets.
sampleRuleSetCommentary[RbnfSampleRuleSets.
sampleRuleSetCommentary.length - 1]);
redisplay();
}
catch (Exception x) {
textField.setText(x.toString());
}
}
e.consume();
}
}
} );
rulesField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
String fieldText = ((TextComponent)(e.getSource())).getText();
if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
try {
RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
temp.setLenientParseMode(lenientParse);
populateRuleSetMenu();
spelloutFormatter = temp;
customRuleSet = fieldText;
formatterMenu.select("Custom");
redisplay();
}
catch (Exception x) {
textField.setText(x.toString());
}
}
rulesField.setText(rulesField.getText()); // rulesField.repaint() didn't work right
}
} );
lenientParseButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
lenientParse = lenientParseButton.getState();
spelloutFormatter.setLenientParseMode(lenientParse);
}
} );
numberField.setText(numberFormatter.format(theNumber));
numberField.selectAll();
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
Panel leftPanel = new Panel();
leftPanel.setLayout(new BorderLayout());
Panel panel = new Panel();
panel.setLayout(new BorderLayout());
Panel panel1 = new Panel();
panel1.setLayout(new GridLayout(3, 1));
panel1.add(new Panel());
panel1.add(numberField, "Center");
panel1.add(lenientParseButton);
panel.add(panel1, "Center");
Panel panel2 = new Panel();
panel2.setLayout(new GridLayout(3, 3));
Button button = new Button("+100");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(100);
}
} );
panel2.add(button);
button = new Button("+10");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(10);
}
} );
panel2.add(button);
button = new Button("+1");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(1);
}
} );
panel2.add(button);
button = new Button("<");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
theNumber *= 10;
redisplay();
}
} );
panel2.add(button);
panel2.add(new Panel());
button = new Button(">");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
theNumber /= 10;
redisplay();
}
} );
panel2.add(button);
button = new Button("-100");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(-100);
}
} );
panel2.add(button);
button = new Button("-10");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(-10);
}
} );
panel2.add(button);
button = new Button("-1");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(-1);
}
} );
panel2.add(button);
panel.add(panel2, "East");
leftPanel.add(panel, "North");
leftPanel.add(textField, "Center");
Panel rightPanel = new Panel();
rightPanel.setLayout(new BorderLayout());
formatterMenu = new Choice();
for (int i = 0; i < RbnfSampleRuleSets.sampleRuleSetNames.length; i++)
formatterMenu.addItem(RbnfSampleRuleSets.sampleRuleSetNames[i]);
formatterMenu.addItem("Custom");
formatterMenu.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
Choice source = (Choice)(e.getSource());
int item = source.getSelectedIndex();
Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
commentaryField.setText(RbnfSampleRuleSets.
sampleRuleSetCommentary[item]);
if (locale != null && (locale.getLanguage().equals("iw")
|| locale.getLanguage().equals("ru") || locale.getLanguage().equals("ja")
|| locale.getLanguage().equals("el")
|| locale.getLanguage().equals("zh"))) {
textField.togglePanes(false);
rulesField.togglePanes(false);
}
else {
textField.togglePanes(true);
rulesField.togglePanes(true);
}
makeNewSpelloutFormatter();
redisplay();
}
} );
ruleSetMenu = new Choice();
populateRuleSetMenu();
ruleSetMenu.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
ruleSetName = ruleSetMenu.getSelectedItem();
redisplay();
}
} );
Panel menuPanel = new Panel();
menuPanel.setLayout(new GridLayout(1, 2));
menuPanel.add(formatterMenu);
menuPanel.add(ruleSetMenu);
rightPanel.add(menuPanel, "North");
rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()]);
rightPanel.add(rulesField, "Center");
mainPanel.add(leftPanel);
mainPanel.add(rightPanel);
window.add(mainPanel, "Center");
window.add(commentaryField, "South");
window.doLayout();
window.show();
return window;
}
void roll(int delta) {
theNumber += delta;
redisplay();
}
void redisplay() {
numberField.setText(numberFormatter.format(theNumber));
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
}
void makeNewSpelloutFormatter() {
int item = formatterMenu.getSelectedIndex();
String formatterMenuItem = formatterMenu.getSelectedItem();
if (formatterMenuItem.equals("Custom")) {
rulesField.setText(customRuleSet);
spelloutFormatter = new RuleBasedNumberFormat(customRuleSet);
}
else {
rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[item]);
Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
if (locale == null)
locale = Locale.getDefault();
spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.
sampleRuleSets[item], locale);
}
spelloutFormatter.setLenientParseMode(lenientParse);
populateRuleSetMenu();
}
void populateRuleSetMenu() {
String[] ruleSetNames = spelloutFormatter.getRuleSetNames();
if (ruleSetMenu != null) {
ruleSetMenu.removeAll();
for (int i = 0; i < ruleSetNames.length; i++)
ruleSetMenu.addItem(ruleSetNames[i]);
ruleSetName = ruleSetMenu.getSelectedItem();
}
else
ruleSetName = ruleSetNames[0];
}
private Frame demoWindow = null;
private TextComponent numberField;
private DemoTextFieldHolder textField;
private DemoTextFieldHolder rulesField;
private TextComponent commentaryField;
private Checkbox lenientParseButton;
private boolean numberFieldHasFocus = true;
private RuleBasedNumberFormat spelloutFormatter;
private DecimalFormat numberFormatter;
private ParsePosition parsePosition;
private boolean lenientParse = true;
private double theNumber = 0;
private boolean canEdit = true;
private Choice formatterMenu;
private Choice ruleSetMenu;
private String ruleSetName;
private String customRuleSet = "NO RULES!";
}
class DemoTextField extends Component {
public DemoTextField() {
}
public void setText(String text) {
this.text = text;
this.repaint();
}
public String getText() {
return text;
}
public void paint(Graphics g) {
Font font = getFont();
FontMetrics fm = g.getFontMetrics();
g.setFont(font);
String text = getText();
BreakIterator bi = BreakIterator.getLineInstance();
bi.setText(text);
int lineHeight = fm.getHeight();
int width = getSize().width;
int penY = fm.getAscent();
int lineStart = 0;
int tempLineEnd = bi.first();
int lineEnd = 0;
int maxLineEnd = 0;
totalHeight = 0;
while (lineStart < text.length()) {
maxLineEnd = text.indexOf('\n', lineStart);
if (maxLineEnd == -1)
maxLineEnd = Integer.MAX_VALUE;
while (tempLineEnd != BreakIterator.DONE && fm.stringWidth(text.substring(
lineStart, tempLineEnd)) < width) {
lineEnd = tempLineEnd;
tempLineEnd = bi.next();
}
if (lineStart >= lineEnd) {
if (tempLineEnd == BreakIterator.DONE)
lineEnd = text.length();
else
lineEnd = tempLineEnd;
}
if (lineEnd > maxLineEnd)
lineEnd = maxLineEnd;
g.drawString(text.substring(lineStart, lineEnd), 0, penY);
penY += lineHeight;
totalHeight += lineHeight;
lineStart = lineEnd;
if (lineStart < text.length() && text.charAt(lineStart) == '\n')
++lineStart;
}
}
/*
public Dimension getPreferredSize() {
Dimension size = getParent().getSize();
return new Dimension(size.width, totalHeight);
}
*/
private String text;
private int totalHeight;
}
class DemoTextFieldHolder extends Panel {
public DemoTextFieldHolder() {
tf1 = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
tf2 = new DemoTextField();
sp = new ScrollPane();
setLayout(new CardLayout());
sp.add(tf2, "TextField1");
sp.setVisible(false);
add(tf1, "TestField2");
add(sp, "ScrollPane");
}
public void addFocusListener(FocusListener l) {
tf1.addFocusListener(l);
}
public void addKeyListener(KeyListener l) {
tf1.addKeyListener(l);
}
public void setText(String text) {
tf1.setText(text);
tf2.setText(text);
}
public String getText() {
return tf1.getText();
}
public void select(int start, int end) {
tf1.select(start, end);
}
public void selectAll() {
tf1.selectAll();
}
public void togglePanes(boolean canShowRealTextField) {
if (canShowRealTextField != showingRealTextField) {
CardLayout layout = (CardLayout)(getLayout());
layout.next(this);
showingRealTextField = canShowRealTextField;
}
}
private TextArea tf1 = null;
private DemoTextField tf2 = null;
private ScrollPane sp = null;
private boolean showingRealTextField = true;
}

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,143 @@
# Composition Exclusions
# This file lists the characters from the UTR #15 Composition Exclusion Table.
#
# For more information, see
# http://www.unicode.org/unicode/reports/tr15/#Primary Exclusion List Table
# (1) Script Specifics
# This list of characters cannot be derived from the UnicodeData file.
0958 # DEVANAGARI LETTER QA
0959 # DEVANAGARI LETTER KHHA
095A # DEVANAGARI LETTER GHHA
095B # DEVANAGARI LETTER ZA
095C # DEVANAGARI LETTER DDDHA
095D # DEVANAGARI LETTER RHA
095E # DEVANAGARI LETTER FA
095F # DEVANAGARI LETTER YYA
09DC # BENGALI LETTER RRA
09DD # BENGALI LETTER RHA
09DF # BENGALI LETTER YYA
0A33 # GURMUKHI LETTER LLA
0A36 # GURMUKHI LETTER SHA
0A59 # GURMUKHI LETTER KHHA
0A5A # GURMUKHI LETTER GHHA
0A5B # GURMUKHI LETTER ZA
0A5E # GURMUKHI LETTER FA
0B5C # ORIYA LETTER RRA
0B5D # ORIYA LETTER RHA
0F43 # TIBETAN LETTER GHA
0F4D # TIBETAN LETTER DDHA
0F52 # TIBETAN LETTER DHA
0F57 # TIBETAN LETTER BHA
0F5C # TIBETAN LETTER DZHA
0F69 # TIBETAN LETTER KSSA
0F76 # TIBETAN VOWEL SIGN VOCALIC R
0F78 # TIBETAN VOWEL SIGN VOCALIC L
0F93 # TIBETAN SUBJOINED LETTER GHA
0F9D # TIBETAN SUBJOINED LETTER DDHA
0FA2 # TIBETAN SUBJOINED LETTER DHA
0FA7 # TIBETAN SUBJOINED LETTER BHA
0FAC # TIBETAN SUBJOINED LETTER DZHA
0FB9 # TIBETAN SUBJOINED LETTER KSSA
FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH
FB2A # HEBREW LETTER SHIN WITH SHIN DOT
FB2B # HEBREW LETTER SHIN WITH SIN DOT
FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT
FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT
FB2E # HEBREW LETTER ALEF WITH PATAH
FB2F # HEBREW LETTER ALEF WITH QAMATS
FB30 # HEBREW LETTER ALEF WITH MAPIQ
FB31 # HEBREW LETTER BET WITH DAGESH
FB32 # HEBREW LETTER GIMEL WITH DAGESH
FB33 # HEBREW LETTER DALET WITH DAGESH
FB34 # HEBREW LETTER HE WITH MAPIQ
FB35 # HEBREW LETTER VAV WITH DAGESH
FB36 # HEBREW LETTER ZAYIN WITH DAGESH
FB38 # HEBREW LETTER TET WITH DAGESH
FB39 # HEBREW LETTER YOD WITH DAGESH
FB3A # HEBREW LETTER FINAL KAF WITH DAGESH
FB3B # HEBREW LETTER KAF WITH DAGESH
FB3C # HEBREW LETTER LAMED WITH DAGESH
FB3E # HEBREW LETTER MEM WITH DAGESH
FB40 # HEBREW LETTER NUN WITH DAGESH
FB41 # HEBREW LETTER SAMEKH WITH DAGESH
FB43 # HEBREW LETTER FINAL PE WITH DAGESH
FB44 # HEBREW LETTER PE WITH DAGESH
FB46 # HEBREW LETTER TSADI WITH DAGESH
FB47 # HEBREW LETTER QOF WITH DAGESH
FB48 # HEBREW LETTER RESH WITH DAGESH
FB49 # HEBREW LETTER SHIN WITH DAGESH
FB4A # HEBREW LETTER TAV WITH DAGESH
FB4B # HEBREW LETTER VAV WITH HOLAM
FB4C # HEBREW LETTER BET WITH RAFE
FB4D # HEBREW LETTER KAF WITH RAFE
FB4E # HEBREW LETTER PE WITH RAFE
# (2) Post Composition Version characters
# These characters cannot be derived from the UnicodeData file.
# (There are no characters in this category in this version of Unicode.)
# (3) Singleton Decompositions
# These characters can be derived from the UnicodeData file
# by including all characters whose canonical decomposition
# consists of a single character.
# These characters are simply quoted here for reference.
# 0340 COMBINING GRAVE TONE MARK
# 0341 COMBINING ACUTE TONE MARK
# 0343 COMBINING GREEK KORONIS
# 0374 GREEK NUMERAL SIGN
# 037E GREEK QUESTION MARK
# 0387 GREEK ANO TELEIA
# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA
# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA
# 1F75 GREEK SMALL LETTER ETA WITH OXIA
# 1F77 GREEK SMALL LETTER IOTA WITH OXIA
# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA
# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA
# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA
# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA
# 1FBE GREEK PROSGEGRAMMENI
# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA
# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA
# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA
# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA
# 1FEE GREEK DIALYTIKA AND OXIA
# 1FEF GREEK VARIA
# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA
# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA
# 1FFD GREEK OXIA
# 2000 EN QUAD
# 2001 EM QUAD
# 2126 OHM SIGN
# 212A KELVIN SIGN
# 212B ANGSTROM SIGN
# 2329 LEFT-POINTING ANGLE BRACKET
# 232A RIGHT-POINTING ANGLE BRACKET
# F900 CJK COMPATIBILITY IDEOGRAPH-F900
#.. FA0D CJK COMPATIBILITY IDEOGRAPH-FA0D
# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10
# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12
# FA15 CJK COMPATIBILITY IDEOGRAPH-FA15
#.. FA1E CJK COMPATIBILITY IDEOGRAPH-FA1E
# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20
# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22
# FA25 CJK COMPATIBILITY IDEOGRAPH-FA25
# FA26 CJK COMPATIBILITY IDEOGRAPH-FA26
# FA2A CJK COMPATIBILITY IDEOGRAPH-FA2A
#.. FA2D CJK COMPATIBILITY IDEOGRAPH-FA2D
# (4) Non-Starter Decompositions
# These characters can be derived from the UnicodeData file
# by including all characters whose canonical decomposition consists
# of a sequence of characters, the first of which has a canonical
# class of zero.
# These characters are simply quoted here for reference.
# 0344 COMBINING GREEK DIALYTIKA TONOS
# 0F73 TIBETAN VOWEL SIGN II
# 0F75 TIBETAN VOWEL SIGN UU
# 0F81 TIBETAN VOWEL SIGN REVERSED II

View file

@ -0,0 +1,145 @@
# Composition Exclusions
# This file lists the characters from the UTR #15 Composition Exclusion Table.
#
# For more information, see
# http://www.unicode.org/unicode/reports/tr15/#Primary Exclusion List Table
# (1) Script Specifics
# This list of characters cannot be derived from the UnicodeData file.
0958 # DEVANAGARI LETTER QA
0959 # DEVANAGARI LETTER KHHA
095A # DEVANAGARI LETTER GHHA
095B # DEVANAGARI LETTER ZA
095C # DEVANAGARI LETTER DDDHA
095D # DEVANAGARI LETTER RHA
095E # DEVANAGARI LETTER FA
095F # DEVANAGARI LETTER YYA
09DC # BENGALI LETTER RRA
09DD # BENGALI LETTER RHA
09DF # BENGALI LETTER YYA
0A33 # GURMUKHI LETTER LLA
0A36 # GURMUKHI LETTER SHA
0A59 # GURMUKHI LETTER KHHA
0A5A # GURMUKHI LETTER GHHA
0A5B # GURMUKHI LETTER ZA
0A5E # GURMUKHI LETTER FA
0B5C # ORIYA LETTER RRA
0B5D # ORIYA LETTER RHA
0F43 # TIBETAN LETTER GHA
0F4D # TIBETAN LETTER DDHA
0F52 # TIBETAN LETTER DHA
0F57 # TIBETAN LETTER BHA
0F5C # TIBETAN LETTER DZHA
0F69 # TIBETAN LETTER KSSA
0F76 # TIBETAN VOWEL SIGN VOCALIC R
0F78 # TIBETAN VOWEL SIGN VOCALIC L
0F93 # TIBETAN SUBJOINED LETTER GHA
0F9D # TIBETAN SUBJOINED LETTER DDHA
0FA2 # TIBETAN SUBJOINED LETTER DHA
0FA7 # TIBETAN SUBJOINED LETTER BHA
0FAC # TIBETAN SUBJOINED LETTER DZHA
0FB9 # TIBETAN SUBJOINED LETTER KSSA
FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH
FB2A # HEBREW LETTER SHIN WITH SHIN DOT
FB2B # HEBREW LETTER SHIN WITH SIN DOT
FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT
FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT
FB2E # HEBREW LETTER ALEF WITH PATAH
FB2F # HEBREW LETTER ALEF WITH QAMATS
FB30 # HEBREW LETTER ALEF WITH MAPIQ
FB31 # HEBREW LETTER BET WITH DAGESH
FB32 # HEBREW LETTER GIMEL WITH DAGESH
FB33 # HEBREW LETTER DALET WITH DAGESH
FB34 # HEBREW LETTER HE WITH MAPIQ
FB35 # HEBREW LETTER VAV WITH DAGESH
FB36 # HEBREW LETTER ZAYIN WITH DAGESH
FB38 # HEBREW LETTER TET WITH DAGESH
FB39 # HEBREW LETTER YOD WITH DAGESH
FB3A # HEBREW LETTER FINAL KAF WITH DAGESH
FB3B # HEBREW LETTER KAF WITH DAGESH
FB3C # HEBREW LETTER LAMED WITH DAGESH
FB3E # HEBREW LETTER MEM WITH DAGESH
FB40 # HEBREW LETTER NUN WITH DAGESH
FB41 # HEBREW LETTER SAMEKH WITH DAGESH
FB43 # HEBREW LETTER FINAL PE WITH DAGESH
FB44 # HEBREW LETTER PE WITH DAGESH
FB46 # HEBREW LETTER TSADI WITH DAGESH
FB47 # HEBREW LETTER QOF WITH DAGESH
FB48 # HEBREW LETTER RESH WITH DAGESH
FB49 # HEBREW LETTER SHIN WITH DAGESH
FB4A # HEBREW LETTER TAV WITH DAGESH
FB4B # HEBREW LETTER VAV WITH HOLAM
FB4C # HEBREW LETTER BET WITH RAFE
FB4D # HEBREW LETTER KAF WITH RAFE
FB4E # HEBREW LETTER PE WITH RAFE
# (2) Post Composition Version characters
# These characters cannot be derived from the UnicodeData file.
# (There are no characters in this category in this version of Unicode.)
# (3) Singleton Decompositions
# These characters can be derived from the UnicodeData file
# by including all characters whose canonical decomposition
# consists of a single character.
# These characters are simply quoted here for reference.
# 0340 COMBINING GRAVE TONE MARK
# 0341 COMBINING ACUTE TONE MARK
# 0343 COMBINING GREEK KORONIS
# 0374 GREEK NUMERAL SIGN
# 037E GREEK QUESTION MARK
# 0387 GREEK ANO TELEIA
# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA
# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA
# 1F75 GREEK SMALL LETTER ETA WITH OXIA
# 1F77 GREEK SMALL LETTER IOTA WITH OXIA
# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA
# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA
# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA
# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA
# 1FBE GREEK PROSGEGRAMMENI
# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA
# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA
# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA
# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA
# 1FEE GREEK DIALYTIKA AND OXIA
# 1FEF GREEK VARIA
# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA
# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA
# 1FFD GREEK OXIA
# 2000 EN QUAD
# 2001 EM QUAD
# 2126 OHM SIGN
# 212A KELVIN SIGN
# 212B ANGSTROM SIGN
# 2329 LEFT-POINTING ANGLE BRACKET
# 232A RIGHT-POINTING ANGLE BRACKET
# F900 CJK COMPATIBILITY IDEOGRAPH-F900
#.. FA0D CJK COMPATIBILITY IDEOGRAPH-FA0D
# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10
# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12
# FA15 CJK COMPATIBILITY IDEOGRAPH-FA15
#.. FA1E CJK COMPATIBILITY IDEOGRAPH-FA1E
# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20
# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22
# FA25 CJK COMPATIBILITY IDEOGRAPH-FA25
# FA26 CJK COMPATIBILITY IDEOGRAPH-FA26
# FA2A CJK COMPATIBILITY IDEOGRAPH-FA2A
#.. FA2D CJK COMPATIBILITY IDEOGRAPH-FA2D
# (4) Non-Starter Decompositions
# These characters can be derived from the UnicodeData file
# by including all characters whose canonical decomposition consists
# of a sequence of characters, the first of which has a canonical
# class of zero.
# These characters are simply quoted here for reference.
# 0344 COMBINING GREEK DIALYTIKA TONOS
# 0F73 TIBETAN VOWEL SIGN II
# 0F75 TIBETAN VOWEL SIGN UU
# 0F81 TIBETAN VOWEL SIGN REVERSED II

View file

@ -0,0 +1,219 @@
# SpecialCasing-2.txt
#
# Special Casing Properties
#
# This file is a supplement to the UnicodeData file.
# It contains additional information about the casing of Unicode characters.
# (For compatibility, the UnicodeData.txt file only contains case mappings for
# characters where they are 1-1, and does not have locale-specific mappings.)
# These are informative character properties.
#
# Send comments to mark@unicode.org
#
# ================================================================================
# Format
# ================================================================================
# The entries in this file are in the following machine-readable format:
#
# <entry> := <case_mapping> <condition_list>? (<s>* "#" <comment>)?
#
# <case_mapping> := <source> <sep> <lower> <sep> <title> <sep> <upper> <sep>
#
# <source> := <code_point>
# <sep> := <s>* ";" <s>*
# <lower> := <code_point_list>
# <title> := <code_point_list>
# <upper> := <code_point_list>
# <code_point_list> := <code_point> (<s>+ <code_point>)*
# <code_point> := <hex><hex><hex><hex>
# <hex> := [0-1A-Fa-f]
# <s> := <space>
#
# <condition_list> := <locale>? (<s>+ <context>)*
# <locale> := <ISO_3166_code> ( "_" <ISO_639_code> )? ( "_" <variant> )?
# <ISO_3166_code> := 2-letter country code,
# as in http://www.unicode.org/unicode/onlinedat/countries.html
# <ISO_639_code> := 2-letter code,
# as in http://www.unicode.org/unicode/onlinedat/languages.html
# <context> := "FINAL" | "NON_FINAL" | "MODERN" | "NON_MODERN"
#
# A condition list overrides the normal behavior if any of the listed conditions is true.
# FINAL: The letter is not followed by a letter of category L* (e.g. Ll, Lt, Lu, Lm, or Lo).
# MODERN: The mapping is only used for modern text.
# Conditions preceded by "NON_" represent the negation of the condition
#
# New contexts may be added in the future.
# Parsers of this file must be prepared to deal with that situation.
# Additional whitespace around elements is optional. Blank lines are ignored in parsing.
# On any line, all text following "#" is a comment, and are ignored in parsing.
# ================================================================================
# ================================================================================
# Unconditional mappings
# ================================================================================
# The German es-zed is special--the normal mapping is to SS.
# Note: the titlecase should never occur in practice. It is equal to titlecase(uppercase(<es-zed>))
00DF; 00DF; 0053 0073; 0053 0053; # LATIN SMALL LETTER SHARP S
# Ligatures
FB00; FB00; 0046 0066; 0046 0046; # LATIN SMALL LIGATURE FF
FB01; FB01; 0046 0069; 0046 0049; # LATIN SMALL LIGATURE FI
FB02; FB02; 0046 006C; 0046 004C; # LATIN SMALL LIGATURE FL
FB03; FB03; 0046 0066 0069; 0046 0046 0049; # LATIN SMALL LIGATURE FFI
FB04; FB04; 0046 0066 006C; 0046 0046 004C; # LATIN SMALL LIGATURE FFL
FB05; FB05; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE LONG S T
FB06; FB06; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE ST
0587; 0587; 0535 0582; 0535 0552; # ARMENIAN SMALL LIGATURE ECH YIWN
FB13; FB13; 0544 0576; 0544 0546; # ARMENIAN SMALL LIGATURE MEN NOW
FB14; FB14; 0544 0565; 0544 0535; # ARMENIAN SMALL LIGATURE MEN ECH
FB15; FB15; 0544 056B; 0544 053B; # ARMENIAN SMALL LIGATURE MEN INI
FB16; FB16; 054E 0576; 054E 0546; # ARMENIAN SMALL LIGATURE VEW NOW
FB17; FB17; 0544 056D; 0544 053D; # ARMENIAN SMALL LIGATURE MEN XEH
# No corresponding uppercase precomposed character
0149; 0149; 02BC 006E; 02BC 004E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
0390; 0390; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
03B0; 03B0; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
01F0; 01F0; 004A 030C; 004A 030C; # LATIN SMALL LETTER J WITH CARON
1E96; 1E96; 0048 0331; 0048 0331; # LATIN SMALL LETTER H WITH LINE BELOW
1E97; 1E97; 0054 0308; 0054 0308; # LATIN SMALL LETTER T WITH DIAERESIS
1E98; 1E98; 0057 030A; 0057 030A; # LATIN SMALL LETTER W WITH RING ABOVE
1E99; 1E99; 0059 030A; 0059 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
1E9A; 1E9A; 0041 02BE; 0041 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
1F50; 1F50; 03A5 0313; 03A5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
1F52; 1F52; 03A5 0313 0300; 03A5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
1F54; 1F54; 03A5 0313 0301; 03A5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
1F56; 1F56; 03A5 0313 0342; 03A5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
1FB6; 1FB6; 0391 0342; 0391 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
1FC6; 1FC6; 0397 0342; 0397 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
1FD2; 1FD2; 0399 0308 0300; 0399 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
1FD3; 1FD3; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
1FD6; 1FD6; 0399 0342; 0399 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
1FD7; 1FD7; 0399 0308 0342; 0399 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
1FE2; 1FE2; 03A5 0308 0300; 03A5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
1FE3; 1FE3; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
1FE4; 1FE4; 03A1 0313; 03A1 0313; # GREEK SMALL LETTER RHO WITH PSILI
1FE6; 1FE6; 03A5 0342; 03A5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
1FE7; 1FE7; 03A5 0308 0342; 03A5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
1FF6; 1FF6; 03A9 0342; 03A9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
# IMPORTANT-when capitalizing iota-subscript (0345)
# It MUST be in normalized form--moved to the end of any sequence of combining marks.
# This is because logically it represents a following base character!
# E.g. <iota_subscript> (<Mn> | <Mc> | <Me>)+ => (<Mn> | <Mc> | <Me>)+ <iota_subscript>
# It should never be the first character in a word, so in titlecasing it can be left as is.
# The following cases are already in the UnicodeData file, so are only commented here.
# 0345; 0345; 0345; 0399; # COMBINING GREEK YPOGEGRAMMENI
# All letters with YPOGEGRAMMENI (iota-subscript) or PROSGEGRAMMENI (iota adscript)
# have special uppercases.
# Note: characters with PROSGEGRAMMENI are actually titlecase, not uppercase!
1F80; 1F80; 1F88; 1F08 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
1F81; 1F81; 1F89; 1F09 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
1F82; 1F82; 1F8A; 1F0A 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F83; 1F83; 1F8B; 1F0B 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F84; 1F84; 1F8C; 1F0C 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F85; 1F85; 1F8D; 1F0D 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F86; 1F86; 1F8E; 1F0E 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F87; 1F87; 1F8F; 1F0F 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F88; 1F80; 1F88; 1F08 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
1F89; 1F81; 1F89; 1F09 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
1F8A; 1F82; 1F8A; 1F0A 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F8B; 1F83; 1F8B; 1F0B 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F8C; 1F84; 1F8C; 1F0C 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F8D; 1F85; 1F8D; 1F0D 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F8E; 1F86; 1F8E; 1F0E 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F8F; 1F87; 1F8F; 1F0F 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1F90; 1F90; 1F98; 1F28 0399; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
1F91; 1F91; 1F99; 1F29 0399; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
1F92; 1F92; 1F9A; 1F2A 0399; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F93; 1F93; 1F9B; 1F2B 0399; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F94; 1F94; 1F9C; 1F2C 0399; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F95; 1F95; 1F9D; 1F2D 0399; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F96; 1F96; 1F9E; 1F2E 0399; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F97; 1F97; 1F9F; 1F2F 0399; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F98; 1F90; 1F98; 1F28 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
1F99; 1F91; 1F99; 1F29 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
1F9A; 1F92; 1F9A; 1F2A 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F9B; 1F93; 1F9B; 1F2B 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F9C; 1F94; 1F9C; 1F2C 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F9D; 1F95; 1F9D; 1F2D 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F9E; 1F96; 1F9E; 1F2E 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F9F; 1F97; 1F9F; 1F2F 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FA0; 1FA0; 1FA8; 1F68 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
1FA1; 1FA1; 1FA9; 1F69 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
1FA2; 1FA2; 1FAA; 1F6A 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1FA3; 1FA3; 1FAB; 1F6B 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1FA4; 1FA4; 1FAC; 1F6C 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1FA5; 1FA5; 1FAD; 1F6D 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1FA6; 1FA6; 1FAE; 1F6E 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1FA7; 1FA7; 1FAF; 1F6F 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1FA8; 1FA0; 1FA8; 1F68 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1FA9; 1FA1; 1FA9; 1F69 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1FAA; 1FA2; 1FAA; 1F6A 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1FAB; 1FA3; 1FAB; 1F6B 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1FAC; 1FA4; 1FAC; 1F6C 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1FAD; 1FA5; 1FAD; 1F6D 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1FAE; 1FA6; 1FAE; 1F6E 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1FAF; 1FA7; 1FAF; 1F6F 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FB3; 1FB3; 1FBC; 0391 0399; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
1FBC; 1FB3; 1FBC; 0391 0399; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1FC3; 1FC3; 1FCC; 0397 0399; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
1FCC; 1FC3; 1FCC; 0397 0399; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1FF3; 1FF3; 1FFC; 03A9 0399; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
1FFC; 1FF3; 1FFC; 03A9 0399; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
# Some characters with YPOGEGRAMMENI are also have no corresponding titlecases
1FB2; 1FB2; 1FBA 0345; 1FBA 0399; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
1FB4; 1FB4; 0386 0345; 0386 0399; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
1FC2; 1FC2; 1FCA 0345; 1FCA 0399; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
1FC4; 1FC4; 0389 0345; 0389 0399; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
1FF2; 1FF2; 1FFA 0345; 1FFA 0399; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
1FF4; 1FF4; 038F 0345; 038F 0399; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
1FB7; 1FB7; 0391 0342 0345; 0391 0342 0399; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
1FC7; 1FC7; 0397 0342 0345; 0397 0342 0399; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
1FF7; 1FF7; 03A9 0342 0345; 03A9 0342 0399; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
# ================================================================================
# Conditional mappings
# ================================================================================
# Special case for final form of sigma
03A3; 03C2; 03A3; 03A3; FINAL; # GREEK CAPITAL LETTER SIGMA
# Note: the following cases for non-final are already in the UnicodeData file.
# 03A3; 03C3; 03A3; 03A3; # GREEK CAPITAL LETTER SIGMA
# 03C3; 03C3; 03A3; 03A3; # GREEK SMALL LETTER SIGMA
# 03C2; 03C2; 03A3; 03A3; # GREEK SMALL LETTER FINAL SIGMA
# Note: the following cases are not included, since they would normalize in lowercasing
# 03C3; 03C2; 03A3; 03A3; FINAL; # GREEK SMALL LETTER SIGMA
# 03C2; 03C3; 03A3; 03A3; NON_FINAL; # GREEK SMALL LETTER FINAL SIGMA
# ================================================================================
# Locale-sensitive mappings
# ================================================================================
# Turkish
0049; 0131; 0049; 0049; TR; # LATIN CAPITAL LETTER I
0069; 0069; 0130; 0130; TR; # LATIN SMALL LETTER I
# Note: the following cases are already in the UnicodeData file.
# 0131; 0131; 0049; 0049; TR; # LATIN SMALL LETTER DOTLESS I
# 0130; 0069; 0130; 0130; TR; # LATIN CAPITAL LETTER I WITH DOT ABOVE

View file

@ -0,0 +1,221 @@
# SpecialCasing-2.txt
#
# Special Casing Properties
#
# This file is a supplement to the UnicodeData file.
# It contains additional information about the casing of Unicode characters.
# (For compatibility, the UnicodeData.txt file only contains case mappings for
# characters where they are 1-1, and does not have locale-specific mappings.)
# These are informative character properties.
#
# Send comments to mark@unicode.org
#
# ================================================================================
# Format
# ================================================================================
# The entries in this file are in the following machine-readable format:
#
# <entry> := <case_mapping> <condition_list>? (<s>* "#" <comment>)?
#
# <case_mapping> := <source> <sep> <lower> <sep> <title> <sep> <upper> <sep>
#
# <source> := <code_point>
# <sep> := <s>* ";" <s>*
# <lower> := <code_point_list>
# <title> := <code_point_list>
# <upper> := <code_point_list>
# <code_point_list> := <code_point> (<s>+ <code_point>)*
# <code_point> := <hex><hex><hex><hex>
# <hex> := [0-1A-Fa-f]
# <s> := <space>
#
# <condition_list> := <locale>? (<s>+ <context>)*
# <locale> := <ISO_3166_code> ( "_" <ISO_639_code> )? ( "_" <variant> )?
# <ISO_3166_code> := 2-letter country code,
# as in http://www.unicode.org/unicode/onlinedat/countries.html
# <ISO_639_code> := 2-letter code,
# as in http://www.unicode.org/unicode/onlinedat/languages.html
# <context> := "FINAL" | "NON_FINAL" | "MODERN" | "NON_MODERN"
#
# A condition list overrides the normal behavior if any of the listed conditions is true.
# FINAL: The letter is not followed by a letter of category L* (e.g. Ll, Lt, Lu, Lm, or Lo).
# MODERN: The mapping is only used for modern text.
# Conditions preceded by "NON_" represent the negation of the condition
#
# New contexts may be added in the future.
# Parsers of this file must be prepared to deal with that situation.
# Additional whitespace around elements is optional. Blank lines are ignored in parsing.
# On any line, all text following "#" is a comment, and are ignored in parsing.
# ================================================================================
# ================================================================================
# Unconditional mappings
# ================================================================================
# The German es-zed is special--the normal mapping is to SS.
# Note: the titlecase should never occur in practice. It is equal to titlecase(uppercase(<es-zed>))
00DF; 00DF; 0053 0073; 0053 0053; # LATIN SMALL LETTER SHARP S
# Ligatures
FB00; FB00; 0046 0066; 0046 0046; # LATIN SMALL LIGATURE FF
FB01; FB01; 0046 0069; 0046 0049; # LATIN SMALL LIGATURE FI
FB02; FB02; 0046 006C; 0046 004C; # LATIN SMALL LIGATURE FL
FB03; FB03; 0046 0066 0069; 0046 0046 0049; # LATIN SMALL LIGATURE FFI
FB04; FB04; 0046 0066 006C; 0046 0046 004C; # LATIN SMALL LIGATURE FFL
FB05; FB05; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE LONG S T
FB06; FB06; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE ST
0587; 0587; 0535 0582; 0535 0552; # ARMENIAN SMALL LIGATURE ECH YIWN
FB13; FB13; 0544 0576; 0544 0546; # ARMENIAN SMALL LIGATURE MEN NOW
FB14; FB14; 0544 0565; 0544 0535; # ARMENIAN SMALL LIGATURE MEN ECH
FB15; FB15; 0544 056B; 0544 053B; # ARMENIAN SMALL LIGATURE MEN INI
FB16; FB16; 054E 0576; 054E 0546; # ARMENIAN SMALL LIGATURE VEW NOW
FB17; FB17; 0544 056D; 0544 053D; # ARMENIAN SMALL LIGATURE MEN XEH
# No corresponding uppercase precomposed character
0149; 0149; 02BC 006E; 02BC 004E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
0390; 0390; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
03B0; 03B0; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
01F0; 01F0; 004A 030C; 004A 030C; # LATIN SMALL LETTER J WITH CARON
1E96; 1E96; 0048 0331; 0048 0331; # LATIN SMALL LETTER H WITH LINE BELOW
1E97; 1E97; 0054 0308; 0054 0308; # LATIN SMALL LETTER T WITH DIAERESIS
1E98; 1E98; 0057 030A; 0057 030A; # LATIN SMALL LETTER W WITH RING ABOVE
1E99; 1E99; 0059 030A; 0059 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
1E9A; 1E9A; 0041 02BE; 0041 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
1F50; 1F50; 03A5 0313; 03A5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
1F52; 1F52; 03A5 0313 0300; 03A5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
1F54; 1F54; 03A5 0313 0301; 03A5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
1F56; 1F56; 03A5 0313 0342; 03A5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
1FB6; 1FB6; 0391 0342; 0391 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
1FC6; 1FC6; 0397 0342; 0397 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
1FD2; 1FD2; 0399 0308 0300; 0399 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
1FD3; 1FD3; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
1FD6; 1FD6; 0399 0342; 0399 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
1FD7; 1FD7; 0399 0308 0342; 0399 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
1FE2; 1FE2; 03A5 0308 0300; 03A5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
1FE3; 1FE3; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
1FE4; 1FE4; 03A1 0313; 03A1 0313; # GREEK SMALL LETTER RHO WITH PSILI
1FE6; 1FE6; 03A5 0342; 03A5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
1FE7; 1FE7; 03A5 0308 0342; 03A5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
1FF6; 1FF6; 03A9 0342; 03A9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
# IMPORTANT-when capitalizing iota-subscript (0345)
# It MUST be in normalized form--moved to the end of any sequence of combining marks.
# This is because logically it represents a following base character!
# E.g. <iota_subscript> (<Mn> | <Mc> | <Me>)+ => (<Mn> | <Mc> | <Me>)+ <iota_subscript>
# It should never be the first character in a word, so in titlecasing it can be left as is.
# The following cases are already in the UnicodeData file, so are only commented here.
# 0345; 0345; 0345; 0399; # COMBINING GREEK YPOGEGRAMMENI
# All letters with YPOGEGRAMMENI (iota-subscript) or PROSGEGRAMMENI (iota adscript)
# have special uppercases.
# Note: characters with PROSGEGRAMMENI are actually titlecase, not uppercase!
1F80; 1F80; 1F88; 1F08 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
1F81; 1F81; 1F89; 1F09 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
1F82; 1F82; 1F8A; 1F0A 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F83; 1F83; 1F8B; 1F0B 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F84; 1F84; 1F8C; 1F0C 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F85; 1F85; 1F8D; 1F0D 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F86; 1F86; 1F8E; 1F0E 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F87; 1F87; 1F8F; 1F0F 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F88; 1F80; 1F88; 1F08 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
1F89; 1F81; 1F89; 1F09 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
1F8A; 1F82; 1F8A; 1F0A 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F8B; 1F83; 1F8B; 1F0B 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F8C; 1F84; 1F8C; 1F0C 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F8D; 1F85; 1F8D; 1F0D 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F8E; 1F86; 1F8E; 1F0E 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F8F; 1F87; 1F8F; 1F0F 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1F90; 1F90; 1F98; 1F28 0399; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
1F91; 1F91; 1F99; 1F29 0399; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
1F92; 1F92; 1F9A; 1F2A 0399; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F93; 1F93; 1F9B; 1F2B 0399; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F94; 1F94; 1F9C; 1F2C 0399; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F95; 1F95; 1F9D; 1F2D 0399; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F96; 1F96; 1F9E; 1F2E 0399; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F97; 1F97; 1F9F; 1F2F 0399; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F98; 1F90; 1F98; 1F28 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
1F99; 1F91; 1F99; 1F29 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
1F9A; 1F92; 1F9A; 1F2A 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F9B; 1F93; 1F9B; 1F2B 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F9C; 1F94; 1F9C; 1F2C 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F9D; 1F95; 1F9D; 1F2D 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F9E; 1F96; 1F9E; 1F2E 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F9F; 1F97; 1F9F; 1F2F 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FA0; 1FA0; 1FA8; 1F68 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
1FA1; 1FA1; 1FA9; 1F69 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
1FA2; 1FA2; 1FAA; 1F6A 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1FA3; 1FA3; 1FAB; 1F6B 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1FA4; 1FA4; 1FAC; 1F6C 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1FA5; 1FA5; 1FAD; 1F6D 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1FA6; 1FA6; 1FAE; 1F6E 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1FA7; 1FA7; 1FAF; 1F6F 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1FA8; 1FA0; 1FA8; 1F68 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1FA9; 1FA1; 1FA9; 1F69 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1FAA; 1FA2; 1FAA; 1F6A 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1FAB; 1FA3; 1FAB; 1F6B 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1FAC; 1FA4; 1FAC; 1F6C 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1FAD; 1FA5; 1FAD; 1F6D 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1FAE; 1FA6; 1FAE; 1F6E 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1FAF; 1FA7; 1FAF; 1F6F 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FB3; 1FB3; 1FBC; 0391 0399; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
1FBC; 1FB3; 1FBC; 0391 0399; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1FC3; 1FC3; 1FCC; 0397 0399; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
1FCC; 1FC3; 1FCC; 0397 0399; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1FF3; 1FF3; 1FFC; 03A9 0399; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
1FFC; 1FF3; 1FFC; 03A9 0399; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
# Some characters with YPOGEGRAMMENI are also have no corresponding titlecases
1FB2; 1FB2; 1FBA 0345; 1FBA 0399; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
1FB4; 1FB4; 0386 0345; 0386 0399; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
1FC2; 1FC2; 1FCA 0345; 1FCA 0399; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
1FC4; 1FC4; 0389 0345; 0389 0399; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
1FF2; 1FF2; 1FFA 0345; 1FFA 0399; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
1FF4; 1FF4; 038F 0345; 038F 0399; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
1FB7; 1FB7; 0391 0342 0345; 0391 0342 0399; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
1FC7; 1FC7; 0397 0342 0345; 0397 0342 0399; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
1FF7; 1FF7; 03A9 0342 0345; 03A9 0342 0399; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
# ================================================================================
# Conditional mappings
# ================================================================================
# Special case for final form of sigma
03A3; 03C2; 03A3; 03A3; FINAL; # GREEK CAPITAL LETTER SIGMA
# Note: the following cases for non-final are already in the UnicodeData file.
# 03A3; 03C3; 03A3; 03A3; # GREEK CAPITAL LETTER SIGMA
# 03C3; 03C3; 03A3; 03A3; # GREEK SMALL LETTER SIGMA
# 03C2; 03C2; 03A3; 03A3; # GREEK SMALL LETTER FINAL SIGMA
# Note: the following cases are not included, since they would normalize in lowercasing
# 03C3; 03C2; 03A3; 03A3; FINAL; # GREEK SMALL LETTER SIGMA
# 03C2; 03C3; 03A3; 03A3; NON_FINAL; # GREEK SMALL LETTER FINAL SIGMA
# ================================================================================
# Locale-sensitive mappings
# ================================================================================
# Turkish
0049; 0131; 0049; 0049; TR; # LATIN CAPITAL LETTER I
0069; 0069; 0130; 0130; TR; # LATIN SMALL LETTER I
# Note: the following cases are already in the UnicodeData file.
# 0131; 0131; 0049; 0049; TR; # LATIN SMALL LETTER DOTLESS I
# 0130; 0069; 0130; 0130; TR; # LATIN CAPITAL LETTER I WITH DOT ABOVE

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,54 @@
/**
* $RCSfile: CalendarApp.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
//import java.text.SimpleDateFormat;
//import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
import com.ibm.text.*;
/**
* CalendarApp demonstrates how Calendar works.
*/
public class CalendarApp extends DemoApplet
{
/**
* The main function which defines the behavior of the CalendarDemo
* applet when an applet is started.
*/
public static void main(String argv[]) {
new CalendarApp().showDemo();
}
/* This creates a CalendarFrame for the demo applet. */
public Frame createDemoFrame(DemoApplet applet) {
return new CalendarFrame(applet);
}
}

View file

@ -0,0 +1,550 @@
/*
* $RCSfile: CalendarCalc.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.util.Date;
import java.awt.*;
import java.awt.event.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParsePosition;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.Locale;
import com.ibm.util.*;
import javax.swing.*;
/**
* CalendarCalc demonstrates how Date/Time formatter works.
*/
public class CalendarCalc extends DemoApplet
{
/**
* 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
{
private static final String creditString = "";
static final Locale[] locales = DemoUtility.getG7Locales();
private static final boolean DEBUG = false;
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].format.toPattern() );
// Force an update of the display
cityChanged();
millisFormat();
}
//------------------------------------------------------------
// 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);
}
rollAddPanel.add(dateLabel);
rollAddPanel.add(dateMenu);
rollAddPanel.add(rollAddBoxes);
rollAddPanel.add(upDown);
}
Panel localePanel = new Panel();
{
// Make the locale popup menus
localeMenu= new Choice();
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());
}
if (locales[i].getLanguage().equals(Locale.getDefault().getLanguage())) {
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);
}
/**
* Called if an action occurs in the CalendarCalcFrame object.
*/
public boolean action(Event evt, Object obj)
{
// *** Button events are handled here.
if (evt.target instanceof Button) {
if (evt.target == up) {
dateFieldChanged(false);
return true;
} else
if (evt.target == down) {
dateFieldChanged(true);
return true;
}
}
return super.action(evt, obj);
}
/**
* 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.
*/
public boolean handleEvent(Event evt)
{
if (evt.id == Event.KEY_RELEASE && evt.target == patternText) {
patternTextChanged();
return true;
}
else if (evt.id == Event.KEY_RELEASE) {
for (int i = 0; i < calendars.length; i++) {
if (evt.target == calendars[i].text) {
textChanged(i);
return true;
}
}
}
else if (evt.id == Event.ACTION_EVENT && evt.target == up) {
dateFieldChanged(true);
return true;
}
else if (evt.id == Event.ACTION_EVENT && evt.target == down) {
dateFieldChanged(false);
return true;
}
else if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else System.exit(0);
return true;
}
return super.handleEvent(evt);
}
/**
* 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 up) {
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, up ? 1 : -1);
} else {
c.roll(field, up);
}
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);
}
}
private static final int FIELD_COLUMNS = 35;
private static final String DEFAULT_FORMAT = "EEEE MMMM d, yyyy G";
class CalendarRec {
public CalendarRec(String nameStr, java.util.Calendar cal)
{
name = nameStr;
calendar = cal;
rollAdd = new Checkbox();
text = new JTextField("",FIELD_COLUMNS);
text.setFont(DemoUtility.editFont);
format = (SimpleDateFormat) IBMCalendar.getDateFormat(cal, DateFormat.FULL,
Locale.getDefault());
//format.applyPattern(DEFAULT_FORMAT);
}
public void setLocale(Locale loc) {
String pattern = format.toPattern();
format = (SimpleDateFormat) IBMCalendar.getDateFormat(calendar, DateFormat.FULL,
loc);
format.applyPattern(pattern);
}
public void applyPattern(String pattern) {
format.applyPattern(pattern);
}
java.util.Calendar calendar;
SimpleDateFormat 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;
};

View file

@ -0,0 +1,407 @@
/**
* $RCSfile: CalendarFrame.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
//import java.text.SimpleDateFormat;
//import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
import com.ibm.text.*;
/**
* 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
{
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();
int selectMe = 1;
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());
}
if (locales[i].getLanguage().equals(Locale.getDefault().getLanguage())) {
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++) {
if (monthFormat[i] == null) { // TODO: optimize
SimpleDateFormat f = (SimpleDateFormat) IBMCalendar.getDateTimeFormat(
calendars[i], DateFormat.MEDIUM, -1,
locales[displayMenu.getSelectedIndex()]);
f.applyPattern("MMMM, yyyy G");
f.setTimeZone(new SimpleTimeZone(0, "UTC"));
monthFormat[i] = f;
}
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 {
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, java.util.Calendar cal)
{
name = nameStr;
calendar = cal;
}
java.util.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 };
}

View file

@ -0,0 +1,368 @@
/**
* $RCSfile: CalendarPanel.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.calendar;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
//import java.text.SimpleDateFormat;
//import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
import com.ibm.text.*;
class CalendarPanel extends Canvas {
public CalendarPanel( Locale locale ) {
setLocale(locale);
}
public void setLocale(Locale locale) {
if (fDisplayLocale == null || !fDisplayLocale.equals(locale)) {
fDisplayLocale = locale;
dirty = true;
for (int i = 0; i < fCalendar.length; i++) {
if (fCalendar[i] != null) {
fSymbols[i] = IBMCalendar.getDateFormatSymbols(fCalendar[i],
fDisplayLocale);
}
}
String lang = locale.getLanguage();
leftToRight = !(lang.equals("iw") || lang.equals("ar"));
repaint();
}
}
public void setDate(Date date) {
fStartOfMonth = date;
dirty = true;
repaint();
}
public void add(int field, int delta)
{
synchronized(fCalendar) {
fCalendar[0].setTime(fStartOfMonth);
fCalendar[0].add(field, delta);
fStartOfMonth = fCalendar[0].getTime();
}
dirty = true;
repaint();
}
public void setColor(int index, Color c) {
fColor[index] = c;
repaint();
}
public void setCalendar(int index, Calendar c) {
Date date = (fCalendar[index] == null) ? new Date()
: fCalendar[index].getTime();
fCalendar[index] = c;
fCalendar[index].setTime(date);
fSymbols[index] = IBMCalendar.getDateFormatSymbols(c, fDisplayLocale);
dirty = true;
repaint();
}
public Calendar getCalendar(int index) {
return fCalendar[index];
}
public Locale getDisplayLocale() {
return fDisplayLocale;
}
public Date firstOfMonth() {
return fStartOfMonth;
}
private Date startOfMonth(Date dateInMonth)
{
synchronized(fCalendar) {
fCalendar[0].setTime(dateInMonth);
int era = fCalendar[0].get(Calendar.ERA);
int year = fCalendar[0].get(Calendar.YEAR);
int month = fCalendar[0].get(Calendar.MONTH);
fCalendar[0].clear();
fCalendar[0].set(Calendar.ERA, era);
fCalendar[0].set(Calendar.YEAR, year);
fCalendar[0].set(Calendar.MONTH, month);
fCalendar[0].set(Calendar.DATE, 1);
return fCalendar[0].getTime();
}
}
private void calculate()
{
//
// As a workaround for JDK 1.1.3 and below, where Calendars and time
// zones are a bit goofy, always set my calendar's time zone to UTC.
// You would think I would want to do this in the "set" function above,
// but if I do that, the program hangs when this class is loaded,
// perhaps due to some sort of static initialization ordering problem.
// So I do it here instead.
//
fCalendar[0].setTimeZone(new SimpleTimeZone(0, "UTC"));
Calendar c = (Calendar)fCalendar[0].clone(); // Temporary copy
fStartOfMonth = startOfMonth(fStartOfMonth);
// Stash away a few useful constants for this calendar and display
minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
// Stash away a Date for the start of this month
// Find the day of week of the first day in this month
c.setTime(fStartOfMonth);
firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
int firstWeek = c.get(Calendar.WEEK_OF_MONTH);
// Now find the # of days in the month
c.roll(Calendar.DATE, false);
daysInMonth = c.get(Calendar.DATE);
// Finally, find the end of the month, i.e. the start of the next one
c.roll(Calendar.DATE, true);
c.add(Calendar.MONTH, 1);
c.getTime(); // JDK 1.1.2 bug workaround
c.add(Calendar.SECOND, -1);
Date endOfMonth = c.getTime();
int lastWeek = c.get(Calendar.WEEK_OF_MONTH);
// Calculate the number of full or partial weeks in this month.
numWeeks = lastWeek - firstWeek + 1;
dirty = false;
}
static final int XINSET = 4;
static final int YINSET = 2;
/*
* Convert from the day number within a month (1-based)
* to the cell coordinates on the calendar (0-based)
*/
private void dateToCell(int date, Point pos)
{
int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
if (firstDayInMonth < firstDayOfWeek) {
cell += daysInWeek;
}
pos.x = cell % daysInWeek;
pos.y = cell / daysInWeek;
}
private Point dateToCell(int date) {
Point p = new Point(0,0);
dateToCell(date, p);
return p;
}
public void paint(Graphics g) {
if (dirty) {
calculate();
}
Point cellPos = new Point(0,0); // Temporary variable
Dimension d = this.getSize();
g.setColor(Color.lightGray);
g.fillRect(0,0,d.width,d.height);
// Draw the day names at the top
g.setColor(Color.black);
g.setFont(DemoUtility.labelFont);
FontMetrics fm = g.getFontMetrics();
int labelHeight = fm.getHeight() + YINSET * 2;
int v = fm.getAscent() + YINSET;
for (int i = 0; i < daysInWeek; i++) {
int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
String dayName = fSymbols[0].getWeekdays()[dayNum];
double h;
if (leftToRight) {
h = d.width*(i + 0.5) / daysInWeek;
} else {
h = d.width*(daysInWeek - i - 0.5) / daysInWeek;
}
h -= fm.stringWidth(dayName) / 2;
g.drawString(dayName, (int)h, v);
}
double cellHeight = (d.height - labelHeight - 1) / numWeeks;
double cellWidth = (double)(d.width - 1) / daysInWeek;
// Draw a white background in the part of the calendar
// that displays this month.
// First figure out how much of the first week should be shaded.
{
g.setColor(Color.white);
dateToCell(1, cellPos);
int width = (int)(cellPos.x*cellWidth); // Width of unshaded area
if (leftToRight) {
g.fillRect((int)(width), labelHeight ,
d.width - width, (int)cellHeight);
} else {
g.fillRect(0, labelHeight ,
d.width - width, (int)cellHeight);
}
// All of the intermediate weeks get shaded completely
g.fillRect(0, (int)(labelHeight + cellHeight),
d.width, (int)(cellHeight * (numWeeks - 2)));
// Now figure out the last week.
dateToCell(daysInMonth, cellPos);
width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area
if (leftToRight) {
g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
width, (int)cellHeight);
} else {
g.fillRect(d.width - width, (int)(labelHeight + (numWeeks-1) * cellHeight),
width, (int)cellHeight);
}
}
// Draw the X/Y grid lines
g.setColor(Color.black);
for (int i = 0; i <= numWeeks; i++) {
int y = (int)(labelHeight + i * cellHeight);
g.drawLine(0, y, d.width - 1, y);
}
for (int i = 0; i <= daysInWeek; i++) {
int x = (int)(i * cellWidth);
g.drawLine(x, labelHeight, x, d.height - 1);
}
// Now loop through all of the days in the month, figure out where
// they go in the grid, and draw the day # for each one
// Figure out the date of the first cell in the calendar display
int cell = (1 + firstDayInMonth - firstDayOfWeek - minDay);
if (firstDayInMonth < firstDayOfWeek) {
cell += daysInWeek;
}
Calendar c = (Calendar)fCalendar[0].clone();
c.setTime(fStartOfMonth);
c.add(Calendar.DATE, -cell);
StringBuffer buffer = new StringBuffer();
for (int row = 0; row < numWeeks; row++) {
for (int col = 0; col < daysInWeek; col++) {
g.setFont(DemoUtility.numberFont);
g.setColor(Color.black);
fm = g.getFontMetrics();
int cellx;
if (leftToRight) {
cellx = (int)((col) * cellWidth);
} else {
cellx = (int)((daysInWeek - col - 1) * cellWidth);
}
int celly = (int)(row * cellHeight + labelHeight);
for (int i = 0; i < 2; i++) {
fCalendar[i].setTime(c.getTime());
int date = fCalendar[i].get(Calendar.DATE);
buffer.setLength(0);
buffer.append(date);
String dayNum = buffer.toString();
int x;
if (leftToRight) {
x = cellx + (int)cellWidth - XINSET - fm.stringWidth(dayNum);
} else {
x = cellx + XINSET;
}
int y = celly + + fm.getAscent() + YINSET + i * fm.getHeight();
if (fColor[i] != null) {
g.setColor(fColor[i]);
}
g.drawString(dayNum, x, y);
if (date == 1 || row == 0 && col == 0) {
g.setFont(DemoUtility.numberFont);
String month = fSymbols[i].getMonths()[
fCalendar[i].get(Calendar.MONTH)];
if (leftToRight) {
x = cellx + XINSET;
} else {
x = cellx + (int)cellWidth - XINSET - fm.stringWidth(month);
}
g.drawString(month, x, y);
}
}
c.add(Calendar.DATE, 1);
}
}
}
// Important state variables
private Calendar[] fCalendar = new Calendar[4];
private Color[] fColor = new Color[4];
private Locale fDisplayLocale;
private DateFormatSymbols[] fSymbols = new DateFormatSymbols[4];
private Date fStartOfMonth = new Date(); // 00:00:00 on first day of month
// Cached calculations to make drawing faster.
private transient int minDay; // Minimum legal day #
private transient int daysInWeek; // # of days in a week
private transient int firstDayOfWeek; // First day to display in week
private transient int numWeeks; // # full or partial weeks in month
private transient int daysInMonth; // # days in this month
private transient int firstDayInMonth; // Day of week of first day in month
private transient boolean leftToRight;
private transient boolean dirty = true;
}

View file

@ -0,0 +1,552 @@
/* ************************************************************* */
/* (C) Copyright Taligent, Inc. 1996-All Rights Reserved. */
/* (C) Copyright IBM Corporation 1996 - 1998 */
/* */
/* Permission is granted to copy, use, modify, and merge this */
/* software into your applications and to permit others to do */
/* any of the foregoing. You must include this permission and */
/* copyright notice in all copies and modified versions of this */
/* software, and include attribution to Taligent in all splash */
/* screens included in any application using this software. */
/* THIS SOFTWARE IS PROVIDED IN ITS 'AS IS' CONDITION. TALIGENT */
/* DISCLAIMS ANY LIABILITY OF ANY KIND FOR DAMAGES WHATSOEVER */
/* RESULTING FROM THE USE OF THIS SOFTWARE. */
/* ************************************************************* */
package com.ibm.demo.holiday;
import com.ibm.demo.*;
import java.awt.*;
/**
* Various graphical borders. The border itself is a Panel so that it can
* contain other Components (i.e. it borders something). You use the
* HolidayBorderPanel like any other Panel: you set the layout that you prefer and
* add Components to it. Beware that a null layout does not obey the insets
* of the panel so if you use null layouts, adjust your measurements to
* handle the border by calling insets().
*
* @author Andy Clark, Taligent Inc.
* @version 1.0
*/
public class HolidayBorderPanel extends Panel {
// Constants
/** Solid border. */
public final static int SOLID = 0;
/** A raised border. */
public final static int RAISED = 1;
/** A lowered border. */
public final static int LOWERED = 2;
/** An etched in border. */
public final static int IN = 3;
/** An etched out border. */
public final static int OUT = 4;
/** Left alignment. */
public final static int LEFT = 0;
/** Center alignment. */
public final static int CENTER = 1;
/** Right alignment. */
public final static int RIGHT = 2;
/** Default style (IN). */
public final static int DEFAULT_STYLE = IN;
/** Default thickness (10). */
public final static int DEFAULT_THICKNESS = 10;
/** Default thickness for solid borders (4). */
public final static int DEFAULT_SOLID_THICKNESS = 4;
/** Default thickness for raised borders (2). */
public final static int DEFAULT_RAISED_THICKNESS = 2;
/** Default thickness for lowered borders (2). */
public final static int DEFAULT_LOWERED_THICKNESS = 2;
/** Default thickness for etched-in borders (10). */
public final static int DEFAULT_IN_THICKNESS = 10;
/** Default thickness for etched-out borders (10). */
public final static int DEFAULT_OUT_THICKNESS = 10;
/** Default gap between border and contained component (5). */
public final static int DEFAULT_GAP = 5;
/** Default color (black). Applies to SOLID and etched borders. */
public final static Color DEFAULT_COLOR = Color.black;
/** Default font (TimesRoman,PLAIN,14). Only applies to etched borders. */
public final static Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14);
/** Default alignment (LEFT). Only applies to etched borders. */
public final static int DEFAULT_ALIGNMENT = LEFT;
// Data
private int style;
private int thickness;
private int gap;
private Color color;
private Font font;
private String text;
private int alignment;
/**
* Constructor. Makes default border.
*/
public HolidayBorderPanel() {
// initialize data
style = DEFAULT_STYLE;
thickness = DEFAULT_THICKNESS;
gap = DEFAULT_GAP;
color = DEFAULT_COLOR;
text = null;
font = DEFAULT_FONT;
alignment = DEFAULT_ALIGNMENT;
}
/**
* Constructor. Makes an etched IN border with given text caption.
*
* @param text Text caption
*/
public HolidayBorderPanel(String text) {
this();
style = IN;
this.text = text;
}
/**
* Constructor. Makes SOLID border with color and thickness given.
*
* @param color The color for the border.
* @param thickness The thickness of the border.
*/
public HolidayBorderPanel(Color color, int thickness) {
this();
style = SOLID;
this.color = color;
this.thickness = thickness;
}
/**
* Constructor. Makes a border of the given style with the default
* thickness for that style.
*
* @param style The style for this border.
*/
public HolidayBorderPanel(int style) {
this();
// set thickness appropriate to this style
int thickness;
switch (style) {
case SOLID: thickness = DEFAULT_SOLID_THICKNESS; break;
case RAISED: thickness = DEFAULT_RAISED_THICKNESS; break;
case LOWERED: thickness = DEFAULT_LOWERED_THICKNESS; break;
case IN: thickness = DEFAULT_IN_THICKNESS; break;
case OUT: thickness = DEFAULT_OUT_THICKNESS; break;
default:
thickness = DEFAULT_THICKNESS;
}
this.style = style;
this.thickness = thickness;
}
/**
* Constructor. Makes border with given style and thickness.
*
* @param style The style for this border.
* @param thickness The thickness for this border.
*/
public HolidayBorderPanel(int style, int thickness) {
this();
this.style = style;
this.thickness = thickness;
}
/**
* Returns the insets of this panel..
*/
public Insets insets() {
int adjustment = 0;
// adjust for text string
if (style == IN || style == OUT) {
if (text != null && text.length() > 0) {
try {
// set font and get info
int height = getGraphics().getFontMetrics(font).getHeight();
if (height > thickness)
adjustment = height - thickness;
}
catch (Exception e) {
// nothing: just in case there is no graphics context
// at the beginning.
}
}
}
// return appropriate insets
int dist = thickness + gap;
return new Insets(dist + adjustment, dist, dist, dist);
}
/**
* Sets the style of the border
*
* @param style The new style.
*/
public HolidayBorderPanel setStyle(int style) {
// set the style and re-layout the panel
this.style = style;
layout();
repaint();
return this;
}
/**
* Gets the style of the border
*/
public int getStyle() {
return style;
}
/**
* Sets the thickness of the border.
*
* @param thickness The new thickness
*/
public HolidayBorderPanel setThickness(int thickness) {
if (thickness > 0) {
this.thickness = thickness;
layout();
repaint();
}
return this;
}
/**
* Gets the thickness of the border.
*/
public int getThickness() {
return thickness;
}
/**
* Sets the gap between the border and the contained Component.
*
* @param gap The new gap, in pixels.
*/
public HolidayBorderPanel setGap(int gap) {
if (gap > -1) {
this.gap = gap;
layout();
repaint();
}
return this;
}
/**
* Gets the gap between the border and the contained Component.
*/
public int getGap() {
return gap;
}
/**
* Sets the current color for SOLID borders and the caption text
* color for etched borders.
*
* @param color The new color.
*/
public HolidayBorderPanel setColor(Color color) {
this.color = color;
if (style == SOLID || style == IN || style == OUT)
repaint();
return this;
}
/**
* Gets the current color for SOLID borders and the caption
* text color for etched borders.
*/
public Color getColor() {
return color;
}
/**
* Sets the font. Only applies to etched borders.
*/
public HolidayBorderPanel setTextFont(Font font) {
// set font
if (font != null) {
this.font = font;
if (style == IN || style == OUT) {
layout();
repaint();
}
}
return this;
}
/**
* Gets the font of the text. Only applies to etched borders.
*/
public Font getTextFont() {
return font;
}
/**
* Sets the text. Only applies to etched borders.
*
* @param text The new text.
*/
public HolidayBorderPanel setText(String text) {
this.text = text;
if (style == IN || style == OUT) {
layout();
repaint();
}
return this;
}
/**
* Gets the text. Only applies to etched borders.
*/
public String getText() {
return text;
}
/**
* Sets the text alignment. Only applies to etched borders.
*
* @param alignment The new alignment.
*/
public HolidayBorderPanel setAlignment(int alignment) {
this.alignment = alignment;
if (style == IN || style == OUT) {
layout();
repaint();
}
return this;
}
/**
* Gets the text alignment.
*/
public int getAlignment() {
return alignment;
}
/**
* Repaints the border.
*
* @param g The graphics context.
*/
public void paint(Graphics g) {
// get current dimensions
Dimension size = size();
int width = size.width;
int height = size.height;
// set colors
Color light = getBackground().brighter().brighter().brighter();
Color dark = getBackground().darker().darker().darker();
// Draw border
switch (style) {
case RAISED: // 3D Border (in or out)
case LOWERED:
Color topleft = null;
Color bottomright = null;
// set colors
if (style == RAISED) {
topleft = light;
bottomright = dark;
}
else {
topleft = dark;
bottomright = light;
}
// draw border
g.setColor(topleft);
for (int i = 0; i < thickness; i++) {
g.drawLine(i, i, width - i - 2, i);
g.drawLine(i, i + 1, i, height - i - 1);
}
g.setColor(bottomright);
for (int i = 0; i < thickness; i++) {
g.drawLine(i + 1, height - i - 1, width - i - 1, height - i - 1);
g.drawLine(width - i - 1, i, width - i - 1, height - i - 2);
}
break;
case IN: // Etched Border (in or out)
case OUT:
int adjust1 = 0;
int adjust2 = 0;
// set font and get info
Font oldfont = g.getFont();
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
int ascent = fm.getAscent();
// set adjustment
if (style == IN)
adjust1 = 1;
else
adjust2 = 1;
// Calculate adjustment for text
int adjustment = 0;
if (text != null && text.length() > 0) {
if (ascent > thickness)
adjustment = (ascent - thickness) / 2;
}
// The adjustment is there so that we always draw the
// light rectangle first. Otherwise, your eye picks up
// the discrepancy where the light rect. passes over
// the darker rect.
int x = thickness / 2;
int y = thickness / 2 + adjustment;
int w = width - thickness - 1;
int h = height - thickness - 1 - adjustment;
// draw rectangles
g.setColor(light);
g.drawRect(x + adjust1, y + adjust1, w, h);
g.setColor(dark);
g.drawRect(x + adjust2, y + adjust2, w, h);
// draw text, if applicable
if (text != null && text.length() > 0) {
// calculate drawing area
int fontheight = fm.getHeight();
int strwidth = fm.stringWidth(text);
int textwidth = width - 2 * (thickness + 5);
if (strwidth > textwidth)
strwidth = textwidth;
// calculate offset for alignment
int offset;
switch (alignment) {
case CENTER:
offset = (width - strwidth) / 2;
break;
case RIGHT:
offset = width - strwidth - thickness - 5;
break;
case LEFT:
default: // assume left alignment if invalid
offset = thickness + 5;
break;
}
// clear drawing area and set clipping region
g.clearRect(offset - 5, 0, strwidth + 10, fontheight);
g.clipRect(offset, 0, strwidth, fontheight);
// draw text
g.setColor(color);
g.drawString(text, offset, ascent);
// restore old clipping area
g.clipRect(0, 0, width, height);
}
g.setFont(oldfont);
break;
case SOLID:
default: // assume SOLID
g.setColor(color);
for (int i = 0; i < thickness; i++)
g.drawRect(i, i, width - 2 * i - 1, height - 2 * i - 1);
}
}
/**
* Returns the settings of this HolidayBorderPanel instance as a string.
*/
public String toString() {
StringBuffer str = new StringBuffer("HolidayBorderPanel[");
// style
str.append("style=");
switch (style) {
case SOLID: str.append("SOLID"); break;
case RAISED: str.append("RAISED"); break;
case LOWERED: str.append("LOWERED"); break;
case IN: str.append("IN"); break;
case OUT: str.append("OUT"); break;
default: str.append("unknown");
}
str.append(",");
// thickness
str.append("thickness=");
str.append(thickness);
str.append(",");
// gap
str.append("gap=");
str.append(gap);
str.append(",");
// color
str.append(color);
str.append(",");
// font
str.append(font);
str.append(",");
// text
str.append("text=");
str.append(text);
str.append(",");
// alignment
str.append("alignment=");
switch (alignment) {
case LEFT: str.append("LEFT"); break;
case CENTER: str.append("CENTER"); break;
case RIGHT: str.append("RIGHT"); break;
default: str.append("unknown");
}
str.append("]");
return str.toString();
}
}

View file

@ -0,0 +1,714 @@
/*
* $RCSfile: HolidayCalendarDemo.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
*/
package com.ibm.demo.holiday;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
import java.util.*;
import com.ibm.util.*;
/**
* CalendarDemo demonstrates how Calendar works.
*/
public class HolidayCalendarDemo extends DemoApplet
{
/**
* The main function which defines the behavior of the CalendarDemo
* applet when an applet is started.
*/
public static void main(String argv[]) {
new HolidayCalendarDemo().showDemo();
}
/* This creates a CalendarFrame for the demo applet. */
public Frame createDemoFrame(DemoApplet applet) {
return new CalendarFrame(applet);
}
/**
* 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.
*/
private static class CalendarFrame extends Frame
{
private static final String creditString = "";
private static final boolean DEBUG = false;
private Locale curLocale = Locale.US;
private DemoApplet applet;
private static final Locale[] calendars = {
//new Locale("de","AT"),
Locale.CANADA,
Locale.CANADA_FRENCH,
Locale.FRANCE,
Locale.GERMANY,
new Locale("iw","IL"),
new Locale("el","GR"),
//new Locale("es","MX"),
Locale.UK,
Locale.US,
};
private static final Locale[] displays = {
Locale.CANADA,
Locale.UK,
Locale.US,
Locale.FRANCE,
Locale.CANADA_FRENCH,
//new Locale("de","AT"),
Locale.GERMAN,
new Locale("el","GR"),
//new Locale("iw","IL"),
new Locale("es","MX"),
};
/**
* Constructs a new CalendarFrame that is initially invisible.
*/
public CalendarFrame(DemoApplet applet)
{
super("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()
{
// Get G7 locales only for demo purpose. To get all the locales
// supported, switch to calling Calendar.getAvailableLocales().
// commented
locales = displays;
buildGUI();
}
//------------------------------------------------------------
// 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
}
private Choice localeMenu;
private Choice displayMenu;
private Locale[] locales;
private Label monthLabel;
private Button prevYear;
private Button prevMonth;
private Button gotoToday;
private Button nextMonth;
private Button nextYear;
private CalendarPanel calendarPanel;
private static final Locale kFirstLocale = Locale.US;
private static void add(Container container, Component component,
GridBagLayout g, GridBagConstraints c)
{
g.setConstraints(component, c);
container.add(component);
}
public void buildGUI()
{
setBackground(DemoUtility.bgColor);
setLayout(new BorderLayout(10,10));
// Label for the demo's title
Label titleLabel = new Label("Calendar Demo", Label.CENTER);
titleLabel.setFont(DemoUtility.titleFont);
// Label for the current month name
monthLabel = new Label("", Label.LEFT);
monthLabel.setFont(new Font(DemoUtility.titleFont.getName(),
DemoUtility.titleFont.getStyle(),
(DemoUtility.titleFont.getSize() * 3)/2));
// Make the locale popup menus
localeMenu= new Choice();
int selectMe = 0;
for (int i = 0; i < calendars.length; i++) {
if (i > 0 &&
calendars[i].getCountry().equals(calendars[i-1].getCountry()) ||
i < calendars.length - 1 &&
calendars[i].getCountry().equals(calendars[i+1].getCountry()))
{
localeMenu.addItem(calendars[i].getDisplayCountry() + " (" +
calendars[i].getDisplayLanguage() + ")");
} else {
localeMenu.addItem( calendars[i].getDisplayCountry() );
}
if (calendars[i].equals(kFirstLocale)) {
selectMe = i;
}
}
localeMenu.setBackground(DemoUtility.choiceColor);
localeMenu.select(selectMe);
displayMenu = new Choice();
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());
}
}
displayMenu.setBackground(DemoUtility.choiceColor);
displayMenu.select(kFirstLocale.getDisplayName());
// Make all the next/previous/today buttons
prevYear = new Button("<<");
prevMonth = new Button("<");
gotoToday = new Button("Today");
nextMonth = new Button(">");
nextYear = new Button(">>");
// The month name and the control buttons are bunched together
Panel monthPanel = new Panel();
{
GridBagLayout g = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
monthPanel.setLayout(g);
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = GridBagConstraints.REMAINDER;
add(monthPanel, monthLabel, g, c);
c.gridwidth = 1;
add(monthPanel, prevYear, g, c);
add(monthPanel, prevMonth, g, c);
add(monthPanel, gotoToday, g, c);
add(monthPanel, nextMonth, g, c);
c.gridwidth = GridBagConstraints.REMAINDER;
add(monthPanel, nextYear, g, c);
}
// Stick the menu and buttons in a little "control panel"
Panel menuPanel = new Panel();
{
GridBagLayout g = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
menuPanel.setLayout(g);
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = GridBagConstraints.RELATIVE;
Label l1 = new Label("Holidays");
l1.setFont(DemoUtility.labelFont);
add(menuPanel, l1, g, c);
c.gridwidth = GridBagConstraints.REMAINDER;
add(menuPanel, localeMenu, g, c);
c.gridwidth = GridBagConstraints.RELATIVE;
Label l2 = new Label("Display:");
l2.setFont(DemoUtility.labelFont);
add(menuPanel, l2, g, c);
c.gridwidth = GridBagConstraints.REMAINDER;
add(menuPanel, displayMenu, g, c);
}
// The title, buttons, etc. go in a panel at the top of the window
Panel topPanel = new Panel();
{
topPanel.setLayout(new BorderLayout());
//topPanel.add("North", titleLabel);
topPanel.add("Center", monthPanel);
topPanel.add("East", menuPanel);
}
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( kFirstLocale );
add("Center", calendarPanel);
updateMonthName();
}
/**
* Called if an action occurs in the CalendarFrame object.
*/
public boolean action(Event evt, Object obj)
{
// *** Button events are handled here.
boolean handled = false;
if (evt.target instanceof Button) {
if (evt.target == nextMonth) {
calendarPanel.add(Calendar.MONTH, +1);
handled = true;
}
else
if (evt.target == prevMonth) {
calendarPanel.add(Calendar.MONTH, -1);
handled = true;
}
else
if (evt.target == prevYear) {
calendarPanel.add(Calendar.YEAR, -1);
handled = true;
}
else
if (evt.target == nextYear) {
calendarPanel.add(Calendar.YEAR, +1);
handled = true;
}
else
if (evt.target == gotoToday) {
calendarPanel.set( new Date() );
handled = true;
}
if (handled) {
updateMonthName();
}
}
return handled || super.action(evt, obj);
}
private void updateMonthName()
{
SimpleDateFormat f = new SimpleDateFormat("MMMM yyyyy",
calendarPanel.getDisplayLocale());
f.setCalendar(calendarPanel.getCalendar());
f.setTimeZone(new SimpleTimeZone(0, "UTC")); // JDK 1.1.2 workaround
monthLabel.setText( f.format( calendarPanel.firstOfMonth() ));
}
/**
* 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.
*/
public boolean handleEvent(Event evt)
{
if (evt.id == Event.ACTION_EVENT && evt.target == localeMenu) {
calendarPanel.setCalendarLocale(calendars[localeMenu.getSelectedIndex()]);
updateMonthName();
return true;
}
if (evt.id == Event.ACTION_EVENT && evt.target == displayMenu) {
calendarPanel.setDisplayLocale(locales[displayMenu.getSelectedIndex()]);
updateMonthName();
return true;
}
else
if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else {
System.exit(0);
}
return true;
}
return super.handleEvent(evt);
}
/**
* Print out the error message while debugging this program.
*/
public void errorText(String s)
{
if (DEBUG)
{
System.out.println(s);
}
}
}
private static class CalendarPanel extends Canvas {
public CalendarPanel( Locale locale ) {
set(locale, locale, new Date());
}
public void setCalendarLocale(Locale locale) {
set(locale, fDisplayLocale, fCalendar.getTime());
}
public void setDisplayLocale(Locale locale) {
set(fCalendarLocale, locale, fCalendar.getTime());
}
public void set(Date date) {
set(fCalendarLocale, fDisplayLocale, date);
}
public void set(Locale loc, Locale display, Date date)
{
if (fCalendarLocale == null || !loc.equals(fCalendarLocale)) {
fCalendarLocale = loc;
fCalendar = Calendar.getInstance(fCalendarLocale);
fAllHolidays = Holiday.getHolidays(fCalendarLocale);
}
if (fDisplayLocale == null || !display.equals(fDisplayLocale)) {
fDisplayLocale = display;
fSymbols = new DateFormatSymbols(fDisplayLocale);
}
fStartOfMonth = date;
dirty = true;
repaint();
}
public void add(int field, int delta)
{
synchronized(fCalendar) {
fCalendar.setTime(fStartOfMonth);
fCalendar.add(field, delta);
fStartOfMonth = fCalendar.getTime();
}
dirty = true;
repaint();
}
public Calendar getCalendar() {
return fCalendar;
}
public Locale getCalendarLocale() {
return fCalendarLocale;
}
public Locale getDisplayLocale() {
return fDisplayLocale;
}
public Date firstOfMonth() {
return fStartOfMonth;
}
private Date startOfMonth(Date dateInMonth)
{
synchronized(fCalendar) {
fCalendar.setTime(dateInMonth); // TODO: synchronization
int era = fCalendar.get(Calendar.ERA);
int year = fCalendar.get(Calendar.YEAR);
int month = fCalendar.get(Calendar.MONTH);
fCalendar.clear();
fCalendar.set(Calendar.ERA, era);
fCalendar.set(Calendar.YEAR, year);
fCalendar.set(Calendar.MONTH, month);
fCalendar.set(Calendar.DATE, 1);
return fCalendar.getTime();
}
}
private void calculate()
{
//
// As a workaround for JDK 1.1.3 and below, where Calendars and time
// zones are a bit goofy, always set my calendar's time zone to UTC.
// You would think I would want to do this in the "set" function above,
// but if I do that, the program hangs when this class is loaded,
// perhaps due to some sort of static initialization ordering problem.
// So I do it here instead.
//
fCalendar.setTimeZone(new SimpleTimeZone(0, "UTC"));
Calendar c = (Calendar)fCalendar.clone(); // Temporary copy
fStartOfMonth = startOfMonth(fStartOfMonth);
// Stash away a few useful constants for this calendar and display
minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
// Stash away a Date for the start of this month
// Find the day of week of the first day in this month
c.setTime(fStartOfMonth);
firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
// Now find the # of days in the month
c.roll(Calendar.DATE, false);
daysInMonth = c.get(Calendar.DATE);
// Finally, find the end of the month, i.e. the start of the next one
c.roll(Calendar.DATE, true);
c.add(Calendar.MONTH, 1);
c.getTime(); // JDK 1.1.2 bug workaround
c.add(Calendar.SECOND, -1);
Date endOfMonth = c.getTime();
//
// Calculate the number of full or partial weeks in this month.
// To do this I can just reuse the code that calculates which
// calendar cell contains a given date.
//
numWeeks = dateToCell(daysInMonth).y - dateToCell(1).y + 1;
// Remember which holidays fall on which days in this month,
// to save the trouble of having to do it later
fHolidays.setSize(0);
for (int h = 0; h < fAllHolidays.length; h++)
{
Date d = fStartOfMonth;
while ( (d = fAllHolidays[h].firstBetween(d, endOfMonth) ) != null)
{
c.setTime(d);
fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE),
fAllHolidays[h],
fAllHolidays[h].getDisplayName(fDisplayLocale) ));
d.setTime( d.getTime() + 1000 ); // "d++"
}
}
dirty = false;
}
static final int INSET = 2;
/*
* Convert from the day number within a month (1-based)
* to the cell coordinates on the calendar (0-based)
*/
private void dateToCell(int date, Point pos)
{
int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
if (firstDayInMonth < firstDayOfWeek) {
cell += daysInWeek;
}
pos.x = cell % daysInWeek;
pos.y = cell / daysInWeek;
}
private Point dateToCell(int date) {
Point p = new Point(0,0);
dateToCell(date, p);
return p;
}
public void paint(Graphics g) {
if (dirty) {
calculate();
}
Point cellPos = new Point(0,0); // Temporary variable
Dimension d = this.size();
g.setColor(DemoUtility.bgColor);
g.fillRect(0,0,d.width,d.height);
// Draw the day names at the top
g.setColor(Color.black);
g.setFont(DemoUtility.labelFont);
FontMetrics fm = g.getFontMetrics();
int labelHeight = fm.getHeight() + INSET * 2;
int v = fm.getAscent() + INSET;
for (int i = 0; i < daysInWeek; i++) {
int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
String dayName = fSymbols.getWeekdays()[dayNum];
int h = (int) (d.width * (i + 0.5)) / daysInWeek;
h -= fm.stringWidth(dayName) / 2;
g.drawString(dayName, h, v);
}
double cellHeight = (d.height - labelHeight - 1) / numWeeks;
double cellWidth = (double)(d.width - 1) / daysInWeek;
// Draw a white background in the part of the calendar
// that displays this month.
// First figure out how much of the first week should be shaded.
{
g.setColor(Color.white);
dateToCell(1, cellPos);
int width = (int)(cellPos.x*cellWidth); // Width of unshaded area
g.fillRect((int)(width), labelHeight ,
(int)(d.width - width), (int)cellHeight);
// All of the intermediate weeks get shaded completely
g.fillRect(0, (int)(labelHeight + cellHeight),
d.width, (int)(cellHeight * (numWeeks - 2)));
// Now figure out the last week.
dateToCell(daysInMonth, cellPos);
width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area
g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
width, (int)(cellHeight));
}
// Draw the X/Y grid lines
g.setColor(Color.black);
for (int i = 0; i <= numWeeks; i++) {
int y = (int)(labelHeight + i * cellHeight);
g.drawLine(0, y, d.width - 1, y);
}
for (int i = 0; i <= daysInWeek; i++) {
int x = (int)(i * cellWidth);
g.drawLine(x, labelHeight, x, d.height - 1);
}
// Now loop through all of the days in the month, figure out where
// they go in the grid, and draw the day # for each one
Font numberFont = new Font("Helvetica",Font.PLAIN,12);
Font holidayFont = DemoUtility.creditFont;
Calendar c = (Calendar)fCalendar.clone();
c.setTime(fStartOfMonth);
for (int i = 1, h = 0; i <= daysInMonth; i++) {
g.setFont(numberFont);
g.setColor(Color.black);
fm = g.getFontMetrics();
dateToCell(i, cellPos);
int x = (int)((cellPos.x + 1) * cellWidth);
int y = (int)(cellPos.y * cellHeight + labelHeight);
StringBuffer buffer = new StringBuffer();
buffer.append(i);
String dayNum = buffer.toString();
x = x - INSET - fm.stringWidth(dayNum);
y = y + fm.getAscent() + INSET;
g.drawString(dayNum, x, y);
// See if any of the holidays land on this day....
HolidayInfo info = null;
int count = 0;
// Coordinates of lower-left corner of cell.
x = (int)((cellPos.x) * cellWidth);
y = (int)((cellPos.y+1) * cellHeight) + labelHeight;
while (h < fHolidays.size() &&
(info = (HolidayInfo)fHolidays.elementAt(h)).date <= i)
{
if (info.date == i) {
// Draw the holiday here.
g.setFont(numberFont);
g.setColor(Color.red);
DemoTextBox box = new DemoTextBox(g, info.name, (int)(cellWidth - INSET));
box.draw(g, x + INSET, y - INSET - box.getHeight());
y -= (box.getHeight() + INSET);
count++;
}
h++;
}
}
}
// Important state variables
private Locale fCalendarLocale; // Whose calendar
private Calendar fCalendar; // Calendar for calculations
private Locale fDisplayLocale; // How to display it
private DateFormatSymbols fSymbols; // Symbols for drawing
private Date fStartOfMonth; // 00:00:00 on first day of month
// Cached calculations to make drawing faster.
private transient int minDay; // Minimum legal day #
private transient int daysInWeek; // # of days in a week
private transient int firstDayOfWeek; // First day to display in week
private transient int numWeeks; // # full or partial weeks in month
private transient int daysInMonth; // # days in this month
private transient int firstDayInMonth; // Day of week of first day in month
private transient Holiday[] fAllHolidays;
private transient Vector fHolidays = new Vector(5,5);
private transient boolean dirty = true;
}
private static class HolidayInfo {
public HolidayInfo(int date, Holiday holiday, String name) {
this.date = date;
this.holiday = holiday;
this.name = name;
}
public Holiday holiday;
public int date;
public String name;
}
}

View file

@ -0,0 +1,97 @@
/*
* $RCSfile: DemoApplet.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo;
import java.applet.Applet;
import java.util.Locale;
import java.awt.*;
import java.awt.event.*;
public abstract class DemoApplet extends java.applet.Applet {
private Button demoButton;
private Frame demoFrame;
private static int demoFrameCount = 0;
protected abstract Frame createDemoFrame(DemoApplet applet);
protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
return new Dimension(700, 550);
}
//Create a button that will display the demo
public void init()
{
setBackground(Color.white);
demoButton = new Button("Demo");
demoButton.setBackground(Color.yellow);
add( demoButton );
demoButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getID() == ActionEvent.ACTION_PERFORMED) {
demoButton.setLabel("loading");
if (demoFrame == null) {
demoFrame = createDemoFrame(DemoApplet.this);
showDemo();
}
demoButton.setLabel("Demo");
}
}
} );
}
public void showDemo()
{
demoFrame = createDemoFrame(this);
demoFrame.layout();
Dimension d = getDefaultFrameSize(this, demoFrame);
demoFrame.resize(d.width, d.height);
demoFrame.show();
demoFrameOpened();
}
public void demoClosed()
{
demoFrame = null;
demoFrameClosed();
}
protected static void demoFrameOpened() {
demoFrameCount++;
}
protected static void demoFrameClosed() {
if (--demoFrameCount == 0) {
System.exit(0);
}
}
}

View file

@ -0,0 +1,118 @@
/*
* $RCSfile: DemoTextBox.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo;
import java.text.BreakIterator;
import java.awt.*;
public class DemoTextBox {
public DemoTextBox(Graphics g, String text, int width)
{
this.text = text;
this.chars = new char[text.length()];
text.getChars(0, text.length(), chars, 0);
this.width = width;
this.port = g;
this.metrics = g.getFontMetrics();
breakText();
}
public int getHeight() {
return (nbreaks + 1) * metrics.getHeight();
}
public void draw(Graphics g, int x, int y)
{
int index = 0;
y += metrics.getAscent();
for (int i = 0; i < nbreaks; i++)
{
g.drawChars(chars, index, breakPos[i] - index, x, y);
index = breakPos[i];
y += metrics.getHeight();
}
g.drawChars(chars, index, chars.length - index, x, y);
}
private void breakText()
{
if (metrics.charsWidth(chars, 0, chars.length) > width)
{
BreakIterator iter = BreakIterator.getWordInstance();
iter.setText(text);
int start = iter.first();
int end = start;
int pos;
while ( (pos = iter.next()) != BreakIterator.DONE )
{
int w = metrics.charsWidth(chars, start, pos - start);
if (w > width)
{
// We've gone past the maximum width, so break the line
if (end > start) {
// There was at least one break position before this point
breakPos[nbreaks++] = end;
start = end;
end = pos;
} else {
// There weren't any break positions before this one, so
// let this word overflow the margin (yuck)
breakPos[nbreaks++] = pos;
start = end = pos;
}
} else {
// the current position still fits on the line; it's the best
// tentative break position we have so far.
end = pos;
}
}
}
}
private String text;
private char[] chars;
private Graphics port;
private FontMetrics metrics;
private int width;
private int[] breakPos = new int[10]; // TODO: get real
private int nbreaks = 0;
}

View file

@ -0,0 +1,127 @@
/*
* $RCSfile: DemoUtility.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo;
import java.awt.*;
import java.lang.*;
import java.util.*;
public class DemoUtility
{
public static final Font titleFont = new Font("TimesRoman",Font.BOLD,18);
public static final Font labelFont = new Font("TimesRoman",Font.BOLD,14);
public static final Font choiceFont = new Font("Helvetica",Font.BOLD,12);
public static final Font editFont = new Font("Helvetica",Font.PLAIN,14);
public static final Font creditFont = new Font("Helvetica",Font.PLAIN,10);
public static final Font numberFont = new Font("sansserif", Font.PLAIN, 14);
public static final Color bgColor = Color.lightGray;
public static final Color choiceColor = Color.white;
public static final String copyright1 =
"(C) Copyright Taligent, Inc. 1996-1998. Copyright (C) IBM, Inc. 1998 - All Rights Reserved";
public static final String copyright2 =
"Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.";
/**
Provides easy way to use basic functions of GridBagLayout, without
the complications. After building a panel, and inserting all the
* subcomponents, call this to lay it out in the desired number of columns.
*/
public static void fixGrid(Container cont, int columns) {
GridBagLayout gridbag = new GridBagLayout();
cont.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.VERTICAL;
c.weightx = 1.0;
c.insets = new Insets(2,2,2,2);
Component[] components = cont.getComponents();
for (int i = 0; i < components.length; ++i) {
int colNumber = i%columns;
c.gridwidth = 1; // default
if ((i%columns) == columns - 1)
c.gridwidth = GridBagConstraints.REMAINDER; // last in grid
if (components[i] instanceof Label) {
switch (((Label)components[i]).getAlignment()) {
case Label.CENTER: c.anchor = GridBagConstraints.CENTER; break;
case Label.LEFT: c.anchor = GridBagConstraints.WEST; break;
case Label.RIGHT: c.anchor = GridBagConstraints.EAST; break;
}
}
gridbag.setConstraints(components[i], c);
}
}
/**
Provides easy way to change the spacing around an object in a GridBagLayout.
Call AFTER fixGridBag, passing in the container, the component, and the
new insets.
*/
public static void setInsets(Container cont, Component comp, Insets insets) {
GridBagLayout gbl = (GridBagLayout)cont.getLayout();
GridBagConstraints g = gbl.getConstraints(comp);
g.insets = insets;
gbl.setConstraints(comp,g);
}
public static Panel createSpacer() {
Panel spacer = new Panel();
spacer.setLayout(null);
spacer.resize(1000, 1);
return spacer;
}
// to avoid goofy updates and misplaced cursors
public static void setText(TextComponent area, String newText) {
String foo = area.getText();
if (foo.equals(newText)) return;
area.setText(newText);
}
/**
* Get the G7 locale list for demos.
*/
public static Locale[] getG7Locales() {
return localeList;
}
private static Locale[] localeList = {
new Locale("DA", "DK", ""),
new Locale("EN", "US", ""),
new Locale("EN", "GB", ""),
new Locale("EN", "CA", ""),
new Locale("FR", "FR", ""),
new Locale("FR", "CA", ""),
new Locale("DE", "DE", ""),
new Locale("IT", "IT", ""),
//new Locale("JA", "JP", ""),
};
}

View file

@ -0,0 +1,475 @@
/*
* $RCSfile: DBBIDemo.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo.RuleBasedBreakIterator;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.BorderFactory;
import java.util.*;
import com.ibm.text.BreakIterator;
public class DBBIDemo extends DemoApplet
{
public static void main(String argv[]) {
Locale.setDefault(new Locale("en", "US", "TEST"));
new DBBIDemo().showDemo();
}
public Frame createDemoFrame(DemoApplet applet) {
return new DBBIFrame(applet);
}
}
class DBBIFrame extends Frame
{
private static final String creditString =
"v1.1a9, Demo";
private static final int FIELD_COLUMNS = 45;
private static final Font choiceFont = null;
private static final boolean DEBUG = false;
private DemoApplet applet;
final String right = "-->";
final String left = "<--";
private BreakIterator enum;
JTextArea text;
// TextArea text;
Choice bound;
public DBBIFrame(DemoApplet applet)
{
this.applet = applet;
init();
start();
}
public void run()
{
/*
while (true) {
try {
checkChange();
Thread.sleep(250);
}
catch (InterruptedException e) {
}
catch (Exception e) {
}
catch (Throwable e) {
}
}
*/
}
int s, e;
int ts, te;
public void checkChange()
{
// System.out.println("checkChange...");
if ((text.getSelectionStart() & 0x7FFF) != ts ||
(text.getSelectionEnd() & 0x7FFF) != te) {
int tempS = text.getSelectionStart() & 0x7FFF;
int tempE = text.getSelectionEnd() & 0x7FFF;
// System.out.println(">");
// select(0, 0);
// select(tempS, tempE);
//select(tempS - (ts - s), tempE - (te - e));
// System.out.println("<");
// if (s != ts || e != te) System.out.println(" s("+s+") ts("+ts+") e("+e+") te("+te+")");
// if (tempS != ts || tempE != te) System.out.println(">s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// select(s - (ts - s), e - (te - e));
// if (tempS != ts || tempE != te) System.out.println("s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// System.out.println("lkdslksj");
}
}
public void select(int sIn, int eIn)
{
s = sIn;
e = eIn;
text.select(s, e);
ts = text.getSelectionStart() & 0x7FFF;
te = text.getSelectionEnd() & 0x7FFF;
// if (s != ts || e != te) {
// System.out.println(">s("+s+") ts("+ts+") e("+e+") te("+te+")");
// System.out.println(" "+(ts-s)+","+(te-e));
// }
}
public int getSelectionStart()
{
checkChange();
// return s;
return text.getSelectionStart() & 0x7FFF;
}
public int getSelectionEnd()
{
checkChange();
// return e;
return text.getSelectionEnd() & 0x7FFF;
}
public final synchronized void selectRange(int s, int e)
{
try {
//if (getSelectionStart() != s || getSelectionEnd() != e) {
//text.select(s, e);
select(s,e);
//}
// if (getSelectionStart() != s || getSelectionEnd() != e) {
// System.out.println("AGH! select("+s+","+e+") -> ("+
// getSelectionStart()+","+getSelectionEnd()+")");
// text.select(s - (getSelectionStart() - s), e - (getSelectionEnd() - e));
// }
} catch (Exception exp) {
errorText(exp.toString());
}
}
public void init()
{
buildGUI();
}
public void start()
{
}
void addWithFont(Container container, Component foo, Font font) {
if (font != null)
foo.setFont(font);
container.add(foo);
}
public void buildGUI()
{
setBackground(DemoUtility.bgColor);
setLayout(new BorderLayout());
Panel topPanel = new Panel();
Label titleLabel =
new Label("Text Boundary Demo", Label.CENTER);
titleLabel.setFont(DemoUtility.titleFont);
topPanel.add(titleLabel);
//Label demo=new Label(creditString, Label.CENTER);
//demo.setFont(DemoUtility.creditFont);
//topPanel.add(demo);
Panel choicePanel = new Panel();
Label demo1=new Label("Boundaries", Label.LEFT);
demo1.setFont(DemoUtility.labelFont);
choicePanel.add(demo1);
bound = new Choice();
bound.setBackground(DemoUtility.choiceColor);
bound.addItem("Sentence");
bound.addItem("Line Break");
bound.addItem("Word");
bound.addItem("Char");
if (choiceFont != null)
bound.setFont(choiceFont);
choicePanel.add(bound);
topPanel.add(choicePanel);
DemoUtility.fixGrid(topPanel,1);
add("North", topPanel);
int ROWS = 15;
int COLUMNS = 50;
// text = new TextArea(getInitialText(), ROWS, COLUMNS);
text = new JTextArea(getInitialText(), ROWS, COLUMNS);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setEditable(true);
text.selectAll();
text.setFont(DemoUtility.editFont);
text.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
add("Center", new JScrollPane(text, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
Panel copyrightPanel = new Panel();
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright1, Label.LEFT),DemoUtility.creditFont);
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright2, Label.LEFT),DemoUtility.creditFont);
DemoUtility.fixGrid(copyrightPanel,1);
add("South", copyrightPanel);
//layout();
handleEnumChanged();
// (new Thread(this)).start();
}
public String getInitialText()
{
return
"When,inthecourseofhumanevents,itbecomesnecessaryforonepeopletodissolvethepoliticalbondswhichhave"
+ "connectedthemwithanother,andtoassumeamongthepowersoftheearth,theseparateandequalstationtowhichthelaws"
+ "ofnatureandofnature'sGodentitlethem,adecentrespecttotheopinionsofmankindrequiresthattheyshoulddeclarethe"
+ "causeswhichimpelthemtotheseparation.\n"
+ "Weholdthesetruthstobeself-evident,thatallmenarecreatedequal,thattheyareendowedbytheirCreatorwithcertain"
+ "unalienablerights,thatamongthesearelife,libertyandthepursuitofhappiness.Thattosecuretheserights,governmentsare"
+ "institutedamongmen,derivingtheirjustpowersfromtheconsentofthegoverned.Thatwheneveranyformofgovernment"
+ "becomesdestructivetotheseends,itistherightofthepeopletoalterortoabolishit,andtoinstitutenewgovernment,laying"
+ "itsfoundationonsuchprinciplesandorganizingitspowersinsuchform,astothemshallseemmostlikelytoeffecttheirsafety"
+ "andhappiness.Prudence,indeed,willdictatethatgovernmentslongestablishedshouldnotbechangedforlightandtransient"
+ "causes;andaccordinglyallexperiencehathshownthatmankindaremoredisposedtosuffer,whileevilsaresufferable,than"
+ "torightthemselvesbyabolishingtheformstowhichtheyareaccustomed.Butwhenalongtrainofabusesandusurpations,"
+ "pursuinginvariablythesameobjectevincesadesigntoreducethemunderabsolutedespotism,itistheirright,itistheirduty,"
+ "tothrowoffsuchgovernment,andtoprovidenewguardsfortheirfuturesecurity.--Suchhasbeenthepatientsufferanceof"
+ "thesecolonies;andsuchisnowthenecessitywhichconstrainsthemtoaltertheirformersystemsofgovernment.Thehistory"
+ "ofthepresentKingofGreatBritainisahistoryofrepeatedinjuriesandusurpations,allhavingindirectobjectthe"
+ "establishmentofanabsolutetyrannyoverthesestates.Toprovethis,letfactsbesubmittedtoacandidworld.\n"
+ "Hehasrefusedhisassenttolaws,themostwholesomeandnecessaryforthepublicgood.\n"
+ "Hehasforbiddenhisgovernorstopasslawsofimmediateandpressingimportance,unlesssuspendedintheiroperationtill"
+ "hisassentshouldbeobtained;andwhensosuspended,hehasutterlyneglectedtoattendtothem.\n"
+ "Hehasrefusedtopassotherlawsfortheaccommodationoflargedistrictsofpeople,unlessthosepeoplewouldrelinquish"
+ "therightofrepresentationinthelegislature,arightinestimabletothemandformidabletotyrantsonly.\n"
+ "Hehascalledtogetherlegislativebodiesatplacesunusual,uncomfortable,anddistantfromthedepositoryoftheirpublic"
+ "records,forthesolepurposeoffatiguingthemintocompliancewithhismeasures.\n"
+ "Hehasdissolvedrepresentativehousesrepeatedly,foropposingwithmanlyfirmnesshisinvasionsontherightsofthepeople.\n"
+ "Hehasrefusedforalongtime,aftersuchdissolutions,tocauseotherstobeelected;wherebythelegislativepowers,"
+ "incapableofannihilation,havereturnedtothepeopleatlargefortheirexercise;thestateremaininginthemeantimeexposed"
+ "toallthedangersofinvasionfromwithout,andconvulsionswithin.\n"
+ "Hehasendeavoredtopreventthepopulationofthesestates;forthatpurposeobstructingthelawsfornaturalizationof"
+ "foreigners;refusingtopassotherstoencouragetheirmigrationhither,andraisingtheconditionsofnewappropriationsof"
+ "lands.\n"
+ "Hehasobstructedtheadministrationofjustice,byrefusinghisassenttolawsforestablishingjudiciarypowers.\n"
+ "Hehasmadejudgesdependentonhiswillalone,forthetenureoftheiroffices,andtheamountandpaymentoftheirsalaries.\n"
+ "Hehaserectedamultitudeofnewoffices,andsenthitherswarmsofofficerstoharassourpeople,andeatouttheir"
+ "substance.\n"
+ "Hehaskeptamongus,intimesofpeace,standingarmieswithouttheconsentofourlegislature.\n"
+ "Hehasaffectedtorenderthemilitaryindependentofandsuperiortocivilpower.\n"
+ "Hehascombinedwithotherstosubjectustoajurisdictionforeigntoourconstitution,andunacknowledgedbyourlaws;"
+ "givinghisassenttotheiractsofpretendedlegislation:\n"
+ "Forquarteringlargebodiesofarmedtroopsamongus:\n"
+ "Forprotectingthem,bymocktrial,frompunishmentforanymurderswhichtheyshouldcommitontheinhabitantsofthese"
+ "states:\n"
+ "Forcuttingoffourtradewithallpartsoftheworld:\n"
+ "Forimposingtaxesonuswithoutourconsent:\n"
+ "Fordeprivingusinmanycases,ofthebenefitsoftrialbyjury:\n"
+ "Fortransportingusbeyondseastobetriedforpretendedoffenses:\n"
+ "ForabolishingthefreesystemofEnglishlawsinaneighboringprovince,establishingthereinanarbitrarygovernment,and"
+ "enlargingitsboundariessoastorenderitatonceanexampleandfitinstrumentforintroducingthesameabsoluteruleinthese"
+ "colonies:\n"
+ "Fortakingawayourcharters,abolishingourmostvaluablelaws,andalteringfundamentallytheformsofourgovernments:\n"
+ "Forsuspendingourownlegislatures,anddeclaringthemselvesinvestedwithpowertolegislateforusinallcaseswhatsoever.\n"
+ "Hehasabdicatedgovernmenthere,bydeclaringusoutofhisprotectionandwagingwaragainstus.\n"
+ "Hehasplunderedourseas,ravagedourcoasts,burnedourtowns,anddestroyedthelivesofourpeople.\n"
+ "Heisatthistimetransportinglargearmiesofforeignmercenariestocompletetheworksofdeath,desolationandtyranny,"
+ "alreadybegunwithcircumstancesofcrueltyandperfidyscarcelyparalleledinthemostbarbarousages,andtotalyunworth"
+ "theheadofacivilizednation.\n"
+ "Hehasconstrainedourfellowcitizenstakencaptiveonthehighseastobeararmsagainsttheircountry,tobecomethe"
+ "executionersoftheirfriendsandbrethren,ortofallthemselvesbytheirhands.\n"
+ "Hehasexciteddomesticinsurrectionsamongstus,andhasendeavoredtobringontheinhabitantsofourfrontiers,the"
+ "mercilessIndiansavages,whoseknownruleofwarfare,isundistinguisheddestructionofallages,sexesandconditions.\n"
+ "Ineverystageoftheseoppressionswehavepetitionedforredressinthemosthumbleterms:ourrepeatedpetitionshave"
+ "beenansweredonlybyrepeatedinjury.Aprince,whosecharacteristhusmarkedbyeveryactwhichmaydefineatyrant,is"
+ "unfittobetherulerofafreepeople.\n"
+ "NorhavewebeenwantinginattentiontoourBritishbrethren.Wehavewarnedthemfromtimetotimeofattemptsbytheir"
+ "legislaturetoextendanunwarrantablejurisdictionoverus.Wehaveremindedthemofthecircumstancesofouremigration"
+ "andsettlementhere.Wehaveappealedtotheirnativejusticeandmagnanimity,andwehaveconjuredthembythetiesofour"
+ "commonkindredtodisavowtheseusurpations,which,wouldinevitablyinterruptourconnectionsandcorrespondence.We"
+ "must,therefore,acquiesceinthenecessity,whichdenouncesourseparation,andholdthem,asweholdtherestofmankind,"
+ "enemiesinwar,inpeacefriends.\n"
+ "We,therefore,therepresentativesoftheUnitedStatesofAmerica,inGeneralCongress,assembled,appealingtothe"
+ "SupremeJudgeoftheworldfortherectitudeofourintentions,do,inthename,andbytheauthorityofthegoodpeopleof"
+ "thesecolonies,solemnlypublishanddeclare,thattheseunitedcoloniesare,andofrightoughttobefreeandindependent"
+ "states;thattheyareabsolvedfromallallegiancetotheBritishCrown,andthatallpoliticalconnectionbetweenthemandthe"
+ "stateofGreatBritain,isandoughttobetotallydissolved;andthatasfreeandindependentstates,theyhavefullpowerto"
+ "leveywar,concludepeace,contractalliances,establishcommerce,andtodoallotheractsandthingswhichindependent"
+ "statesmayofrightdo.Andforthesupportofthisdeclaration,withafirmrelianceontheprotectionofDivineProvidence,we"
+ "mutuallypledgetoeachotherourlives,ourfortunesandoursacredhonor.\n";
}
public void handleEnumChanged()
{
String s = bound.getSelectedItem();
if (s.equals("Char")) {
errorText("getCharacterInstance");
enum = BreakIterator.getCharacterInstance();
}
else if (s.equals("Word")) {
errorText("tWordBreak");
enum = BreakIterator.getWordInstance();
}
else if (s.equals("Line Break")) {
errorText("getLineInstance");
enum = BreakIterator.getLineInstance();
}
else /* if (s.equals("Sentence")) */ {
errorText("getSentenceInstance");
enum = BreakIterator.getSentenceInstance();
}
enum.setText(text.getText());
selectRange(0, 0);
//text.select(0,0);
}
public void handleForward()
{
try {
// System.out.println("entering handleForward");
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
// System.out.println("handleForward: oldStart=" + oldStart + ", oldEnd=" + oldEnd);
if (oldEnd < 1) {
selectRange(0, enum.following(0));
}
else {
int s = enum.following(oldEnd-1);
int e = enum.next();
if (e == -1) {
e = s;
}
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" +
s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public void handleBackward()
{
try {
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
if (oldStart < 1) {
selectRange(0, 0);
}
else {
int e = enum.following(oldStart-1);
int s = enum.previous();
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" + s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public boolean action(Event evt, Object obj)
{
if(evt.target instanceof Button && left.equals(obj))
{
handleBackward();
return true;
}
else if(evt.target instanceof Button && right.equals(obj))
{
handleForward();
return true;
}
else if(evt.target instanceof Choice)
{
handleEnumChanged();
return true;
}
return false;
}
public boolean handleEvent(Event evt)
{
if (evt.id == Event.KEY_PRESS || evt.id == Event.KEY_ACTION) {
if (evt.key == Event.RIGHT || (evt.key == 0x0E && evt.controlDown())) {
handleForward();
return true;
}
else if (evt.key == Event.LEFT || (evt.key == 0x10 && evt.controlDown())) {
handleBackward();
return true;
}
}
else
if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else System.exit(0);
return true;
}
return super.handleEvent(evt);
}
public void errorText(String s)
{
if (DEBUG)
System.out.println(s);
}
}

View file

@ -0,0 +1,441 @@
/*
* $RCSfile: TextBoundDemo.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:47 $
*
* (C) Copyright Taligent, Inc. 1996 - 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.demo.RuleBasedBreakIterator;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.BorderFactory;
import java.util.*;
import com.ibm.text.BreakIterator;
public class TextBoundDemo extends DemoApplet
{
public static void main(String argv[]) {
new TextBoundDemo().showDemo();
}
public Frame createDemoFrame(DemoApplet applet) {
return new TextBoundFrame(applet);
}
}
class TextBoundFrame extends Frame
{
private static final String creditString =
"v1.1a9, Demo";
private static final int FIELD_COLUMNS = 45;
private static final Font choiceFont = null;
private static final boolean DEBUG = false;
private DemoApplet applet;
final String right = "-->";
final String left = "<--";
private BreakIterator enum;
JTextArea text;
// TextArea text;
Choice bound;
public TextBoundFrame(DemoApplet applet)
{
this.applet = applet;
init();
start();
}
public void run()
{
/*
while (true) {
try {
checkChange();
Thread.sleep(250);
}
catch (InterruptedException e) {
}
catch (Exception e) {
}
catch (Throwable e) {
}
}
*/
}
int s, e;
int ts, te;
public void checkChange()
{
// System.out.println("checkChange...");
if ((text.getSelectionStart() & 0x7FFF) != ts ||
(text.getSelectionEnd() & 0x7FFF) != te) {
int tempS = text.getSelectionStart() & 0x7FFF;
int tempE = text.getSelectionEnd() & 0x7FFF;
// System.out.println(">");
// select(0, 0);
// select(tempS, tempE);
//select(tempS - (ts - s), tempE - (te - e));
// System.out.println("<");
// if (s != ts || e != te) System.out.println(" s("+s+") ts("+ts+") e("+e+") te("+te+")");
// if (tempS != ts || tempE != te) System.out.println(">s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// select(s - (ts - s), e - (te - e));
// if (tempS != ts || tempE != te) System.out.println("s("+s+") tempS("+tempS+") e("+e+") tempE("+tempE+")");
// System.out.println("lkdslksj");
}
}
public void select(int sIn, int eIn)
{
s = sIn;
e = eIn;
text.select(s, e);
ts = text.getSelectionStart() & 0x7FFF;
te = text.getSelectionEnd() & 0x7FFF;
// if (s != ts || e != te) {
// System.out.println(">s("+s+") ts("+ts+") e("+e+") te("+te+")");
// System.out.println(" "+(ts-s)+","+(te-e));
// }
}
public int getSelectionStart()
{
checkChange();
// return s;
return text.getSelectionStart() & 0x7FFF;
}
public int getSelectionEnd()
{
checkChange();
// return e;
return text.getSelectionEnd() & 0x7FFF;
}
public final synchronized void selectRange(int s, int e)
{
try {
//if (getSelectionStart() != s || getSelectionEnd() != e) {
//text.select(s, e);
select(s,e);
//}
// if (getSelectionStart() != s || getSelectionEnd() != e) {
// System.out.println("AGH! select("+s+","+e+") -> ("+
// getSelectionStart()+","+getSelectionEnd()+")");
// text.select(s - (getSelectionStart() - s), e - (getSelectionEnd() - e));
// }
} catch (Exception exp) {
errorText(exp.toString());
}
}
public void init()
{
buildGUI();
}
public void start()
{
}
void addWithFont(Container container, Component foo, Font font) {
if (font != null)
foo.setFont(font);
container.add(foo);
}
public void buildGUI()
{
setBackground(DemoUtility.bgColor);
setLayout(new BorderLayout());
Panel topPanel = new Panel();
Label titleLabel =
new Label("Text Boundary Demo", Label.CENTER);
titleLabel.setFont(DemoUtility.titleFont);
topPanel.add(titleLabel);
//Label demo=new Label(creditString, Label.CENTER);
//demo.setFont(DemoUtility.creditFont);
//topPanel.add(demo);
Panel choicePanel = new Panel();
Label demo1=new Label("Boundaries", Label.LEFT);
demo1.setFont(DemoUtility.labelFont);
choicePanel.add(demo1);
bound = new Choice();
bound.setBackground(DemoUtility.choiceColor);
bound.addItem("Sentence");
bound.addItem("Line Break");
bound.addItem("Word");
bound.addItem("Char");
if (choiceFont != null)
bound.setFont(choiceFont);
choicePanel.add(bound);
topPanel.add(choicePanel);
DemoUtility.fixGrid(topPanel,1);
add("North", topPanel);
int ROWS = 15;
int COLUMNS = 50;
// text = new TextArea(getInitialText(), ROWS, COLUMNS);
text = new JTextArea(getInitialText(), ROWS, COLUMNS);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setEditable(true);
text.selectAll();
text.setFont(DemoUtility.editFont);
text.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
add("Center", new JScrollPane(text, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
Panel copyrightPanel = new Panel();
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright1, Label.LEFT),DemoUtility.creditFont);
addWithFont (copyrightPanel,
new Label(DemoUtility.copyright2, Label.LEFT),DemoUtility.creditFont);
DemoUtility.fixGrid(copyrightPanel,1);
add("South", copyrightPanel);
//layout();
handleEnumChanged();
// (new Thread(this)).start();
}
public String getInitialText()
{
return
/*
"\"This is a sentence.\" This is not.\" \"because. And go. " +
"This is a simple 012.566,5 sample sentence. \n"+
"It does not have to make any sense as you can see. \n"+
"Nel mezzo del cammin di nostra vita, mi ritrovai in "+
"una selva oscura. \n"+
"Che la dritta via aveo smarrita. \n"+
"He said, that I said, that you said!! \n"+
"Don't rock the boat.\n\n"+
"Because I am the daddy, that is why. \n"+
"Not on my time (el timo.)! \n"+
"Tab\tTab\rTab\tWow."+
"So what!!\n\n"+
"Is this a question??? " +
"I wonder...Hmm.\n" +
"Harris thumbed down several, including \"Away We Go\" "+
"(which became the huge success Oklahoma!). \n"+
"One species, B. anthracis, is highly virulent.\n"+
"Wolf said about Sounder: \"Beautifully thought-out and "+
"directed.\"\n"+
"Have you ever said, \"This is where I shall live\"? \n"+
"He 1000,233,456.000 answered, \"You may not!\" \n"+
"Another popular saying is: \"How do you do?\". \n"+
"What is the proper use of the abbreviation pp.? \n"+
"Yes, I am 1,23.322% definatelly 12\" tall!!";
*/
"(\"This is a complete sentence.\") This is (\"not.\") also. "
+"An abbreviation in the middle, etc. and one at the end, etc. "+
"This "
+"is a simple sample 012.566,5 sentence. It doesn't "
+"have to make any sense, as you can see. Nel mezzo del c"
+"ammin di nostra vita, mi ritrovai in una selva oscura. Che "
+"la dritta via aveo smarrita. Not on my time (el timo.)! And "
+"tabulated columns: \tCol1\tCol2\t3,456%.\t "
+"Is this a question??? I wonder... Hmm. Harris thumbed "
+"down several, including \"Away We Go\" (which became the "
+"huge success Oklahoma!). One species, B. anthracis, is "
+"highly virulent. Wolf said about Sounder: \"Beautifully "
+"thought-out and directed.\" Have you ever said, \"This is "+
"where I "
+"shall live\"? He said 1000,233,456.000 and answered, \"You "+
"may not!\" "
+"Another popular saying is: \"How do you do?\". What is the "
+"proper use of the abbreviation pp.? Yes, I am 12\' 3\" tall!!";
}
public void handleEnumChanged()
{
String s = bound.getSelectedItem();
if (s.equals("Char")) {
errorText("getCharacterInstance");
enum = BreakIterator.getCharacterInstance();
}
else if (s.equals("Word")) {
errorText("tWordBreak");
enum = BreakIterator.getWordInstance();
}
else if (s.equals("Line Break")) {
errorText("getLineInstance");
enum = BreakIterator.getLineInstance();
}
else /* if (s.equals("Sentence")) */ {
errorText("getSentenceInstance");
enum = BreakIterator.getSentenceInstance();
}
enum.setText(text.getText());
selectRange(0, 0);
//text.select(0,0);
}
public void handleForward()
{
try {
// System.out.println("entering handleForward");
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
// System.out.println("handleForward: oldStart=" + oldStart + ", oldEnd=" + oldEnd);
if (oldEnd < 1) {
selectRange(0, enum.following(0));
}
else {
int s = enum.following(oldEnd-1);
int e = enum.next();
if (e == -1) {
e = s;
}
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" +
s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public void handleBackward()
{
try {
enum.setText(text.getText());
int oldStart = getSelectionStart();
int oldEnd = getSelectionEnd();
if (oldStart < 1) {
selectRange(0, 0);
}
else {
int e = enum.following(oldStart-1);
int s = enum.previous();
selectRange(s, e);
}
//text.select(s, e);
errorText("<" + oldStart + "," + oldEnd + "> -> <" + s + "," + e + ">");
}
catch (Exception exp) {
errorText(exp.toString());
}
}
public boolean action(Event evt, Object obj)
{
if(evt.target instanceof Button && left.equals(obj))
{
handleBackward();
return true;
}
else if(evt.target instanceof Button && right.equals(obj))
{
handleForward();
return true;
}
else if(evt.target instanceof Choice)
{
handleEnumChanged();
return true;
}
return false;
}
public boolean handleEvent(Event evt)
{
if (evt.id == Event.KEY_PRESS || evt.id == Event.KEY_ACTION) {
if (evt.key == Event.RIGHT || (evt.key == 0x0E && evt.controlDown())) {
handleForward();
return true;
}
else if (evt.key == Event.LEFT || (evt.key == 0x10 && evt.controlDown())) {
handleBackward();
return true;
}
}
else
if (evt.id == Event.WINDOW_DESTROY && evt.target == this) {
this.hide();
this.dispose();
if (applet != null) {
applet.demoClosed();
} else System.exit(0);
return true;
}
return super.handleEvent(evt);
}
public void errorText(String s)
{
if (DEBUG)
System.out.println(s);
}
}

View file

@ -0,0 +1,533 @@
/*
* (C) IBM Corp. 1997-1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.demo.rbnf;
import com.ibm.demo.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.text.BreakIterator;
import java.text.ParsePosition;
import java.util.Locale;
import com.ibm.text.RuleBasedNumberFormat;
public class RbnfDemo extends DemoApplet {
/**
* Puts a copyright in the .class file
*/
private static final String copyrightNotice
= "Copyright \u00a91997-1998 IBM Corp. All rights reserved.";
/*
* code to run the demo as an application
*/
public static void main(String[] argv) {
new RbnfDemo().showDemo();
}
protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
return new Dimension(430,270);
}
protected Frame createDemoFrame(DemoApplet applet) {
final Frame window = new Frame("Number Spellout Demo");
window.setSize(800, 600);
window.setLayout(new BorderLayout());
Panel mainPanel = new Panel();
mainPanel.setLayout(new GridLayout(1,2));
commentaryField = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
commentaryField.setSize(800, 50);
commentaryField.setText(RbnfSampleRuleSets.sampleRuleSetCommentary[0]);
commentaryField.setEditable(false);
commentaryField.setFont(new Font("Helvetica", Font.PLAIN, 14));
spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.usEnglish, Locale.US);
spelloutFormatter.setLenientParseMode(lenientParse);
populateRuleSetMenu();
numberFormatter = new DecimalFormat("#,##0.##########");
parsePosition = new ParsePosition(0);
theNumber = 0;
numberField = new TextField();
numberField.setFont(new Font("Serif", Font.PLAIN, 24));
textField = new DemoTextFieldHolder();
textField.setFont(new Font("Serif", Font.PLAIN, 24));
rulesField = new DemoTextFieldHolder();
rulesField.setFont(new Font("Serif", Font.PLAIN, 14));
lenientParseButton = new Checkbox("Lenient parse", lenientParse);
numberField.addTextListener(new TextListener() {
public void textValueChanged(TextEvent e) {
if (!numberFieldHasFocus)
return;
String fieldText = ((TextComponent)(e.getSource())).getText();
parsePosition.setIndex(0);
Number temp = numberFormatter.parse(fieldText, parsePosition);
if (temp == null || parsePosition.getIndex() == 0) {
theNumber = 0;
textField.setText("PARSE ERROR");
}
else {
theNumber = temp.doubleValue();
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
}
}
} );
numberField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
numberFieldHasFocus = false;
numberField.setText(numberFormatter.format(theNumber));
}
public void focusGained(FocusEvent e) {
numberFieldHasFocus = true;
numberField.selectAll();
}
} );
textField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '\t') {
String fieldText = ((TextComponent)(e.getSource())).getText();
parsePosition.setIndex(0);
theNumber = spelloutFormatter.parse(fieldText, parsePosition)
.doubleValue();
if (parsePosition.getIndex() == 0) {
theNumber = 0;
numberField.setText("PARSE ERROR");
textField.selectAll();
}
else if (parsePosition.getIndex() < fieldText.length()) {
textField.select(parsePosition.getIndex(), fieldText.length());
numberField.setText(numberFormatter.format(theNumber));
}
else {
textField.selectAll();
numberField.setText(numberFormatter.format(theNumber));
}
e.consume();
}
}
} );
textField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
String fieldText = ((TextComponent)(e.getSource())).getText();
parsePosition.setIndex(0);
theNumber = spelloutFormatter.parse(fieldText, parsePosition)
.doubleValue();
if (parsePosition.getIndex() == 0)
numberField.setText("PARSE ERROR");
else
numberField.setText(numberFormatter.format(theNumber));
textField.setText(textField.getText()); // textField.repaint() didn't work right
}
public void focusGained(FocusEvent e) {
textField.selectAll();
}
} );
rulesField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '\t') {
String fieldText = ((TextComponent)(e.getSource())).getText();
if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
try {
RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
temp.setLenientParseMode(lenientParse);
populateRuleSetMenu();
spelloutFormatter = temp;
customRuleSet = fieldText;
formatterMenu.select("Custom");
commentaryField.setText(RbnfSampleRuleSets.
sampleRuleSetCommentary[RbnfSampleRuleSets.
sampleRuleSetCommentary.length - 1]);
redisplay();
}
catch (Exception x) {
textField.setText(x.toString());
}
}
e.consume();
}
}
} );
rulesField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
String fieldText = ((TextComponent)(e.getSource())).getText();
if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
try {
RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
temp.setLenientParseMode(lenientParse);
populateRuleSetMenu();
spelloutFormatter = temp;
customRuleSet = fieldText;
formatterMenu.select("Custom");
redisplay();
}
catch (Exception x) {
textField.setText(x.toString());
}
}
rulesField.setText(rulesField.getText()); // rulesField.repaint() didn't work right
}
} );
lenientParseButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
lenientParse = lenientParseButton.getState();
spelloutFormatter.setLenientParseMode(lenientParse);
}
} );
numberField.setText(numberFormatter.format(theNumber));
numberField.selectAll();
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
Panel leftPanel = new Panel();
leftPanel.setLayout(new BorderLayout());
Panel panel = new Panel();
panel.setLayout(new BorderLayout());
Panel panel1 = new Panel();
panel1.setLayout(new GridLayout(3, 1));
panel1.add(new Panel());
panel1.add(numberField, "Center");
panel1.add(lenientParseButton);
panel.add(panel1, "Center");
Panel panel2 = new Panel();
panel2.setLayout(new GridLayout(3, 3));
Button button = new Button("+100");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(100);
}
} );
panel2.add(button);
button = new Button("+10");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(10);
}
} );
panel2.add(button);
button = new Button("+1");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(1);
}
} );
panel2.add(button);
button = new Button("<");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
theNumber *= 10;
redisplay();
}
} );
panel2.add(button);
panel2.add(new Panel());
button = new Button(">");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
theNumber /= 10;
redisplay();
}
} );
panel2.add(button);
button = new Button("-100");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(-100);
}
} );
panel2.add(button);
button = new Button("-10");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(-10);
}
} );
panel2.add(button);
button = new Button("-1");
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
roll(-1);
}
} );
panel2.add(button);
panel.add(panel2, "East");
leftPanel.add(panel, "North");
leftPanel.add(textField, "Center");
Panel rightPanel = new Panel();
rightPanel.setLayout(new BorderLayout());
formatterMenu = new Choice();
for (int i = 0; i < RbnfSampleRuleSets.sampleRuleSetNames.length; i++)
formatterMenu.addItem(RbnfSampleRuleSets.sampleRuleSetNames[i]);
formatterMenu.addItem("Custom");
formatterMenu.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
Choice source = (Choice)(e.getSource());
int item = source.getSelectedIndex();
Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
commentaryField.setText(RbnfSampleRuleSets.
sampleRuleSetCommentary[item]);
if (locale != null && (locale.getLanguage().equals("iw")
|| locale.getLanguage().equals("ru") || locale.getLanguage().equals("ja")
|| locale.getLanguage().equals("el")
|| locale.getLanguage().equals("zh"))) {
textField.togglePanes(false);
rulesField.togglePanes(false);
}
else {
textField.togglePanes(true);
rulesField.togglePanes(true);
}
makeNewSpelloutFormatter();
redisplay();
}
} );
ruleSetMenu = new Choice();
populateRuleSetMenu();
ruleSetMenu.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
ruleSetName = ruleSetMenu.getSelectedItem();
redisplay();
}
} );
Panel menuPanel = new Panel();
menuPanel.setLayout(new GridLayout(1, 2));
menuPanel.add(formatterMenu);
menuPanel.add(ruleSetMenu);
rightPanel.add(menuPanel, "North");
rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()]);
rightPanel.add(rulesField, "Center");
mainPanel.add(leftPanel);
mainPanel.add(rightPanel);
window.add(mainPanel, "Center");
window.add(commentaryField, "South");
window.doLayout();
window.show();
return window;
}
void roll(int delta) {
theNumber += delta;
redisplay();
}
void redisplay() {
numberField.setText(numberFormatter.format(theNumber));
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
}
void makeNewSpelloutFormatter() {
int item = formatterMenu.getSelectedIndex();
String formatterMenuItem = formatterMenu.getSelectedItem();
if (formatterMenuItem.equals("Custom")) {
rulesField.setText(customRuleSet);
spelloutFormatter = new RuleBasedNumberFormat(customRuleSet);
}
else {
rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[item]);
Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
if (locale == null)
locale = Locale.getDefault();
spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.
sampleRuleSets[item], locale);
}
spelloutFormatter.setLenientParseMode(lenientParse);
populateRuleSetMenu();
}
void populateRuleSetMenu() {
String[] ruleSetNames = spelloutFormatter.getRuleSetNames();
if (ruleSetMenu != null) {
ruleSetMenu.removeAll();
for (int i = 0; i < ruleSetNames.length; i++)
ruleSetMenu.addItem(ruleSetNames[i]);
ruleSetName = ruleSetMenu.getSelectedItem();
}
else
ruleSetName = ruleSetNames[0];
}
private Frame demoWindow = null;
private TextComponent numberField;
private DemoTextFieldHolder textField;
private DemoTextFieldHolder rulesField;
private TextComponent commentaryField;
private Checkbox lenientParseButton;
private boolean numberFieldHasFocus = true;
private RuleBasedNumberFormat spelloutFormatter;
private DecimalFormat numberFormatter;
private ParsePosition parsePosition;
private boolean lenientParse = true;
private double theNumber = 0;
private boolean canEdit = true;
private Choice formatterMenu;
private Choice ruleSetMenu;
private String ruleSetName;
private String customRuleSet = "NO RULES!";
}
class DemoTextField extends Component {
public DemoTextField() {
}
public void setText(String text) {
this.text = text;
this.repaint();
}
public String getText() {
return text;
}
public void paint(Graphics g) {
Font font = getFont();
FontMetrics fm = g.getFontMetrics();
g.setFont(font);
String text = getText();
BreakIterator bi = BreakIterator.getLineInstance();
bi.setText(text);
int lineHeight = fm.getHeight();
int width = getSize().width;
int penY = fm.getAscent();
int lineStart = 0;
int tempLineEnd = bi.first();
int lineEnd = 0;
int maxLineEnd = 0;
totalHeight = 0;
while (lineStart < text.length()) {
maxLineEnd = text.indexOf('\n', lineStart);
if (maxLineEnd == -1)
maxLineEnd = Integer.MAX_VALUE;
while (tempLineEnd != BreakIterator.DONE && fm.stringWidth(text.substring(
lineStart, tempLineEnd)) < width) {
lineEnd = tempLineEnd;
tempLineEnd = bi.next();
}
if (lineStart >= lineEnd) {
if (tempLineEnd == BreakIterator.DONE)
lineEnd = text.length();
else
lineEnd = tempLineEnd;
}
if (lineEnd > maxLineEnd)
lineEnd = maxLineEnd;
g.drawString(text.substring(lineStart, lineEnd), 0, penY);
penY += lineHeight;
totalHeight += lineHeight;
lineStart = lineEnd;
if (lineStart < text.length() && text.charAt(lineStart) == '\n')
++lineStart;
}
}
/*
public Dimension getPreferredSize() {
Dimension size = getParent().getSize();
return new Dimension(size.width, totalHeight);
}
*/
private String text;
private int totalHeight;
}
class DemoTextFieldHolder extends Panel {
public DemoTextFieldHolder() {
tf1 = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
tf2 = new DemoTextField();
sp = new ScrollPane();
setLayout(new CardLayout());
sp.add(tf2, "TextField1");
sp.setVisible(false);
add(tf1, "TestField2");
add(sp, "ScrollPane");
}
public void addFocusListener(FocusListener l) {
tf1.addFocusListener(l);
}
public void addKeyListener(KeyListener l) {
tf1.addKeyListener(l);
}
public void setText(String text) {
tf1.setText(text);
tf2.setText(text);
}
public String getText() {
return tf1.getText();
}
public void select(int start, int end) {
tf1.select(start, end);
}
public void selectAll() {
tf1.selectAll();
}
public void togglePanes(boolean canShowRealTextField) {
if (canShowRealTextField != showingRealTextField) {
CardLayout layout = (CardLayout)(getLayout());
layout.next(this);
showingRealTextField = canShowRealTextField;
}
}
private TextArea tf1 = null;
private DemoTextField tf2 = null;
private ScrollPane sp = null;
private boolean showingRealTextField = true;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,271 @@
/*
* $RCSfile: TestFmwk.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1996-1998 Sun Microsystems, Inc.
* All Rights Reserved.
*
* The original version of this source code and documentation
* is copyrighted and owned by Taligent, Inc., a wholly-owned
* subsidiary of IBM. These materials are provided under terms
* of a License Agreement between Taligent and Sun. This technology
* is protected by multiple US and International patents.
*
* This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.test;
import java.lang.reflect.*;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.io.*;
import java.text.*;
/**
* BITestFmwk is a base class for tests that can be run conveniently from
* the command line as well as under the Java test harness.
* <p>
* Sub-classes implement a set of methods named Test<something>. Each
* of these methods performs some test. Test methods should indicate
* errors by calling either err or errln. This will increment the
* errorCount field and may optionally print a message to the log.
* Debugging information may also be added to the log via the log
* and logln methods. These methods will add their arguments to the
* log only if the test is being run in verbose mode.
*/
public class TestFmwk {
/**
* Puts a copyright in the .class file
*/
private static final String copyrightNotice
= "Copyright \u00a91997-1998 IBM Corp. All rights reserved.";
//------------------------------------------------------------------------
// Everything below here is boilerplate code that makes it possible
// to add a new test by simply adding a function to an existing class
//------------------------------------------------------------------------
protected TestFmwk() {
// Create a hashtable containing all the test methods.
testMethods = new Hashtable();
Method[] methods = getClass().getDeclaredMethods();
for( int i=0; i<methods.length; i++ ) {
if( methods[i].getName().startsWith("Test") ) {
testMethods.put( methods[i].getName(), methods[i] );
}
}
}
protected void run(String[] args) throws Exception
{
System.out.println(getClass().getName() + " {");
indentLevel++;
// Set up the log and reference streams. We use PrintWriters in order to
// take advantage of character conversion. The JavaEsc converter will
// convert Unicode outside the ASCII range to Java's \\uxxxx notation.
log = new PrintWriter(System.out,true);
// Parse the test arguments. They can be either the flag
// "-verbose" or names of test methods. Create a list of
// tests to be run.
Vector testsToRun = new Vector( args.length );
for( int i=0; i<args.length; i++ ) {
if( args[i].equals("-verbose") ) {
verbose = true;
}
else if( args[i].equals("-prompt") ) {
prompt = true;
} else if (args[i].equals("-nothrow")) {
nothrow = true;
} else {
Object m = testMethods.get( args[i] );
if( m != null ) {
testsToRun.addElement( m );
}
else {
usage();
return;
}
}
}
// If no test method names were given explicitly, run them all.
if( testsToRun.size() == 0 ) {
Enumeration methodNames = testMethods.elements();
while( methodNames.hasMoreElements() ) {
testsToRun.addElement( methodNames.nextElement() );
}
}
// Run the list of tests given in the test arguments
for( int i=0; i<testsToRun.size(); i++ ) {
int oldCount = errorCount;
Method testMethod = (Method)testsToRun.elementAt(i);
writeTestName(testMethod.getName());
try {
testMethod.invoke(this, new Object[0]);
}
catch( IllegalAccessException e ) {
errln("Can't acces test method " + testMethod.getName());
}
catch( InvocationTargetException e ) {
errln("Uncaught exception thrown in test method "
+ testMethod.getName());
e.getTargetException().printStackTrace(this.log);
}
writeTestResult(errorCount - oldCount);
}
indentLevel--;
writeTestResult(errorCount);
if (prompt) {
System.out.println("Hit RETURN to exit...");
try {
System.in.read();
}
catch (IOException e) {
System.out.println("Exception: " + e.toString() + e.getMessage());
}
}
if (nothrow) {
System.exit(errorCount);
}
}
/**
* Adds given string to the log if we are in verbose mode.
*/
protected void log( String message ) {
if( verbose ) {
indent(indentLevel + 1);
log.print( message );
log.flush();
}
}
protected void logln( String message ) {
log(message + System.getProperty("line.separator"));
}
/**
* Report an error
*/
protected void err( String message ) {
errorCount++;
indent(indentLevel + 1);
log.print( message );
log.flush();
if (!nothrow) {
throw new RuntimeException(message);
}
}
protected void errln( String message ) {
err(message + System.getProperty("line.separator"));
}
protected int getErrorCount() {
return errorCount;
}
protected void writeTestName(String testName) {
indent(indentLevel);
log.print(testName);
log.flush();
needLineFeed = true;
}
protected void writeTestResult(int count) {
if (!needLineFeed) {
indent(indentLevel);
log.print("}");
}
needLineFeed = false;
if (count != 0)
log.println(" FAILED");
else
log.println(" Passed");
}
private final void indent(int distance) {
if (needLineFeed) {
log.println(" {");
needLineFeed = false;
}
log.print(spaces.substring(0, distance * 2));
}
/**
* Print a usage message for this test class.
*/
void usage() {
System.out.println(getClass().getName() +
": [-verbose] [-nothrow] [-prompt] [test names]");
System.out.println("test names:");
Enumeration methodNames = testMethods.keys();
while( methodNames.hasMoreElements() ) {
System.out.println("\t" + methodNames.nextElement() );
}
}
public static String hex(char ch) {
StringBuffer result = new StringBuffer();
String foo = Integer.toString(ch,16).toUpperCase();
for (int i = foo.length(); i < 4; ++i) {
result.append('0');
}
return result + foo;
}
public static String hex(String s) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < s.length(); ++i) {
if (i != 0) result.append(',');
result.append(hex(s.charAt(i)));
}
return result.toString();
}
public static String hex(StringBuffer s) {
return hex(s.toString());
}
private boolean prompt = false;
private boolean nothrow = false;
protected boolean verbose = false;
private PrintWriter log;
private int indentLevel = 0;
private boolean needLineFeed = false;
private int errorCount = 0;
private Hashtable testMethods;
private final String spaces = " ";
}

View file

@ -0,0 +1,341 @@
package com.ibm.test.bnf;
import com.ibm.test.*;
import com.ibm.text.*;
import java.text.ParseException;
import java.util.*;
import java.math.BigInteger;
/**
* @test
* General test of Big NumberFormat
*/
public class BigNumberFormatTest extends TestFmwk {
static final int ILLEGAL = -1;
public static void main(String[] args) throws Exception {
new BigNumberFormatTest().run(args);
}
public void TestExponent() {
DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
DecimalFormat fmt1 = new DecimalFormat("0.###E0", US);
DecimalFormat fmt2 = new DecimalFormat("0.###E+0", US);
Number n = new Long(1234);
expect(fmt1, n, "1.234E3");
expect(fmt2, n, "1.234E+3");
expect(fmt1, "1.234E3", n);
expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
expect(fmt2, "1.234E+3", n);
}
private void expectPad(DecimalFormat fmt, String pat, int pos) {
expectPad(fmt, pat, pos, 0, (char)0);
}
private void expectPad(DecimalFormat fmt, String pat,
int pos, int width, char pad) {
int apos = 0, awidth = 0;
char apad = 0;
try {
fmt.applyPattern(pat);
apos = fmt.getPadPosition();
awidth = fmt.getFormatWidth();
apad = fmt.getPadCharacter();
} catch (IllegalArgumentException e) {
apos = -1;
awidth = width;
apad = pad;
}
if (apos == pos && awidth == width && apad == pad) {
logln("Ok \"" + pat + "\" pos=" + apos +
((pos == -1) ? "" : " width=" + awidth + " pad=" + apad));
} else {
logln("FAIL \"" + pat + "\" pos=" + apos +
" width=" + awidth + " pad=" + apad +
", expected " + pos + " " + width + " " + pad);
}
}
/**
*/
public void TestPatterns() {
DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
DecimalFormat fmt = new DecimalFormat("#", US);
expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, '^');
expectPad(fmt, "$*^#", DecimalFormat.PAD_AFTER_PREFIX, 2, '^');
expectPad(fmt, "#*^", DecimalFormat.PAD_BEFORE_SUFFIX, 1, '^');
expectPad(fmt, "#$*^", DecimalFormat.PAD_AFTER_SUFFIX, 2, '^');
expectPad(fmt, "$*^$#", ILLEGAL);
expectPad(fmt, "#$*^$", ILLEGAL);
expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat.PAD_BEFORE_SUFFIX,
12, 'x');
expectPad(fmt, "''#0*x", DecimalFormat.PAD_BEFORE_SUFFIX,
3, 'x');
expectPad(fmt, "'I''ll'*a###.##", DecimalFormat.PAD_AFTER_PREFIX,
10, 'a');
fmt.applyPattern("AA#,##0.00ZZ");
fmt.setPadCharacter('^');
fmt.setFormatWidth(10);
fmt.setPadPosition(DecimalFormat.PAD_BEFORE_PREFIX);
expectPat(fmt, "*^AA#,##0.00ZZ");
fmt.setPadPosition(DecimalFormat.PAD_BEFORE_SUFFIX);
expectPat(fmt, "AA#,##0.00*^ZZ");
fmt.setPadPosition(DecimalFormat.PAD_AFTER_SUFFIX);
expectPat(fmt, "AA#,##0.00ZZ*^");
// 12 3456789012
String exp = "AA*^#,##0.00ZZ";
fmt.setFormatWidth(12);
fmt.setPadPosition(DecimalFormat.PAD_AFTER_PREFIX);
expectPat(fmt, exp);
fmt.setFormatWidth(13);
// 12 34567890123
expectPat(fmt, "AA*^##,##0.00ZZ");
fmt.setFormatWidth(14);
// 12 345678901234
expectPat(fmt, "AA*^###,##0.00ZZ");
fmt.setFormatWidth(15);
// 12 3456789012345
expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
fmt.setFormatWidth(16);
// 12 34567890123456
expectPat(fmt, "AA*^#,###,##0.00ZZ");
}
private void expectPat(DecimalFormat fmt, String exp) {
String pat = fmt.toPattern();
if (pat.equals(exp)) {
logln("Ok \"" + pat + '"');
} else {
errln("FAIL \"" + pat + "\", expected \"" + exp + '"');
}
}
/**
* Test the handling of the AlphaWorks BigDecimal
*/
public void TestAlphaBigDecimal() {
DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
expect(NumberFormat.getScientificInstance(Locale.US),
new Number[] { new com.ibm.math.BigDecimal("12345.678901"),
},
"1.234568E4");
expect(new DecimalFormat("##0.####E0", US),
new Number[] { new com.ibm.math.BigDecimal("12345.4999"),
new com.ibm.math.BigDecimal("12344.5001"),
},
"12.345E3");
expect(new DecimalFormat("##0.####E0", US),
new Number[] { new com.ibm.math.BigDecimal("12345.5000"),
new com.ibm.math.BigDecimal("12346.5000"),
},
"12.346E3");
}
/**
*/
public void TestScientific() {
DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
expect(NumberFormat.getScientificInstance(Locale.US),
new Number[] { new Double(12345.678901),
new java.math.BigDecimal("12345.678901"),
},
"1.234568E4");
expect(new DecimalFormat("##0.###E0", US),
new Double(12345),
"12.34E3");
expect(new DecimalFormat("##0.###E0", US),
new Double(12345.00001),
"12.35E3");
expect(new DecimalFormat("##0.####E0", US),
new Number[] { new Integer(12345),
new Long(12345),
new java.math.BigDecimal("12345.4999"),
new java.math.BigDecimal("12344.5001"),
},
"12.345E3");
expect(new DecimalFormat("##0.####E0", US),
new Number[] { new java.math.BigDecimal("12345.5000"),
new java.math.BigDecimal("12346.5000"),
},
"12.346E3");
expect(NumberFormat.getScientificInstance(Locale.FRANCE),
new Double(12345.678901),
"1,234568E4");
expect(new DecimalFormat("##0.####E0", US),
new Double(789.12345e-9),
"789.12E-9");
expect(new DecimalFormat("##0.####E0", US),
new Double(780.e-9),
"780E-9");
expect(new DecimalFormat(".###E0", US),
new Double(45678),
".457E5");
expect(new DecimalFormat(".###E0", US),
new Long(0),
".0E0");
expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
new DecimalFormat("##E0", US),
new DecimalFormat("####E0", US),
new DecimalFormat("0E0", US),
new DecimalFormat("00E0", US),
new DecimalFormat("000E0", US),
},
new Long(45678000),
new String[] { "4.5678E7",
"45.678E6",
"4567.8E4",
"5E7",
"46E6",
"457E5",
}
);
expect(new DecimalFormat("###E0", US),
new Object[] { new Double(0.0000123), "12.3E-6",
new Double(0.000123), "123E-6",
new java.math.BigDecimal("0.00123"), "1.23E-3", // Cafe VM messes up Double(0.00123)
new Double(0.0123), "12.3E-3",
new Double(0.123), "123E-3",
new Double(1.23), "1.23E0",
new Double(12.3), "12.3E0",
new Double(123), "123E0",
new Double(1230), "1.23E3",
});
expect(new DecimalFormat("0.#E+00", US),
new Object[] { new Double(0.00012), "1.2E-04",
new Long(12000), "1.2E+04",
});
}
/**
*/
public void TestPad() {
DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
expect(new DecimalFormat("*^##.##", US),
new Object[] { new Long(0), "^^^^0",
new Double(-1.3), "^-1.3",
}
);
expect(new DecimalFormat("##0.0####E0*_ g-m/s^2", US),
new Object[] { new Long(0), "0.0E0______ g-m/s^2",
new Double(1.0/3), "333.333E-3_ g-m/s^2",
}
);
expect(new DecimalFormat("##0.0####*_ g-m/s^2", US),
new Object[] { new Long(0), "0.0______ g-m/s^2",
new Double(1.0/3), "0.33333__ g-m/s^2",
}
);
}
private void expect(NumberFormat fmt, Object[] data) {
for (int i=0; i<data.length; i+=2) {
expect(fmt, (Number) data[i], (String) data[i+1]);
}
}
private void expect(Object fmto, Object numo, Object expo) {
NumberFormat fmt = null, fmts[] = null;
Number num = null, nums[] = null;
String exp = null, exps[] = null;
if (fmto instanceof NumberFormat[]) {
fmts = (NumberFormat[]) fmto;
} else {
fmt = (NumberFormat) fmto;
}
if (numo instanceof Number[]) {
nums = (Number[]) numo;
} else {
num = (Number) numo;
}
if (expo instanceof String[]) {
exps = (String[]) expo;
} else {
exp = (String) expo;
}
int n = 1;
if (fmts != null) {
n = Math.max(n, fmts.length);
}
if (nums != null) {
n = Math.max(n, nums.length);
}
if (exps != null) {
n = Math.max(n, exps.length);
}
for (int i=0; i<n; ++i) {
expect(fmts == null ? fmt : fmts[i],
nums == null ? num : nums[i],
exps == null ? exp : exps[i]);
}
}
private static String showNumber(Number n) {
String cls = n.getClass().getName();
if (!(n instanceof com.ibm.math.BigDecimal
|| n instanceof java.math.BigDecimal)) {
int i = cls.lastIndexOf('.');
cls = cls.substring(i+1);
}
return n.toString() + " (" + cls + ')';
}
private void expect(NumberFormat fmt, Number n, String exp) {
String saw = fmt.format(n);
String pat = ((DecimalFormat) fmt).toPattern();
if (saw.equals(exp)) {
logln("Ok " + showNumber(n) + " x " +
pat + " = \"" +
saw + '"');
} else {
errln("FAIL " + showNumber(n) + " x " +
pat + " = \"" +
saw + "\", expected \"" + exp + '"');
}
}
private void expect(NumberFormat fmt, String str, Number exp) {
Number saw = null;
try {
saw = fmt.parse(str);
} catch (ParseException e) {
saw = null;
}
String pat = ((DecimalFormat) fmt).toPattern();
if (saw.equals(exp)) {
logln("Ok \"" + str + "\" x " +
pat + " = " +
showNumber(saw));
} else {
errln("FAIL \"" + str + "\" x " +
pat + " = " +
showNumber(saw) + ", expected " + showNumber(exp));
}
}
public void Test4161100() {
NumberFormat f = NumberFormat.getInstance();
f.setMinimumFractionDigits(1);
f.setMaximumFractionDigits(1);
double a = -0.09;
String s = f.format(a);
logln(a + " x " +
((DecimalFormat) f).toPattern() + " = " +
s);
if (!s.equals("-0.1")) {
errln("FAIL");
}
}
}

View file

@ -0,0 +1,220 @@
/*
* (C) IBM Corp. 1997-1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.test.rbnf;
import com.ibm.text.RuleBasedNumberFormat;
import com.ibm.test.TestFmwk;
import java.util.Locale;
import java.text.NumberFormat;
public class RbnfRoundTripTest extends TestFmwk {
/**
* Puts a copyright in the .class file
*/
private static final String copyrightNotice
= "Copyright \u00a91997-1998 IBM Corp. All rights reserved.";
public static void main(String[] args) {
RbnfRoundTripTest test = new RbnfRoundTripTest();
try {
test.run(args);
}
catch (Throwable e) {
System.out.println("Entire test failed because of exception: "
+ e.toString());
e.printStackTrace();
}
}
/**
* Perform an exhaustive round-trip test on the English spellout rules
*/
public void TestEnglishSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.US,
RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, -12345678, 12345678);
}
/**
* Perform an exhaustive round-trip test on the duration-formatting rules
*/
public void TestDurationsRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.US,
RuleBasedNumberFormat.DURATION);
doTest(formatter, 0, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Spanish spellout rules
*/
public void TestSpanishSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("es", "es",
""), RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, -12345678, 12345678);
}
/**
* Perform an exhaustive round-trip test on the French spellout rules
*/
public void TestFrenchSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.FRANCE,
RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, -12345678, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Swiss French spellout rules
*/
public void TestSwissFrenchSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("fr", "CH",
""), RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, -12345678, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Italian spellout rules
*/
public void TestItalianSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.ITALIAN,
RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, -999999, 999999);
}
/**
* Perform an exhaustive round-trip test on the German spellout rules
*/
public void TestGermanSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.GERMANY,
RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, 0, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Swedish spellout rules
*/
public void TestSwedishSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("sv", "SE",
""), RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, 0, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Dutch spellout rules
*/
public void TestDutchSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("nl", "NL",
""), RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, -12345678, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Japanese spellout rules
*/
public void TestJapaneseSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.JAPAN,
RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, 0, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Russian spellout rules
*/
public void TestRussianSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("ru", "RU",
""), RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, 0, 12345678);
}
/**
* Perform an exhaustive round-trip test on the Greek spellout rules
*/
public void TestGreekSpelloutRT() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("el", "GR",
""), RuleBasedNumberFormat.SPELLOUT);
doTest(formatter, 0, 12345678);
}
void doTest(RuleBasedNumberFormat formatter, long lowLimit,
long highLimit) {
try {
long count = 0;
long increment = 1;
for (long i = lowLimit; i <= highLimit; i += increment) {
if (count % 1000 == 0)
logln(Long.toString(i));
if (Math.abs(i) < 5000)
increment = 1;
else if (Math.abs(i) < 500000)
increment = 2737;
else
increment = 267437;
String text = formatter.format(i);
long rt = formatter.parse(text).longValue();
if (rt != i) {
errln("Round-trip failed: " + i + " -> " + text +
" -> " + rt);
}
++count;
}
if (lowLimit < 0) {
double d = 1.234;
while (d < 1000) {
String text = formatter.format(d);
double rt = formatter.parse(text).doubleValue();
if (rt != d) {
errln("Round-trip failed: " + d + " -> " + text +
" -> " + rt);
}
d *= 10;
}
}
}
catch (Throwable e) {
errln("Test failed with exception: " + e.toString());
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,388 @@
/*
* (C) IBM Corp. 1997-1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.test.rbnf;
import com.ibm.text.RuleBasedNumberFormat;
import com.ibm.test.TestFmwk;
import java.util.Locale;
import java.text.NumberFormat;
public class RbnfTest extends TestFmwk {
/**
* Puts a copyright in the .class file
*/
private static final String copyrightNotice
= "Copyright \u00a91997-1999 IBM Corp. All rights reserved.";
public static void main(String[] args) {
RbnfTest test = new RbnfTest();
try {
test.run(args);
}
catch (Throwable e) {
System.out.println("Entire test failed because of exception: "
+ e.toString());
e.printStackTrace();
}
}
/**
* Perform a simple spot check on the English spellout rules
*/
public void TestEnglishSpellout() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.US,
RuleBasedNumberFormat.SPELLOUT);
String[][] testData = {
{ "1", "one" },
{ "15", "fifteen" },
{ "20", "twenty" },
{ "23", "twenty-three" },
{ "73", "seventy-three" },
{ "88", "eighty-eight" },
{ "100", "one hundred" },
{ "106", "one hundred and six" },
{ "127", "one hundred and twenty-seven" },
{ "200", "two hundred" },
{ "579", "five hundred and seventy-nine" },
{ "1,000", "one thousand" },
{ "2,000", "two thousand" },
{ "3,004", "three thousand and four" },
{ "4,567", "four thousand five hundred and sixty-seven" },
{ "15,943", "fifteen thousand nine hundred and forty-three" },
{ "2,345,678", "two million, three hundred and forty-five "
+ "thousand, six hundred and seventy-eight" },
{ "-36", "minus thirty-six" },
{ "234.567", "two hundred and thirty-four point five six seven" }
};
doTest(formatter, testData, true);
formatter.setLenientParseMode(true);
String[][] lpTestData = {
{ "FOurhundred thiRTY six", "436" },
{ "2 thousand six HUNDRED fifty-7", "2,657" },
{ "fifteen hundred and zero", "1,500" }
};
doLenientParseTest(formatter, lpTestData);
}
/**
* Perform a simple spot check on the English ordinal-abbreviation rules
*/
public void TestOrdinalAbbreviations() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.US,
RuleBasedNumberFormat.ORDINAL);
String[][] testData = {
{ "1", "1st" },
{ "2", "2nd" },
{ "3", "3rd" },
{ "4", "4th" },
{ "7", "7th" },
{ "10", "10th" },
{ "11", "11th" },
{ "13", "13th" },
{ "20", "20th" },
{ "21", "21st" },
{ "22", "22nd" },
{ "23", "23rd" },
{ "24", "24th" },
{ "33", "33rd" },
{ "102", "102nd" },
{ "312", "312th" },
{ "12,345", "12,345th" }
};
doTest(formatter, testData, false);
}
/**
* Perform a simple spot check on the duration-formatting rules
*/
public void TestDurations() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.US,
RuleBasedNumberFormat.DURATION);
String[][] testData = {
{ "1", "1 sec." },
{ "24", "24 sec." },
{ "60", "1:00" },
{ "73", "1:13" },
{ "145", "2:25" },
{ "666", "11:06" },
{ "3,600", "1:00:00" },
{ "3,740", "1:02:20" },
{ "10,293", "2:51:33" }
};
doTest(formatter, testData, true);
formatter.setLenientParseMode(true);
String[][] lpTestData = {
{ "2-51-33", "10,293" }
};
doLenientParseTest(formatter, lpTestData);
}
/**
* Perform a simple spot check on the Spanish spellout rules
*/
public void TestSpanishSpellout() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("es", "es",
""), RuleBasedNumberFormat.SPELLOUT);
String[][] testData = {
{ "1", "uno" },
{ "6", "seis" },
{ "16", "diecis\u00e9is" },
{ "20", "veinte" },
{ "24", "veinticuatro" },
{ "26", "veintis\u00e9is" },
{ "73", "setenta y tres" },
{ "88", "ochenta y ocho" },
{ "100", "cien" },
{ "106", "ciento seis" },
{ "127", "ciento veintisiete" },
{ "200", "doscientos" },
{ "579", "quinientos setenta y nueve" },
{ "1,000", "mil" },
{ "2,000", "dos mil" },
{ "3,004", "tres mil cuatro" },
{ "4,567", "cuatro mil quinientos sesenta y siete" },
{ "15,943", "quince mil novecientos cuarenta y tres" },
{ "2,345,678", "dos mill\u00f3n trescientos cuarenta y cinco mil "
+ "seiscientos setenta y ocho"},
{ "-36", "menos treinta y seis" },
{ "234.567", "doscientos treinta y cuatro punto cinco seis siete" }
};
doTest(formatter, testData, true);
}
/**
* Perform a simple spot check on the French spellout rules
*/
public void TestFrenchSpellout() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.FRANCE,
RuleBasedNumberFormat.SPELLOUT);
String[][] testData = {
{ "1", "un" },
{ "15", "quinze" },
{ "20", "vingt" },
{ "21", "vingt-et-un" },
{ "23", "vingt-trois" },
{ "62", "soixante-deux" },
{ "70", "soixante-dix" },
{ "71", "soixante et onze" },
{ "73", "soixante-treize" },
{ "80", "quatre-vingts" },
{ "88", "quatre-vingt-huit" },
{ "100", "cent" },
{ "106", "cent six" },
{ "127", "cent vingt-sept" },
{ "200", "deux cents" },
{ "579", "cinq cents soixante-dix-neuf" },
{ "1,000", "mille" },
{ "1,123", "onze cents vingt-trois" },
{ "1,594", "mille cinq cents quatre-vingt-quatorze" },
{ "2,000", "deux mille" },
{ "3,004", "trois mille quatre" },
{ "4,567", "quatre mille cinq cents soixante-sept" },
{ "15,943", "quinze mille neuf cents quarante-trois" },
{ "2,345,678", "deux million trois cents quarante-cinq mille "
+ "six cents soixante-dix-huit" },
{ "-36", "moins trente-six" },
{ "234.567", "deux cents trente-quatre virgule cinq six sept" }
};
doTest(formatter, testData, true);
formatter.setLenientParseMode(true);
String[][] lpTestData = {
{ "trente-un", "31" },
{ "un cents quatre vingt dix huit", "198" }
};
doLenientParseTest(formatter, lpTestData);
}
/**
* Perform a simple spot check on the Swiss French spellout rules
*/
public void TestSwissFrenchSpellout() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(new Locale("fr", "CH",
""), RuleBasedNumberFormat.SPELLOUT);
String[][] testData = {
{ "1", "un" },
{ "15", "quinze" },
{ "20", "vingt" },
{ "21", "vingt-et-un" },
{ "23", "vingt-trois" },
{ "62", "soixante-deux" },
{ "70", "septante" },
{ "71", "septante-et-un" },
{ "73", "septante-trois" },
{ "80", "octante" },
{ "88", "octante-huit" },
{ "100", "cent" },
{ "106", "cent six" },
{ "127", "cent vingt-sept" },
{ "200", "deux cents" },
{ "579", "cinq cents septante-neuf" },
{ "1,000", "mille" },
{ "1,123", "onze cents vingt-trois" },
{ "1,594", "mille cinq cents nonante-quatre" },
{ "2,000", "deux mille" },
{ "3,004", "trois mille quatre" },
{ "4,567", "quatre mille cinq cents soixante-sept" },
{ "15,943", "quinze mille neuf cents quarante-trois" },
{ "2,345,678", "deux million trois cents quarante-cinq mille "
+ "six cents septante-huit" },
{ "-36", "moins trente-six" },
{ "234.567", "deux cents trente-quatre virgule cinq six sept" }
};
doTest(formatter, testData, true);
}
/**
* Perform a simple spot check on the Italian spellout rules
*/
public void TestItalianSpellout() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.ITALIAN,
RuleBasedNumberFormat.SPELLOUT);
String[][] testData = {
{ "1", "uno" },
{ "15", "quindici" },
{ "20", "venti" },
{ "23", "ventitre" },
{ "73", "settantatre" },
{ "88", "ottantotto" },
{ "100", "cento" },
{ "106", "centosei" },
{ "108", "centotto" },
{ "127", "centoventisette" },
{ "181", "centottantuno" },
{ "200", "duecento" },
{ "579", "cinquecentosettantanove" },
{ "1,000", "mille" },
{ "2,000", "duemila" },
{ "3,004", "tremilaquattro" },
{ "4,567", "quattromilacinquecentosessantasette" },
{ "15,943", "quindicimilanovecentoquarantatre" },
{ "-36", "meno trentisei" },
{ "234.567", "duecentotrentiquattro virgola cinque sei sette" }
};
doTest(formatter, testData, true);
}
/**
* Perform a simple spot check on the German spellout rules
*/
public void TestGermanSpellout() {
RuleBasedNumberFormat formatter
= new RuleBasedNumberFormat(Locale.GERMANY,
RuleBasedNumberFormat.SPELLOUT);
String[][] testData = {
{ "1", "eins" },
{ "15", "f\u00fcnfzehn" },
{ "20", "zwanzig" },
{ "23", "dreiundzwanzig" },
{ "73", "dreiundsiebzig" },
{ "88", "achtundachtzig" },
{ "100", "hundert" },
{ "106", "hundertsechs" },
{ "127", "hundertsiebenundzwanzig" },
{ "200", "zweihundert" },
{ "579", "f\u00fcnfhundertneunundsiebzig" },
{ "1,000", "tausend" },
{ "2,000", "zweitausend" },
{ "3,004", "dreitausendvier" },
{ "4,567", "viertausendf\u00fcnfhundertsiebenundsechzig" },
{ "15,943", "f\u00fcnfzehntausendneunhundertdreiundvierzig" },
{ "2,345,678", "zwei Millionen dreihundertf\u00fcnfundvierzigtausend"
+ "sechshundertachtundsiebzig" }
};
doTest(formatter, testData, true);
formatter.setLenientParseMode(true);
String[][] lpTestData = {
{ "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }
};
doLenientParseTest(formatter, lpTestData);
}
void doTest(RuleBasedNumberFormat formatter, String[][] testData,
boolean testParsing) {
NumberFormat decFmt = NumberFormat.getInstance(Locale.US);
try {
for (int i = 0; i < testData.length; i++) {
String number = testData[i][0];
String expectedWords = testData[i][1];
String actualWords = formatter.format(decFmt.parse(number));
if (!actualWords.equals(expectedWords)) {
errln("Spot check failed: for " + number + ", expected "
+ expectedWords + ", but got " +
actualWords);
}
else if (testParsing) {
String actualNumber = decFmt.format(formatter
.parse(actualWords));
if (!actualNumber.equals(number)) {
errln("Spot check failed: for " + actualWords +
", expected " + number + ", but got " +
actualNumber);
}
}
}
}
catch (Throwable e) {
errln("Test failed with exception: " + e.toString());
e.printStackTrace();
}
}
void doLenientParseTest(RuleBasedNumberFormat formatter,
String[][] testData) {
NumberFormat decFmt = NumberFormat.getInstance(Locale.US);
try {
for (int i = 0; i < testData.length; i++) {
String words = testData[i][0];
String expectedNumber = testData[i][1];
String actualNumber = decFmt.format(formatter.parse(words));
if (!actualNumber.equals(expectedNumber)) {
errln("Lenient-parse spot check failed: for "
+ words + ", expected " + expectedNumber
+ ", but got " + actualNumber);
}
}
}
catch (Throwable e) {
errln("Test failed with exception: " + e.toString());
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,338 @@
/*
* $RCSfile: BasicTest.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:48 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.test.normalizer;
import com.ibm.test.*;
import com.ibm.text.*;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
public class BasicTest extends TestFmwk {
public static void main(String[] args) throws Exception {
new BasicTest().run(args);
}
String[][] canonTests = {
// Input Decomposed Composed
{ "cat", "cat", "cat" },
{ "\u00e0ardvark", "a\u0300ardvark", "\u00e0ardvark", },
{ "\u1e0a", "D\u0307", "\u1e0a" }, // D-dot_above
{ "D\u0307", "D\u0307", "\u1e0a" }, // D dot_above
{ "\u1e0c\u0307", "D\u0323\u0307", "\u1e0c\u0307" }, // D-dot_below dot_above
{ "\u1e0a\u0323", "D\u0323\u0307", "\u1e0c\u0307" }, // D-dot_above dot_below
{ "D\u0307\u0323", "D\u0323\u0307", "\u1e0c\u0307" }, // D dot_below dot_above
{ "\u1e10\u0307\u0323", "D\u0327\u0323\u0307", "\u1e10\u0323\u0307"}, // D dot_below cedilla dot_above
{ "D\u0307\u0328\u0323","D\u0328\u0323\u0307", "\u1e0c\u0328\u0307"}, // D dot_above ogonek dot_below
{ "\u1E14", "E\u0304\u0300", "\u1E14" }, // E-macron-grave
{ "\u0112\u0300", "E\u0304\u0300", "\u1E14" }, // E-macron + grave
{ "\u00c8\u0304", "E\u0300\u0304", "\u00c8\u0304" }, // E-grave + macron
{ "\u212b", "A\u030a", "\u00c5" }, // angstrom_sign
{ "\u00c5", "A\u030a", "\u00c5" }, // A-ring
{ "ýffin", "A\u0308ffin", "ýffin" },
{ "ý\uFB03n", "A\u0308\uFB03n", "ý\uFB03n" },
{ "Henry IV", "Henry IV", "Henry IV" },
{ "Henry \u2163", "Henry \u2163", "Henry \u2163" },
{ "\u30AC", "\u30AB\u3099", "\u30AC" }, // ga (Katakana)
{ "\u30AB\u3099", "\u30AB\u3099", "\u30AC" }, // ka + ten
{ "\uFF76\uFF9E", "\uFF76\uFF9E", "\uFF76\uFF9E" }, // hw_ka + hw_ten
{ "\u30AB\uFF9E", "\u30AB\uFF9E", "\u30AB\uFF9E" }, // ka + hw_ten
{ "\uFF76\u3099", "\uFF76\u3099", "\uFF76\u3099" }, // hw_ka + ten
};
String[][] compatTests = {
// Input Decomposed Composed
{ "\uFB4f", "\u05D0\u05DC", "\u05D0\u05DC", }, // Alef-Lamed vs. Alef, Lamed
{ "ýffin", "A\u0308ffin", "ýffin" },
{ "ý\uFB03n", "A\u0308ffin", "ýffin" }, // ffi ligature -> f + f + i
{ "Henry IV", "Henry IV", "Henry IV" },
{ "Henry \u2163", "Henry IV", "Henry IV" },
{ "\u30AC", "\u30AB\u3099", "\u30AC" }, // ga (Katakana)
{ "\u30AB\u3099", "\u30AB\u3099", "\u30AC" }, // ka + ten
{ "\uFF76\u3099", "\u30AB\u3099", "\u30AC" }, // hw_ka + ten
/* These two are broken in Unicode 2.1.2 but fixed in 2.1.5 and later
{ "\uFF76\uFF9E", "\u30AB\u3099", "\u30AC" }, // hw_ka + hw_ten
{ "\u30AB\uFF9E", "\u30AB\u3099", "\u30AC" }, // ka + hw_ten
*/
};
// With Canonical decomposition, Hangul syllables should get decomposed
// into Jamo, but Jamo characters should not be decomposed into
// conjoining Jamo
String[][] hangulCanon = {
// Input Decomposed Composed
{ "\ud4db", "\u1111\u1171\u11b6", "\ud4db" },
{ "\u1111\u1171\u11b6", "\u1111\u1171\u11b6", "\ud4db" },
};
// With compatibility decomposition turned on,
// it should go all the way down to conjoining Jamo characters.
// THIS IS NO LONGER TRUE IN UNICODE v2.1.8, SO THIS TEST IS OBSOLETE
String[][] hangulCompat = {
// Input Decomposed Composed
// { "\ud4db", "\u1111\u116e\u1175\u11af\u11c2", "\ud478\u1175\u11af\u11c2" },
};
public void TestHangulCompose() {
// Make sure that the static composition methods work
logln("Canonical composition...");
staticTest(Normalizer.COMPOSE, 0, hangulCanon, 2);
logln("Compatibility composition...");
staticTest(Normalizer.COMPOSE_COMPAT, 0, hangulCompat, 2);
// Now try iterative composition....
logln("Static composition...");
Normalizer norm = new Normalizer("", Normalizer.COMPOSE, 0);
iterateTest(norm, hangulCanon, 2);
norm.setMode(Normalizer.COMPOSE_COMPAT);
iterateTest(norm, hangulCompat, 2);
// And finally, make sure you can do it in reverse too
logln("Reverse iteration...");
norm.setMode(Normalizer.COMPOSE);
backAndForth(norm, hangulCanon);
}
public void TestHangulDecomp() {
// Make sure that the static decomposition methods work
logln("Canonical decomposition...");
staticTest(Normalizer.DECOMP, 0, hangulCanon, 1);
logln("Compatibility decomposition...");
staticTest(Normalizer.DECOMP_COMPAT, 0, hangulCompat, 1);
// Now the iterative decomposition methods...
logln("Iterative decomposition...");
Normalizer norm = new Normalizer("", Normalizer.DECOMP, 0);
iterateTest(norm, hangulCanon, 1);
norm.setMode(Normalizer.DECOMP_COMPAT);
iterateTest(norm, hangulCompat, 1);
// And finally, make sure you can do it in reverse too
logln("Reverse iteration...");
norm.setMode(Normalizer.DECOMP);
backAndForth(norm, hangulCanon);
}
public void TestPrevious() {
Normalizer norm = new Normalizer("", Normalizer.DECOMP, 0);
logln("testing decomp...");
backAndForth(norm, canonTests);
logln("testing compose...");
norm.setMode(Normalizer.COMPOSE);
backAndForth(norm, canonTests);
}
public void TestDecomp() {
Normalizer norm = new Normalizer("", Normalizer.DECOMP, 0);
iterateTest(norm, canonTests, 1);
staticTest(Normalizer.DECOMP, 0, canonTests, 1);
}
public void TestCompatDecomp() {
Normalizer norm = new Normalizer("", Normalizer.DECOMP_COMPAT, 0);
iterateTest(norm, compatTests, 1);
staticTest(Normalizer.DECOMP_COMPAT, 0, compatTests, 1);
}
public void TestCanonCompose() {
Normalizer norm = new Normalizer("", Normalizer.COMPOSE, 0);
iterateTest(norm, canonTests, 2);
staticTest(Normalizer.COMPOSE, 0, canonTests, 2);
}
public void TestCompatCompose() {
Normalizer norm = new Normalizer("", Normalizer.COMPOSE_COMPAT, 0);
iterateTest(norm, compatTests, 2);
staticTest(Normalizer.COMPOSE_COMPAT, 0, compatTests, 2);
}
public void TestExplodingBase() {
// \u017f - Latin small letter long s
// \u0307 - combining dot above
// \u1e61 - Latin small letter s with dot above
// \u1e9b - Latin small letter long s with dot above
String[][] canon = {
// Input Decomposed Composed
{ "Tschu\u017f", "Tschu\u017f", "Tschu\u017f" },
{ "Tschu\u1e9b", "Tschu\u017f\u0307", "Tschu\u1e9b" },
};
String[][] compat = {
// Input Decomposed Composed
{ "\u017f", "s", "s" },
{ "\u1e9b", "s\u0307", "\u1e61" },
};
staticTest(Normalizer.DECOMP, 0, canon, 1);
staticTest(Normalizer.COMPOSE, 0, canon, 2);
staticTest(Normalizer.DECOMP_COMPAT, 0, compat, 1);
staticTest(Normalizer.COMPOSE_COMPAT, 0, compat, 2);
Normalizer norm = new Normalizer("", Normalizer.DECOMP_COMPAT);
iterateTest(norm, compat, 1);
backAndForth(norm, compat);
norm.setMode(Normalizer.COMPOSE_COMPAT);
iterateTest(norm, compat, 2);
backAndForth(norm, compat);
}
/** The Tibetan vowel sign AA, 0f71, was messed up prior to Unicode version 2.1.9
& Once 2.1.9 or 3.0 is released, uncomment this test
public void TestTibetan() {
String[][] decomp = {
{ "\u0f77", "\u0f77", "\u0fb2\u0f71\u0f80" }
};
String[][] compose = {
{ "\u0fb2\u0f71\u0f80", "\u0fb2\u0f71\u0f80", "\u0fb2\u0f71\u0f80" }
};
staticTest(Normalizer.DECOMP, 0, decomp, 1);
staticTest(Normalizer.DECOMP_COMPAT, 0, decomp, 2);
staticTest(Normalizer.COMPOSE, 0, compose, 1);
staticTest(Normalizer.COMPOSE_COMPAT, 0, compose, 2);
}
*/
//------------------------------------------------------------------------
// Internal utilities
//
private void backAndForth(Normalizer iter, String input)
{
iter.setText(input);
// Run through the iterator forwards and stick it into a StringBuffer
StringBuffer forward = new StringBuffer();
for (char ch = iter.first(); ch != iter.DONE; ch = iter.next()) {
forward.append(ch);
}
// Now do it backwards
StringBuffer reverse = new StringBuffer();
for (char ch = iter.last(); ch != iter.DONE; ch = iter.previous()) {
reverse.insert(0, ch);
}
if (!forward.toString().equals(reverse.toString())) {
errln("Forward/reverse mismatch for input " + hex(input)
+ ", forward: " + hex(forward) + ", backward: " + hex(reverse));
}
}
private void backAndForth(Normalizer iter, String[][] tests)
{
for (int i = 0; i < tests.length; i++)
{
iter.setText(tests[i][0]);
// Run through the iterator forwards and stick it into a StringBuffer
StringBuffer forward = new StringBuffer();
for (char ch = iter.first(); ch != iter.DONE; ch = iter.next()) {
forward.append(ch);
}
// Now do it backwards
StringBuffer reverse = new StringBuffer();
for (char ch = iter.last(); ch != iter.DONE; ch = iter.previous()) {
reverse.insert(0, ch);
}
if (!forward.toString().equals(reverse.toString())) {
errln("Forward/reverse mismatch for input " + hex(tests[i][0])
+ ", forward: " + hex(forward) + ", backward: " + hex(reverse));
}
}
}
private void staticTest(Normalizer.Mode mode, int options, String[][] tests, int outCol)
{
for (int i = 0; i < tests.length; i++)
{
String input = tests[i][0];
String expect = tests[i][outCol];
logln("Normalizing '" + input + "' (" + hex(input) + ")" );
String output = Normalizer.normalize(input, mode, options);
if (!output.equals(expect)) {
errln("ERROR: case " + i
+ " expected '" + expect + "' (" + hex(expect) + ")"
+ " but got '" + output + "' (" + hex(output) + ")" );
}
}
}
private void iterateTest(Normalizer iter, String[][] tests, int outCol)
{
for (int i = 0; i < tests.length; i++)
{
String input = tests[i][0];
String expect = tests[i][outCol];
logln("Normalizing '" + input + "' (" + hex(input) + ")" );
iter.setText(input);
assertEqual(expect, iter, "ERROR: case " + i + " ");
}
}
private void assertEqual(String expected, Normalizer iter, String errPrefix)
{
int index = 0;
for (char ch = iter.first(); ch != iter.DONE; ch = iter.next())
{
if (index >= expected.length()) {
errln(errPrefix + "Unexpected character '" + ch + "' (" + hex(ch) + ")"
+ " at index " + index);
break;
}
char want = expected.charAt(index);
if (ch != want) {
errln(errPrefix + "got '" + ch + "' (" + hex(ch) + ")"
+ " but expected '" + want + "' (" + hex(want) + ")"
+ " at index " + index);
}
index++;
}
if (index < expected.length()) {
errln(errPrefix + "Only got " + index + " chars, expected " + expected.length());
}
}
}

View file

@ -0,0 +1,140 @@
/*
* $RCSfile: ExhaustiveTest.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:49 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.test.normalizer;
import com.ibm.test.*;
import com.ibm.text.*;
public class ExhaustiveTest extends TestFmwk
{
private static UInfo info;
public static void main(String[] args) throws Exception
{
String[] tempArgs = new String[args.length];
int count = 0;
// Allow the test to be pointed at a specific version of the Unicode database
for (int i = 0; i < args.length; i++)
{
if (args[i].equals("-data")) {
info = new UInfo(args[++i]);
} else {
tempArgs[count++] = args[i];
}
}
args = new String[count];
System.arraycopy(tempArgs, 0, args, 0, count);
if (info == null) {
info = new UInfo();
}
new ExhaustiveTest().run(args);
}
/**
* Run through all of the characters returned by a composed-char iterator
* and make sure that:
* <ul>
* <li>a) They do indeed have decompositions.
* <li>b) The decomposition according to the iterator is the same as
* returned by Normalizer.decompose().
* <li>c) All characters <em>not</em> returned by the iterator do not
* have decompositions.
* </ul>
*/
public void TestComposedCharIter() {
doTestComposedChars(false);
}
public void doTestComposedChars(boolean compat) {
int options = Normalizer.IGNORE_HANGUL;
ComposedCharIter iter = new ComposedCharIter(compat, options);
char lastChar = 0;
while (iter.hasNext()) {
char ch = iter.next();
// Test all characters between the last one and this one to make
// sure that they don't have decompositions
assertNoDecomp(lastChar, ch, compat, options);
lastChar = ch;
// Now make sure that the decompositions for this character
// make sense
String chString = new StringBuffer().append(ch).toString();
String iterDecomp = iter.decomposition();
String normDecomp = Normalizer.decompose(chString, compat, 0);
if (iterDecomp.equals(chString)) {
errln("ERROR: " + hex(ch) + " has identical decomp");
}
else if (!iterDecomp.equals(normDecomp)) {
errln("ERROR: Normalizer decomp for " + hex(ch) + " (" + hex(normDecomp) + ")"
+ " != iter decomp (" + hex(iterDecomp) + ")" );
}
}
assertNoDecomp(lastChar, '\uFFFF', compat, options);
}
void assertNoDecomp(char start, char limit, boolean compat, int options)
{
for (char x = ++start; x < limit; x++) {
String xString = new StringBuffer().append(x).toString();
String decomp = Normalizer.decompose(xString, compat, options);
if (!decomp.equals(xString)) {
errln("ERROR: " + hex(x) + " has decomposition (" + hex(decomp) + ")"
+ " but was not returned by iterator");
}
}
}
public void TestRoundTrip() {
int options = Normalizer.IGNORE_HANGUL;
boolean compat = false;
ComposedCharIter iter = new ComposedCharIter(false, options);
while (iter.hasNext()) {
char ch = iter.next();
String chStr = new StringBuffer().append(ch).toString();
String decomp = Normalizer.decompose(chStr, compat, options);
String comp = Normalizer.compose(decomp, compat, options);
short cClass = info.getCanonicalClass(decomp.charAt(0));
if (info.isExcludedComposition(ch)) {
logln("Skipped excluded char " + hex(ch) + " (" + info.getName(ch,true) + ")" );
continue;
}
// Avoid disparaged characters
if (info.getDecomposition(ch).length() == 4) continue;
if (!comp.equals(chStr)) {
errln("ERROR: Round trip invalid: " + hex(chStr) + " --> " + hex(decomp)
+ " --> " + hex(comp));
errln(" char decomp is '" + info.getDecomposition(ch) + "'");
}
}
}
}

View file

@ -0,0 +1,120 @@
// FooTest.java
package com.ibm.test.normalizer;
import com.ibm.test.*;
import com.ibm.text.*;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
public class FooTest extends TestFmwk {
public static void main(String[] args) throws Exception {
new FooTest().run(args);
}
public void testTibetan() {
String[][] decomp = {
{ "\u0f77", "\u0fb2\u0f71\u0f80", "\u0f77" }
};
String[][] compose = {
{ "\u0fb2\u0f71\u0f80", "\u0f77" }
};
staticTest(Normalizer.DECOMP, 0, decomp, 1);
staticTest(Normalizer.COMPOSE, 0, compose, 1);
}
public void TestCombineZero() {
String[][] decomp = {
{ "\u09CB", "\u09C7\u09BE", "\u09CB" }
};
String[][] compose = {
{ "\u09C7\u09BE", "\u09CB" }
};
staticTest(Normalizer.DECOMP, 0, decomp, 1);
staticTest(Normalizer.COMPOSE, 0, compose, 1);
}
private void backAndForth(Normalizer iter, String[][] tests)
{
for (int i = 0; i < tests.length; i++)
{
iter.setText(tests[i][0]);
// Run through the iterator forwards and stick it into a StringBuffer
StringBuffer forward = new StringBuffer();
for (char ch = iter.first(); ch != iter.DONE; ch = iter.next()) {
forward.append(ch);
}
// Now do it backwards
StringBuffer reverse = new StringBuffer();
for (char ch = iter.last(); ch != iter.DONE; ch = iter.previous()) {
reverse.insert(0, ch);
}
if (!forward.toString().equals(reverse.toString())) {
errln("Forward/reverse mismatch for input " + hex(tests[i][0])
+ ", forward: " + hex(forward) + ", backward: " + hex(reverse));
}
}
}
private void staticTest(Normalizer.Mode mode, int options, String[][] tests, int outCol)
{
for (int i = 0; i < tests.length; i++)
{
String input = tests[i][0];
String expect = tests[i][outCol];
logln("Normalizing '" + input + "' (" + hex(input) + ")" );
String output = Normalizer.normalize(input, mode, options);
if (!output.equals(expect)) {
errln("ERROR: case " + i
+ " expected '" + expect + "' (" + hex(expect) + ")"
+ " but got '" + output + "' (" + hex(output) + ")" );
}
}
}
private void iterateTest(Normalizer iter, String[][] tests, int outCol)
{
for (int i = 0; i < tests.length; i++)
{
String input = tests[i][0];
String expect = tests[i][outCol];
logln("Normalizing '" + input + "' (" + hex(input) + ")" );
iter.setText(input);
assertEqual(expect, iter, "ERROR: case " + i + " ");
}
}
private void assertEqual(String expected, Normalizer iter, String errPrefix)
{
int index = 0;
for (char ch = iter.first(); ch != iter.DONE; ch = iter.next())
{
if (index >= expected.length()) {
errln(errPrefix + "Unexpected character '" + ch + "' (" + hex(ch) + ")"
+ " at index " + index);
break;
}
char want = expected.charAt(index);
if (ch != want) {
errln(errPrefix + "got '" + ch + "' (" + hex(ch) + ")"
+ " but expected '" + want + "' (" + hex(want) + ")"
+ " at index " + index);
}
index++;
}
if (index < expected.length()) {
errln(errPrefix + "Only got " + index + " chars, expected " + expected.length());
}
}
}

View file

@ -0,0 +1,95 @@
Sizes of Normalizer data:
Before any work
Total runtime size of decomp data is 30200
offsets: 16128
canonClasses: 4096
replace: 9976
Total runtime size of compose data is 113361
lookup: 16640
actions: 83808
actionIndex: 2244
typeMask: 394
replace: 10275
Turn on overlapping in CompactArray:
Total runtime size of decomp data is 28830
offsets: 14758
canonClasses: 4096
replace: 9976
Total runtime size of compose data is 112039
lookup: 15318
actions: 83808
actionIndex: 2244
typeMask: 394
replace: 10275
Turn "actions" into a CompactArray and turn overlapping back off due to a bug:
Total runtime size of decomp data is 30200
offsets: 16128
canonClasses: 4096
replace: 9976
Total runtime size of compose data is 70272
lookup: 16640
actions: 40704
actionIndex: 2244
typeMask: 394
replace: 10275
Put compatibility decomps first in "replace" array and eliminate dups:
Total runtime size of decomp data is 27980
offsets: 16128
canonClasses: 4096
replace: 7756
Total runtime size of compose data is 68052
lookup: 16640
actions: 40704
actionIndex: 2244
typeMask: 394
replace: 8070
Tweak CompactArray block size to 32
Total runtime size of decomp data is 26892
offsets: 15040
canonClasses: 4096
replace: 7756
Total runtime size of compose data is 49044
lookup: 16192
actions: 22144
actionIndex: 2244
typeMask: 394
replace: 8070
Use 2 bits for length of decomposition:
Total runtime size of decomp data is 23738
offsets: 14976
canonClasses: 4096
replace: 4666
Total runtime size of compose data is 49051
lookup: 16192
actions: 22144
actionIndex: 2244
typeMask: 394
replace: 8077
----------------------------------------------------------------------
Now using UnicodeData-2.1.2.txt (overlapping is still off)
Total runtime size of decomp data is 23532
offsets: 14400
canonClasses: 4096
replace: 5036
Total runtime size of compose data is 50520
lookup: 15872
actions: 23872
actionIndex: 2298
typeMask: 406
replace: 8072

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,261 @@
/*
* (C) IBM Corp. 1997-1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.test.RuleBasedBreakIterator;
import java.util.Locale;
import com.ibm.text.BreakIterator;
public class SimpleBITest {
public static final String testText =
// "The rain in Spain stays mainly on the plain. The plains in Spain are mainly pained with rain.";
//"one-two now-- Hah! You owe me exactly $1,345.67... Pay up, huh? By the way, why don't I send you my re\u0301sume\u0301? This is a line\r\nbreak.";
//"nowisthetimeforallgoodmen... tocometothehelpoftheircountry";
"When, in the course of human events, it becomes necessary for one people to dissolve the political bonds which have "
//"When,inthecourseofhumanevents,itbecomesnecessaryforonepeopletodissolvethepoliticalbondswhichhave"
+ "connectedthemwithanother,andtoassumeamongthepowersoftheearth,theseparateandequalstationtowhichthelaws"
+ "ofnatureandofnature'sGodentitlethem,adecentrespecttotheopinionsofmankindrequiresthattheyshoulddeclarethe"
+ "causeswhichimpelthemtotheseparation\n"
+ "Weholdthesetruthstobeself-evident,thatallmenarecreatedequal,thattheyareendowedbytheirCreatorwithcertain"
+ "unalienablerights,thatamongthesearelife,libertyandthepursuitofhappiness.Thattosecuretheserights,governmentsare"
+ "institutedamongmen,derivingtheirjustpowersfromtheconsentofthegoverned.Thatwheneveranyformofgovernment"
+ "becomesdestructivetotheseends,itistherightofthepeopletoalterortoabolishit,andtoinstitutenewgovernment,laying"
+ "itsfoundationonsuchprinciplesandorganizingitspowersinsuchform,astothemshallseemmostlikelytoeffecttheirsafety"
+ "andhappiness.Prudence,indeed,willdictatethatgovernmentslongestablishedshouldnotbechangedforlightandtransient"
+ "causes;andaccordinglyallexperiencehathshownthatmankindaremoredisposedtosuffer,whileevilsaresufferable,than"
+ "torightthemselvesbyabolishingtheformstowhichtheyareaccustomed.Butwhenalongtrainofabusesandusurpations,"
+ "pursuinginvariablythesameobjectevincesadesigntoreducethemunderabsolutedespotism,itistheirright,itistheirduty,"
+ "tothrowoffsuchgovernment,andtoprovidenewguardsfortheirfuturesecurity.--Suchhasbeenthepatientsufferanceof"
+ "thesecolonies;andsuchisnowthenecessitywhichconstrainsthemtoaltertheirformersystemsofgovernment.Thehistory"
+ "ofthepresentKingofGreatBritainisahistoryofrepeatedinjuriesandusurpations,allhavingindirectobjectthe"
+ "establishmentofanabsolutetyrannyoverthesestates.Toprovethis,letfactsbesubmittedtoacandidworld.\n"
+ "Hehasrefusedhisassenttolaws,themostwholesomeandnecessaryforthepublicgood.\n"
+ "Hehasforbiddenhisgovernorstopasslawsofimmediateandpressingimportance,unlesssuspendedintheiroperationtill"
+ "hisassentshouldbeobtained;andwhensosuspended,hehasutterlyneglectedtoattendtothem.\n"
+ "Hehasrefusedtopassotherlawsfortheaccommodationoflargedistrictsofpeople,unlessthosepeoplewouldrelinquish"
+ "therightofrepresentationinthelegislature,arightinestimabletothemandformidabletotyrantsonly.\n"
+ "Hehascalledtogetherlegislativebodiesatplacesunusual,uncomfortable,anddistantfromthedepositoryoftheirpublic"
+ "records,forthesolepurposeoffatiguingthemintocompliancewithhismeasures.\n"
+ "Hehasdissolvedrepresentativehousesrepeatedly,foropposingwithmanlyfirmnesshisinvasionsontherightsofthepeople.\n"
+ "Hehasrefusedforalongtime,aftersuchdissolutions,tocauseotherstobeelected;wherebythelegislativepowers,"
+ "incapableofannihilation,havereturnedtothepeopleatlargefortheirexercise;thestateremaininginthemeantimeexposed"
+ "toallthedangersofinvasionfromwithout,andconvulsionswithin.\n"
+ "Hehasendeavoredtopreventthepopulationofthesestates;forthatpurposeobstructingthelawsfornaturalizationof"
+ "foreigners;refusingtopassotherstoencouragetheirmigrationhither,andraisingtheconditionsofnewappropriationsof"
+ "lands.\n"
+ "Hehasobstructedtheadministrationofjustice,byrefusinghisassenttolawsforestablishingjudiciarypowers.\n"
+ "Hehasmadejudgesdependentonhiswillalone,forthetenureoftheiroffices,andtheamountandpaymentoftheirsalaries.\n"
+ "Hehaserectedamultitudeofnewoffices,andsenthitherswarmsofofficerstoharassourpeople,andeatouttheir"
+ "substance.\n"
+ "Hehaskeptamongus,intimesofpeace,standingarmieswithouttheconsentofourlegislature.\n"
+ "Hehasaffectedtorenderthemilitaryindependentofandsuperiortocivilpower.\n"
+ "Hehascombinedwithotherstosubjectustoajurisdictionforeigntoourconstitution,andunacknowledgedbyourlaws;"
+ "givinghisassenttotheiractsofpretendedlegislation:\n"
+ "Forquarteringlargebodiesofarmedtroopsamongus:\n"
+ "Forprotectingthem,bymocktrial,frompunishmentforanymurderswhichtheyshouldcommitontheinhabitantsofthese"
+ "states:\n"
+ "Forcuttingoffourtradewithallpartsoftheworld:\n"
+ "Forimposingtaxesonuswithoutourconsent:\n"
+ "Fordeprivingusinmanycases,ofthebenefitsoftrialbyjury:\n"
+ "Fortransportingusbeyondseastobetriedforpretendedoffenses:\n"
+ "ForabolishingthefreesystemofEnglishlawsinaneighboringprovince,establishingthereinanarbitrarygovernment,and"
+ "enlargingitsboundariessoastorenderitatonceanexampleandfitinstrumentforintroducingthesameabsoluteruleinthese"
+ "colonies:\n"
+ "Fortakingawayourcharters,abolishingourmostvaluablelaws,andalteringfundamentallytheformsofourgovernments:\n"
+ "Forsuspendingourownlegislatures,anddeclaringthemselvesinvestedwithpowertolegislateforusinallcaseswhatsoever.\n"
+ "Hehasabdicatedgovernmenthere,bydeclaringusoutofhisprotectionandwagingwaragainstus.\n"
+ "Hehasplunderedourseas,ravagedourcoasts,burnedourtowns,anddestroyedthelivesofourpeople.\n"
+ "Heisatthistimetransportinglargearmiesofforeignmercenariestocompletetheworksofdeath,desolationandtyranny,"
+ "alreadybegunwithcircumstancesofcrueltyandperfidyscarcelyparalleledinthemostbarbarousages,andtotalyunworth"
+ "theheadofacivilizednation.\n"
+ "Hehasconstrainedourfellowcitizenstakencaptiveonthehighseastobeararmsagainsttheircountry,tobecomethe"
+ "executionersoftheirfriendsandbrethren,ortofallthemselvesbytheirhands.\n"
+ "Hehasexciteddomesticinsurrectionsamongstus,andhasendeavoredtobringontheinhabitantsofourfrontiers,the"
+ "mercilessIndiansavages,whoseknownruleofwarfare,isundistinguisheddestructionofallages,sexesandconditions.\n"
+ "Ineverystageoftheseoppressionswehavepetitionedforredressinthemosthumbleterms:ourrepeatedpetitionshave"
+ "beenansweredonlybyrepeatedinjury.Aprince,whosecharacteristhusmarkedbyeveryactwhichmaydefineatyrant,is"
+ "unfittobetherulerofafreepeople.\n"
+ "NorhavewebeenwantinginattentiontoourBritishbrethren.Wehavewarnedthemfromtimetotimeofattemptsbytheir"
+ "legislaturetoextendanunwarrantablejurisdictionoverus.Wehaveremindedthemofthecircumstancesofouremigration"
+ "andsettlementhere.Wehaveappealedtotheirnativejusticeandmagnanimity,andwehaveconjuredthembythetiesofour"
+ "commonkindredtodisavowtheseusurpations,which,wouldinevitablyinterruptourconnectionsandcorrespondence.We"
+ "must,therefore,acquiesceinthenecessity,whichdenouncesourseparation,andholdthem,asweholdtherestofmankind,"
+ "enemiesinwar,inpeacefriends.\n"
+ "We,therefore,therepresentativesoftheUnitedStatesofAmerica,inGeneralCongress,assembled,appealingtothe"
+ "SupremeJudgeoftheworldfortherectitudeofourintentions,do,inthename,andbytheauthorityofthegoodpeopleof"
+ "thesecolonies,solemnlypublishanddeclare,thattheseunitedcoloniesare,andofrightoughttobefreeandindependent"
+ "states;thattheyareabsolvedfromallallegiancetotheBritishCrown,andthatallpoliticalconnectionbetweenthemandthe"
+ "stateofGreatBritain,isandoughttobetotallydissolved;andthatasfreeandindependentstates,theyhavefullpowerto"
+ "leveywar,concludepeace,contractalliances,establishcommerce,andtodoallotheractsandthingswhichindependent"
+ "statesmayofrightdo.Andforthesupportofthisdeclaration,withafirmrelianceontheprotectionofDivineProvidence,we"
+ "mutuallypledgetoeachotherourlives,ourfortunesandoursacredhonor.\n";
public static void main(String[] args) throws java.io.IOException {
Locale locale = new Locale("en", "US", "TEST");
/*
System.out.println("==================================");
System.out.println("Character break:");
BreakIterator charBreak = BreakIterator.getCharacterInstance(locale);
doTest(charBreak);
*/
System.out.println("==================================");
System.out.println("Word break:");
BreakIterator wordBreak = BreakIterator.getWordInstance(locale);
doTest(wordBreak);
System.out.println("==================================");
System.out.println("Line break:");
BreakIterator lineBreak = BreakIterator.getLineInstance(locale);
doTest(lineBreak);
System.out.println("==================================");
System.out.println("Sentence break:");
BreakIterator sentenceBreak = BreakIterator.getSentenceInstance(locale);
doTest(sentenceBreak);
/*
java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
System.out.print("?");
String line = in.readLine();
while (line.length() != 0) {
System.out.println(line);
RuleBasedBreakIterator test = new RuleBasedBreakIterator(line);
System.out.print("?");
line = in.readLine();
}
*/
}
public static void doTest(BreakIterator bi) {
{
//System.out.println("Total number of characters in test string = " + testText.length());
// forward
bi.setText(testText);
int p = bi.first();
int lastP = p;
String fragment;
int breaks = 0;
System.out.println("Forward...");
while (p != BreakIterator.DONE) {
//System.out.print(">>>");
p = bi.next();
System.out.print(p);
if (p != BreakIterator.DONE)
fragment = testText.substring(lastP, p);
else
fragment = testText.substring(lastP);
//System.out.println();
debugPrintln(": >" + fragment + "<");
++breaks;
lastP = p;
}
//RuleBasedBreakIterator.printVisitedCharCount();
//System.out.println("Total number of break positions encountered = " + breaks);
}
/*
{
// backward
bi.setText(testText);
int p = bi.last();
int lastP = p;
int breaks = 0;
String fragment;
System.out.println("Backward...");
while (p != BreakIterator.DONE) {
//System.out.print(">>>");
p = bi.previous();
if (p != BreakIterator.DONE)
fragment = testText.substring(p, lastP);
else
fragment = testText.substring(0, lastP);
//System.out.println();
debugPrintln(">" + fragment + "<");
++breaks;
lastP = p;
}
//RuleBasedBreakIterator.printVisitedCharCount();
//System.out.println("Total number of break positions encountered = " + breaks);
}
{
// forward with following()
bi.setText(testText);
int p = 0;
int lastP = p;
int breaks = 0;
String fragment;
System.out.println("Following...");
while (p < testText.length()) {
//System.out.print(">>>");
p = bi.following(p);
fragment = testText.substring(lastP, p);
//System.out.println();
debugPrintln(">" + fragment + "<");
++breaks;
lastP = p;
}
}
{
// backward with preceding()
bi.setText(testText);
int p = testText.length();
int lastP = p;
int breaks = 0;
String fragment;
System.out.println("Preceding...");
while (p > 0) {
//System.out.print(">>>");
p = bi.preceding(p);
fragment = testText.substring(p, lastP);
//System.out.println();
debugPrintln(">" + fragment + "<");
++breaks;
lastP = p;
}
//RuleBasedBreakIterator.printVisitedCharCount();
//System.out.println("Total number of break positions encountered = " + breaks);
}
*/
}
public static void debugPrintln(String s) {
final String zeros = "0000";
String temp;
StringBuffer out = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= ' ' && c < '\u007f')
out.append(c);
else {
out.append("\\u");
temp = Integer.toHexString((int)c);
out.append(zeros.substring(0, 4 - temp.length()));
out.append(temp);
}
}
System.out.println(out);
}
public static void debugPrintln2(String s) {
StringBuffer out = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= '\u0100')
out.append("<" + ((int)c - 0x100) + ">");
else
out.append(c);
}
System.out.println(out);
}
}

View file

@ -0,0 +1,229 @@
/*
*******************************************************************************
* *
* COPYRIGHT: *
* (C) Copyright International Business Machines Corporation, 1997 - 1999 *
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
* US Government Users Restricted Rights - Use, duplication, or disclosure *
* restricted by GSA ADP Schedule Contract with IBM Corp. *
* *
*******************************************************************************
*/
package com.ibm.tools.compression;
import com.ibm.text.*;
/**
* Utility class to generate the tables used by the SCSU interface and
* the UnicodeCompressor class.
*
* @author Stephen F. Booth
* @version 1.0 08 Mar 99
*/
class CompressionTableGenerator
{
// duplicate of constants in SCSU
final static int LATININDEX = 0xF9;
final static int IPAEXTENSIONINDEX = 0xFA;
final static int GREEKINDEX = 0xFB;
final static int ARMENIANINDEX = 0xFC;
final static int HIRAGANAINDEX = 0xFD;
final static int KATAKANAINDEX = 0xFE;
final static int HALFWIDTHKATAKANAINDEX = 0xFF;
final static int SDEFINEX = 0x0B;
final static int SRESERVED = 0x0C; // reserved value
final static int SQUOTEU = 0x0E;
final static int SCHANGEU = 0x0F;
final static int SQUOTE0 = 0x01;
final static int SQUOTE1 = 0x02;
final static int SQUOTE2 = 0x03;
final static int SQUOTE3 = 0x04;
final static int SQUOTE4 = 0x05;
final static int SQUOTE5 = 0x06;
final static int SQUOTE6 = 0x07;
final static int SQUOTE7 = 0x08;
final static int SCHANGE0 = 0x10;
final static int SCHANGE1 = 0x11;
final static int SCHANGE2 = 0x12;
final static int SCHANGE3 = 0x13;
final static int SCHANGE4 = 0x14;
final static int SCHANGE5 = 0x15;
final static int SCHANGE6 = 0x16;
final static int SCHANGE7 = 0x17;
final static int SDEFINE0 = 0x18;
final static int SDEFINE1 = 0x19;
final static int SDEFINE2 = 0x1A;
final static int SDEFINE3 = 0x1B;
final static int SDEFINE4 = 0x1C;
final static int SDEFINE5 = 0x1D;
final static int SDEFINE6 = 0x1E;
final static int SDEFINE7 = 0x1F;
//==========================
// Unicode mode tags
//==========================
final static int UCHANGE0 = 0xE0;
final static int UCHANGE1 = 0xE1;
final static int UCHANGE2 = 0xE2;
final static int UCHANGE3 = 0xE3;
final static int UCHANGE4 = 0xE4;
final static int UCHANGE5 = 0xE5;
final static int UCHANGE6 = 0xE6;
final static int UCHANGE7 = 0xE7;
final static int UDEFINE0 = 0xE8;
final static int UDEFINE1 = 0xE9;
final static int UDEFINE2 = 0xEA;
final static int UDEFINE3 = 0xEB;
final static int UDEFINE4 = 0xEC;
final static int UDEFINE5 = 0xED;
final static int UDEFINE6 = 0xEE;
final static int UDEFINE7 = 0xEF;
final static int UQUOTEU = 0xF0;
final static int UDEFINEX = 0xF1;
final static int URESERVED = 0xF2; // reserved value
final static int BLOCKSIZE = 0xFF;
/**
* Generate the table used as sOffsetTable in SCSU.
* This table contains preformed indices so we can do array lookups
* instead of calculations for speed during decompression.
*/
static void printOffsetTable()
{
int i = 0;
int [] offsetTable = new int [ BLOCKSIZE + 1 ];
// 0x00 is reserved
// half blocks from U+0080 to U+3380
for( i = 0x01; i < 0x68; i++ )
offsetTable[i] = i * 0x80;
// half blocks from U+E000 to U+FF80
for( i = 0x68; i < 0xA8; i++ )
offsetTable[i] = (i * 0x80) + 0xAC00;
// 0xA8..0xF8 is reserved
offsetTable[ LATININDEX ] = 0x00C0;
offsetTable[ IPAEXTENSIONINDEX ] = 0x0250;
offsetTable[ GREEKINDEX ] = 0x0370;
offsetTable[ ARMENIANINDEX ] = 0x0530;
offsetTable[ HIRAGANAINDEX ] = 0x3040;
offsetTable[ KATAKANAINDEX ] = 0x30A0;
offsetTable[ HALFWIDTHKATAKANAINDEX ] = 0xFF60;
// dump the generated table
System.out.println("static int [] sOffsetTable = {");
for(i = 0; i < offsetTable.length - 1; i++)
System.out.print("0x" + Integer.toHexString(offsetTable[i])
+ ", ");
for(i = offsetTable.length - 1; i < offsetTable.length; i++)
System.out.print("0x" + Integer.toHexString(offsetTable[i]));
System.out.println();
System.out.println("};");
}
/**
* Generate the table used as sSingleTagTable in UnicodeCompressor.
* This table contains boolean values indicating if a byte is a
* single-byte mode tag.
*/
static void printSingleTagTable()
{
int i = 0;
boolean [] singleTagTable = new boolean [ BLOCKSIZE + 1 ];
for( i = 0x00; i <= BLOCKSIZE; i++ ) {
switch( i ) {
case SQUOTEU: case SCHANGEU:
case SDEFINEX: case SRESERVED:
case SQUOTE0: case SQUOTE1:
case SQUOTE2: case SQUOTE3:
case SQUOTE4: case SQUOTE5:
case SQUOTE6: case SQUOTE7:
case SCHANGE0: case SCHANGE1:
case SCHANGE2: case SCHANGE3:
case SCHANGE4: case SCHANGE5:
case SCHANGE6: case SCHANGE7:
case SDEFINE0: case SDEFINE1:
case SDEFINE2: case SDEFINE3:
case SDEFINE4: case SDEFINE5:
case SDEFINE6: case SDEFINE7:
singleTagTable[i] = true;
break;
default:
singleTagTable[i] = false;
break;
}
}
// dump the generated table
System.out.println("private static boolean [] sSingleTagTable = {");
for(i = 0; i < singleTagTable.length - 1; i++)
System.out.print(singleTagTable[i] + ", ");
for(i = singleTagTable.length - 1; i < singleTagTable.length; i++)
System.out.print(singleTagTable[i]);
System.out.println();
System.out.println("};");
}
/**
* Generate the table used as sUnicodeTagTable in
* This table contains boolean values indicating if a byte is a
* unicode mode tag.
*/
static void printUnicodeTagTable()
{
int i = 0;
boolean [] unicodeTagTable = new boolean [ BLOCKSIZE + 1 ];
for( i = 0x00; i <= BLOCKSIZE; i++ ) {
switch( i ) {
case UQUOTEU: case UDEFINEX:
case URESERVED:
case UCHANGE0: case UCHANGE1:
case UCHANGE2: case UCHANGE3:
case UCHANGE4: case UCHANGE5:
case UCHANGE6: case UCHANGE7:
case UDEFINE0: case UDEFINE1:
case UDEFINE2: case UDEFINE3:
case UDEFINE4: case UDEFINE5:
case UDEFINE6: case UDEFINE7:
unicodeTagTable[i] = true;
break;
default:
unicodeTagTable[i] = false;
break;
}
}
// dump the generated table
System.out.println("private static boolean [] sUnicodeTagTable = {");
for(i = 0; i < unicodeTagTable.length - 1; i++)
System.out.print(unicodeTagTable[i] + ", ");
for(i = unicodeTagTable.length - 1; i < unicodeTagTable.length; i++)
System.out.print(unicodeTagTable[i]);
System.out.println();
System.out.println("};");
}
public static void main(String[] argv)
{
printOffsetTable();
printSingleTagTable();
printUnicodeTagTable();
}
};

View file

@ -0,0 +1,189 @@
package com.ibm.tools.normalizer;
import com.ibm.text.*;
import com.ibm.util.*;
import com.ibm.util.CompactByteArray;
import com.ibm.util.CompactCharArray;
import java.io.*;
/**
* CPPWriter knows how to write data structures out to C++ source and header files
*/
class CPPWriter extends SourceWriter {
PrintStream source;
PrintStream header;
String className;
public CPPWriter(String fileName, String cName) throws FileNotFoundException {
className = cName;
// Find the class name
header = new PrintStream(new FileOutputStream(fileName + ".h"));
header.println(kHeader);
header.println("#include \"ptypes.h\"");
header.println("#include \"cmpbytea.h\"");
header.println("#include \"cmpchara.h\"");
header.println("");
header.println("struct " + className + " {"); // "struct" makes everything public
source = new PrintStream(new FileOutputStream(fileName + ".cpp"));
source.println(kHeader);
source.println("#include \"" + fileName + ".h\" ");
source.println("\n");
}
public void close() {
header.println("};");
header.close();
source.close();
header = null;
source = null;
}
public void write(String name, short value) {
header.println(" enum { " + name + " = " + value + " };");
}
public void write(String name, int value) {
header.println(" enum { " + name + " = " + value + " };");
}
public void writeHex(String name, char value) {
header.println(" enum { " + name + " = 0x" + UInfo.hex(value) + " };");
}
public void writeHex(String name, int value) {
header.println(" enum { " + name + " = 0x" + Integer.toString(value,16) + " };");
}
public void write(String name, CompactCharArray array) {
array.compact(false);
String indexName = name + "_index";
String valueName = name + "_values";
write(indexName, array.getIndexArray());
write(valueName, array.getValueArray());
header.println("");
header.println(" static const CompactCharArray " + name + ";");
source.println("");
source.println("const CompactCharArray " + className + "::" + name + "("
+ indexName + "," + valueName
+ ", " + array.getValueArray().length + ");" );
}
public void write(String name, CompactByteArray array) {
array.compact(false);
String indexName = name + "_index";
String valueName = name + "_values";
write(indexName, array.getIndexArray());
write(valueName, array.getValueArray());
header.println("");
header.println(" static CompactByteArray " + name + ";");
source.println("");
// TODO: add "const" here when CompactByteArray::get is made const
source.println("CompactByteArray " + className + "::" + name + "("
+ "(UniChar*)" + indexName + ", (t_int8*)" + valueName
+ ", " + array.getValueArray().length + ");" );
}
public void write(String name, StringBuffer str) {
write(name, str.toString().toCharArray());
}
public void write(String name, char[] array) {
header.println("");
header.println(" static const UniChar " + name + "[];");
source.println("");
source.println("const UniChar " + className + "::" + name + "[] = {");
source.print(" ");
for (int i = 0; i < array.length; i++) {
if (i > 0 && i % 8 == 0) {
source.print("\n ");
}
source.print("0x" + UInfo.hex(array[i]) + ", ");
}
source.println("};");
}
public void write(String name, short[] array) {
header.println("");
header.println(" static const t_uint16 " + name + "[];");
source.println("");
source.println("const t_uint16 " + className + "::" + name + "[] = {");
source.print(" ");
for (int i = 0; i < array.length; i++) {
if (i > 0 && i % 8 == 0) {
source.print("\n ");
}
source.print("0x" + UInfo.hex((char)array[i]) + ", ");
}
source.println("};");
}
public void write(String name, int[] array) {
header.println("");
header.println(" static const t_int32 " + name + "[];");
source.println("");
source.println("const t_int32 " + className + "::" + name + "[] = {");
source.print(" ");
for (int i = 0; i < array.length; i++) {
if (i > 0 && i % 8 == 0) {
source.print("\n ");
}
source.print("0x" + Integer.toString(array[i],16) + ", ");
}
source.println("};");
}
public void write(String name, byte[] array) {
header.println("");
header.println(" static const t_int8 " + name + "[];");
source.println("");
source.println("const t_int8 " + className + "::" + name + "[] = {");
source.print(" ");
for (int i = 0; i < array.length; i++) {
if (i > 0 && i % 8 == 0) {
source.print("\n ");
}
int value = array[i];
if (value < 0) value += 256;
source.print("(t_int8)0x" + Integer.toString(value,16) + ", ");
}
source.println("};");
}
static final String kHeader =
"/*\n"
+" * @(#)$RCSFile$ $Revision: 1.1 $ $Date: 2000/02/10 06:25:54 $\n"
+" *\n"
+" * (C) Copyright IBM Corp. 1997-1998 - All Rights Reserved\n"
+" *\n"
+" * The program is provided 'as is' without any warranty express or\n"
+" * implied, including the warranty of non-infringement and the implied\n"
+" * warranties of merchantibility and fitness for a particular purpose.\n"
+" * IBM will not be liable for any damages suffered by you as a result\n"
+" * of using the Program. In no event will IBM be liable for any\n"
+" * special, indirect or consequential damages or lost profits even if\n"
+" * IBM has been advised of the possibility of their occurrence. IBM\n"
+" * will not be liable for any third party claims against you.\n"
+" *\n"
+" * This class is MACHINE GENERATED. Run NormalizerBuilder to regenerate.\n"
+" */\n"
+"\n";
}

View file

@ -0,0 +1,107 @@
package com.ibm.tools.normalizer;
//import com.ibm.text.*;
import com.ibm.util.Utility;
import com.ibm.util.CompactCharArray;
import com.ibm.util.CompactByteArray;
import java.io.*;
/**
* JavaWriter knows how to write data structures out to a Java source file
*/
class JavaWriter extends SourceWriter {
PrintStream out;
public JavaWriter(String name) throws FileNotFoundException {
// Find the class name
int cIndex = name.lastIndexOf('/');
String cName = (cIndex >= 0) ? name.substring(cIndex+1) : name;
out = new PrintStream(new FileOutputStream(name + ".java"));
out.println(kHeader);
out.println("class " + cName + " {");
}
public void close() {
out.println("}");
out.close();
out = null;
}
public void write(String name, short value) {
out.println(" static final short " + name + " = " + value + ";");
}
public void write(String name, int value) {
out.println(" static final int " + name + " = " + value + ";");
}
public void writeHex(String name, char value) {
out.println(" static final char " + name + " = 0x" + Integer.toString((int)value,16) + ";");
}
public void writeHex(String name, int value) {
out.println(" static final int " + name + " = 0x" + Integer.toString(value,16) + ";");
}
public void write(String name, CompactCharArray array) {
array.compact(false);
out.println("");
out.println(" static final CompactCharArray " + name + " = new CompactCharArray(");
out.println(Utility.formatForSource(Utility.arrayToRLEString(array.getIndexArray())));
out.println(" ," );
out.println(Utility.formatForSource(Utility.arrayToRLEString(array.getValueArray())));
out.println(" );" );
}
public void write(String name, CompactByteArray array) {
array.compact(false);
out.println("");
out.println(" static final CompactByteArray " + name + " = new CompactByteArray(");
out.println(Utility.formatForSource(Utility.arrayToRLEString(array.getIndexArray())));
out.println(" ," );
out.println(Utility.formatForSource(Utility.arrayToRLEString(array.getValueArray())));
out.println(" );" );
}
public void write(String name, StringBuffer str) {
out.println("");
out.println(" static final String " + name + " = ");
out.println(Utility.formatForSource(str.toString()));
out.println(" ;");
}
public void write(String name, char[] array) {
out.println("");
out.println(" static final char[] " + name + " = Utility.RLEStringToCharArray(");
out.println(Utility.formatForSource(Utility.arrayToRLEString(array)));
out.println(" );");
}
public void write(String name, int[] array) {
out.println("");
out.println(" static final int[] " + name + " = Utility.RLEStringToIntArray(");
out.println(Utility.formatForSource(Utility.arrayToRLEString(array)));
out.println(" );");
}
static final String kHeader =
"/*\n"
+" * (C) Copyright IBM Corp. 1997-1998 - All Rights Reserved\n"
+" *\n"
+" * The program is provided 'as is' without any warranty express or\n"
+" * implied, including the warranty of non-infringement and the implied\n"
+" * warranties of merchantibility and fitness for a particular purpose.\n"
+" * IBM will not be liable for any damages suffered by you as a result\n"
+" * of using the Program. In no event will IBM be liable for any\n"
+" * special, indirect or consequential damages or lost profits even if\n"
+" * IBM has been advised of the possibility of their occurrence. IBM\n"
+" * will not be liable for any third party claims against you.\n"
+" */\n"
+"\n"
+"package com.ibm.text;\n"
+ "// This class is MACHINE GENERATED. Run NormalizerBuilder to regenerate.\n"
+"\n";
}

View file

@ -0,0 +1,34 @@
// MutableChar.java
package com.ibm.tools.normalizer;
import com.ibm.text.*;
import java.lang.Comparable;
import java.io.Serializable;
class MutableChar implements Cloneable, Comparable, Serializable {
public char value;
public MutableChar(char newValue) {
value = newValue;
}
public MutableChar set(char newValue) {
value = newValue;
return this;
}
public boolean equals(Object other) {
return value == ((MutableChar)other).value;
}
public int hashCode() {
return value;
}
public String toString() {
return String.valueOf(value);
}
public int compareTo(Object b) {
char ch = ((MutableChar)b).value;
return value == ch ? 0 : value < ch ? -1 : 1;
}
}

View file

@ -0,0 +1,986 @@
package com.ibm.tools.normalizer;
import java.io.*;
import java.util.*;
import com.ibm.text.*;
import com.ibm.util.CompactByteArray;
import com.ibm.util.CompactCharArray;
public final class NormalizerBuilder
{
public static void main(String args[]) throws IOException {
try {
NormalizerBuilder foo = new NormalizerBuilder(args);
} catch (Throwable e) {
System.err.println(e.getLocalizedMessage());
e.printStackTrace();
System.in.read();
}
}
private UInfo uinfo;
private DecompMap decomps = new DecompMap();
private DecompMap explodeCompat = new DecompMap();
private DecompMap explodeOnly = new DecompMap();
private CompMap permutedCompositions = new CompMap();
private CompMap binaryCompositions = new CompMap();
private CharSet bases = new CharSet();
private CharSet combining = new CharSet();
private Map pairExplosions = new HashMap();
private boolean fVerbose = false;
private boolean fWriteData = false;
private boolean fShowSizes = false;
private boolean fPrompt = false;
private boolean fJava = true;
private boolean fCPP = false;
/**
* The highest Unicode character that has a canonical decomposition.
* (i.e. largest char that can result from a primary canonical composition.)
*/
char largestChar = 0;
public NormalizerBuilder(String[] args) throws IOException
{
// Parse my command line
for (int i = 0; i < args.length; i++)
{
if (args[i].equals("-data")) {
uinfo = new UInfo(args[++i]);
}
else if (args[i].equals("-write")) {
fWriteData = true;
}
else if (args[i].equals("-verbose")) {
fVerbose = true;
}
else if (args[i].equals("-size")) {
fShowSizes = true;
}
else if (args[i].equals("-prompt")) {
fPrompt = true;
}
else if (args[i].equals("-java")) {
fJava = true;
fCPP = false;
}
else if (args[i].equals("-cpp")) {
fCPP = true;
fJava = false;
}
}
if (uinfo == null) {
uinfo = new UInfo();
}
boolean canonicalOnly = true;
createDecompositions();
out("\nGenerating permuted compositions...");
// Form the list of all the permuted sequences that are canonically
// equivalent to the canonical decompositions.
// As a by-product, find out which are not combining character sequences,
for (char ch = 0; ch < 0xFFFF; ch++) {
String decomp = decomps.get(ch);
if (decomp != null) {
boolean done = false;
if (!uinfo.getFullDecomposition(ch,true).equals(
uinfo.getFullDecomposition(ch,false)))
{
explodeCompat.put(ch, uinfo.getFullDecomposition(ch, false));
done = true;
}
if (uinfo.hasCanonicalDecomposition(ch) && decomp.length() > 1
&& !uinfo.isExcludedComposition(ch) && uinfo.isCBS(decomp))
{
if (decomp.length() <= 2) {
permutedCompositions.put(decomp, ch);
}
else {
List alternatives = concat(decomp.charAt(0),
jumble(decomp.substring(1, decomp.length())));
for (int i = 0; i < alternatives.size(); ++i)
{
String variant = (String)alternatives.get(i);
String normalized = uinfo.fixCanonical(variant);
if (normalized.equals(decomp)) {
permutedCompositions.put(variant, ch);
}
}
}
largestChar = ch;
done = true;
}
if (!done) {
explodeOnly.put(ch, decomp); // Disparaged
}
}
}
out("\nLargest composed char: " + uinfo.hex(largestChar));
// Form the binary compositions
out("\nGenerating pairwise compositions...");
Iterator list = permutedCompositions.keySet().iterator();
while (list.hasNext()) {
String decomp = (String)list.next();
char ch = permutedCompositions.get(decomp);
if (decomp.length() > 2) {
//
// If this is a composition of more than two characters,
// see if its initial portion is also a composition. If so, that lets
// us build up this composed character iteratively.
//
for (int i = decomp.length()-1; i > 1; --i) {
String partial = decomp.substring(0,i);
char partialMap = permutedCompositions.get(partial);
if (partialMap != 0) {
decomp = partialMap + decomp.substring(i);
break;
}
}
}
if (decomp.length() <= 2) {
binaryCompositions.put(decomp, ch);
} else {
//
// The composition takes more than two characters, and there's
// no way to build it up from smaller ones.
//
if (decomp.equals(uinfo.fixCanonical(decomp)))
{
// If the decomp is in canonical order, we're in trouble,
// since that means there's no way to generate this composed
// character from its canonically decomposed equivalent.
err("No pairwise compose of " + uinfo.hex(decomp) +
" > " + uinfo.hex(ch) + " " + uinfo.getName(ch,true) );
}
else {
// If the decomp is *not* in canonical order, it's not as
// bad, since composition will still work as long as
warn("No pairwise compose of non-canon " + uinfo.hex(decomp) +
" > " + uinfo.hex(ch) + " " + uinfo.getName(ch,true) );
}
}
bases.add(decomp.charAt(0));
// add to list of all combining characters in composites
for (int q = 1; q < decomp.length(); ++q) {
combining.add(decomp.charAt(q));
}
}
// Generate the pairwise explosions, where a composed char + combining char
// transforms into a different pair of characters, usually because the
// canonical combining classes are reversed.
out("\nGenerating exploding pairs....");
List binaryValues = new ArrayList(binaryCompositions.values());
Collections.sort(binaryValues);
for (char addOn = 0; addOn < 0xFFFF; addOn++) {
if (combining.contains(addOn))
{
list = binaryValues.iterator();
while (list.hasNext()) {
MutableChar unichar = (MutableChar)list.next();
String chStr = String.valueOf(unichar.value);
String source = chStr + addOn;
String comp = binaryComposition(source);
if (comp.length() == 1) continue; // don't care if combines
if (comp.charAt(0) == addOn || comp.charAt(1) == addOn) continue; // rearranges
if (!source.equals(comp)) {
String decomp = fullDecomposition(source);
pairExplosions.put(source,comp);
bases.add(unichar);
}
}
}
}
buildDecompData();
buildComposeData();
out("Success!");
if (fPrompt) {
System.out.println("\nHit any key to continue...");
System.in.read();
}
}
public String fullDecomposition(String s) {
return fullDecomposition(s, new StringBuffer()).toString();
}
public StringBuffer fullDecomposition(char ch, StringBuffer output) {
String value = decomps.get(ch);
if (value == null) {
bubbleAppend(output, ch);
}
else {
bubbleAppend(output, value);
}
return output;
}
public StringBuffer fullDecomposition(String s, StringBuffer output) {
for (int i = 0; i < s.length(); ++i) {
fullDecomposition(s.charAt(i),output);
}
return output;
}
public String binaryComposition(String sr) {
// set up decomposed string, init variables
StringBuffer output = new StringBuffer();
StringBuffer decomp = new StringBuffer();
if (sr.length() == 0) return output.toString();
// First generate the full decomposition of the input string
fullDecomposition(sr, decomp);
int basePosition = 0;
char base = decomp.charAt(0);
output.append(base);
// handle degenerate case--no base character at start
if (uinfo.getCanonicalClass(base) != 0) {
// later
}
// loop through, composing items with base
for (int i = 1; i < decomp.length(); ++i) {
char ch = decomp.charAt(i);
short can = uinfo.getCanonicalClass(ch);
char value = binaryCompositions.get(String.valueOf(base) + ch);
if (value != 0 && noObstructions(output, basePosition, can)) {
base = value;
output.setCharAt(basePosition, base);
} else if (can == 0) {
basePosition = output.length();
base = ch;
output.append(ch);
} else {
bubbleAppend(output, ch, can);
}
}
return output.toString();
}
public boolean noObstructions(StringBuffer buffer, int pos, short can) {
for (int j = buffer.length()-1; j > pos; --j) {
if (can == uinfo.getCanonicalClass(buffer.charAt(j))) {
return false;
}
}
return true;
}
public void bubbleAppend(StringBuffer buffer, char ch, short can) {
for (int j = buffer.length()-1; j >= 0; --j) {
if (can >= uinfo.getCanonicalClass(buffer.charAt(j))) {
buffer.insert(j + 1, ch);
return;
}
}
buffer.insert(0, ch);
}
public void bubbleAppend(StringBuffer buffer, char ch) {
bubbleAppend(buffer, ch, uinfo.getCanonicalClass(ch));
}
public void bubbleAppend(StringBuffer buffer, String s) {
for (int i = 0; i < s.length(); ++i) {
bubbleAppend(buffer, s.charAt(i));
}
}
String getDecomposition(char ch) {
return decomps.get(ch);
}
/**
* Generate a Map of all decompositions in Unicode.
* The keys in the map are MutableChar objects, one for each character that has a decomposition.
* The values are String objects containing the full decomposition for the character,
* in canonical order.
*/
private void createDecompositions()
{
out("\nGenerating Full decompositions...");
StringBuffer temp = new StringBuffer();
short compatCount=0, canonCount=0;
for (char ch = 0; ch < 0xFFFF; ++ch) {
if (ch >= '\u4E00' && ch <= '\uD7A3') continue; // skip ideos
short category = uinfo.getCategory(ch);
if (category == uinfo.UNASSIGNED) continue; //skip reserved
if (category == uinfo.CONTROL) continue;
if (category == uinfo.FORMAT) continue;
if (category == uinfo.PRIVATE_USE) continue;
if (category == uinfo.SURROGATE) continue;
boolean canon = uinfo.hasCanonicalDecomposition(ch);
if (uinfo.hasCanonicalDecomposition(ch)) canonCount++;
if (uinfo.hasCompatibilityDecomposition(ch)) compatCount++;
if (canon || uinfo.hasCompatibilityDecomposition(ch)) {
String decomp = uinfo.getFullDecomposition(ch, canon);
temp.setLength(0);
temp.append(decomp);
uinfo.fixCanonical(temp);
decomps.put(ch, temp.toString() );
}
}
}
static List concat(char ch, List a) {
for (int i = 0; i < a.size(); ++i) {
a.set(i, ch + (String)a.get(i));
}
return a;
}
/**
* Return a list of Strings for all possible permutations of the
* characters in the input string.
*/
static List jumble (String source)
{
ArrayList result = new ArrayList();
if (source.length() == 1) {
result.add(source);
} else for (int i = 0; i < source.length(); ++i) {
result.addAll( concat( source.charAt(i),
jumble(source.substring(0,i)
+ source.substring(i+1,source.length()))));
}
return result;
}
static final int STR_INDEX_SHIFT = 2;
static final int STR_LENGTH_MASK = 0x0003;
static final int DECOMP_RECURSE = 0x00008000;
static final int DECOMP_MASK = 0x00007FFF;
/**
* Generate a new "DecompData.java" that contains the CompactArray definitions
* used in the {@link Normalizer.DECOMPOSE} operation.
*/
void buildDecompData() throws IOException {
out("\nGenerating DecompData.java....");
//
// For each Unicode character that has a decomposition, we put its
// fully-decomposed form at the end of the "contents" string, followed
// by a null, and we put its index in "contents" into the CompactArray.
// If it does not have a decomposition, we store a bogus index.
//
// We do this first for all of the compatibility decompositions, save
// the index in MAX_COMPAT, and then do it again for the canonical
// decompositions. When the array is used later, any character whose
// decomp has an index greater than MAX_COMPAT is a canonical decomp.
//
int canonIndex = 0;
int compatIndex = 0;
// Map from Unicode character to replacement string index
CompactCharArray offsets = new CompactCharArray((char)0);
// We also need a place to store the replacement strings. Add a char at
// the front so that "0" won't be the index of any of the replacement strings.
StringBuffer replace = new StringBuffer().append("\uffff");
for (char ch = 0; ch < 0xFFFF; ch++) {
if (uinfo.hasCompatibilityDecomposition(ch)) {
compatIndex = putLength(replace, decomps.get(ch), 0);
offsets.setElementAt(ch, (char)compatIndex);
}
}
// Add the canonical decomps. Their indices must be > compatIndex.
for (char ch = 0; ch < 0xFFFF; ch++) {
if (uinfo.hasCanonicalDecomposition(ch)) {
if (ch == 0x0f77) {
out("0F77: decomps.get() = " + uinfo.hex(decomps.get(ch)));
out("0F77: fullDecomp = " + uinfo.hex(uinfo.getFullDecomposition(ch,false)));
}
canonIndex = putLength(replace, decomps.get(ch), compatIndex);
// If this character's full compatibility decomposition is different from
// its canonical decomp, that means one of the characters in its
// canonical decomp itself has a compatibility decomp. To deal with this,
// we set a bit flag telling the decomposer to recurse on this character.
if (!uinfo.getFullDecomposition(ch,true).equals(uinfo.getFullDecomposition(ch,false))) {
offsets.setElementAt(ch, (char)(canonIndex | DECOMP_RECURSE));
} else {
offsets.setElementAt(ch, (char)canonIndex);
}
}
}
//
// Now generate another CompactArray containing the combining class of every
// character in Unicode
//
final byte BASE = 0;
CompactByteArray canonClasses = new CompactByteArray(BASE);
for (char ch = 0; ch < 0xFFFF; ch++) {
short canonClass = uinfo.getCanonicalClass(ch);
if (canonClass != 0) {
canonClasses.setElementAt(ch, (byte)canonClass);
}
}
// Finally, write the data out to a compilable Java source file
if (fJava) {
writeDecompData(new JavaWriter("../src/com/ibm/text/DecompData"),
canonIndex, compatIndex, BASE, offsets, replace, canonClasses);
}
if (fCPP) {
writeDecompData(new CPPWriter("/intlwork/source/collate/CPP/dcmpdata", "DecompData"),
canonIndex, compatIndex, BASE, offsets, replace, canonClasses);
}
out("Decomp data: MAX_CANONICAL = " + canonIndex + ", MAX_DECOMP = " + compatIndex);
if (fShowSizes) {
int offsetSize = offsets.getIndexArray().length * 2 + offsets.getValueArray().length * 2;
int canonSize = canonClasses.getIndexArray().length * 2 + canonClasses.getValueArray().length;
int replaceLength = replace.length();
out("Total runtime size of decomp data is "
+ (offsetSize + canonSize + replaceLength));
out(" offsets: " + offsetSize);
out(" canonClasses: " + canonSize);
out(" replace: " + replaceLength);
}
}
void writeDecompData(SourceWriter out, int maxCanon, int maxCompat, short BASE,
CompactCharArray offsets, StringBuffer contents,
CompactByteArray canonClasses)
{
out.write("MAX_CANONICAL", maxCanon );
out.write("MAX_COMPAT", maxCompat );
out.write("DECOMP_MASK", DECOMP_MASK );
out.write("DECOMP_RECURSE", DECOMP_RECURSE );
out.write("BASE", BASE );
out.write("offsets", offsets );
out.write("contents", contents );
out.write("canonClass", canonClasses );
out.close();
}
//==========================================================================================
// Methods for generating and writing the composition data
//
final int TYPE_MASK = 0x0007;
final int INDEX_MASK = 0xFFF8;
final int INDEX_SHIFT = 3;
// MAX_BASES is used to map a 2-diminsional (base,combining) index pair onto a
// one-dimensional CompactArray. We could just use baseCount, but making it a power
// of two allows slightly better compaction.
final int MAX_BASES = 1024; // Product must be <= 64K
final int MAX_COMBINE = 65536/MAX_BASES;
final char // for character types
IGNORE = 0,
BASE = 1,
EXPLODING_BASE = 2,
COMBINING = 3,
INITIAL_JAMO = 4,
MEDIAL_JAMO = 5,
FINAL_JAMO = 6,
HANGUL = 7;
// These variables actually hold the composition data.
short baseCount = 1; // Leave 0 as an invalid index
short combineCount = 1; // Leave 0 as an invalid index
short nccCount = 0;
int maxCompat = 0;
int maxCanon = 0;
// This array contains types (from the set above) and indices into the "replace"
// and "actions" arrays
CompactCharArray lookup = new CompactCharArray(IGNORE);
// We also need a place to store the strings that result from replacements,
// explosions, and combinations. Add a char at the front so that "0" won't
// be the index of any of the replacement strings.
StringBuffer replace = new StringBuffer().append(" ");
// We need to represent each canonical character class as a single bit
// so that we can OR together a mask of all combining char classes seen
// Build an array that maps from combining class to bit mask.
int[] classMap = new int[256];
int[] typeMask;
// Build a two-dimensional array of the action to take for each base/combining pair
CompactCharArray actions = new CompactCharArray((char)0);
char[] actionIndex;
/**
* Generate a new "ComposeData.java" that contains the CompactArray definitions
* used in the {@link Normalizer.COMPOSE} operation.
*/
void buildComposeData() throws IOException
{
out("\nGenerating ComposeData.java....");
BitSet usedIndices = new BitSet();
CharSet explodingBases = new CharSet();
// Find all characters that are both bases *and* have compatibility
// decompositions. These are weird
for (char ch = 0; ch < 0xFFFF; ch++) {
if (bases.contains(ch) && uinfo.hasCompatibilityDecomposition(ch)) {
//
// Add this character's explosion to the replacement string list.
// We're going to make sure that its "base index", i.e. the
// index for it in the actions array, is the same as the
// explosion's index in the replace string. This lets
// us use the same index for the character's two behaviors
//
int index = put(replace, explodeCompat.get(ch), 0);
out(uinfo.hex(ch) + " is base and has compat explosion "
+ uinfo.hex(explodeCompat.get(ch)) );
addChar(lookup, ch, EXPLODING_BASE, index);
usedIndices.set(index);
explodingBases.add(ch);
}
}
// First add the base characters to the array.
// At the same time, compute their indices.
// Leave an empty base index of 0 as a placeholder for null operations.
//
for (char ch = 0; ch < 0xFFFF; ch++)
{
if (explodingBases.contains(ch)) {
continue;
}
short cclass = uinfo.getCanonicalClass(ch);
if (bases.contains(ch)) {
// Make sure that we don't use a base index that was already used
// for an exploding base character.
while (usedIndices.get(baseCount)) {
baseCount++;
}
// Now add the character to lookup as a base
addChar(lookup, ch, BASE, baseCount++);
}
if (combining.contains(ch)) {
classMap[cclass] = 1; // Mark this combining class as being used
addChar(lookup, ch, COMBINING, combineCount++);
}
if (ch >= '\u1100' && ch < '\u1160') {
addChar(lookup, ch, INITIAL_JAMO, 0);
}
if (ch >= '\u1161' && ch < '\u11a6') {
addChar(lookup, ch, MEDIAL_JAMO, 0);
}
if (ch >= '\u11a7' && ch < '\u11fa') {
addChar(lookup, ch, FINAL_JAMO, 0);
}
if (ch >= 0xac00 && ch <= 0xd7a4) {
addChar(lookup, ch, HANGUL, 0);
}
// Add explosions for all compatibility decompositions,
// including the Jamo --> Conjoining Jamo decomps.
if (explodeCompat.contains(ch))
{
maxCompat = put(replace, explodeCompat.get(ch), 0);
addExplosion(lookup, ch, maxCompat);
}
}
// Now add the explosions resulting from canonical decompositions
// These will all have indices greater than "maxCompat" so we can distinguish them.
//
for (char ch = 0; ch < 0xFFFF; ch++) {
short cclass = uinfo.getCanonicalClass(ch);
if (explodeOnly.contains(ch) && uinfo.hasCanonicalDecomposition(ch)) {
maxCanon = put(replace, explodeOnly.get(ch), maxCompat);
addExplosion(lookup, ch, maxCanon);
}
else if (!combining.contains(ch) && cclass != 0 && classMap[cclass] != 0) {
//
// If a combining character didn't happen to end up in one of
// the pairwise combinations or explosions we use but still has
// a combining class that is the same as a character we *do* use,
// we need to save its class so that we don't combine things "past" it.
//
// However, if the character has an explosion we *don't* need it, because
// we'll never see it, only the results of its explosion.
//
addChar(lookup, ch, COMBINING, 0);
nccCount++;
}
}
// Now run through the combining classes again and assign bitmasks
// in the same ascending order as the canonical classes
int maskShift = 0;
for (int i = 0; i < 256; i++) {
if (classMap[i] != 0) {
classMap[i] = (1 << (maskShift++));
}
}
if (maskShift > 32) {
err(Integer.toString(maskShift) + "combining classes; max is 32");
}
out("# of combining classes is " + maskShift);
out("baseCount=" + baseCount + ", combineCount=" + combineCount
+ ", nccCount=" + nccCount);
if (baseCount > MAX_BASES) {
err(Integer.toString(baseCount) + " bases, limit is " + MAX_BASES);
err(Integer.toString(combineCount) + " combining chars, limit is " + MAX_COMBINE);
}
// Now build the "actions" array that tells what to do when each base /
// combining pair is seen.
//
// First do character pairs that combine into a single character...
//
Iterator iter = binaryCompositions.keySet().iterator();
while (iter.hasNext()) {
String source = (String)iter.next();
char ch = binaryCompositions.get(source);
int baseIndex = lookup.elementAt(source.charAt(0)) >>> INDEX_SHIFT;
int combiningIndex = lookup.elementAt(source.charAt(1)) >>> INDEX_SHIFT;
actions.setElementAt((char)(baseIndex + MAX_BASES*combiningIndex), ch);
}
//
// Pair explosions: base/combining pairs that explode into something else
// We're squeezing the indices for these in between MAX_COMPOSED and 0xFFFF,
// which means they can't be indexes into the "replace" string; those are too big.
// Instead they're indexes into the "actionIndex" array, which in turn contains
// indices in "replace"
//
actionIndex = new char[ pairExplosions.size() ];
short index = 0;
iter = pairExplosions.keySet().iterator();
while (iter.hasNext()) {
String source = (String)iter.next();
char base = source.charAt(0);
char combining = source.charAt(1);
int strIndex = put(replace, (String)pairExplosions.get(source), 0);
actionIndex[index] = (char)strIndex;
int baseIndex = lookup.elementAt(base) >>> INDEX_SHIFT;
int combiningIndex = lookup.elementAt(combining) >>> INDEX_SHIFT;
actions.setElementAt((char)(baseIndex + MAX_BASES*combiningIndex),
(char)(index + largestChar));
index++;
}
// Fill in the "type mask" array that maps from combining character index
// to a bit mask representing the canonical combining class
typeMask = new int[combineCount + nccCount];
for (char ch = 0; ch < 0xFFFF; ch++) {
int value = lookup.elementAt(ch);
int type = value & TYPE_MASK;
if (type == COMBINING) {
int ind = value >>> INDEX_SHIFT;
int cclass = uinfo.getCanonicalClass(ch);
typeMask[ind] = classMap[cclass];
}
}
if (fJava) {
writeComposeData(new JavaWriter("../src/com/ibm/text/ComposeData"));
}
if (fCPP) {
writeComposeData(new CPPWriter("/intlwork/source/collate/CPP/compdata", "ComposeData"));
}
if (fShowSizes) {
int lookupSize = lookup.getIndexArray().length * 2 + lookup.getValueArray().length * 2;
int actionSize = actions.getIndexArray().length * 2 + actions.getValueArray().length * 2;
int actIndexSize = actionIndex.length * 2;
int replaceSize = replace.length();
int typeMaskSize = typeMask.length * 2;
out("Total runtime size of compose data is "
+ (lookupSize + actionSize + actIndexSize + replaceSize + typeMaskSize));
out(" lookup: " + lookupSize);
out(" actions: " + actionSize);
out(" actionIndex: " + actIndexSize);
out(" typeMask: " + typeMaskSize);
out(" replace: " + replaceSize);
}
}
void writeComposeData(SourceWriter out) {
out.write("BASE_COUNT", baseCount);
out.write("COMBINING_COUNT", combineCount);
out.write("MAX_COMPAT", maxCompat);
out.write("MAX_CANON", maxCanon);
out.writeHex("MAX_COMPOSED", largestChar);
int maxIndex = replace.length();
out.write("MAX_INDEX", maxIndex );
out.write("INITIAL_JAMO_INDEX", maxIndex + 1);
out.write("MEDIAL_JAMO_INDEX", maxIndex + 2);
out.write("MAX_BASES", MAX_BASES );
out.write("MAX_COMBINE", MAX_COMBINE);
out.writeHex("TYPE_MASK", TYPE_MASK);
out.write("INDEX_SHIFT", INDEX_SHIFT);
// The character types
out.write("IGNORE", (int)IGNORE);
out.write("BASE", (int)BASE);
out.write("EXPLODING_BASE", (int)EXPLODING_BASE);
out.write("COMBINING", (int)COMBINING);
out.write("INITIAL_JAMO", (int)INITIAL_JAMO);
out.write("MEDIAL_JAMO", (int)MEDIAL_JAMO);
out.write("FINAL_JAMO", (int)FINAL_JAMO);
out.write("HANGUL", (int)HANGUL);
out.write("lookup", lookup );
out.write("actions", actions );
out.write("actionIndex", actionIndex );
out.write("replace", replace );
out.write("typeMask", typeMask );
out.close();
}
void addChar(CompactCharArray lookup, char ch, int type, int index)
{
// First make sure it's not already present
if (lookup.elementAt(ch) != IGNORE)
{
char oldValue = lookup.elementAt(ch);
err(typeName(type) + " char is also "
+ typeName(oldValue & TYPE_MASK) + ": "
+ uinfo.hex(ch) + " " + uinfo.getName(ch,true));
}
else if ((index << INDEX_SHIFT) > 65536) {
err("not enough bits: index " + index + " << INDEX_SHIFT = " + (index << INDEX_SHIFT));
} else {
lookup.setElementAt(ch, (char)(type | (index << INDEX_SHIFT)));
}
}
void addExplosion(CompactCharArray lookup, char ch, int index)
{
// First make sure it doesn't already have an index
char oldValue = lookup.elementAt(ch);
int oldIndex = oldValue >>> INDEX_SHIFT;
if (oldValue != IGNORE) {
err("Exploding char is already " + typeName(oldValue & TYPE_MASK)
+ " (index " + oldIndex + "): "
+ uinfo.hex(ch) + " " + uinfo.getName(ch,true));
}
if (oldIndex != 0) {
err("Exploding char is already " + typeName(oldValue & TYPE_MASK)
+ " (index " + oldIndex + "): "
+ uinfo.hex(ch) + " " + uinfo.getName(ch,true));
}
else if ((index << INDEX_SHIFT) > 65536) {
err("not enough bits: index " + index + " << INDEX_SHIFT = " + (index << INDEX_SHIFT));
} else {
lookup.setElementAt(ch, (char)((oldValue & ~INDEX_MASK) | (index << INDEX_SHIFT)));
}
}
String typeName(int type) {
switch (type) {
case IGNORE: return "Ignored";
case BASE: return "Base";
case EXPLODING_BASE: return "Exploding Base";
case COMBINING: return "Combining";
case INITIAL_JAMO: return "Initial Jamo";
case MEDIAL_JAMO: return "Medial Jamo";
case FINAL_JAMO: return "Final Jamo";
case HANGUL: return "Hangul";
default: return "Unknown";
}
}
static final int put(StringBuffer buf, String str, int minIndex)
{
str = str + '\u0000'; // Add trailing null
int index = buf.toString().indexOf(str);
if (index <= minIndex) {
index = buf.length();
buf.append(str);
}
return index;
}
static final int putLength(StringBuffer buf, String str, int minIndex) {
int length = str.length();
if (length >= (1 << STR_INDEX_SHIFT)) {
// There's no room to store the length in the index, so
// add a null terminator and use a 0 length to flag this
str = str + '\u0000';
length = 0;
}
int index = buf.toString().indexOf(str);
if (index <= minIndex) {
index = buf.length();
buf.append(str);
}
return (index << STR_INDEX_SHIFT) | length;
}
//--------------------------------------------------------------------------------
// Source file headers
//
static final String kCHeader =
"/*\n"
+" * (C) Copyright IBM Corp. 1997-1998 - All Rights Reserved\n"
+" *\n"
+" * The program is provided 'as is' without any warranty express or\n"
+" * implied, including the warranty of non-infringement and the implied\n"
+" * warranties of merchantibility and fitness for a particular purpose.\n"
+" * IBM will not be liable for any damages suffered by you as a result\n"
+" * of using the Program. In no event will IBM be liable for any\n"
+" * special, indirect or consequential damages or lost profits even if\n"
+" * IBM has been advised of the possibility of their occurrence. IBM\n"
+" * will not be liable for any third party claims against you.\n"
+" */\n"
+ "// This class is MACHINE GENERATED. Run NormalizerBuilder to regenerate.\n"
+"\n";
void out(String str) {
if (fVerbose) System.out.println(str);
}
void warn(String str) {
System.err.println("Warning: " + str);
}
void err(String str) {
System.err.println("ERROR: " + str);
}
}
//-----------------------------------------------------------------------------
// Utility classes
//-----------------------------------------------------------------------------
class DecompMap extends HashMap {
public DecompMap() {
}
void put(char ch, String value) {
put(new MutableChar(ch), value);
}
String get(char ch) {
Object obj = get(probe.set(ch));
return (obj != null) ? (String)obj : null;
}
boolean contains(char ch) {
return containsKey(probe.set(ch));
}
MutableChar probe = new MutableChar(' ');
}
class CompMap extends HashMap {
public CompMap() {
}
void put(String key, char value) {
put(key, new MutableChar(value));
}
char get(String key) {
Object obj = get((Object)key);
return (obj != null) ? ((MutableChar)obj).value : 0;
}
}
class CharSet extends HashSet {
public CharSet() {
}
public void add(char ch) {
add(new MutableChar(ch));
}
public boolean contains(char ch) {
return contains(probe.set(ch));
}
MutableChar probe = new MutableChar(' ');
}

View file

@ -0,0 +1,25 @@
package com.ibm.tools.normalizer;
import com.ibm.text.*;
import com.ibm.util.CompactCharArray;
import com.ibm.util.CompactByteArray;
//===========================================================================================
// Utilities for writing data out as compilable source code
//
public abstract class SourceWriter {
abstract public void close();
abstract public void write(String name, short value);
abstract public void write(String name, int value);
abstract public void write(String name, CompactCharArray array);
abstract public void write(String name, CompactByteArray array);
abstract public void write(String name, StringBuffer str);
abstract public void write(String name, char[] array);
abstract public void write(String name, int[] array);
abstract public void writeHex(String name, char value);
abstract public void writeHex(String name, int value);
}

View file

@ -0,0 +1,656 @@
/*
* @(#)Utility.java 1.9 98/06/29
*
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* Portions copyright (c) 1997, 1998 Sun Microsystems, Inc.
* All Rights Reserved.
*
* The original version of this source code and documentation
* is copyrighted and owned by Taligent, Inc., a wholly-owned
* subsidiary of IBM. These materials are provided under terms
* of a License Agreement between Taligent and Sun. This technology
* is protected by multiple US and International patents.
*
* This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.ibm.util;
public final class Utility {
/**
* Convenience utility to compare two Object[]s.
* Ought to be in System
*/
public final static boolean arrayEquals(Object[] source, Object target) {
if (source == null) return (target == null);
if (!(target instanceof Object[])) return false;
Object[] targ = (Object[]) target;
return (source.length == targ.length
&& arrayRegionMatches(source, 0, targ, 0, source.length));
}
/**
* Convenience utility to compare two int[]s
* Ought to be in System
*/
public final static boolean arrayEquals(int[] source, Object target) {
if (source == null) return (target == null);
if (!(target instanceof int[])) return false;
int[] targ = (int[]) target;
return (source.length == targ.length
&& arrayRegionMatches(source, 0, targ, 0, source.length));
}
/**
* Convenience utility to compare two double[]s
* Ought to be in System
*/
public final static boolean arrayEquals(double[] source, Object target) {
if (source == null) return (target == null);
if (!(target instanceof double[])) return false;
double[] targ = (double[]) target;
return (source.length == targ.length
&& arrayRegionMatches(source, 0, targ, 0, source.length));
}
/**
* Convenience utility to compare two Object[]s
* Ought to be in System
*/
public final static boolean arrayEquals(Object source, Object target) {
if (source == null) return (target == null);
// for some reason, the correct arrayEquals is not being called
// so do it by hand for now.
if (source instanceof Object[])
return(arrayEquals((Object[]) source,target));
if (source instanceof int[])
return(arrayEquals((int[]) source,target));
if (source instanceof double[])
return(arrayEquals((int[]) source,target));
return source.equals(target);
}
/**
* Convenience utility to compare two Object[]s
* Ought to be in System.
* @param len the length to compare.
* The start indices and start+len must be valid.
*/
public final static boolean arrayRegionMatches(Object[] source, int sourceStart,
Object[] target, int targetStart,
int len)
{
int sourceEnd = sourceStart + len;
int delta = targetStart - sourceStart;
for (int i = sourceStart; i < sourceEnd; i++) {
if (!arrayEquals(source[i],target[i + delta]))
return false;
}
return true;
}
/**
* Convenience utility to compare two int[]s.
* @param len the length to compare.
* The start indices and start+len must be valid.
* Ought to be in System
*/
public final static boolean arrayRegionMatches(int[] source, int sourceStart,
int[] target, int targetStart,
int len)
{
int sourceEnd = sourceStart + len;
int delta = targetStart - sourceStart;
for (int i = sourceStart; i < sourceEnd; i++) {
if (source[i] != target[i + delta])
return false;
}
return true;
}
/**
* Convenience utility to compare two arrays of doubles.
* @param len the length to compare.
* The start indices and start+len must be valid.
* Ought to be in System
*/
public final static boolean arrayRegionMatches(double[] source, int sourceStart,
double[] target, int targetStart,
int len)
{
int sourceEnd = sourceStart + len;
int delta = targetStart - sourceStart;
for (int i = sourceStart; i < sourceEnd; i++) {
if (source[i] != target[i + delta])
return false;
}
return true;
}
/**
* Convenience utility. Does null checks on objects, then calls equals.
*/
public final static boolean objectEquals(Object source, Object target) {
if (source == null)
return (target == null);
else
return source.equals(target);
}
/**
* The ESCAPE character is used during run-length encoding. It signals
* a run of identical chars.
*/
private static final char ESCAPE = '\uA5A5';
/**
* The ESCAPE_BYTE character is used during run-length encoding. It signals
* a run of identical bytes.
*/
static final byte ESCAPE_BYTE = (byte)0xA5;
/**
* Construct a string representing an int array. Use run-length encoding.
* A character represents itself, unless it is the ESCAPE character. Then
* the following notations are possible:
* ESCAPE ESCAPE ESCAPE literal
* ESCAPE n c n instances of character c
* Since an encoded run occupies 3 characters, we only encode runs of 4 or
* more characters. Thus we have n > 0 and n != ESCAPE and n <= 0xFFFF.
* If we encounter a run where n == ESCAPE, we represent this as:
* c ESCAPE n-1 c
* The ESCAPE value is chosen so as not to collide with commonly
* seen values.
*/
static public final String arrayToRLEString(int[] a) {
StringBuffer buffer = new StringBuffer();
appendInt(buffer, a.length);
int runValue = a[0];
int runLength = 1;
for (int i=1; i<a.length; ++i) {
int s = a[i];
if (s == runValue && runLength < 0xFFFF) {
++runLength;
} else {
encodeRun(buffer, runValue, runLength);
runValue = s;
runLength = 1;
}
}
encodeRun(buffer, runValue, runLength);
return buffer.toString();
}
/**
* Construct a string representing a short array. Use run-length encoding.
* A character represents itself, unless it is the ESCAPE character. Then
* the following notations are possible:
* ESCAPE ESCAPE ESCAPE literal
* ESCAPE n c n instances of character c
* Since an encoded run occupies 3 characters, we only encode runs of 4 or
* more characters. Thus we have n > 0 and n != ESCAPE and n <= 0xFFFF.
* If we encounter a run where n == ESCAPE, we represent this as:
* c ESCAPE n-1 c
* The ESCAPE value is chosen so as not to collide with commonly
* seen values.
*/
static public final String arrayToRLEString(short[] a) {
StringBuffer buffer = new StringBuffer();
// for (int i=0; i<a.length; ++i) buffer.append((char) a[i]);
buffer.append((char) (a.length >> 16));
buffer.append((char) a.length);
short runValue = a[0];
int runLength = 1;
for (int i=1; i<a.length; ++i) {
short s = a[i];
if (s == runValue && runLength < 0xFFFF) ++runLength;
else {
encodeRun(buffer, runValue, runLength);
runValue = s;
runLength = 1;
}
}
encodeRun(buffer, runValue, runLength);
return buffer.toString();
}
/**
* Construct a string representing a char array. Use run-length encoding.
* A character represents itself, unless it is the ESCAPE character. Then
* the following notations are possible:
* ESCAPE ESCAPE ESCAPE literal
* ESCAPE n c n instances of character c
* Since an encoded run occupies 3 characters, we only encode runs of 4 or
* more characters. Thus we have n > 0 and n != ESCAPE and n <= 0xFFFF.
* If we encounter a run where n == ESCAPE, we represent this as:
* c ESCAPE n-1 c
* The ESCAPE value is chosen so as not to collide with commonly
* seen values.
*/
static public final String arrayToRLEString(char[] a) {
StringBuffer buffer = new StringBuffer();
buffer.append((char) (a.length >> 16));
buffer.append((char) a.length);
char runValue = a[0];
int runLength = 1;
for (int i=1; i<a.length; ++i) {
char s = a[i];
if (s == runValue && runLength < 0xFFFF) ++runLength;
else {
encodeRun(buffer, (short)runValue, runLength);
runValue = s;
runLength = 1;
}
}
encodeRun(buffer, (short)runValue, runLength);
return buffer.toString();
}
/**
* Construct a string representing a byte array. Use run-length encoding.
* Two bytes are packed into a single char, with a single extra zero byte at
* the end if needed. A byte represents itself, unless it is the
* ESCAPE_BYTE. Then the following notations are possible:
* ESCAPE_BYTE ESCAPE_BYTE ESCAPE_BYTE literal
* ESCAPE_BYTE n b n instances of byte b
* Since an encoded run occupies 3 bytes, we only encode runs of 4 or
* more bytes. Thus we have n > 0 and n != ESCAPE_BYTE and n <= 0xFF.
* If we encounter a run where n == ESCAPE_BYTE, we represent this as:
* b ESCAPE_BYTE n-1 b
* The ESCAPE_BYTE value is chosen so as not to collide with commonly
* seen values.
*/
static public final String arrayToRLEString(byte[] a) {
StringBuffer buffer = new StringBuffer();
buffer.append((char) (a.length >> 16));
buffer.append((char) a.length);
byte runValue = a[0];
int runLength = 1;
byte[] state = new byte[2];
for (int i=1; i<a.length; ++i) {
byte b = a[i];
if (b == runValue && runLength < 0xFF) ++runLength;
else {
encodeRun(buffer, runValue, runLength, state);
runValue = b;
runLength = 1;
}
}
encodeRun(buffer, runValue, runLength, state);
// We must save the final byte, if there is one, by padding
// an extra zero.
if (state[0] != 0) appendEncodedByte(buffer, (byte)0, state);
return buffer.toString();
}
/**
* Encode a run, possibly a degenerate run (of < 4 values).
* @param length The length of the run; must be > 0 && <= 0xFFFF.
*/
private static final void encodeRun(StringBuffer buffer, int value, int length) {
if (length < 4) {
for (int j=0; j<length; ++j) {
if (value == ESCAPE) {
appendInt(buffer, value);
}
appendInt(buffer, value);
}
}
else {
if (length == (int) ESCAPE) {
if (value == (int) ESCAPE) {
appendInt(buffer, ESCAPE);
}
appendInt(buffer, value);
--length;
}
appendInt(buffer, ESCAPE);
appendInt(buffer, length);
appendInt(buffer, value); // Don't need to escape this value
}
}
private static final void appendInt(StringBuffer buffer, int value) {
buffer.append((char)(value >>> 16));
buffer.append((char)(value & 0xFFFF));
}
/**
* Encode a run, possibly a degenerate run (of < 4 values).
* @param length The length of the run; must be > 0 && <= 0xFFFF.
*/
private static final void encodeRun(StringBuffer buffer, short value, int length) {
if (length < 4) {
for (int j=0; j<length; ++j) {
if (value == (int) ESCAPE) buffer.append(ESCAPE);
buffer.append((char) value);
}
}
else {
if (length == (int) ESCAPE) {
if (value == (int) ESCAPE) buffer.append(ESCAPE);
buffer.append((char) value);
--length;
}
buffer.append(ESCAPE);
buffer.append((char) length);
buffer.append((char) value); // Don't need to escape this value
}
}
/**
* Encode a run, possibly a degenerate run (of < 4 values).
* @param length The length of the run; must be > 0 && <= 0xFF.
*/
private static final void encodeRun(StringBuffer buffer, byte value, int length,
byte[] state) {
if (length < 4) {
for (int j=0; j<length; ++j) {
if (value == ESCAPE_BYTE) appendEncodedByte(buffer, ESCAPE_BYTE, state);
appendEncodedByte(buffer, value, state);
}
}
else {
if (length == ESCAPE_BYTE) {
if (value == ESCAPE_BYTE) appendEncodedByte(buffer, ESCAPE_BYTE, state);
appendEncodedByte(buffer, value, state);
--length;
}
appendEncodedByte(buffer, ESCAPE_BYTE, state);
appendEncodedByte(buffer, (byte)length, state);
appendEncodedByte(buffer, value, state); // Don't need to escape this value
}
}
/**
* Append a byte to the given StringBuffer, packing two bytes into each
* character. The state parameter maintains intermediary data between
* calls.
* @param state A two-element array, with state[0] == 0 if this is the
* first byte of a pair, or state[0] != 0 if this is the second byte
* of a pair, in which case state[1] is the first byte.
*/
private static final void appendEncodedByte(StringBuffer buffer, byte value,
byte[] state) {
if (state[0] != 0) {
char c = (char) ((state[1] << 8) | (((int) value) & 0xFF));
buffer.append(c);
state[0] = 0;
}
else {
state[0] = 1;
state[1] = value;
}
}
/**
* Construct an array of ints from a run-length encoded string.
*/
static public final int[] RLEStringToIntArray(String s) {
int length = getInt(s, 0);
int[] array = new int[length];
int ai = 0, i = 1;
int maxI = s.length() / 2;
while (ai < length && i < maxI) {
int c = getInt(s, i++);
if (c == ESCAPE) {
c = getInt(s, i++);
if (c == ESCAPE) {
array[ai++] = c;
} else {
int runLength = c;
int runValue = getInt(s, i++);
for (int j=0; j<runLength; ++j) {
array[ai++] = runValue;
}
}
}
else {
array[ai++] = c;
}
}
if (ai != length || i != maxI) {
throw new InternalError("Bad run-length encoded int array");
}
return array;
}
static final int getInt(String s, int i) {
return (((int) s.charAt(2*i)) << 16) | (int) s.charAt(2*i+1);
}
/**
* Construct an array of shorts from a run-length encoded string.
*/
static public final short[] RLEStringToShortArray(String s) {
int length = (((int) s.charAt(0)) << 16) | ((int) s.charAt(1));
short[] array = new short[length];
int ai = 0;
for (int i=2; i<s.length(); ++i) {
char c = s.charAt(i);
if (c == ESCAPE) {
c = s.charAt(++i);
if (c == ESCAPE) {
array[ai++] = (short) c;
} else {
int runLength = (int) c;
short runValue = (short) s.charAt(++i);
for (int j=0; j<runLength; ++j) array[ai++] = runValue;
}
}
else {
array[ai++] = (short) c;
}
}
if (ai != length)
throw new InternalError("Bad run-length encoded short array");
return array;
}
/**
* Construct an array of shorts from a run-length encoded string.
*/
static public final char[] RLEStringToCharArray(String s) {
int length = (((int) s.charAt(0)) << 16) | ((int) s.charAt(1));
char[] array = new char[length];
int ai = 0;
for (int i=2; i<s.length(); ++i) {
char c = s.charAt(i);
if (c == ESCAPE) {
c = s.charAt(++i);
if (c == ESCAPE) {
array[ai++] = c;
} else {
int runLength = (int) c;
char runValue = s.charAt(++i);
for (int j=0; j<runLength; ++j) array[ai++] = runValue;
}
}
else {
array[ai++] = c;
}
}
if (ai != length)
throw new InternalError("Bad run-length encoded short array");
return array;
}
/**
* Construct an array of bytes from a run-length encoded string.
*/
static public final byte[] RLEStringToByteArray(String s) {
int length = (((int) s.charAt(0)) << 16) | ((int) s.charAt(1));
byte[] array = new byte[length];
boolean nextChar = true;
char c = 0;
int node = 0;
int runLength = 0;
int i = 2;
for (int ai=0; ai<length; ) {
// This part of the loop places the next byte into the local
// variable 'b' each time through the loop. It keeps the
// current character in 'c' and uses the boolean 'nextChar'
// to see if we've taken both bytes out of 'c' yet.
byte b;
if (nextChar) {
c = s.charAt(i++);
b = (byte) (c >> 8);
nextChar = false;
}
else {
b = (byte) (c & 0xFF);
nextChar = true;
}
// This part of the loop is a tiny state machine which handles
// the parsing of the run-length encoding. This would be simpler
// if we could look ahead, but we can't, so we use 'node' to
// move between three nodes in the state machine.
switch (node) {
case 0:
// Normal idle node
if (b == ESCAPE_BYTE) {
node = 1;
}
else {
array[ai++] = b;
}
break;
case 1:
// We have seen one ESCAPE_BYTE; we expect either a second
// one, or a run length and value.
if (b == ESCAPE_BYTE) {
array[ai++] = ESCAPE_BYTE;
node = 0;
}
else {
runLength = b;
// Interpret signed byte as unsigned
if (runLength < 0) runLength += 0x100;
node = 2;
}
break;
case 2:
// We have seen an ESCAPE_BYTE and length byte. We interpret
// the next byte as the value to be repeated.
for (int j=0; j<runLength; ++j) array[ai++] = b;
node = 0;
break;
}
}
if (node != 0)
throw new InternalError("Bad run-length encoded byte array");
if (i != s.length())
throw new InternalError("Excess data in RLE byte array string");
return array;
}
/**
* Format a String for representation in a source file. This includes
* breaking it into lines escaping characters using octal notation
* when necessary (control characters and double quotes).
*/
static public final String formatForSource(String s) {
StringBuffer buffer = new StringBuffer();
for (int i=0; i<s.length();) {
if (i > 0) buffer.append("+\n");
buffer.append(" \"");
int count = 11;
while (i<s.length() && count<80) {
char c = s.charAt(i++);
if (c < '\u0020' || c == '"' || c == '\\') {
// Represent control characters, backslash and double quote
// using octal notation; otherwise the string we form
// won't compile, since Unicode escape sequences are
// processed before tokenization.
buffer.append('\\');
buffer.append(HEX_DIGIT[(c & 0700) >> 6]); // HEX_DIGIT works for octal
buffer.append(HEX_DIGIT[(c & 0070) >> 3]);
buffer.append(HEX_DIGIT[(c & 0007)]);
count += 4;
}
else if (c <= '\u007E') {
buffer.append(c);
count += 1;
}
else {
buffer.append("\\u");
buffer.append(HEX_DIGIT[(c & 0xF000) >> 12]);
buffer.append(HEX_DIGIT[(c & 0x0F00) >> 8]);
buffer.append(HEX_DIGIT[(c & 0x00F0) >> 4]);
buffer.append(HEX_DIGIT[(c & 0x000F)]);
count += 6;
}
}
buffer.append('"');
}
return buffer.toString();
}
static final char[] HEX_DIGIT = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'};
/**
* Convert characters outside the range U+0020 to U+007F to
* Unicode escapes, and convert backslash to a double backslash.
*/
public static final String escape(String s) {
StringBuffer buf = new StringBuffer();
for (int i=0; i<s.length(); ++i) {
char c = s.charAt(i);
if (c >= ' ' && c <= 0x007F) {
if (c == '\\') {
buf.append("\\\\"); // That is, "\\"
} else {
buf.append(c);
}
} else {
buf.append("\\u");
if (c < 0x1000) {
buf.append('0');
if (c < 0x100) {
buf.append('0');
if (c < 0x10) {
buf.append('0');
}
}
}
buf.append(Integer.toHexString(c));
}
}
return buf.toString();
}
}

View file

@ -0,0 +1,354 @@
/*
* @(#)src/classes/sov/java/text/resources/BreakIteratorRules.java, hsdev, hsdev, hsdev-19991007 1.2
* ===========================================================================
* Licensed Materials - Property of IBM
* IBM Java(tm)2 SDK, Standard Edition, v 1.2
*
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
* Copyright 1998 by Sun Microsystems, Inc.,
* ===========================================================================
*/
/*
* ===========================================================================
* Change activity:
*
* Reason Date Origin Description
* ------ ---- ------ ----------------------------------------------------
* 270799 New file.
* ===========================================================================
* Module Information:
*
* DESCRIPTION: Hindi, Thai, and Bidi enhancements.
* ===========================================================================
*/
//ibm.597
/*
* (C) IBM Corp. 1997-1998. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.text.resources;
import java.util.ListResourceBundle;
/**
* Default break-iterator rules. These rules are more or less general for
* all locales, although there are probably a few we're missing. The
* behavior currently mimics the behavior of BreakIterator in JDK 1.2.
* There are known deficiencies in this behavior, including the fact that
* the logic for handling CJK characters works for Japanese but not for
* Chinese, and that we don't currently have an appropriate locale for
* Thai. The resources will eventually be updated to fix these problems.
*/
/* Modified for Hindi 3/1/99. */
public class BreakIteratorRules extends ListResourceBundle {
public Object[][] getContents() {
return contents;
}
static final Object[][] contents = {
// BreakIteratorClasses lists the class names to instantiate for each
// built-in type of BreakIterator
{ "BreakIteratorClasses",
new String[] { "RuleBasedBreakIterator", // character-break iterator class
"RuleBasedBreakIterator", // word-break iterator class
"RuleBasedBreakIterator", // line-break iterator class
"RuleBasedBreakIterator" } // sentence-break iterator class
},
// rules describing how to break between logical characters
{ "CharacterBreakRules",
// ignore non-spacing marks and enclosing marks (since we never
// put a break before ignore characters, this keeps combining
// accents with the base characters they modify)
"$ignore=[[:Mn:][:Me:]];"
// other category definitions
+ "choseong=[\u1100-\u115f];"
+ "jungseong=[\u1160-\u11a7];"
+ "jongseong=[\u11a8-\u11ff];"
+ "surr-hi=[\ud800-\udbff];"
+ "surr-lo=[\udc00-\udfff];"
// break after every character, except as follows:
+ ".;"
// keep CRLF sequences together
+ "\r\n;"
// keep surrogate pairs together
+ "{surr-hi}{surr-lo};"
// keep Hangul syllables spelled out using conjoining jamo together
+ "{choseong}*{jungseong}*{jongseong}*;"
// various additions for Hindi support
+ "nukta=[\u093c];"
+ "danda=[\u0964\u0965];"
+ "virama=[\u094d];"
+ "devVowelSign=[\u093e-\u094c\u0962\u0963];"
+ "devConsonant=[\u0915-\u0939];"
+ "devNuktaConsonant=[\u0958-\u095f];"
+ "devCharEnd=[\u0902\u0903\u0951-\u0954];"
+ "zwj=[\u200d];"
+ "devCAMN=({devConsonant}{nukta}?);"
+ "devConsonant1=({devNuktaConsonant}|{devCAMN});"
+ "devConjunct=(({devConsonant1}{virama}{zwj}?)?{devConsonant1});"
+ "{devConjunct}{devVowelSign}?{devCharEnd}?;"
+ "{danda}{nukta};"
},
// default rules for finding word boundaries
{ "WordBreakRules",
// ignore non-spacing marks, enclosing marks, and format characters,
// all of which should not influence the algorithm
"$ignore=[[:Mn:][:Me:][:Cf:]];"
// Hindi phrase separator, kanji, katakana, hiragana, CJK diacriticals,
// other letters, and digits
+ "danda=[\u0964\u0965];"
+ "kanji=[\u3005\u4e00-\u9fa5\uf900-\ufa2d];"
+ "kata=[\u3099-\u309c\u30a1-\u30fe];"
+ "hira=[\u3041-\u309e\u30fc];"
+ "let=[[[:L:][:Mc:]]-[{kanji}{kata}{hira}]];"
+ "dgt=[:N:];"
// punctuation that can occur in the middle of a word: currently
// dashes, apostrophes, quotation marks, and periods
+ "mid-word=[[:Pd:]\u00ad\u2027\\\"\\\'\\.];"
// punctuation that can occur in the middle of a number: currently
// apostrophes, qoutation marks, periods, commas, and the Arabic
// decimal point
+ "mid-num=[\\\"\\\'\\,\u066b\\.];"
// punctuation that can occur at the beginning of a number: currently
// the period, the number sign, and all currency symbols except the cents sign
+ "pre-num=[[[:Sc:]-[\u00a2]]\\#\\.];"
// punctuation that can occur at the end of a number: currently
// the percent, per-thousand, per-ten-thousand, and Arabic percent
// signs, the cents sign, and the ampersand
+ "post-num=[\\%\\&\u00a2\u066a\u2030\u2031];"
// line separators: currently LF, FF, PS, and LS
+ "ls=[\n\u000c\u2028\u2029];"
// whitespace: all space separators and the tab character
+ "ws=[[:Zs:]\t];"
// a word is a sequence of letters that may contain internal
// punctuation, as long as it begins and ends with a letter and
// never contains two punctuation marks in a row
+ "word=({let}+({mid-word}{let}+)*{danda}?);"
// a number is a sequence of digits that may contain internal
// punctuation, as long as it begins and ends with a digit and
// never contains two punctuation marks in a row.
+ "number=({dgt}+({mid-num}{dgt}+)*);"
// break after every character, with the following exceptions
// (this will cause punctuation marks that aren't considered
// part of words or numbers to be treated as words unto themselves)
+ ".;"
// keep together any sequence of contiguous words and numbers
// (including just one of either), plus an optional trailing
// number-suffix character
+ "{word}?({number}{word})*({number}{post-num}?)?;"
// keep together and sequence of contiguous words and numbers
// that starts with a number-prefix character and a number,
// and may end with a number-suffix character
+ "{pre-num}({number}{word})*({number}{post-num}?)?;"
// keep together runs of whitespace (optionally with a single trailing
// line separator or CRLF sequence)
+ "{ws}*\r?{ls}?;"
// keep together runs of Katakana
+ "{kata}*;"
// keep together runs of Hiragana
+ "{hira}*;"
// keep together runs of Kanji
+ "{kanji}*;"
},
// default rules for determining legal line-breaking positions
{ "LineBreakRules",
// ignore non-spacing marks, enclosing marks, and format characters
"$ignore=[[:Mn:][:Me:][:Cf:]];"
// Hindi phrase separators
+ "danda=[\u0964\u0965];"
// characters that always cause a break: ETX, tab, LF, FF, LS, and PS
+ "break=[\u0003\t\n\f\u2028\u2029];"
// characters that always prevent a break: the non-breaking space
// and similar characters
+ "nbsp=[\u00a0\u2007\u2011\ufeff];"
// whitespace: space separators and control characters, except for
// CR and the other characters mentioned above
+ "space=[[[:Zs:][:Cc:]]-[{nbsp}{break}\r]];"
// dashes: dash punctuation and the discretionary hyphen, except for
// non-breaking hyphens
+ "dash=[[[:Pd:]\u00ad]-[{nbsp}]];"
// characters that stick to a word if they precede it: currency symbols
// (except the cents sign) and starting punctuation
+ "pre-word=[[[:Sc:]-[\u00a2]][:Ps:]\\\"\\\'];"
// characters that stick to a word if they follow it: ending punctuation,
// other punctuation that usually occurs at the end of a sentence,
// small Kana characters, some CJK diacritics, etc.
+ "post-word=[[:Pe:]\\!\\\"\\\'\\%\\.\\,\\:\\;\\?\u00a2\u00b0\u066a\u2030-\u2034"
+ "\u2103\u2105\u2109\u3001\u3002\u3005\u3041\u3043\u3045\u3047\u3049\u3063"
+ "\u3083\u3085\u3087\u308e\u3099-\u309e\u30a1\u30a3\u30a5\u30a7\u30a9"
+ "\u30c3\u30e3\u30e5\u30e7\u30ee\u30f5\u30f6\u30fc-\u30fe\uff01\uff0c"
+ "\uff0e\uff1f];"
// Kanji: actually includes both Kanji and Kana, except for small Kana and
// CJK diacritics
+ "kanji=[[\u4e00-\u9fa5\uf900-\ufa2d\u3041-\u3094\u30a1-\u30fa]-[{post-word}{$ignore}]];"
// digits
+ "digit=[[:Nd:][:No:]];"
// punctuation that can occur in the middle of a number: periods and commas
+ "mid-num=[\\.\\,];"
// everything not mentioned above, plus the quote marks (which are both
// <pre-word>, <post-word>, and <char>)
+ "char=[^{break}{space}{dash}{kanji}{nbsp}{$ignore}{pre-word}{post-word}{mid-num}{danda}\r\\\"\\\'];"
// a "number" is a run of prefix characters and dashes, followed by one or
// more digits with isolated number-punctuation characters interspersed
+ "number=([{pre-word}{dash}]*{digit}+({mid-num}{digit}+)*);"
// the basic core of a word can be either a "number" as defined above, a single
// "Kanji" character, or a run of any number of not-explicitly-mentioned
// characters (this includes Latin letters)
+ "word-core=([{pre-word}{char}]*|{kanji}|{number});"
// a word may end with an optional suffix that be either a run of one or
// more dashes or a run of word-suffix characters, followed by an optional
// run of whitespace
+ "word-suffix=(({dash}+|{post-word}*){space}*);"
// a word, thus, is an optional run of word-prefix characters, followed by
// a word core and a word suffix (the syntax of <word-core> and <word-suffix>
// actually allows either of them to match the empty string, putting a break
// between things like ")(" or "aaa(aaa"
+ "word=({pre-word}*{word-core}{word-suffix});"
// finally, the rule that does the work: Keep together any run of words that
// are joined by runs of one of more non-spacing mark. Also keep a trailing
// line-break character or CRLF combination with the word. (line separators
// "win" over nbsp's)
+ "{word}({nbsp}+{word})*\r?{break}?;"
},
// default rules for finding sentence boundaries
{ "SentenceBreakRules",
// ignore non-spacing marks, enclosing marks, and format characters
"$ignore=[[:Mn:][:Me:][:Cf:]];"
// lowercase letters
+ "lc=[:Ll:];"
// uppercase Latin letters
+ "ucLatin=[A-Z];"
// whitespace (line separators are treated as whitespace)
+ "space=[\t\r\f\n\u2028[:Zs:]];"
// punctuation which may occur at the beginning of a sentence: "starting
// punctuation" and quotation marks
+ "start=[[:Ps:]\\\"\\\'];"
// punctuation with may occur at the end of a sentence: "ending punctuation"
// and quotation marks
+ "end=[[:Pe:]\\\"\\\'];"
// digits
+ "digit=[:N:];"
// characters that unambiguously signal the end of a sentence
+ "term=[\\!\\?\u3002\uff01\uff1f];"
// periods, which MAY signal the end of a sentence
+ "period=[\\.\uff0e];"
// characters that may occur at the beginning of a sentence: basically anything
// not mentioned above (lowercase letters and digits are specifically excluded)
+ "sent-start=[^{lc}{ucLatin}{space}{start}{end}{digit}{term}{period}\u2029{$ignore}];"
// Hindi phrase separator
+ "danda=[\u0964\u0965];"
// always break sentences after paragraph separators
+ ".*?\u2029?;"
// always break after a danda, if it's followed by whitespace
+ ".*?{danda}{space}*;"
// if you see a period, skip over additional periods and ending punctuation
// and if the next character is a paragraph separator, break after the
// paragraph separator
+ ".*?{period}[{period}{end}]*{space}*\u2029;"
// if you see a period, skip over additional periods and ending punctuation,
// followed by optional whitespace, followed by optional starting punctuation,
// and if the next character is something that can start a sentence
// (basically, a capital letter), then put the sentence break between the
// whitespace and the opening punctuation
+ ".*?{period}[{period}{end}]*{space}*/({start}*{sent-start}|{start}+{ucLatin});"
// same as above, except that there's a sentence break before a Latin capital
// letter only if there's at least one space after the period
+ ".*?{period}[{period}{end}]*{space}+/{ucLatin};"
// if you see a sentence-terminating character, skip over any additional
// terminators, periods, or ending punctuation, followed by any whitespace,
// followed by a SINGLE optional paragraph separator, and put the break there
+ ".*?{term}[{term}{period}{end}]*{space}*\u2029?;"
// The following rules are here to aid in backwards iteration. The automatically
// generated backwards state table will rewind to the beginning of the
// paragraph all the time (or all the way to the beginning of the document
// if the document doesn't use the Unicode PS character) because the only
// unambiguous character pairs are those involving paragraph separators.
// These specify a few more unambiguous breaking situations.
// if you see a sentence-starting character, followed by starting punctuation
// (remember, we're iterating backwards), followed by an optional run of
// whitespace, followed by an optional run of ending punctuation, followed
// by a period, this is a safe place to turn around
+ "![{sent-start}{ucLatin}]{start}*{space}+{end}*{period};"
// if you see a letter or a digit, followed by an optional run of
// starting punctuation, followed by an optional run of whitespace,
// followed by an optional run of ending punctuation, followed by
// a sentence terminator, this is a safe place to turn around
+ "![{sent-start}{lc}{digit}]{start}*{space}*{end}*{term};"
}
};
}

View file

@ -0,0 +1,123 @@
/*
* @(#)src/i18n/sov/java/text/resources/BreakIteratorRules_th.java, asdev, asdev, asdev-19991007 1.1
* ===========================================================================
* IBM Confidential
* OCO Source Materials
*
* IBM Java(tm)2 SDK, Standard Edition, v 1.2
*
* (C) Copyright IBM Corp. 1999
*
* The source code for this program is not published or otherwise divested of
* its trade secrets, irrespective of what has been deposited with the U.S.
* Copyright office.
* ===========================================================================
* Change activity:
*
* Reason Date Origin Description
* ------ ---- ------ ----------------------------------------------------
* 270799 New file.
* ===========================================================================
* Module Information:
*
* DESCRIPTION: Hindi, Thai, and Bidi enhancements.
* ===========================================================================
*/
package com.ibm.text.resources;
import java.util.ListResourceBundle;
import java.util.MissingResourceException;
import java.net.URL;
public class BreakIteratorRules_th extends ListResourceBundle {
public Object[][] getContents() {
URL url = getClass().getResource("thai_dict");
// if dictionary wasn't found, then this resource bundle doesn't have
// much to contribute...
if (url == null) {
return new Object[0][0];
}
return new Object[][] {
// names of classes to instantiate for the different kinds of break
// iterator. Notice we're now using DictionaryBasedBreakIterator
// for word and line breaking.
{ "BreakIteratorClasses",
new String[] { "RuleBasedBreakIterator", // character-break iterator class
"DictionaryBasedBreakIterator", // word-break iterator class
"DictionaryBasedBreakIterator", // line-break iterator class
"RuleBasedBreakIterator" } // sentence-break iterator class
},
{ "WordBreakRules",
"$dictionary=[\u0e01-\u0e2e\u0e30-\u0e3a\u0e40-\u0e44\u0e47-\u0e4e];" // this rule breaks the iterator with mixed Thai and English
+ "$ignore=[[[:Mn:][:Me:][:Cf:]]-{$dictionary}];"
+ "paiyannoi=[\u0e2f];"
+ "maiyamok=[\u0e46];"
+ "danda=[\u0964\u0965];"
+ "kanji=[\u3005\u4e00-\u9fa5\uf900-\ufa2d];"
+ "kata=[\u30a1-\u30fa];"
+ "hira=[\u3041-\u3094];"
+ "cjk-diacrit=[\u3099-\u309c];"
+ "let=[[[:L:][:Mc:]]-[{kanji}{kata}{hira}{cjk-diacrit}{$dictionary}]];"
+ "dgt=[:N:];"
+ "mid-word=[[:Pd:]\u00ad\u2027\\\"\\\'\\.];"
+ "mid-num=[\\\"\\\'\\,\u066b\\.];"
+ "pre-num=[[[:Sc:]-[\u00a2]]\\#\\.];"
+ "post-num=[\\%\\&\u00a2\u066a\u2030\u2031];"
+ "ls=[\n\u000c\u2028\u2029];"
+ "ws=[[:Zs:]\t];"
+ "word=(({let}+({mid-word}{let}+)*){danda}?);"
+ "number=({dgt}+({mid-num}{dgt}+)*);"
+ "thai-etc={paiyannoi}\u0e25{paiyannoi};"
+ ".;"
+ "{word}?({number}{word})*({number}{post-num}?)?;"
+ "{pre-num}({number}{word})*({number}{post-num}?)?;"
+ "{$dictionary}+({paiyannoi}{maiyamok}?)?;"
+ "{$dictionary}+{paiyannoi}/([^\u0e25{$ignore}]"
+ "|\u0e25[^{paiyannoi}{$ignore}]);"
+ "{thai-etc};"
+ "{ws}*\r?{ls}?;"
+ "[{kata}{cjk-diacrit}]*;"
+ "[{hira}{cjk-diacrit}]*;"
+ "{kanji}*;"
},
{ "LineBreakRules",
"$dictionary=[\u0e01-\u0e2e\u0e30-\u0e3a\u0e40-\u0e44\u0e47-\u0e4e];" // this rule breaks the iterator with mixed Thai and English
+ "$ignore=[[[:Mn:][:Me:][:Cf:]]-[{$dictionary}]];"
+ "danda=[\u0964\u0965];"
+ "break=[\u0003\t\n\f\u2028\u2029];"
+ "nbsp=[\u00a0\u2007\u2011\ufeff];"
+ "space=[[[:Zs:][:Cc:]]-[{nbsp}{break}\r]];"
+ "dash=[[[:Pd:]\u00ad]-{nbsp}];"
+ "paiyannoi=[\u0e2f];"
+ "maiyamok=[\u0e46];"
+ "thai-etc=({paiyannoi}\u0e25{paiyannoi});"
+ "pre-word=[[[:Sc:]-[\u00a2]][:Ps:]\\\"];"
+ "post-word=[[:Pe:]\\!\\%\\.\\,\\:\\;\\?\\\"\u00a2\u00b0\u066a\u2030-\u2034\u2103"
+ "\u2105\u2109\u3001\u3002\u3005\u3041\u3043\u3045\u3047\u3049\u3063"
+ "\u3083\u3085\u3087\u308e\u3099-\u309e\u30a1\u30a3\u30a5\u30a7\u30a9"
+ "\u30c3\u30e3\u30e5\u30e7\u30ee\u30f5\u30f6\u30fc-\u30fe\uff01\uff0e"
+ "\uff1f{maiyamok}];"
+ "kanji=[[\u4e00-\u9fa5\uf900-\ufa2d\u3041-\u3094\u30a1-\u30fa]-[{post-word}{$ignore}]];"
+ "digit=[[:Nd:][:No:]];"
+ "mid-num=[\\.\\,];"
+ "char=[^{break}{space}{dash}{kanji}{nbsp}{$ignore}{pre-word}{post-word}"
+ "{mid-num}\r{danda}{$dictionary}{paiyannoi}{maiyamok}];"
+ "number=([{pre-word}{dash}]*{digit}+({mid-num}{digit}+)*);"
+ "word-core=({char}*|{kanji}|{number}|{$dictionary}+|{thai-etc});"
+ "word-suffix=(({dash}+|{post-word}*){space}*);"
+ "word=({pre-word}*{word-core}{word-suffix});"
+ "{word}({nbsp}+{word})*(\r?{break}?|{paiyannoi}\r{break}|{paiyannoi}{break})?;"
+ "{word}({nbsp}+{word})*{paiyannoi}/([^[\u0e25{$ignore}]]|"
+ "\u0e25[^{paiyannoi}{$ignore}]);"
},
{ "WordBreakDictionary", url },
{ "LineBreakDictionary", url }
};
}
}

View file

@ -0,0 +1,36 @@
/*
* $RCSfile: BuddhistCalendarSymbols.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Default Date Format symbols for the Buddhist Calendar
*/
public class BuddhistCalendarSymbols extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "Eras", new String[] {
"BE"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,36 @@
/*
* $RCSfile: BuddhistCalendarSymbols_ar.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Default Date Format symbols for the Buddhist Calendar
*/
public class BuddhistCalendarSymbols_ar extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1999 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "Eras", new String[] {
"\u0627\u0644\u062A\u0642\u0648\u064A\u0645 \u0627\u0644\u0628\u0648\u0630\u064A"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,36 @@
/*
* $RCSfile: BuddhistCalendarSymbols_hu.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Hungarian Date Format symbols for the Buddhist Calendar
*/
public class BuddhistCalendarSymbols_hu extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "Eras", new String[] {
"BK"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,36 @@
/*
* $RCSfile: BuddhistCalendarSymbols_th.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Thai version of the Date Format symbols for the Buddhist calendar
*/
public class BuddhistCalendarSymbols_th extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "Eras", new String[] {
"\u0e1e.\u0e28."
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,104 @@
/*
* $RCSfile: ChineseCalendarSymbols.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
public class ChineseCalendarSymbols extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1999 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "DateTimePatterns",
new String[] {
"h:mm:ss a z", // full time pattern
"h:mm:ss a z", // long time pattern
"h:mm:ss a", // medium time pattern
"h:mm a", // short time pattern
"EEEE, MMMM d, yy", // full date pattern
"MMMM d, yy", // long date pattern
"MMM d, yy", // medium date pattern
"M/d/yy", // short date pattern
"{1} {0}" // date-time pattern
}
},
{ "DisplayName", "Chinese lunar" },
{ "Eras", new String[] {} },
{ "MonthTypes", new String[] {
"", "leap"
}
},
{ "StemNames",
new String[] {
"Jia",
"Yi",
"Bing",
"Ding",
"Wu",
"Ji",
"Geng",
"Xin",
"Ren",
"Gui",
}
},
{ "BranchNames",
new String[] {
"Rat",
"Ox",
"Tiger",
"Hare",
"Dragon",
"Snake",
"Horse",
"Sheep",
"Monkey",
"Fowl",
"Dog",
"Pig",
}
},
{ "TermNames",
new String[] {
"Beginning of Spring",
"Rain Water",
"Waking of Insects",
"Spring Equinox",
"Pure Brightness",
"Grain Rain",
"Beginning of Summer",
"Grain Full",
"Grain in Ear",
"Summer Solstice",
"Slight Heat",
"Great Heat",
"Beginning of Autumn",
"Limit of Heat",
"White Dew",
"Autumnal Equinox",
"Cold Dew",
"Descent of Frost",
"Beginning of Winter",
"Slight Snow",
"Great Snow",
"Winter Solstice",
"Slight Cold",
"Great Cold",
}
},
};
public synchronized Object[][] getContents() {
return fContents;
}
}

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: HebrewCalendarSymbols.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Default Date Format symbols for the Hebrew Calendar
*/
public class HebrewCalendarSymbols extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Tishri",
"Heshvan",
"Kislev",
"Tevet",
"Shevat",
"Adar I", // Leap years only
"Adar",
"Nisan",
"Iyar",
"Sivan",
"Tamuz",
"Av",
"Elul",
} },
{ "Eras", new String[] {
"AM"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,54 @@
/*
* $RCSfile: HebrewCalendarSymbols_fi.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Finnish date format symbols for the Hebrew Calendar
*/
public class HebrewCalendarSymbols_fi extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "Name", "Juutalainen kalenteri" },
{ "MonthNames", new String[] {
"Ti\u0161r\u00ECkuu", // Tishri
"He\u0161v\u00E1nkuu", // Heshvan
"Kisl\u00E9vkuu", // Kislev
"Tev\u00E9tkuu", // Tevet
"\u0160evatkuu", // Shevat
"Ad\u00E1rkuu", // Adar I
"Ad\u00E1rkuu II", // Adar
"Nis\u00E1nkuu", // Nisan
"Ijj\u00E1rkuu", // Iyar
"Siv\u00E1nkuu", // Sivan
"Tamm\u00FAzkuu", // Tamuz
"Abkuu", // Av
"El\u00FAlkuu", // Elul
} },
{ "Eras", new String[] {
"AM" // Anno Mundi
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: HebrewCalendarSymbols_fr.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* French date format symbols for the Hebrew Calendar.
* This data actually applies to French Canadian. If we receive
* official French data from our France office, we should move the
* French Canadian data (if it's different) down into _fr_CA
*/
public class HebrewCalendarSymbols_fr extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Tisseri", // Tishri
"Hesvan", // Heshvan
"Kislev", // Kislev
"T\u00e9beth", // Tevet
"Sch\u00e9bat", // Shevat
"Adar", // Adar I
"Adar II", // Adar
"Nissan", // Nisan
"Iyar", // Iyar
"Sivan", // Sivan
"Tamouz", // Tamuz
"Ab", // Av
"Elloul", // Elul
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: HebrewCalendarSymbols_hu.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Hungarian date format symbols for the Hebrew Calendar
*/
public class HebrewCalendarSymbols_hu extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Tisri", // Tishri
"Hesv\u00E1n", // Heshvan
"Kiszl\u00E9v", // Kislev
"T\u00E9v\u00E9sz", // Tevet
"Sv\u00E1t", // Shevat
"\u00C1d\u00E1r ris\u00F3n", // Adar I
"\u00C1d\u00E1r s\u00E9ni", // Adar
"Nisz\u00E1n", // Nisan
"Ij\u00E1r", // Iyar
"Sziv\u00E1n", // Sivan
"Tamuz", // Tamuz
"\u00C1v", // Av
"Elul", // Elul
} },
{ "Eras", new String[] {
"T\u00C9"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: HebrewCalendarSymbols_iw.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Hebrew-language date format symbols for the Hebrew Calendar
*/
public class HebrewCalendarSymbols_iw extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"\u05EA\u05E9\u05E8\u05D9", // Tishri
"\u05D7\u05E9\u05D5\u05DF", // Heshvan
"\u05DB\u05E1\u05DC\u05D5", // Kislev
"\u05D8\u05D1\u05EA", // Tevet
"\u05E9\u05D1\u05D8", // Shevat
"\u05E9\u05D1\u05D8", // Adar I
"\u05D0\u05D3\u05E8 \u05E9\u05E0\u05D9", // Adar
"\u05E0\u05D9\u05E1\u05DF", // Nisan
"\u05D0\u05D9\u05D9\u05E8", // Iyar
"\u05E1\u05D9\u05D5\u05DF", // Sivan
"\u05EA\u05DE\u05D5\u05D6", // Tamuz
"\u05D0\u05D1", // Av
"\u05D0\u05DC\u05D5\u05DC", // Elul
} },
{ "Eras", new String[] {
"\u05DC\u05D1\u05D4\042\u05E2"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,48 @@
/*
* $RCSfile: HebrewCalendarSymbols_nl.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:55 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Dutch date format symbols for the Hebrew Calendar
*/
public class HebrewCalendarSymbols_nl extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Tisjrie", // Tishri
"Chesjwan", // Heshvan
"Kislev", // Kislev
"Tevet", // Tevet
"Sjevat", // Shevat
"Adar", // Adar I
"Adar B", // Adar
"Nisan", // Nisan
"Ijar", // Iyar
"Sivan", // Sivan
"Tammoez", // Tamuz
"Av", // Av
"Elloel", // Elul
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,24 @@
// HolidayBundle.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.ListResourceBundle;
public class HolidayBundle extends ListResourceBundle {
// Normally, each HolidayBundle uses the holiday's US English name
// as the string key for looking up the localized name. This means
// that the key itself can be used if no name is found for the requested
// locale.
//
// For holidays where the key is _not_ the English name, e.g. in the
// case of conflicts, the English name must be given here.
//
static private final Object[][] fContents = {
{ "", "" }, // Can't be empty!
};
public synchronized Object[][] getContents() { return fContents; };
};

View file

@ -0,0 +1,27 @@
// HolidayBundle_da
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_da extends ListResourceBundle
{
static private final Object[][] fContents =
{
{ "Armistice Day", "v…benhvile" },
{ "Ascension", "himmelfart" },
{ "Boxing Day", "anden juledag" },
{ "Christmas Eve", "juleaften" },
{ "Easter", "p…ske" },
{ "Epiphany", "helligtrekongersdag" },
{ "Good Friday", "langfredag" },
{ "Halloween", "allehelgensaften" },
{ "Maundy Thursday", "sk†rtorsdag" },
{ "Palm Sunday", "palmes°ndag" },
{ "Pentecost", "pinse" },
{ "Shrove Tuesday", "hvidetirsdag" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,33 @@
// HolidayBundle_da_DK
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_da_DK extends ListResourceBundle
{
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
new SimpleHoliday(Calendar.APRIL, 30, -Calendar.FRIDAY, "General Prayer Day"),
new SimpleHoliday(Calendar.JUNE, 5, "Constitution Day"),
SimpleHoliday.CHRISTMAS_EVE,
SimpleHoliday.CHRISTMAS,
SimpleHoliday.BOXING_DAY,
SimpleHoliday.NEW_YEARS_EVE,
// Easter and related holidays
EasterHoliday.MAUNDY_THURSDAY,
EasterHoliday.GOOD_FRIDAY,
EasterHoliday.EASTER_SUNDAY,
EasterHoliday.EASTER_MONDAY,
EasterHoliday.ASCENSION,
EasterHoliday.WHIT_MONDAY,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,62 @@
// German names for holidays
package com.ibm.util.resources;
import java.util.ListResourceBundle;
public class HolidayBundle_de extends ListResourceBundle {
static private final Object[][] fContents = {
{ "All Saints' Day", "Allerheiligen" },
{ "All Souls' Day", "Allerseelen" },
{ "Armistice Day", "Waffenstillstandstag" },
{ "Ascension", "Christi Himmelfahrt" },
{ "Ash Wednesday", "Aschermittwoch" },
{ "Assumption", "Mari„ Himmelfahrt" },
{ "Boxing Day", "2. Weihnachtstag" },
{ "Carnival", "Karneval" },
{ "Christmas", "Weihnachtstag" },
{ "Civic Holiday", "Brgerfeiertag" },
{ "Constitution Day", "Verfassungstag" },
{ "Corpus Christi", "Fronleichnam" },
{ "Day of Prayer and Repentance", "Buž- und Bettag" },
{ "Easter Monday", "Ostermonntag" },
{ "Easter Sunday", "Ostersonntag" },
{ "Epiphany", "Heilige 3 K÷nige" },
{ "Father's Day", "Vatertag" },
{ "Flag Day", "Jahrestag der Nationalflagge" },
{ "German Unity Day", "Tag der deutschen Einheit" },
{ "Good Friday", "Karfreitag" },
{ "Halloween", "Abend vor Allerheiligen" },
{ "Immaculate Conception", "Mari„ Empf„ngnis" },
{ "Independence Day", "Unabh„ngigkeitstag" },
{ "Labor Day", "Tag der Arbeit" },
{ "Liberation Day", "Befreiungstag" },
{ "Mardi Gras", "Faschingsdienstag" },
{ "Maundy Thursday", "Grndonnerstag" },
{ "May Day", "Maifeiertag" },
{ "Memorial Day", "Tag des Gedenkens" },
{ "Mother's Day", "Muttertag" },
{ "National Holiday", "Nationalfeiertag" },
{ "New Year's Day", "Neujahr" },
{ "New Year's Eve", "Silvesterabend" },
{ "Palm Sunday", "Palmsonntag" },
{ "Pentecost", "Pfingsten" },
{ "Presidents' Day", "Pr„sidentstag" },
{ "Remembrance Day", "Volkstrauertag" },
{ "Revolution Day", "Jahrestag der Revolution" },
{ "Rose Monday", "Rosenmontag" },
{ "St. Stephen's Day", "Stephanitag" },
{ "Shrove Tuesday", "Faschingsdienstag" },
{ "Spring Holiday", "Tag des Frhlings" },
{ "Summer Bank Holiday", "Bankfeiertag" },
{ "Thanksgiving", "Dankfest" },
{ "Unity Day", "Einheitstag" },
{ "Veterans' Day", "Veteranstag" },
{ "Victory Day", "Tag der Befreiung" },
{ "Washington's Birthday", "Washingtons Geburtstag" },
{ "Whit Monday", "Pfingstmontag" },
{ "Whit Sunday", "Pfingstsonntag" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,38 @@
// Austrian holidays
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_de_AT extends ListResourceBundle {
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
SimpleHoliday.EPIPHANY,
EasterHoliday.GOOD_FRIDAY,
EasterHoliday.EASTER_SUNDAY,
EasterHoliday.EASTER_MONDAY,
EasterHoliday.ASCENSION,
EasterHoliday.WHIT_SUNDAY,
EasterHoliday.WHIT_MONDAY,
EasterHoliday.CORPUS_CHRISTI,
SimpleHoliday.ASSUMPTION,
SimpleHoliday.ALL_SAINTS_DAY,
SimpleHoliday.IMMACULATE_CONCEPTION,
SimpleHoliday.CHRISTMAS,
SimpleHoliday.ST_STEPHENS_DAY,
new SimpleHoliday(Calendar.MAY, 1, 0, "National Holiday"),
new SimpleHoliday(Calendar.OCTOBER, 31, -Calendar.MONDAY, "National Holiday"),
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
// Only holidays names different from those used in Germany are listed here
{ "Christmas", "Christtag" },
{ "New Year's Day", "Neujahrstag" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,33 @@
// HolidayBundle_de_DE.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_de_DE extends ListResourceBundle {
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
SimpleHoliday.MAY_DAY,
new SimpleHoliday(Calendar.JUNE, 15, Calendar.WEDNESDAY, "Memorial Day"),
new SimpleHoliday(Calendar.OCTOBER, 3, 0, "Unity Day"),
SimpleHoliday.ALL_SAINTS_DAY,
new SimpleHoliday(Calendar.NOVEMBER, 18, 0, "Day of Prayer and Repentance"),
SimpleHoliday.CHRISTMAS,
SimpleHoliday.BOXING_DAY,
// Easter and related holidays
EasterHoliday.GOOD_FRIDAY,
EasterHoliday.EASTER_SUNDAY,
EasterHoliday.EASTER_MONDAY,
EasterHoliday.ASCENSION,
EasterHoliday.WHIT_SUNDAY,
EasterHoliday.WHIT_MONDAY,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,26 @@
// HolidayBundle_el.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_el extends ListResourceBundle {
static private final Object[][] fContents =
{
{ "Assumption", "15 \u0391\u03cd\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5" },
{ "Boxing Day", "\u0394\u03b5\u03cd\u03c4\u03b5\u03c1\u03b7 \u03bc\u03ad\u03c1\u03b1 \u03c4\u03ce\u03bd \u03a7\u03c1\u03b9\u03c3\u03c4\u03bf\u03c5\u03b3\u03ad\u03bd\u03bd\u03c9\u03bd" },
{ "Christmas", "\u03a7\u03c1\u03b9\u03c3\u03c4\u03bf\u03cd\u03b3\u03b5\u03bd\u03bd\u03b1" },
{ "Clean Monday", "\u039a\u03b1\u03b8\u03b1\u03c1\u03ae \u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1" },
{ "Easter Monday", "\u0394\u03b5\u03cd\u03c4\u03b5\u03c1\u03b7 \u03bc\u03ad\u03c1\u03b1 \u03c4\u03bf\u03cd \u03a0\u03ac\u03c3\u03c7\u03b1" },
{ "Epiphany", "\u0388\u03c0\u03b9\u03c6\u03ac\u03bd\u03b5\u03b9\u03b1" },
{ "Good Friday", "\u039c\u03b5\u03b3\u03ac\u03bb\u03b7 \u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae" },
{ "May Day", "\u03a0\u03c1\u03c9\u03c4\u03bf\u03bc\u03b1\u03b3\u03b9\u03ac" },
{ "New Year's Day", "\u03a0\u03c1\u03c9\u03c4\u03bf\u03c7\u03c1\u03bf\u03bd\u03b9\u03ac" },
{ "Ochi Day", "28 \u038c\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5" },
{ "Whit Monday", "\u0394\u03b5\u03cd\u03c4\u03b5\u03c1\u03b7 \u03bc\u03ad\u03c1\u03b1 \u03c4\u03bf\u03cd \u03a0\u03b5\u03bd\u03c4\u03b7\u03ba\u03bf\u03c3\u03c4\u03ae" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,34 @@
// HolidayBundle_el_GR.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_el_GR extends ListResourceBundle {
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
SimpleHoliday.EPIPHANY,
new SimpleHoliday(Calendar.MARCH, 25, 0, "Independence Day"),
SimpleHoliday.MAY_DAY,
SimpleHoliday.ASSUMPTION,
new SimpleHoliday(Calendar.OCTOBER, 28, 0, "Ochi Day"),
SimpleHoliday.CHRISTMAS,
SimpleHoliday.BOXING_DAY,
// Easter and related holidays in the Orthodox calendar
new EasterHoliday(-2, true, "Good Friday"),
new EasterHoliday( 0, true, "Easter Sunday"),
new EasterHoliday( 1, true, "Easter Monday"),
new EasterHoliday(50, true, "Whit Monday"),
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,24 @@
// HolidayBundle.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.ListResourceBundle;
public class HolidayBundle_en extends ListResourceBundle {
// Normally, each HolidayBundle uses the holiday's US English name
// as the string key for looking up the localized name. This means
// that the key itself can be used if no name is found for the requested
// locale.
//
// For holidays where the key is _not_ the English name, e.g. in the
// case of conflicts, the English name must be given here.
//
static private final Object[][] fContents = {
{ "", "" }, // Can't be empty!
};
public synchronized Object[][] getContents() { return fContents; };
};

View file

@ -0,0 +1,35 @@
// HolidayBundle_en_CA
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_en_CA extends ListResourceBundle {
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
new SimpleHoliday(Calendar.MAY, 19, 0, "Victoria Day"),
new SimpleHoliday(Calendar.JULY, 1, 0, "Canada Day"),
new SimpleHoliday(Calendar.AUGUST, 1, Calendar.MONDAY, "Civic Holiday"),
new SimpleHoliday(Calendar.SEPTEMBER, 1, Calendar.MONDAY, "Labor Day"),
new SimpleHoliday(Calendar.OCTOBER, 8, Calendar.MONDAY, "Thanksgiving"),
new SimpleHoliday(Calendar.NOVEMBER, 11, 0, "Remembrance Day"),
SimpleHoliday.CHRISTMAS,
SimpleHoliday.BOXING_DAY,
SimpleHoliday.NEW_YEARS_EVE,
// Easter and related holidays
//hey {jf} - where are these from?
// EasterHoliday.GOOD_FRIDAY,
// EasterHoliday.EASTER_SUNDAY,
// EasterHoliday.EASTER_MONDAY,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
{ "Labor Day", "Labour Day" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,31 @@
// HolidayBundle_en_GB
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_en_GB extends ListResourceBundle
{
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
SimpleHoliday.MAY_DAY,
new SimpleHoliday(Calendar.MAY, 31, -Calendar.MONDAY, "Spring Holiday"),
new SimpleHoliday(Calendar.AUGUST, 31, -Calendar.MONDAY, "Summer Bank Holiday"),
SimpleHoliday.CHRISTMAS,
SimpleHoliday.BOXING_DAY,
new SimpleHoliday(Calendar.DECEMBER, 31, -Calendar.MONDAY, "Christmas Holiday"),
// Easter and related holidays
EasterHoliday.GOOD_FRIDAY,
EasterHoliday.EASTER_SUNDAY,
EasterHoliday.EASTER_MONDAY,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
{ "Labor Day", "Labour Day" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,41 @@
// HolidayBundle_en_US
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_en_US extends ListResourceBundle
{
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
new SimpleHoliday(Calendar.JANUARY, 15, Calendar.MONDAY, "Martin Luther King Day", 1986),
new SimpleHoliday(Calendar.FEBRUARY, 15, Calendar.MONDAY, "Presidents' Day", 1976),
new SimpleHoliday(Calendar.FEBRUARY, 22, "Washington's Birthday", 1776, 1975),
EasterHoliday.GOOD_FRIDAY,
EasterHoliday.EASTER_SUNDAY,
new SimpleHoliday(Calendar.MAY, 8, Calendar.SUNDAY, "Mother's Day", 1914),
new SimpleHoliday(Calendar.MAY, 31, -Calendar.MONDAY, "Memorial Day", 1971),
new SimpleHoliday(Calendar.MAY, 30, "Memorial Day", 1868, 1970),
new SimpleHoliday(Calendar.JUNE, 15, Calendar.SUNDAY, "Father's Day", 1956),
new SimpleHoliday(Calendar.JULY, 4, "Independence Day", 1776),
new SimpleHoliday(Calendar.SEPTEMBER, 1, Calendar.MONDAY, "Labor Day", 1894),
new SimpleHoliday(Calendar.NOVEMBER, 2, Calendar.TUESDAY, "Election Day"),
new SimpleHoliday(Calendar.OCTOBER, 8, Calendar.MONDAY, "Columbus Day", 1971),
new SimpleHoliday(Calendar.OCTOBER , 31, "Halloween"),
new SimpleHoliday(Calendar.NOVEMBER, 11, "Veterans' Day", 1918),
new SimpleHoliday(Calendar.NOVEMBER, 22, Calendar.THURSDAY, "Thanksgiving", 1863),
SimpleHoliday.CHRISTMAS,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,46 @@
// Spanish holiday names
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.ListResourceBundle;
public class HolidayBundle_es extends ListResourceBundle {
static private final Object[][] fContents = {
{ "All Saints' Day", "Todos los Santos" },
{ "Armistice Day", "D嵈 del Armisticio" },
{ "Ascension", "Ascensin" },
{ "Benito Ju腤ez Day", "D嵈 de la Benito Ju腤ez" },
{ "Boxing Day", "D嵈 en que se dan Aguinaldos Navide得s" },
{ "Canada Day", "D嵈 del Canad<61>" },
{ "Christmas Eve", "Visperas de Navidad" },
{ "Christmas", "Navidad" },
{ "Constitution Day", "D嵈 de la Constitucin" },
{ "Day of the Dead", "D嵈 de los Muertos" },
{ "Easter Sunday", "Pascua" },
{ "Easter Monday", "Pascua Lunes" },
{ "Epiphany", "Epifan嵈" },
{ "Father's Day", "D嵈 del Padre" },
{ "Flag Day", "D嵈 de la Bandera" },
{ "Good Friday", "Viernes Santo" },
{ "Halloween", "v峥pera de Todos los Santos" },
{ "Independence Day", "D嵈 de la Independencia" },
{ "Labor Day", "D嵈 de Trabajadores" },
{ "Maundy Thursday", "Jueves Santo" },
{ "May Day", "Primero de Mayo" },
{ "Memorial Day", "D嵈 de la Rememoracin" },
{ "Mother's Day", "D嵈 de la Madre" },
{ "New Year's Day", "A得 Nuevo" },
{ "Palm Sunday", "Domingo de Ramos" },
{ "Pentecost", "Pentecost统" },
{ "Presidents' Day", "D嵈 de Presidentes" },
{ "Revolution Day", "D嵈 de la Revolucin" },
{ "Shrove Tuesday", "Martes de Carnaval" },
{ "Thanksgiving", "D嵈 de Accin de Gracias" },
{ "Veterans' Day", "D嵈 de Veteranos" },
{ "Victoria Day", "D嵈 de Victoria" },
{ "Whit Sunday", "Pentecost统" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,29 @@
// HolidayBundle_es_MX.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_es_MX extends ListResourceBundle {
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
new SimpleHoliday(Calendar.FEBRUARY, 5, 0, "Constitution Day"),
new SimpleHoliday(Calendar.MARCH, 21, 0, "Benito Jußrez Day"),
SimpleHoliday.MAY_DAY,
new SimpleHoliday(Calendar.MAY, 5, 0, "Cinco de Mayo"),
new SimpleHoliday(Calendar.JUNE, 1, 0, "Navy Day"),
new SimpleHoliday(Calendar.SEPTEMBER, 16, 0, "Independence Day"),
new SimpleHoliday(Calendar.OCTOBER, 12, 0, "D<EFBFBD>a de la Raza"),
SimpleHoliday.ALL_SAINTS_DAY,
new SimpleHoliday(Calendar.NOVEMBER, 2, 0, "Day of the Dead"),
new SimpleHoliday(Calendar.NOVEMBER, 20, 0, "Revolution Day"),
new SimpleHoliday(Calendar.DECEMBER, 12, 0, "Flag Day"),
SimpleHoliday.CHRISTMAS,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,39 @@
// HolidayBundle_fr.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.ListResourceBundle;
public class HolidayBundle_fr extends ListResourceBundle {
static private final Object[][] fContents = {
{ "All Saints' Day", "Toussaint" },
{ "Armistice Day", "Jour de l'Armistice" },
{ "Ascension", "Ascension" },
{ "Bastille Day", "FŠte de la Bastille" },
{ "Benito Jußrez Day", "FŠte de Benito Jußrez" },
{ "Boxing Day", "Lendemain de Nol" },
{ "Christmas Eve", "Veille de Nol" },
{ "Christmas", "Nol" },
{ "Easter Monday", "Pques lundi" },
{ "Easter Sunday", "Pques" },
{ "Epiphany", "l'Ðpiphanie" },
{ "Flag Day", "FŠte du Drapeau" },
{ "Good Friday", "Vendredi Saint" },
{ "Halloween", "Veille de la Toussaint" },
{ "All Saints' Day", "Toussaint" },
{ "Independence Day", "FŠte Ind‰pendance" },
{ "Maundy Thursday", "Jeudi Saint" },
{ "Mother's Day", "FŠte des mˆres" },
{ "National Day", "FŠte Nationale" },
{ "New Year's Day", "Jour de l'an" },
{ "Palm Sunday", "les Rameaux" },
{ "Pentecost", "PentecŸte" },
{ "Shrove Tuesday", "Mardi Gras" },
{ "St. Stephen's Day", "Saint-Ðtienne" },
{ "Victoria Day", "FŠte de la Victoria" },
{ "Victory Day", "FŠte de la Victoire" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,32 @@
// HolidayBundle_fr_CA
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_fr_CA extends ListResourceBundle {
static private final Holiday[] fHolidays = {
new SimpleHoliday(Calendar.JANUARY, 1, 0, "New Year's Day"),
new SimpleHoliday(Calendar.MAY, 19, 0, "Victoria Day"),
new SimpleHoliday(Calendar.JUNE, 24, 0, "National Day"),
new SimpleHoliday(Calendar.JULY, 1, 0, "Canada Day"),
new SimpleHoliday(Calendar.AUGUST, 1, Calendar.MONDAY, "Civic Holiday"),
new SimpleHoliday(Calendar.SEPTEMBER, 1, Calendar.MONDAY, "Labour Day"),
new SimpleHoliday(Calendar.OCTOBER, 8, Calendar.MONDAY, "Thanksgiving"),
new SimpleHoliday(Calendar.NOVEMBER, 11, 0, "Remembrance Day"),
SimpleHoliday.CHRISTMAS,
SimpleHoliday.BOXING_DAY,
SimpleHoliday.NEW_YEARS_EVE,
// Easter and related holidays
EasterHoliday.GOOD_FRIDAY,
EasterHoliday.EASTER_SUNDAY,
EasterHoliday.EASTER_MONDAY,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,31 @@
// HolidayBundle_fr_FR
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_fr_FR extends ListResourceBundle {
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
new SimpleHoliday(Calendar.MAY, 1, 0, "Labor Day"),
new SimpleHoliday(Calendar.MAY, 8, 0, "Victory Day"),
new SimpleHoliday(Calendar.JULY, 14, 0, "Bastille Day"),
SimpleHoliday.ASSUMPTION,
SimpleHoliday.ALL_SAINTS_DAY,
new SimpleHoliday(Calendar.NOVEMBER, 11, 0, "Armistice Day"),
SimpleHoliday.CHRISTMAS,
// Easter and related holidays
EasterHoliday.EASTER_SUNDAY,
EasterHoliday.EASTER_MONDAY,
EasterHoliday.ASCENSION,
EasterHoliday.WHIT_SUNDAY,
EasterHoliday.WHIT_MONDAY,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,32 @@
// HolidayBundle_it.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_it extends ListResourceBundle {
static private final Object[][] fContents =
{
{ "All Saints' Day", "Ognissanti" },
{ "Armistice Day", "armistizio" },
{ "Ascension", "ascensione" },
{ "Ash Wednesday", "mercoledŒ delle ceneri" },
{ "Boxing Day", "Santo Stefano" },
{ "Christmas", "natale" },
{ "Easter Sunday", "pasqua" },
{ "Epiphany", "Epifania" },
{ "Good Friday", "venerdŒ santo" },
{ "Halloween", "vigilia di Ognissanti" },
{ "Maundy Thursday", "giovedŒ santo" },
{ "New Year's Day", "anno nuovo" },
{ "Palm Sunday", "domenica delle palme" },
{ "Pentecost", "di Pentecoste" },
{ "Shrove Tuesday", "martedi grasso" },
{ "St. Stephen's Day", "Santo Stefano" },
{ "Thanksgiving", "Giorno del Ringraziamento" },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,30 @@
// HolidayBundle_it_IT.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_it_IT extends ListResourceBundle {
static private final Holiday[] fHolidays = {
SimpleHoliday.NEW_YEARS_DAY,
SimpleHoliday.EPIPHANY,
new SimpleHoliday(Calendar.APRIL, 1, 0, "Liberation Day"),
new SimpleHoliday(Calendar.MAY, 1, 0, "Labor Day"),
SimpleHoliday.ASSUMPTION,
SimpleHoliday.ALL_SAINTS_DAY,
SimpleHoliday.IMMACULATE_CONCEPTION,
SimpleHoliday.CHRISTMAS,
new SimpleHoliday(Calendar.DECEMBER, 26, 0, "St. Stephens Day"),
SimpleHoliday.NEW_YEARS_EVE,
// Easter and related holidays
EasterHoliday.EASTER_SUNDAY,
EasterHoliday.EASTER_MONDAY,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,16 @@
// HolidayBundle_iw.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.ListResourceBundle;
public class HolidayBundle_iw extends ListResourceBundle {
static private final Object[][] fContents = {
{ "", "" }, // Can't be empty!
};
public synchronized Object[][] getContents() { return fContents; };
};

View file

@ -0,0 +1,24 @@
// HolidayBundle_iw_IL
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_iw_IL extends ListResourceBundle {
static private final Holiday[] fHolidays = {
HebrewHoliday.ROSH_HASHANAH,
HebrewHoliday.YOM_KIPPUR,
HebrewHoliday.HANUKKAH,
HebrewHoliday.PURIM,
HebrewHoliday.PASSOVER,
HebrewHoliday.SHAVUOT,
HebrewHoliday.SELIHOT,
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,17 @@
// HolidayBundle_jp_JP.java
package com.ibm.util.resources;
import com.ibm.util.*;
import java.util.Calendar;
import java.util.ListResourceBundle;
public class HolidayBundle_ja_JP extends ListResourceBundle {
static private final Holiday[] fHolidays = {
new SimpleHoliday(Calendar.FEBRUARY, 11, 0, "National Foundation Day"),
};
static private final Object[][] fContents = {
{ "holidays", fHolidays },
};
public synchronized Object[][] getContents() { return fContents; }
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: IslamicCalendarSymbols.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:56 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Default Date Format symbols for the Islamic Calendar
*/
public class IslamicCalendarSymbols extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998-1999 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Muharram",
"Safar",
"Rabi' I",
"Rabi' II",
"Jumada I",
"Jumada I",
"Rajab",
"Sha'ban",
"Ramadan",
"Shawwal",
"Dhu'l-Qi'dah",
"Dhu'l-Hijjah",
} },
{ "Eras", new String[] {
"AH"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: IslamicCalendarSymbols_ar.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:56 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Default Date Format symbols for the Islamic Calendar
*/
public class IslamicCalendarSymbols_ar extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1999 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"\u0645\u062D\u0631\u0645", // Muharram
"\u0635\u0641\u0631", // Safar
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644", // Rabi' I
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0622\u062E\u0631", // Rabi' II
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649", // Jumada I
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629", // Jumada I
"\u0631\u062C\u0628", // Rajab
"\u0634\u0639\u0628\u0627\u0646", // Sha'ban
"\u0631\u0645\u0636\u0627\u0646", // Ramadan
"\u0634\u0648\u0627\u0644", // Shawwal
"\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629", // Dhu'l-Qi'dah
"\u0630\u0648 \u0627\u0644\u062D\u062C\u0629", // Dhu'l-Hijjah
} },
{ "Eras", new String[] {
"\u0647\u200D", // AH
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: IslamicCalendarSymbols_fi.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:56 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Finnish date format symbols for the Islamic Calendar
*/
public class IslamicCalendarSymbols_fi extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Muh\u00E1rram", // Muharram
"S\u00E1far", // Safar
"Rab\u00ED' al-\u00E1wwal", // Rabi' al-awwal
"Rab\u00ED' al-\u00E1khir", // Rabi' al-thani
"D\u017Eumada-l-\u00FAla", // Jumada al-awwal
"D\u017Eumada-l-\u00E1khira", // Jumada al-thani
"Rad\u017Eab", // Rajab
"\u0160a'b\u00E1n", // Sha'ban
"Ramad\u00E1n", // Ramadan
"\u0160awwal", // Shawwal
"Dhu-l-qada", // Dhu al-Qi'dah
"Dhu-l-hidd\u017Ea", // Dhu al-Hijjah
} },
{ "Eras", new String[] {
"AH" // Anno Hid\u017Era
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,54 @@
/*
* $RCSfile: IslamicCalendarSymbols_fr.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:56 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* French date format symbols for the Islamic Calendar
* This data actually applies to French Canadian. If we receive
* official French data from our France office, we should move the
* French Canadian data (if it's different) down into _fr_CA
*/
public class IslamicCalendarSymbols_fr extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Mouharram", // Muharram
"Safar", // Safar
"Rabi'-oul-Aououal", // Rabi' al-awwal
"Rabi'-out-Tani", // Rabi' al-thani
"Djoumada-l-Oula", // Jumada al-awwal
"Djoumada-t-Tania", // Jumada al-thani
"Radjab", // Rajab
"Cha'ban", // Sha'ban
"Ramadan", // Ramadan
"Chaououal", // Shawwal
"Dou-l-Qa'da", // Dhu al-Qi'dah
"Dou-l-Hidjja", // Dhu al-Hijjah
} },
{ "Eras", new String[] {
"AH" // Anno Hijri
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: IslamicCalendarSymbols_hu.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:56 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Hungarian date format symbols for the Islamic Calendar
*/
public class IslamicCalendarSymbols_hu extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"Moharrem", // Muharram
"Safar", // Safar
"R\u00E9bi el avvel", // Rabi' al-awwal
"R\u00E9bi el accher", // Rabi' al-thani
"Dsem\u00E1di el avvel", // Jumada al-awwal
"Dsem\u00E1di el accher", // Jumada al-thani
"Redseb", // Rajab
"Sab\u00E1n", // Sha'ban
"Ramad\u00E1n", // Ramadan
"Sevv\u00E1l", // Shawwal
"Ds\u00FCl kade", // Dhu al-Qi'dah
"Ds\u00FCl hedse", // Dhu al-Hijjah
} },
{ "Eras", new String[] {
"MF"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

View file

@ -0,0 +1,51 @@
/*
* $RCSfile: IslamicCalendarSymbols_iw.java,v $ $Revision: 1.1 $ $Date: 2000/02/10 06:25:56 $
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*
*/
package com.ibm.util.resources;
import java.util.ListResourceBundle;
/**
* Default Date Format symbols for the Islamic Calendar
*/
public class IslamicCalendarSymbols_iw extends ListResourceBundle {
private static String copyright = "Copyright \u00a9 1998 IBM Corp. All Rights Reserved.";
static final Object[][] fContents = {
{ "MonthNames", new String[] {
"\u05DE\u05D5\u05D7\u05E8\u05DD", // Muharram
"\u05E1\u05E4\u05E8", // Safar
"\u05E8\u05D1\u05D9\u05E2 \u05D0\u05DC-\u05D0\u05D5\u05D5\u05D0\u05DC", // Rabi' al-awwal
"\u05E8\u05D1\u05D9\u05E2 \u05D0\u05DC-\u05EA\u05E0\u05D9", // Rabi' al-thani
"\u05D2'\u05D5\u05DE\u05D3\u05D4 \u05D0\u05DC-\u05D0\u05D5\u05D5\u05D0\u05DC", // Jumada al-awwal
"\u05D2'\u05D5\u05DE\u05D3\u05D4 \u05D0\u05DC-\u05EA\u05E0\u05D9", // Jumada al-thani
"\u05E8\u05D2'\u05D0\u05D1", // Rajab
"\u05E9\u05E2\u05D1\u05D0\u05DF", // Sha'ban
"\u05E8\u05D0\u05DE\u05D3\u05DF", // Ramadan
"\u05E9\u05D5\u05D5\u05D0\u05DC", // Shawwal
"\u05E9\u05D5\u05D5\u05D0\u05DC", // Dhu al-Qi'dah
"\u05D6\u05D5 \u05D0\u05DC-\u05D7\u05D9\u05D2'\u05D4", // Dhu al-Hijjah
} },
{ "Eras", new String[] {
"\u05E9\u05E0\u05EA \u05D4\u05D9\u05D2'\u05E8\u05D4"
} },
};
public synchronized Object[][] getContents() {
return fContents;
}
};

Some files were not shown because too many files have changed in this diff Show more