This page gives an overview of the Gettext Commons and describes how to integrate the library into existing Java applications.
Quick Links: I18nExample.java, API Documentation
The Gettext Commons provide the class I18n that has methods that need to be invoked each time a user visible string is used:
I18n i18n = I18nFactory.getI18n(getClass()); System.out.println(i18n.tr("This text will be translated"));
I18n also supports proper handling of plurals:
System.out.println(i18n.trn("Copied file.", "Copied files.", 1)); // will print "Copied file." System.out.println(i18n.trn("Copied file.", "Copied files.", 4)); // will print "Copied files."
In addition there are convenience methods that use the Java API MessageFormat.format() for substitution:
System.out.println(i18n.tr("Folder: {0}", new File("/home/xnap-commons")); System.out.println(i18n.trn("{0} file", "{0} files", 5, new Integer(5)));
And sometimes it is necessary to provide different translations of the same word as some words may have multiple meanings in the native language the program is written but not in other languages:
System.out.println(i18n.trc("chat (verb)", "chat")); System.out.println(i18n.trc("chat (noun)", "chat"));
The preferable way to create an I18n object is through the I18nFactory. The factory caches the I18n object internally using the the package name of the provided class object and registers it with I18nManager. Thus all classes of the same package will use the same I18n instance.
public class SampleClass { private static I18n i18n = I18nFactory.getI18n(SampleClass.class); String localizedString; public SampleClass() { localizedString = i18n.tr("Hello, World"); } }
I18nManager lets you register independently created I18n objects and provides the facility to change the locale of all registered I18n objects thereby notifying possible LocaleChangeListeners:
public class LocaleChangeAwareClass implements LocaleChangeListener { private static I18n i18n = I18nFactory.getI18n(LocaleChangeAwareClass.class); String localizedString; public LocaleChangeAwareClass() { localizedString = i18n.tr("Hello, World"); I18nManager.getInstance().addWeakLocaleChangeListener(this); } public void localeChanged(LocaleChangeEvent event) { // update strings localizedString = i18n.tr("Hello, World"); ... } }
Once the source code has been internationalized, i.e. all
user visible strings are wrapped by a call to
i18n.tr()
, xgettext can be used to extract these
strings for localization.
This 3 step process is illustrated in this figure:
Here is a simple example of running the gettext commands:
# extract keys xgettext -ktrc -ktr -kmarktr -ktrn:1,2 -o po/keys.pot src/*.java # merge keys into localized po file msgmerge -U po/de.po po/keys.pot # translate file poedit po/de.po # create German ResourceBundle class file in app.i18n package msgfmt --java2 -d src/conf -r app.i18n.Messages -l de po/de.po
In order to specify the name of the resource bundles you want to use, you create an i18n.properties file and place it in your application's toplevel package. All subpackages will use this configuration file unless they find a different one on the way up in the package hierarchy.
i18n.properties expects the base name of the resources as the value of the key basename:
basename=app.i18n.Messages
For more information on how the resource lookup works, please read here.