i18n Constants

  1. Constants
  2. ConstantsWithLookup
  3. Using Annotations
  4. Using Properties Files

Constants

This example will walk through the process of creating a class of internationalized constant strings "hello, world" and "goodbye, world" in your GWT application. The example will create a Java interface named MyConstants that abstracts those strings. You can reference the MyConstants methods in your GWT code when you want to display one of those strings to the user and they will be translated appropriately for all locales that have matching .properties files.

Begin by creating a default properties file called MyConstants.properties in your GWT project. You can place the file anywhere in your module's source path, but the .properties file and corresponding interface must be in the same package. It's fine to place the file in the same package as your module's entry point class.

helloWorld = hello, world
goodbyeWorld = goodbye, world

You can also create a localized translation for each supported locale in separate properties files. The properties file must be named the same as our interface name, in our case MyConstants, with the appropriate suffix that indicates the locale setting. In this case, we localize for Spanish using the filename MyConstants_es.properties:

helloWorld = hola, mundo
goodbyeWorld = adiós, mundo

Now define an interface that abstracts those strings by extending the built-in Constants interface. Create a new Java interface in the same package where the .properties files were created. The method names must match the tag names uses in the .properties files:

public interface MyConstants extends Constants {
  String helloWorld();
  String goodbyeWorld();
}

Tip: The i18nCreator tool automates the generation of Constants interface subinterfaces like the one above. The tool generates Java code so that you only need to maintain the .properties files. It also works for ConstantsWithLookup and Messages classes.

Note that MyConstants is declared as an interface, so you cannot instantiate it directly with new. To use the internationalized constants, you create a Java instance of MyConstants using the GWT.create(Class) facility:

public void useMyConstants() {
  MyConstants myConstants = GWT.create(MyConstants.class);
  Window.alert(myConstants.helloWorld());
}

You don't need to worry about the Java implementation of your static string classes. Static string initialization uses a deferred binding generator which allows the GWT compiler to take care of automatically generating the Java code necessary to implement your Constants subinterface depending on the locale.

ConstantsWithLookup

The ConstantsWithLookup interface is identical to Constants except that the interface also includes a method to look up strings by property name, which facilitates dynamic binding to constants by name at runtime. ConstantsWithLookup can sometimes be useful in highly data-driven applications. One caveat: ConstantsWithLookup is less efficient than Constants because the compiler cannot discard unused constant methods, resulting in larger applications.

Using Annotations

The annotations discussed here are the ones specific to Constants and ConstantsWithLookup — for shared annotations see the main Internationalization page.

Method Annotations

The following annotations apply to methods in a Constants subtype and must correspond to the return type of the method. They provide a type-safe way to reference constants, and can include Java compile-time constant references.

Using Property Files

The properties file format for Constants and ConstantsWithLookup is simply key=value, but there are a few points to remember:

  • # must be escaped as it is a comment character
  • When the type of the method is String[], an ASCII comma is used to separate values, which means that any commas included in a value must be escaped with a backslash. Also, beware of translators using a different character to separate translated values.
  • In the case of a Map-valued method, the entry in the properties file for that method will be a comma-separated set of keys, and then those keys have their own entries with their associated value. Example:
  Map<String,String> colorMap();

  colors=header, body, footer
  header=red
  body=white
  footer=blue
  

produces a map { header=>red, body=>white, footer=>blue }