Mensajes multi-idioma en Java

0
36538

Aplicaciones Internacionalizadas en Java

Cuando diseñamos una aplicación Java, tenemos que tener en cuenta tanto las necesidades actuales como futuras de nuestra aplicación. 

Es posible que pensemos que nuestro programa solo necesita mostrar mensajes en nuestro idioma local (en este caso castellano) pero, con mucha probabilidad, en un futuro cercano deba funcionar en otros ….. pongase Ingles, Catalán, etc 

Una vez completada una aplicación, sin tener este factor en cuenta, el coste
de internacionalizarla y realizar las prubas de regresión puede ser muy elevado
o incluso …. puede ser necesario un rediseño completo.

Java, propociona un conjunto de clases para facilitarnos esta labor…

 

Locale

Un Locale representa una región concreta … podemos ver la seleccionada
actualmente.

package roberto;
/*
 * primerPrograma.java
 *
 * Created on July 16, 2003, 3:53 AM
 */
import java.text.*;
import java.util.*;

/**
 *
 * @author  Administrator
 */
public class primerPrograma {

    /** Constructor por defecto de la clase */
    public primerPrograma() {
    }

    /**
     * Punto de entrada estático de la aplicación
     * @param args recibe los parámetros de linea de comando
     */
    public static void main(String[] args) {
        primerPrograma oInstanciaLocal = new primerPrograma();
        oInstanciaLocal.ejecutaProceso();
    }

    /**
     * Ejecutamos el proceso como un instancia local
     */
    private void ejecutaProceso()
    {
        Locale lDefecto = Locale.getDefault();
        muestraDatosLocale(lDefecto);

        Locale[] listaLocales = Locale.getAvailableLocales();

        for(int i=0 ; i < listaLocales.length ; i++)
        {
            muestraDatosLocaleTab(listaLocales[i]);
        }
    }

    void muestraDatosLocale(Locale lActual)
    {
        depura("El pais mostrado es: " +lActual.getDisplayCountry());
        depura("El pais es: " +lActual.getCountry());
        depura("El lenguaje actual es: " + lActual.getLanguage());
        depura("La varidedad del lenguaje es: " + lActual.getDisplayVariant());
        depura("El pais actual es: " +lActual.getLanguage());
        depura("El nobre actual es: " +lActual.getDisplayName());

        try
        {
            depura("El pais ISO actual es: " +lActual.getISO3Country());
            depura("El lenguaje ISO actual es: " +lActual.getISO3Language());
            depura("");
        }
        catch (Exception e)
        {
        }
     }

    void muestraDatosLocaleTab(Locale lActual)
    {
        muestraSimple(lActual.getDisplayCountry());
        muestraSimple(lActual.getCountry());
        muestraSimple(lActual.getLanguage());
        muestraSimple(lActual.getDisplayVariant());
        muestraSimple(lActual.getLanguage());
        muestraSimple(lActual.getDisplayName());

        try
        {
            muestraSimple(lActual.getISO3Country());
            muestraSimple(lActual.getISO3Language());
            depura("");
        }
        catch (Exception e)
        {
        }
     }

    void muestraSimple(String pCadena)
    {
          System.out.print(pCadena + "\t");
    }

    void depura(String pCadena)
    {
        System.out.println(pCadena);
    }
}
    

La salida actual es:

Y todas las actualmente definidas (las hemos importado en excel)

Crear una nueva localización

Vamos a crear una localización que represente España

package roberto;
/*
 * primerPrograma.java
 *
 * Created on July 16, 2003, 3:53 AM
 */
import java.text.*;
import java.util.*;


/**
 *
 * @author  Administrator
 */
public class primerPrograma {

    /** Constructor por defecto de la clase */
    public primerPrograma() {
    }

    /**
     * Punto de entrada estático de la aplicación
     * @param args recibe los parámetros de linea de comando
     */
    public static void main(String[] args) {
        primerPrograma oInstanciaLocal = new primerPrograma();
        oInstanciaLocal.ejecutaProceso();
    }

    /**
     * Ejecutamos el proceso como un instancia local
     */
    private void ejecutaProceso()
    {
        Locale lDefecto = Locale.getDefault();
        muestraDatosLocale(lDefecto);

        Locale lCastellano = new Locale("ES","es");
        muestraDatosLocale(lCastellano);

    }

