Global Programming with Java
™ 1.1Intro
n
Internationalization
n
Locales
n
ResourceBundlesl
The Big Picturel
The ResourceBundle Classl
Using ResourceBundlesl
Creating ResourceBundles
n
The java.text Packagel
The DateFormat Class (dates & times)l
The NumberFormat Class (general numbers & currency)l
The MessageFormat Class
n
Unicode
n
Conclusion
What is a Global Program?
One Way:
Better Way:
n
You must identify the locale-specific portions of your program during design
n
You must create the locale-specific objects for each locale you want to support
Some Terminology
I18N
Internationalization. Separating out the locale-dependent portions of a program.L10N
Localization. Adapting an internationalized program to a specific locale.Locale
A name for a set of user conventions forl
Languagel
Date & Time formattingl
Number & Currency formattingExample: "fr_CH" is French/Switzerland
The Locale Class
n
In package java.util
n
Locale objects constructed froml
A language code (ISO 639) such as "en", "fr", "es", etc.l
A country code (ISO 3166) such as "US", "CH", "GB", etc.l
A variant
n
Constants such as Locale.GERMANY, Locale.GERMAN, etc.
n
Class methodsl
GetDefault()l
setDefault(Locale newLocale)
n
Instance methods includel
getDisplayCountry()l
getDisplayCountry(Locale inLocale)
n
A Locale object indentifies a locale, that’s all!
Locales
|
ar Arabic (Egypt) be Belorussian (Belarus) bg Bulgarian (Bulgaria) ca Catalan (Spain) cs Czech (Czech Republic) da Danish (Denmark) de German (Germany) de_AT German (Austria) de_CH German (Switzerland) el Greek (Greece) en English (US) en_CA English (Canada) en_GB English (United Kingdom) en_IE English (Ireland) es Spanish (Spain) et Estonian (Estonia) fi Finnish (Finland) fr French (France) fr_BE French (Belgium) fr_CA French (Canada) fr_CH French (Switzerland) hr Croatian (Croatia) hu Hungarian (Hungary) is Icelandic (Iceland) it Italian (Italy) it_CH Italian (Switzerland)
|
iw Hebrew (Israel) ja Jananese (Japan) ko Korean (Korea) lt Lithuanian (Lituania) lv Latvian (Latvia) mk Macedonian (Macedonia) nl Dutch (Netherlands) nl_BE Dutch (Belgium) no Norwegian (Bokmål) no_NO_NY Norwegian pl Polish (Poland) pt Portuguese (Portugal) ro Romanian (Romania) ru Russian (Russia) sh Serbian (Latin) (Serbia) sk Slovak (Slovakia) sl Slovene (Slovenia) sq Albanian (Albania) sr Servian (Cyrillic) (Serbia) sv Swedish (Sweden) tr Turkish (Turkey) uk Ukranian (Ukraine) zh Chinese (China) zh_TW Chinese (ROC)
|
Locale Example
import java.util.Locale;
class Example01 {
public static void main(String[] args) {
String ans = Locale.getDefault().
getDisplayName(Locale.GERMANY);
System.out.println(ans);
}
}
Produces the following output (in the US):
Englisch (Vereinigte Staaten)
Resource Bundles
A ResourceBundle object translates a key into an object.
The Big Picture
You must create ResourceBundle classes for the Locales you want to support. Java helps you organize and use them.
The ResoureBundle Class
n
In package java.util
n
abstract
n
Class "factory" methodsl
getBundle(String baseName)l
getBundle(String baseName, Locale locale)where
baseName is the name you select when you create your resource bundles
n
Instance methods includel
GetObject(String key)l
GetString(String key)
n
A ResourceBundle object provides Locale-specific objects
Using ResourceBundles — 1
import java.util.Locale; import java.util.ResourceBundle;
public class Ultimate {
private static void dumpEm(Locale locale) {
System.out.println("Locale: " + locale);
ResourceBundle rb = ResourceBundle.getBundle
("UltPkg.UltB", locale);
System.out.println(" Title: " +
rb.getString("Title"));
System.out.println(" Button: " +
rb.getString("Button"));
System.out.println();
}
public static void main(String[] a) {
try {
System.setOut(new java.io.PrintStream
(new java.io.FileOutputStream("C:\\VANCE\\ANS")));
} catch (Exception e) {e.printStackTrace();}
dumpEm(Locale.getDefault());
dumpEm(new Locale("en","US"));
dumpEm(new Locale("en","US","Syracuse"));
dumpEm(new Locale("en","US","Rochester"));
dumpEm(new Locale("en","US","Utica"));
dumpEm(new Locale("en","CA"));
dumpEm(new Locale("en","GB"));
dumpEm(new Locale("fr","CA"));
dumpEm(new Locale("fr","BE"));
dumpEm(Locale.FRENCH);
}
}
Using ResourceBundles — 2
Output
Locale: en_US
Title: "Title in US English."
Button: "US is great!"
Locale: en_US
Title: "Title in US English."
Button: "US is great!"
Locale: en_US_SYRACUSE
Title: "Title in US English."
Button: "Syracuse is great!"
Locale: en_US_ROCHESTER
Title: "Title in US English."
Button: "Rochester is great!"
Locale: en_US_UTICA
Title: "Title in US English."
Button: "US is great!"
Locale: en_CA
Title: "Title in Canadian English."
Button: "Canada is great!"
Locale: en_GB
Title: "Don't know what language to use."
Button: "Unsupported locale."
Locale: fr_CA
Title: "Title in French Canadian."
Button: "Canada est bon!"
Locale: fr_BE
Title: "En francais."
Button: "Ici est bon!"
Locale: fr
Title: "En francais."
Button: "Ici est bon!"
Property Files
If all your resources are Strings, simply create property files.
UltPkg.UltB
Title="Don't know what language to use."
Button="Unsupported locale."
UltPkg.UltB_en_CA
Title="Title in Canadian English."
Button="Canada is great!"
UltPkg.UltB_en_US
Title="Title in US English."
Button="US is great!"
UltPkg.UltB_en_US_Syracuse
Button="Syracuse is great!"
UltPkg.UltB_en_US_Rochester
Button="Rochester is great!"
UltPkg.UltB_fr
Title="En francais."
Button="Ici est bon!"
UltPkg.UltB_fr_CA
Title="Title in French Canadian."
Button="Canada est bon!"
The ListResourceBundle Class
If your ResourceBundles need to contain other objects besides Strings, use the ListResourceBundle class.
public class UltimateBundle extends java.util.ListResourceBundle {
private java.awt.Button button_1 =
new java.awt.Button("Button in English-US");
Object[][] contents ={{"Title","Title in English"},
{"Button", button_1}};
// Required method.
protected Object[][] getContents() {
return (contents);
}
}
Questions
1. What would the output of main be if the Locale were set to "tr" (Turkey)?
2. If you create multiple resource bundles, do you get multiple resources?
3. What would happen if you invoked
getObject with a key that wasn’t handled by your resource bundle?4. How would you modify the design to support the Locales fr and fr_BE (French and French-Belgium)?
5. What would happen if you didn’t put the resource bundles in their own package?
On to international text manipulation ...
The DateFormat Class
n
In package java.text
n
Includes a class method getAvailableLocales()
n
A DateFormat object is used to read and write dates
n
A DateFormat object can be obtained from various factory methods in the class, includingl
getDateInstance()l
getDateInstance(int style)l
getDateInstance(int style, Locale aLocale)where
style is DEFAULT, FULL, LONG, MEDIUM, or SHORT
n
Exampleimport java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
class DateIt {
public static void main (String[] a) {
DateFormat df = DateFormat.getDateInstance
(DateFormat.SHORT,Locale.UK);
System.out.println(df.format(new Date()));
}
}
23/09/97
The NumberFormat Class
n
In package java.text
n
Includes a class method getAvailableLocales()
n
A NumberFormat object is used to read and write currency, numbers, and percents
n
A NumberFormat object can be obtained from various factory methods in the class, includingl
getCurrencyInstance(Locale inLocale)l
getNumberInstance(Locale inLocale)l
getPercentInstance(Locale inLocale)
n
Example
import java.text.NumberFormat;
import java.util.Locale;
class CashIt {
public static void main(String[] a) {
NumberFormat nf = NumberFormat.
getCurrencyInstance(Locale.UK);
System.out.println(nf.format(5.5));
}
}
ú5.50 (should have been £5.50)
The MessageFormat Class
n
In package java.text
n
Provides functionality similar to printf() in C
n
Example
import java.text.MessageFormat;
class PrintIt {
public static void main(String[] a) {
Object[] numbers = {"1","2","3"};
System.out.println(MessageFormat.format
("{0} plus {1} is {2}", numbers));
}
}
1 plus 2 is 3
The Char Type
n
A char value in Java is 16 bits so characters and strings in any language may be represented using the Unicode standard.|
Range |
Alphabet |
|
0x0000 — 0x007f |
Basic Latin (ASCII) |
|
0x0080 — 0x00ff |
Latin-1 Supplement |
|
etc |
... |
n
The Unicode standard defines a mapping from 16-bit numbers to names (not visual representations)0x0041
0x0f40
« TIBETAN LETTER KA
n
Fonts map numbers to glyphs (or BELL, DELETE, etc.). A glyph is a visual representation.0x0041
0x0f40
«l
A font may only provide unique glyphs for 7 or 8-bit numbers. It may map other numbers mod 128 or 256.l
A font may map a number to a glyph that has no relation to the Unicode name for that number.
Conclusion: You can’t use Java to print Japanese, Hebrew, Greek, whatever unless you have the right font.
Netscape 3.0 Unicode Support
Latin-1, Latin-2, Chinese, Japanese, and Korean are supported in Netscape 3.0 as long as the required characters can be rendered with an existing system font.

Example:
System.out.println("\u00c5ngstrom"); // prints Ångstrom
Creating Java Source
The Java Language Specification states "Java programs are written using the Unicode character set."
In fact, Java source may be written
l
In ASCII (each character takes 8 bits)l
In Unicode (each character takes 16 bits)
Java source written in Unicode could, for example, contain variable names in Korean.
To compile Java source written in Unicode with an ASCII-based compiler, the source must first be translated into ASCII. Each non-ASCII Unicode character is translated into a Unicode escape.
We may write Java source in ASCII as if it were translated from Unicode.
Example:
class UniTest {
int \u00c5ngstrom;
}
compiles. The variable name is Ångstrom.
Java Source Example
An Israeli with the right font could write "Hello World" like this:
public static void main(String[
] System.out.println("
");
}
}
Conclusion
It’s not to soon
to start internationalizing
your Java applications
and applets!