Rationale

All Java programs consist of one or more classes that build the program. The elements of the user interface are therefore also kept in classes. These classes are combined and used together to build an actual program. Generally, for a Java program, each classes' source code has its own file.

The core Java libraries offer a quite sophisticated localization system. To use it, all parts of the program which could be language dependant must be (or at least: must be expressed as) simple Strings, e.g. the label on a button, in a menu or a certain rule to express the date format. In the next step, these Strings are labelled so that they can be referenced in the program, then taken out of the real Java source code and stored in seperate files. Normally, for each source code file, we get an accompaigning so called "properties file" which contains the stuff to be localized.

Example

You have in the program

--- Demo.java ---
Button closebutton=new Button("Close");
-----------------

This defines a button object with the label "Close". To make this ready for localization, you take the "Close" label away, give it a name (e.g. "button.close") and write this definition in a properties file which has a name somehow associated with the original classes' name:

--- Demo p.properties ---
button.close=Close
-------------------------

To actually use this properties file now, just take the Java Localization framework. This will not be discussed further here, just have a look at the replacement code in the Java source code:

--- Demo.java (new) ---
ResourceBundle rb=new ResourceBundle("Demo_p");
Button closebutton=new Button(rb.getString("button.close"));
-----------------------

Note that this new source code does nowhere contain any language or locale specific parts any more.

To actually localize or translate the program, one now takes this properties file, creates another one following certain naming conventions and simply translates all Strings into another language or locale.

Example (continued)

You want to have a German version of the program at your hands. You simply create a new file:

--- Demo p de.properties ---
button.close=Schließen
----------------------------

Now you have to tell your program to use this locale. This is normally done automatically by the runtime environment. You could force usage of the German localization by some code like this:

--- Demo.java (even newer) ---
Locale.setDefault(new Locale("de"));
ResourceBundle rb=new ResourceBundle("Demo_p");
Button closebutton=new Button(rb.getString("button.close"));
------------------------------

As you see by the example, the properties files for the additional localizations must have the same base name as the "main" file, and an extension to this seperated by "_". The extension itself contains of up to three parts:

Country and variant are optional and can be left out. Normally, you define a localization for a certain language (without country) and create more specific locales (with country code and even variant) only for seperate groups of this language which differ.

Example

Suppose a locale "de" which contains

--- example de.properties ---
month.1=Januar
month.2=Februar
month.3=März
-----------------------------

Now, if you want to make a special adaption for Austrian users of the program, you would create a locale "de AT" which contains only the changes between German German and Austrian German

--- example de AT.properties --
month.1=Jänner
-------------------------------

The names of February and March are not redefined for Austria, as they are the same as in Germany.

These concepts work for big programs as for small ones. The big ones, however, tend to produce some handling problems:

I18NEdit takes care of all of these schemes and ideas by the following steps:

  1. It encapsulates the explained structure of the properties files and hides them from the translator.

  2. It stores additional information about all the Strings and can by these means deduce not only what was added, but also what changed since a certain translation was done the last time.

  3. This leads finally to a nice and effective user interface that allows very fast and convenient translation operations - not only the first time, but also in subsequent steps when only parts of the system have to be (re-)translated.