    void muestraDatosLocale(Locale lActual)
    {
        depura("El pais mostrado es: " +lActual.getDisplayCountry());
        depura("El pais es: " +lActual.getCountry());
        depura("El lenguaje actual es: " + lActual.getLanguage());
        depura("La varidedad del lenguaje es: " + lActual.getDisplayVariant());
        depura("El pais actual es: " +lActual.getLanguage());
        depura("El nobre actual es: " +lActual.getDisplayName());

        try
        {
            depura("El pais ISO actual es: " +lActual.getISO3Country());
            depura("El lenguaje ISO actual es: " +lActual.getISO3Language());
            depura("");
        }
        catch (Exception e)
        {
        }
     }

    void depura(String pCadena)
    {
        System.out.println(pCadena);
    }
}

La salida del programa es

El pais mostrado es: United States
El pais es: US
El lenguaje actual es: en
La varidedad del lenguaje es:
El pais actual es: en
El nobre actual es: English (United States)
El pais ISO actual es: USA
El lenguaje ISO actual es: eng
El pais mostrado es: Spain
El pais es: ES
El lenguaje actual es: es
La varidedad del lenguaje es:
El pais actual es: es
El nobre actual es: Spanish (Spain)
El pais ISO actual es: ESP
El lenguaje ISO actual es: spa

Ficheros de recursos para cada idioma

En siguiente paso sería crear una mecanismo para que en función del idioma,
se utilice un juego particular.

Podemos crear un fichero de propiedades, que tengan la misma clave y un valor
distinto para cada idioma. Solo tenemos que tener la precaucion de saber como
nombrarlos….

Recurrimos a la ayuda Java

Nos ayudamos de NetBeans para crear el fichero de propiedades 

Seleccionamos el nombre

Añadimos una versión «localizada»

Seleccionamos Español de España

Comprobamos que se ha creado y pulsamos el botón de nueva
propiedad

Creamos una nueva propiedad  (ver que tenemos seleccionado
la versión local españona)

Podemos editar la tabla para cambiar el texto en la inglesa

Realmente se han creado dos ficheros en el sistema

Si vemos el Ingles tiene este aspecto

# Sample ResourceBundle properties file

#Este es el saludo de bienvenida
SALUDO=Hello Word

Y el castellano

# Sample ResourceBundle properties file

#Este es el saludo de bienvenida
SALUDO=Hola compa\u00F1eros

Si ejecutamos nuestro programa

package roberto;
/*
 * primerPrograma.java
 *
 * Created on July 16, 2003, 3:53 AM
 */
import java.text.*;
import java.util.*;


/**
 *
 * @author  Administrator
 */
public class primerPrograma {

    /** Constructor por defecto de la clase */
    public primerPrograma() {
    }

    /**
     * Punto de entrada estático de la aplicación
     * @param args recibe los parámetros de linea de comando
     */
    public static void main(String[] args) {
        primerPrograma oInstanciaLocal = new primerPrograma();
        oInstanciaLocal.ejecutaProceso();
    }

    /**
     * Ejecutamos el proceso como un instancia local
     */
    private void ejecutaProceso()
    {
        Locale lDefecto = Locale.getDefault();
        muestraDatosLocale(lDefecto);

        ResourceBundle recursos = ResourceBundle.getBundle("CRecursosApp",lDefecto);
        depura("El saludo en Ingles es: " + recursos.getString("SALUDO"));

        Locale lCastellano = new Locale("ES","es");
        muestraDatosLocale(lCastellano);

        recursos = ResourceBundle.getBundle("CRecursosApp",lCastellano);
        depura("El saludo en Castellano es: " + recursos.getString("SALUDO"));
    }

    void muestraDatosLocale(Locale lActual)
    {
        depura("El pais mostrado es: " +lActual.getDisplayCountry());
        depura("El pais es: " +lActual.getCountry());
        depura("El lenguaje actual es: " + lActual.getLanguage());
        depura("La varidedad del lenguaje es: " + lActual.getDisplayVariant());
        depura("El pais actual es: " +lActual.getLanguage());
        depura("El nobre actual es: " +lActual.getDisplayName());

        try
        {
            depura("El pais ISO actual es: " +lActual.getISO3Country());
            depura("El lenguaje ISO actual es: " +lActual.getISO3Language());
            depura("");
        }
        catch (Exception e)
        {
        }
     }

