An Example Program: Before And After Internationalization

1. Before Internationalization

Most programs that are written in one particular language and locale (in our case English), and have text hard-coded into the program code. As an example, you have written the following program entitled "NotInternationalized":

public class NotInternationalized {
    static public void main(String[] args) {
        System.out.println("Hello.");
    }
}

You would like this program to display the same messages for users in Germany and France. Since you do not know German and French, you will need to hire a translator, and since the translator will not be used to looking at the code, and the text that needs to be translated needs to be moved into a separate file. Also, you are interested in translating this program into other languages in the future. The best method of efficiently translating these messages is to internationalize the program.

2. After Internationalization

The program after internationalization looks like the following example. The messages are not hardcoded into the program.

import java.util.*;
public class InternationalizedSample {
    static public void main(String[] args) {
        String language;
        String country;
        if (args.length != 2) {
            language = new String("en");
            country = new String("US");
        } else {
            language = new String(args[0]);
            country = new String(args[1]);
        }
        Locale currentLocale;
        ResourceBundle messages;
        currentLocale = new Locale(language, country);
        messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);
        System.out.println(messages.getString("greetings"));
    }
}

Java Internationalizing the Sample Program

As you can see, the internationalized source code has the hardcoded messages removed. The language is specified at run time, therefore, the program can be distributed worldwide. The steps for creating the internationalized program is as follows:

1. Create the Properties Files

A properties file stores the text that needs to be translated. The properties file is in plain-text format, and can be created using any text editor. We will name the properties file MessagesBundle.properties, and it has the following text:

greetings = Hello

We will create a new properties file for every language that we would like the text translated to. For the French text, we will create the MessagesBundle_fr_FR.properties file. MessagesBundle_fr_FR.properties file contains the fr language code and the FR country code, and contains these lines:

greetings = Bonjour.

The values on the left sign of the equal sign are called "keys", and these remain the same in every properties file. These are the references that the globalized program uses to call the values in a particular language.

2. Define the Locale

A Locale object specified a particular region and language. A Locale for the English language and the United States is as follows:

aLocale = new Locale("en","US");

To create Locale objects for the French language in Canada and France, we have the following:

caLocale = new Locale("fr","CA");

frLocale = new Locale("fr","FR");

The internationalized program gets the hardcoded language and country codes from the command line at run time:

String language = new String(args[0]);

String country = new String(args[1]);

currentLocale = new Locale(language, country);

Specifying a local only identifies a region and language. For other functions, additional code must be written to format dates, numbers, currencies, time zones, etc. These objects are locale-sensitive because their behavior varies according to Locale. A ResourceBundle is an example of a locale-sensitive object.

3. Create a ResourceBundle

A ResourceBundle contains locale-specific objects like translatable text. The ResourceBundle uses properties files that contain the text to be displayed. The ResourceBundle is created as follows:

messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);

There are two inputs to the getBundle method: the properties file and the locale. "MessagesBundle" refers to the family of properties files:

MessagesBundle_en_US.properties

MessagesBundle_fr_FR.properties

MessagesBundle_de_DE.properties

The locale will specify which MessagesBundle files is chosen using the language and country code, which follows the MessagesBundle in the names of the properties files. The next step is to obtain the translated messages from the ResourceBundle.

4. Fetch the Text from the ResourceBundle

To retrieve the message from the ResourceBundle, the getString method is used. The keys are hardcoded into the code, and the keys fetch the values which are the translated messages. An example of the getString method is as follows:

String msg1 = messages.getString("greetings");

Conclusion

As you can see, the basic steps of internationalizing a program are simple. It requires some planning and some extra coding, but the process of internationalization can save a lot of time if the program needs to be used in multiple locales. The topics and examples in this tutorial provide a starting point for some of the other internationalization features of the Java programming language.

Using PhraseApp to Help With Java Internationalization

PhraseApp helps you to manage your software localization projects on-line while being fully integrated with major software technologies. The translation center allows you to edit and control localization files in your browser. The in-line context editor provides translators with useful contextual information to improve overall translation quality. The platforms and formats that Phraseapp supports include Java, Ruby, PHP, Python, javascript, as well as many more.