Image Bundles and Localization

Sometimes applications need different images depending on the locale that the user is in. When using image bundles, this means that we need different image bundles for different locales. Although image bundles and localization are orthogonal concepts, they can work together by having locale-specific factories create instances of image bundles.

The best way to explain this technique is with an example. Suppose that we define the following ImageBundle for use by a mail application:

public interface MailImageBundle extends ImageBundle {

  /**
   * The default 'Compose New Message' icon if no locale-specific
   * image is specified.
   *
   * @gwt.resource compose_new_message_icon.gif
   */
  public AbstractImagePrototype composeNewMessageIcon();

  /**
   * The default 'Help' icon if no locale-specific image is specified.
   * Will match 'help_icon.png', 'help_icon.gif', or 'help_icon.jpg' in
   * the same package as this type.
   */
  public AbstractImagePrototype help_icon();
}
Suppose the application has to handle both English and French users. We define English and French variations of each image in MailImageBundle by creating locale-specific image bundles that extend MailImageBundle:
public interface MailImageBundle_en extends MailImageBundle {

  /**
   * The English version of the 'Compose New Message' icon.
   * Since we are not overriding the help_icon() method, this bundle
   * uses the inherited method from MailImageBundle.
   *
   * @gwt.resource compose_new_message_icon_en.gif
   */
  public AbstractImagePrototype composeNewMessageIcon();
}
public interface MailImageBundle_fr extends MailImageBundle {

  /**
   * The French version of the 'Compose New Message' icon.
   *
   * @gwt.resource compose_new_message_icon_fr.gif
   */
  public AbstractImagePrototype composeNewMessageIcon();

  /**
   * The French version of the 'Help' icon.
   *
   * @gwt.resource help_icon_fr.gif
   */
  public AbstractImagePrototype help_icon();
}
The final step is to create a mechanism for choosing the correct image bundle based on the user's locale. By extending Localizable, we can create a locale-sensitive factory that will return new instances of MailImageBundle that match the factory's locale:
public interface MailImageBundleFactory extends Localizable {

  public MailImageBundle createImageBundle();
}
public class MailImageBundleFactory_en implements MailImageBundleFactory {

  public MailImageBundle createImageBundle() {
    return (MailImageBundle) GWT.create(MailImageBundle_en.class);
  }
}
public class MailImageBundleFactory_fr implements MailImageBundleFactory {

  public MailImageBundle createImageBundle() {
    return (MailImageBundle) GWT.create(MailImageBundle_fr.class);
  }
}
The application code that utilizes a locale-sensitive image bundle would look something like this:
public void useLocalizedImageBundle() {
  // Create a locale-sensitive MailImageBundleFactory
  MailImageBundleFactory mailImageBundleFactory = (MailImageBundleFactory) GWT
      .create(MailImageBundleFactory.class);

  // This will return a locale-sensitive MailImageBundle, since we are using
  // a locale-sensitive factory to create it.
  MailImageBundle mailImageBundle = mailImageBundleFactory.createImageBundle();

  // Get the image prototype for the icon that we are interested in.
  AbstractImagePrototype helpIconProto = mailImageBundle.help_icon();

  // Create an Image object from the prototype and add it to a panel.
  HorizontalPanel panel = new HorizontalPanel();
  panel.add(helpIconProto.createImage());
}

Related topics

ImageBundle, Localizable