★ wanayoo — archive 1999 http://ibm.com/java/education/international-unicode/unicode2.2.htmlNouvelle recherche | Portail wanayoo

Introduction to IBM Classes for Unicode


2.2 Translate Strings

The first step to take in preparing your program is to enable translation of display strings by separating them from the rest of your code. This is done via ResourceBundles . These provide a general mechanism that allows you to access strings and other objects according to locale conventions. In principle, they are fairly simple: They simply provide a mapping from <key,locale> to <value>. However, they also supply inheritance among locale resources that allows you to minimize duplication across countries, and gives you a graceful degradation in case the exact locale does not have localized resources. As you will see, the use of ResourceBundles requires a different syntax in Java then it does in C++ (and thus C).

Unfortunately, at this point in time, you will have to change your code by hand to make your strings translatable. You can do the bulk of the work with a PERL script if you want, but you will still have to check the results. The general problem with converting strings automatically is the difficulty in distinguishing display strings from non-display strings. In the case of Java, once the commercial Java development environments fully support resource bundles, this task should become easier, since they will make it easy to avoid mixing display strings in the code in the first place.

Resource bundles do not have the same meaning in Java as they do in C/C++. In Java, they are both the object and the class file (compiled format) storing relevant localized information. In C/C++ a Resource Bundle is the object that allows your programs to interface with a text format resource file containing relevant localized information.

Resource bundles in Java are very flexible--so flexible that getting started may be mystifying. You can use list resource bundles, property resource bundles, or you can make your own. You can have fine-grained bundles or coarse-grained, and so on. To give you some direction, we'll start by showing one particular way to use resource bundles, you can see other options by looking at the JDK API.

Making a ResourceBundle in Java

In Java, create a class called MyResources.

A French resource bundle might contain the following

 Java

public class MyResources extends ListResourceBundle {

// boilerplate

public static ResourceBundle rb = ResourceBundle.getBundle("MyResources");

public Object[][] getContents() { return contents; }

static final Object[][] contents = {

{"Greeting", "Bonjour"},

{"Thanks", "Merci"}

{"DayAbreviations",

new String[] {

"dim.", "lun.", "mar.",

"mer.", "jeu.", "ven.", "sam."

}

}

};

}

//rb is a convenience for getting resource bundle objects 
//getContents is required in all ListResourceBundles 
//contents will hold localization data, as we'll see later

 

Making a ResourceBundle in C++/C

The resource bundle file is a text (ASCII or Unicode) file with the format:

"Key1" {Value1} 
"Key2" {Value2} 

The keys are used to retrieve the value later. You may not have multiple instances of the same key.  
e.g. A French Locale file might contain the following: 

C/C++

"Greeting" {"Bonjour"} 
"Thanks" {"Merci"} 
"DayAbbreviations" {

"dim.", "lun.", "mar.",

"mer.", "jeu.", "ven.", "sam." 

Four value types are supported. These are solitary strings, comma-delimited lists of strings, 2-dimensional arrays of strings, and tagged lists of strings. See Appendix C for more details.

Moving Strings to Resource Bundles

Move the text for display strings into resource bundles. Instead of hard coding the display string, the new code will use a resource bundle and a key to look up the localized display strings.

    Java

Old
display("Clean ink cartridge before printing document");
new
display(MyResources.rb.getString("CleanCartridge"));
Resource Bundle
quot;CleanCartridge", "Clean ink cartridge before printing document"},

   

C++

Old
display("Clean ink cartridge before printing document");
new
rb.getString("CleanCartridge", uniString, err); 
display(uniString); 

     

C

Old
display("Clean ink cartridge before printing document");
new
T_ResourceBundle_getString(rb,"CleanCartridge",uniString,&err); 
display(uniString);

 
 

C/C++ Resource Bundle

"CleanCartridge" {"Clean ink cartridge before printing document"}

 

You have now set up a series of resource pairs of the form "{key, value}" in Java and"key1 {value1)" in C/C++). The resource key (such as "CleanCartridge") can be any unique string you want, even the original string. However, you are better off using short, clear names: remember that your translators will be seeing these too.

