Internacionalization es un tema que tiene que estar presente en la cabeza de todos los desarrolladores de esta era tan globalizada. Por suerte Java nos da una API que es sumamente rápida de implementar y fácil de entender. En este tutorial corto pero efectivo vamos a ir paso a paso de como internacionalizar tu aplicación para poder ser vista en varios idiomas.

Vamos a plantear un escenario, una aplicación desktop donde el usuario elige el idioma que quiere durante la instalación. Ahora pensemos que nos llega el valor, lo que vamos a hacer primero que nada es setear el Locale object para que Java I18N haga el resto del trabajo.

String country = "AR";
String language = "es";

Ya tenemos el país (Argentina) y el lenguage (Español), ahora vamos al código de la implentación.

Vamos a saber que hay 2 tipos de implemetación para estos casos, files de traducción tipo Java o files tipo Properties. En mi caso prefiero los Java ya que son más rápidos (es un Map de key/values) y considero que cambiar un archivo y recompilarlo forma parte del mismo software lo cual sería el mismo update necesario que actualizar un properties file.

ResourceBundles son las clases que vamos a utilizar para la traducción, así se compone el mío en espanol:

import java.util.ListResourceBundle;
public class MyResourceBundle_es_AR extends ListResourceBundle {
  static Object[][] contents = {
    {"label.name", "Nombre"},
    {"label.phone", "Teléfono"},
  }
  protected Object[][] getContents() {
    return contents;
  }

Cabe destacar que es súper importante la nomenclatura de los archivos java. Como es esto ? bueno, sencillo, si tu archivo es de traducción para el espanol este se tiene que llamar MyResource_es y si es específico para Argentina MyResource_es_AR. En cambio si hay terminos para España, podemos nombrarlo MyResource_es_ES. Java busca los _language_COUNTRY en el final de los archivos para seleccionarlos.

Tu aplicación va a terminar con varios archivos de traducción como podemos ver acá:

MyResourceBundle_es.java // no importa el pais, si el idioma
MyResourceBundle_es_AR.java // si el locale fue seteado como es AR, este es el archivo seleccionado
MyResourceBundle_en.java // la traduccion al ingles.
MyResourceBundle_en_UK.java // implemento algunos terminos british.

Y ahora otra en en inglés.

import java.util.ListResourceBundle;
public class MyResourceBundle_en extends ListResourceBundle {
  static Object[][] contents = {
    {"label.name", "Name"},
    {"label.phone", "Phone"},
  }
  protected Object[][] getContents() {
    return contents;
  }

Ahora vamos a ver de que manera enlazamos lo que el usuario ve a la traducción, vamos a hacer un frame y mostremos los labels segun el idioma.

public class MyFrame() extends JFrame {
  public MyFrame() {
    JLabel nameLabel = new JLabel();
    nameLabel.setText(this.getResourceBundle().getString("label.name"));
    JLabel phoneLabel = new JLabel();
    phoneLabel.setText(this.getResourceBundle().getString("label.phone"));
    this.setLayout(new FlowLayout());
    this.add(nameLabel);
    this.add(phoneLabel);
    this.setSize(300, 100);
    this.pack();
    this.setVisible(true);
  }

  private ResourceBundle getResourceBundle() {
    if (this.resourceBundle != null) {
      String country = "AR";  // a setear por el usuario
      String language = "es";  // a setear por el usuario
      this.resourceBundle = ResourceBundle.getBundle("MyResourceBundle", new Locale(language, country));
    }
    return this.resourceBundle;
  }
}

De ésta manera segun el Locale que hayamos seteado vamos a ver la traducción correspondiente. Es importante destacar la instanciación del resource bundle.

ResourceBundle.getBundle("MyResourceBundle", new Locale(language, country));

Cuando pasamos el nombre de la clase al factory no le pasamos el nombre completo de la clase (MyResourceBundle_es_AR), sino solo el prefix (MyResourceBundle). Por que ? porque java decide que archivo seleccionar según el Locale que se haya pasado como parámetro.

Todo éste código debería ser suficiente para que comiencen a darse una idea de I18N. Espero les sirva.