i18n

GWT includes a flexible set of tools to help you internationalize your applications and libraries. GWT internationalization support provides a variety of techniques to internationalize strings, typed values, and classes.

Do you really just want a simple way to get properties files down to the client regardless of localization?

You can do that, too. Try using Constants and just not having any locale-specific property files.

Internationalization Techniques

GWT offers multiple internationalization techniques to afford maximum flexibility to GWT developers and to make it possible to design for efficiency, maintainability, flexibility, and interoperability in whichever combinations are most useful.

A family of efficient and type-safe techniques that rely on strongly-typed Java interfaces, properties files, and code generation to provide locale-aware messages and configuration settings. These techniques depend on the interfaces Constants, ConstantsWithLookup, and Messages.

A simple and flexible technique for looking up localized values defined in a module's host page without needing to recompile your application. This technique is supported by the class Dictionary.

Extending or implementing Localizable

Provides a method for internationalizing sets of algorithms using locale-sensitive type substitution. This is an advanced technique that you probably will not need to use directly, although it is useful for implementing complex internationalized libraries. For details on this technique, see the Localizable class documentation.

The GWT internationalization types reside in the com.google.gwt.i18n package. To use any of these types, your module must inherit from the I18N module (com.google.gwt.i18n.I18N).

<module>
<inherits name="com.google.gwt.i18n.I18N"/>
</module>

As of GWT 1.5, the User module (com.google.gwt.user.User) inherits the I18N module. So if your project's module XML file inherits the User module (which generally it does), it does not need to specify explicitly an inherit for the I18N module.

Locales in GWT

GWT is different than most toolkits by performing most locale-related work at compile time rather than runtime. This allows GWT to do compile-time error checking, such as when a parameter is left out or the translated value is not of the correct type, and for optimizations to take into account known facts about the locale. This also allows an end user to download only the translations that are relevant for them.

Static String Internationalization

Static string internationalization is the most efficient way to localize your application for different locales in terms of runtime performance. This approach is called “static” because it refers to creating tags that are matched up with human readable strings at compile time. At compile time, mappings between tags and strings are created for all languages defined in the module. The module startup sequence maps the appropriate implementation based on the locale setting using deferred binding.

Static string localization relies on code generation from standard Java properties files or annotations in the Java source. GWT supports static string localization through three tag interfaces (that is, interfaces having no methods that represent a functionality contract) and a code generation library to generate implementations of those interfaces.

Extending the Constants Interface

The Constants interface allows you to localize constant values in a type-safe manner, all resolved at compile time. At some cost of runtime overhead, you can also allow runtime lookup by key names with the ConstantsWithLookup interface.

Using the Messages Interface

The Messages interface allows you to substitute parameters into messages and to even re-order those parameters for different locales as needed. The format of the messages in the properties files follows the specification in Java MessageFormat. The interface you create will contain a Java method with parameters matching those specified in the format string.

In addition, the Messages interface supports Plural Forms to allow your application to accurately reflect text changes based on the count of something.

Which Interface to Use?

Here are some guidelines to help choose the right interface for your application's needs:

Extend Constants to create a collection of constant values of a variety of types that can be accessed by calling methods (called constant accessors) on an interface. Constant accessors may return a variety of types, including strings, numbers, booleans, and even maps. A compile-time check is done to ensure that the value in a properties file matches the return type declared by its corresponding constant accessor. In other words, if a constant accessor is declared to return an int, its associated property is guaranteed to be a valid int value — avoiding a potential source of runtime errors.

The ConstantsWithLookup interface is identical to Constants except that the interface also includes a method to look up values 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 and the lookup cannot be resolved at compile-time.

Extend Messages to create a collection of formatted messages that can accept parameters. You might think of the Messages interface as a statically verifiable equivalent of the traditional Java combination of Properties, ResourceBundle, and MessageFormat rolled into a single mechanism.

Dynamic String Internationalization

For existing applications that may not support the GWT locale client property, GWT offers dynamic string internationalization to easily integrate GWT internationalization.

The Dictionary class lets your GWT application consume strings supplied by the host HTML page. This approach is convenient if your existing web server has a localization system that you do not wish to integrate with the static string internationalization methods. Instead, simply print your strings within the body of your HTML page as a JavaScript structure, and your GWT application can reference and display them to end users. Since it binds directly to the key/value pairs in the host HTML, whatever they may be, the Dictionary class is not sensitive to the GWT locale setting. Thus, the burden of generating localized strings is on your web server.

Dynamic string localization allows you to look up localized strings defined in a host HTML page at runtime using string-based keys. This approach is typically slower and larger than the static string approach, but does not require application code to be recompiled when messages are altered or the set of locales changes.

Tip: The Dictionary class is completely dynamic, so it provides no static type checking, and invalid keys cannot be checked by the compiler. This is another reason we recommend using static string internationalization where possible.

Java Annotations

The recommended approach for specifying the default values for Constants or Messages interfaces is using Java annotations. The advantage of this approach is that you can keep the values with the source, so when refactoring the interface or creating new methods in your IDE it is easier to keep things up to date. Also, if you are using a custom key generator or generating output files for translation, you need to use annotations.

The annotations that apply everywhere are discussed here — for annotations that are only used on Constants and Messages are discussed there.

Class Annotations

The following annotations apply to classes or interfaces:

Localized Properties Files

Static string internationalization uses traditional Java .properties files to manage translating tags into localized values. These files may be placed into the same package as your main module class. They must be placed in the same package as their corresponding Constants/Messages subinterface definition file.

Both Constants and Messages use traditional Java properties files, with one notable difference: properties files used with GWT should be encoded as UTF-8 and may contain Unicode characters directly, avoiding the need for native2ascii. See the API documentation for the above interfaces for examples and formatting details. Many thanks to the Tapestry project for solving the problem of reading UTF-8 properties files in Tapestry's LocalizedProperties class.

In order to use internationalized characters, make sure that your host HTML file contains the charset=utf8 content type in the meta tag in the header:

<meta http-equiv="content-type" content="text/html;charset=utf-8" />

You must also ensure that all relevant source and .properties files are set to be in the UTF-8 charset in your IDE.