Translating Resource Bundles

In Java,

To then create a new French translation for your program in Java:

  • Copy MyResources.java and rename it to MyResources_fr.java by appending the proper Java language ID. (You can see a list of the language IDs on the Unicode Web site. By convention, language codes are lowercased.)
    • Make it extend its parent, MyResources.
    • Remove the static rb (you only want this on the root class).
    • Translate the resource values into French (but not the keys!).
    • If any of the values are unchanged--the same as the parent--remove the whole {key, value} pair. (You can do this because the {key, value} pairs are inherited from the parent.)
    • Do the same again for any other language you want to support.
    • Once you have set up a resource Bundle, replace literal strings in your code by accessing the resource bundle (The literal strings are moved to the resource bundle)

    If you have special strings for a particular country--and not just language--then you do much the same as above.

  • Create a bundle in the same way for that country, such as MyResources_fr_BE for Belgium, by appending the proper Java country ID (You can see a list of the country IDs on the Unicode Web site By convention, country codes are uppercased.)
    • Make it extend its parent; in this case, MyResources_fr
    • If any of the values are unchanged--the same as the parent--remove the whole {key, value} pair.

 

Java Resource Bundle

English
//MyResources.java

public class MyResources extends ListResourceBundle {

// boilerplate

public static ResourceBundle rb = ResourceBundle.getBundle("MyResources");

public Object[][] getContents() { return contents; }

static final Object[][] contents = {

{"CleanCartridge", "Clean ink cartridge before printing document"}

};

}

French 
//MyResources_fr.java

public class MyResources_fr extends MyResources {

public Object[][] getContents() { return contents; }

static final Object[][] contents = {

{"CleanCartridge", "Nettoyez la cartouche d'encre avant d'inprimer votre document"}

};

}

French (Belgium)
//MyResources_fr_BE.java

public class MyResources_fr_BE extends MyResources_fr {

public Object[][] getContents() { return contents; }

static final Object[][] contents = {

{"CleanCartridge", "Citoyens Belges: Nettoyez la cartouche d'encre avant d'inprimer votre document"}

};

}

 

If your resource bundle gets too large then you can subdivide it into other resource bundles, such as myPrintingResources following the same pattern. You can make this as fine-grained as you want, so that you only load the resources for a part of your program when that part gets used. You can return arbitrary objects, not only strings, since it is often easier (and sometimes necessary, such as for graphics that need to be localized).

In C++ and C,

To then create a new French translation for your program in C++ or C:

  • Make sure that a locale file is present in the specified directory with the appropriate language ID.(You can see a list of the language IDs on the Unicode Web site. By convention, language codes are lowercased.).
  • Create an ResourceBundle object that will allow your program to interface with the information in the Resource bundle file

If more specific locale is available for a language, create a file with a more specific Locale ID name, containing the appropriate information.

 

C/C++ Resource Bundle

English
//in MyResources.txt 

"CleanCartridge" {"Clean ink cartridge before printing document"},

French 
//in MyResources_fr.txt 

"CleanCartridge" {"Nettoyez la cartouche d'encre avant d'inprimer votre document"},

French (Belgium)
//in MyResources_fr_BE.txt 

"CleanCartridge" {"Citoyens Belges: Nettoyez la cartouche d'encre avant d'inprimer votre document"},

 

Moving Objects to Resource Bundles in Java

For convenience, and because the Java language allows it, you can store localized objects in resource bundles in Java as the following example shows in Java you can store objects in Resource Bundles:

 

Java

Old
MyCheckbox = new Checkbox("Clean ink cartridge before printing document");
New
MyCheckbox = (Checkbox) MyResources.rb.getObject("CleanCartridge");
Resource Bundle
{"CleanCartridge", new Checkbox("Clean ink cartridge before printing document")}, 
...




JavaTM is a trademark of Sun Microsystems, Inc.

Microsoft is a registered trademark of Microsoft Corporation.

Other companies, products, and service names may be trademarks or service marks of others.

Copyright    Trademark



IBM HomeOrderEmployment