    void depura(String pCadena)
    {
        System.out.println(pCadena);
    }
}   

La salida es

El pais mostrado es: United States
El pais es: US
El lenguaje actual es: en
La varidedad del lenguaje es:
El pais actual es: en
El nobre actual es: English (United States)
El pais ISO actual es: USA
El lenguaje ISO actual es: eng
El saludo en Ingles es: Hello Word
El pais mostrado es: Spain
El pais es: ES
El lenguaje actual es: es
La varidedad del lenguaje es:
El pais actual es: es
El nobre actual es: Spanish (Spain)
El pais ISO actual es: ESP
El lenguaje ISO actual es: spa
El saludo en Castellano es: Hola compañeros

MessageFormat, Mensajes con parámetros variables

Normalmente los mensajes no son solo texto sino que hay que intercalar
variables dentro del mensaje.

Todo esto ya esta pensado ….

Podemos definir en nuestra cadena de caracteres … por indice basado en 0

Es decir … del tipo

Hello Word, user number {0} of today, day {1}

Modificamos nuestro código … podemos recuperar la cadena y crear un
formateador

       MessageFormat
fCadenaFormatear = new MessageFormat(recursos.getString(«SALUDO»));       

Creamos un array

       Object
aoParametros[] = {«1»,new Date()};   

 Y decimos que se combinen ambos

fCadenaFormatear.format(aoParametros)

En el caso de la cadena en castellano, podemos decir que los objetos se
formatéen, usando los parámetros locales

       fCadenaFormatear.setLocale(lCastellano);
 

package roberto;
/*
 * primerPrograma.java
 *
 * Created on July 16, 2003, 3:53 AM
 */
import java.text.*;
import java.util.*;


/**
 *
 * @author  Administrator
 */
public class primerPrograma {

    /** Constructor por defecto de la clase */
    public primerPrograma() {
    }

    /**
     * Punto de entrada estático de la aplicación
     * @param args recibe los parámetros de linea de comando
     */
    public static void main(String[] args) {
        primerPrograma oInstanciaLocal = new primerPrograma();
        oInstanciaLocal.ejecutaProceso();
    }

    /**
     * Ejecutamos el proceso como un instancia local
     */
    private void ejecutaProceso()
    {
        Locale lDefecto = Locale.getDefault();
        ResourceBundle recursos = ResourceBundle.getBundle("CRecursosApp",lDefecto);
        MessageFormat fCadenaFormatear = new MessageFormat(recursos.getString("SALUDO"));
        Object aoParametros[] = {"1",new Date()};
        depura("Cadena Formateada en Ingles " + fCadenaFormatear.format(aoParametros));
 
        // ahora en castellano
        Locale lCastellano = new Locale("ES","es");
        recursos = ResourceBundle.getBundle("CRecursosApp",lCastellano);
        fCadenaFormatear = new MessageFormat(recursos.getString("SALUDO"));
        fCadenaFormatear.setLocale(lCastellano);
        depura("Cadena Formateada en Castellano es " + fCadenaFormatear.format(aoParametros));
    }


    void depura(String pCadena)
    {
        System.out.println(pCadena);
    }
}
    

La salida, podemos ver que aparece tal y como deseamos.

Cadena Formateada en Ingles Hello Word, user number 1 of today, day 7/18/03 8:57 AM
Cadena Formateada en Castellano es Hola eres el usuario 1 de hoy, dia
18/07/03 8:57

Podemos especificar el formato con más detalle

Modificando la cadena, sin modificar el programa

Hello Word, user number {0,number,
#,000.##
} of today, day {1,date,short}

La salida es:

Cadena Formateada en Ingles Hello Word, user number 001 of today, day
7/18/03
Cadena Formateada en Castellano es Hola eres el usuario 1 de hoy, dia 18/07/03 9:29

Sobre el
Autor ..

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad