Código Java – Internacionalización de Aplicaciones con ResourceBundle


Este es el Ejemplo #19 del Topic: Programación Gráfica en Java.

Con este post aprenderemos a hacer nuestras aplicaciones en java internacionales y poder generar software en varios idiomas como queramos. Esto yo es algo que la mayoría de las aplicaciones lo vienen realizando sean de escritorio o aplicaciones web que hacen uso de la internacionalización, que no es otra cosa más que adaptar nuestro software a diferentes idiomas y regiones, todo ello sin necesidad de hacer cambios considerables en el código fuente, sino haciendo uso de ficheros de propiedades que nos serán de gran ayuda.

En Java debemos acceder a la clase ResourceBundle que deberá enlazarse con el fichero de propiedades(.properties) y de esa manera obtener el recurso a usar. Deberán existir tantos ficheros de propiedades como idiomas que soportará la aplicación, cuyo nombre del fichero deberá guardar relación con los siguientes estándares:

Para el idioma – ISO 639.
Para el país – ISO3166

La composición del nombre de identificación deberá contar con el NombreFichero_pais_IDIOMA; respetando mayúsculas y minúsculas:
LANG_en_US – Inglés/EE.UU
LANG_es_PE – Español/Perú

El fichero de propiedades deberá contener la palabra clave y el texto con el cual está relacionado. La palabra clave deberá ser la misma en todos los ficheros de cada idioma, por ejemplo:

LANG_en_US.properties
IDIOMA=Spanish

LANG_es_PE.properties
IDIOMA=Español

Al momento de construir los ficheros properties de la aplicación,algunos programadores suelen usar el nombre del componente como palabra clave, yo prefiero poner como palabra clave la ruta completa de los componentes, y cuando sea necesaria alguna propiedad, por ejemplo hago uso de this cuando me refiero el contenedor principal.
En este ejemplo, el directorio donde estarán ubicados los ficheros de propiedades guardará la siguiente organización:

Para efectos didácticos solo usaré 2 idiomas, Ingles (en_US), y español (es_PE), además del fichero que se usará por defecto identificado solo como LANG.properties. Cada uno de estos ficheros deberá contener los siguientes datos:

LANG_en_US.properties
beastieux.gui.Ejm19_Internacionalizacion.this=Configuration
beastieux.gui.Ejm19_Internacionalizacion.lbl1=Country
beastieux.gui.Ejm19_Internacionalizacion.lbl2=City
beastieux.gui.Ejm19_Internacionalizacion.lbl3=Language

LANG_es_PE.properties
beastieux.gui.Ejm19_Internacionalizacion.this=Configuración
beastieux.gui.Ejm19_Internacionalizacion.lbl1=País
beastieux.gui.Ejm19_Internacionalizacion.lbl2=Ciudad
beastieux.gui.Ejm19_Internacionalizacion.lbl3=Idioma

El siguiente procedimiento recibirá como único parámetro la ruta del fichero de propiedades ejm: beastieux.language.LANG_en_US, y seteará el ResourceBundle con los datos de dicho fichero, con el cual cambiará automáticamente al idioma definido.

...
    private void setBundles(String propertyFile)
    {
            ResourceBundle rb = ResourceBundle.getBundle(propertyFile);

            String keyBundle=this.getClass().getName();

            this.setTitle(rb.getString(keyBundle + ".this"));
            this.lbl1.setText(rb.getString(keyBundle + ".lbl1"));
            this.lbl2.setText(rb.getString(keyBundle + ".lbl2"));
            this.lbl3.setText(rb.getString(keyBundle + ".lbl3"));
    }
...

Código de Ejemplo:

package beastieux.gui;

import java.awt.GridLayout;
import java.util.ResourceBundle;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

/**
 *
 * @author beastieux
 */
public class Ejm19_Internacionalizacion extends JFrame{

    JLabel lbl1;
    JLabel lbl2;
    JLabel lbl3;
    JTextField txt1;
    JTextField txt2;
    JComboBox cmb1;

    public Ejm19_Internacionalizacion()
    {

        lbl1=new JLabel();
        txt1=new JTextField();

        lbl2=new JLabel();
        txt2=new JTextField();

        lbl3=new JLabel();

        cmb1=new JComboBox();
        cmb1.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cmb1ItemStateChanged(evt);
            }
        });

        cmb1.addItem("Inglés");
        cmb1.addItem("Español");

        this.add(lbl1);
        this.add(txt1);
        this.add(lbl2);
        this.add(txt2);
        this.add(lbl3);
        this.add(cmb1);

        this.setLayout(new GridLayout(3,2));
        this.setSize(400, 100);

        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }

    private void cmb1ItemStateChanged(java.awt.event.ItemEvent evt) {

        switch(this.cmb1.getSelectedIndex())
        {
            case 0:setBundles("beastieux.language.LANG_en_US"); break;
            case 1:setBundles("beastieux.language.LANG_es_PE"); break;
            default:setBundles("beastieux.language.LANG");
        }
    }

    private void setBundles(String propertyFile)
    {
            ResourceBundle rb = ResourceBundle.getBundle(propertyFile);

            String keyBundle=this.getClass().getName();

            this.setTitle(rb.getString(keyBundle + ".this"));
            this.lbl1.setText(rb.getString(keyBundle + ".lbl1"));
            this.lbl2.setText(rb.getString(keyBundle + ".lbl2"));
            this.lbl3.setText(rb.getString(keyBundle + ".lbl3"));

    }

    public static void main(String args[]) {
        Ejm19_Internacionalizacion obj = new Ejm19_Internacionalizacion();
        obj.setVisible(true);
    }

}

Finalmente, cabe mencionar que los IDE’s de desarrollo modernos nos permiten realizar esta tarea fácilmente como es el caso de NetBeans o Eclipse. El procedimiento en Netbeans seria ir al menu Tools –> Internationalization, y elegir la modalidad, el más sencillo es con Internationalization Wizard.

Anuncios

Código Java – Establecer Conexión a Base de Datos con JDBC


Por fin he preparado el Ejemplo #12 del Topic: Programación Gráfica en Java, en el cual explicaré sobre cómo conectarnos a una base de datos cualquiera desde Java, manteniendo una misma estructura.

Para realizar la conexión a base de datos desde java necesitamos hacer uso de JDBC. Las bases de datos que deseemos conectar deberán proveernos el driver JDBC en un empaquetado JAR para añadirlo a las librerías del proyecto.

Deberemos conseguir la librería de acuerdo a la versión de la Base de Datos al cual deseemos conectarnos. Es posible que su IDE reconozca la existencia del driver si la base de datos ha sido instalada en el mismo ordenador junto con sus librerías, solo haría falta añadirlo a la lista de librerías que se usarán en el proyecto, por ejemplo en NetBeans se podría ir al directorio Libraries del Proyecto, hacer clic derecho sobre el y elegir Add Library y en la lista podría encontrase la que necesitemos, o si queremos agregarla manualmente Add JAR/Folder y seleccionar desde la dirección donde lo tenemos almacenado.

Add Library:

Add JAR/Folder:

Una vez agregada la librería, vamos a realizar el código de conexión, el cual nos debe presentar una clase con 2 métodos que a mi parecer no deberían faltar. Debería existir una función(Las funciones retornan datos) que nos retorne un CachedRowSet que es algo similar al ResultSet que no podemos retornar mientras el Statement esté sin cerrar, pero es obvio que por seguridad deberemos tener todas las conexiones cerradas, por eso no retornamos directamente el ResultSet y hacerlo sin cerrar las conexiones sería de muy mala práctica. En cambio, el CachedRowSet almacena todos los registros y podemos manipularla con las conexiones cerradas, cosa que no podemos hacer con los ResultSets, ya que éstos necesitan al Statement Abierto, y el Statement a su vez necesita la conexión abierta. Por otro lado deberíamos tener un procedimiento(No retorna ningún dato), no retorna nada ya que se encargará de realizar operaciones unidireccionales.

En conclusión, usamos la Función cuando usemos Sentencias DML SELECT incluyendo las Funciones y usar el Procedimiento cuando usemos INSERT, DELETE O UPDATE, incluyendo los StoreProcedures(Procedimientos Almacenados); aunque podemos conocer algunas bases de datos que permitan retornar datos desde StoreProcedures, lo ideal seria hacerlo desde funciones, manteniendo cada uno para su propósito. Del mismo modo, habrán podido darse cuenta que ambos métodos reciben una variable String como parámetro, ésta es nada menos que la Sentencia DML que deseamos ejecutar.

package beastieux.gui;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import javax.sql.rowset.CachedRowSet;
import com.sun.rowset.CachedRowSetImpl;
/**
 *
 * @author beastieux
 */
public class Ejm12_ConectarDataBase {

    public CachedRowSet Function(String sql)
    {
            try
            {
                    Class.forName("Driver");

                    String url = "jdbc:motor:servidor:puerto/basededatos";
                    Connection con = DriverManager.getConnection(url, "usuario","contraseña");
                    Statement s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                                                      ResultSet.CONCUR_READ_ONLY);

                    ResultSet rs= s.executeQuery(sql);

                    CachedRowSet crs = new CachedRowSetImpl();
                    crs.populate(rs);

                    rs.close();
                    s.close();
                    con.close();

                    return crs;

            }
            catch(Exception e)
            {
                   System.out.println(e.getMessage());
            }

            return null;
    }

    public void StoreProcedure(String sql)
    {

            try
            {
                    Class.forName("Driver");

                    String url = "jdbc:motor:servidor:puerto/basededatos";
                    Connection con = DriverManager.getConnection(url, "usuario","contraseña");
                    Statement s = con.createStatement();

                    s.execute(sql);

                    s.close();
                    con.close();

            }
            catch(Exception e)
            {
                   System.out.println(e.getMessage());
            }
    }
}

Como habrán podido apreciar en el código, el manejo de excepciones es relativamente sencilla, lo ideal sería especificar las excepciones por cada conexion, statement y resultset para de esa manera asegurarnos que permanezcan cerradas al finalizar la ejecución o aun cuando existieran errores; de igual manera sería muy útil obligar a cerrar las conexiones desde dentro de una clausula finally anexada al try – catch.

Por último la url de conexión “jdbc:motor:servidor:puerto/basededatos”, variará a continuación de jdbc, según el motor de base de datos al que deseemos conectarnos (PostgreSQL, MySQL, Oracle, Derby, etc) , la dirección IP del servidor, el puerto y finalmente el nombre de la base de datos al que queramos acceder.

En los próximos posts se presentará las conexiones a las diversas bases de datos y la explicación de como usar la clase creada.

Código Java – Conexión a Base de Datos PostgreSQL
Código Java – Conexión a Base de Datos MySQL
Código Java – Conexión a Base de Datos Apache Derby (Embebida y Cliente – Servidor)

Programación Gráfica en Java


Desde hace algunos años se ha estado compartiendo por medio de este blog muchos códigos sencillos escritos en java, específicamente algoritmos y ejemplos clásicos para iniciarse en el mundo de la programación. La idea ahora es compartirles los conocimientos básicos y a la vez esenciales para dar apertura a la programación gráfica.

Seguiré con el esquema de siempre, pues no se tratará de enseñar a programar, que para eso existen muchísimos otros sitios, páginas, web, foros, etc; lo que siempre he pretendido es brindar los métodos, técnicas, herramientas, referencias, etc; para que su labor en la programación sea menos trunca como suele suceder al momento de iniciarse, claro está que serán bienvenidas las preguntas, opiniones y críticas, como se ha venido haciendo todo este tiempo.

La IDE de desarrollo que uso es NetBeans; a la fecha de publicación de este post se encuentra en la versión estable 6.9.1. El Sistema Operativo sobre el cual trabajo es Debian Linux, aunque eso no sea de mucha importancia ahora, pues NetBeans como Java son multiplataforma, por lo tanto funciona en cualquier SO. Ustedes pueden elegir la IDE de desarrollo y el Sistema operativo que prefieran, eso si, algunos post referentes a configuraciones del entorno de desarrollo estarán basados en NetBeans y Linux.

Éste post, estará en constante modificación de acuerdo a las entradas que se realicen sobre el tema: “Programación Gráfica en Java”, en los cuales, como ya se anticipó, se brindará los conocimientos necesario para empezar con un proyecto relativamente serio.

  1. Código Java – Copiar Ficheros
  2. Código Java – Llenar JTable
  3. Código Java – Ocultar Columnas de un JTable
  4. Código Java – Desabilitar Edición de Celdas de JTable
  5. Código Java – Evento MouseClicked en JTable
  6. Código Java – For Each / Instance Of
  7. Código Java – Evento de Cambio de Texto en JTextField
  8. Código Java – Centrar un JFrame en Pantalla
  9. Código Java – Función de Encriptación mediante MD5
  10. Código Java – Realizar Búsquedas en un Array
  11. Código Java – Convertir un String a Date (Fecha)
  12. Código Java – Establecer Conexión a Base de Datos con JDBC
  13. Código Java – Llenar un JTable desde una consulta a Base de Datos
  14. Código Java – Procedimiento para llenar un JTable desde un CachedRowSet
  15. Código Java – Función para Convertir un ResultSet a Array
  16. Código Java – Agregar un Componente CheckBoxList al Proyecto
  17. Código Java – Agregar un Componente JCalendar al Proyecto
  18. Código Java – Cambiar la Apariencia de la Interfaz Gráfica con LookAndFeel
  19. Código Java – Internacionalización de Aplicaciones con ResourceBundle
  20. Código Java – Abrir Reportes Creados con JasperReports
  21. Código Java – Redimensionar Matrices sin Borrar Registros con Redim Preserve
  22. Código Java – Autoajustar Imágenes en un Contenedor
  23. Código Java – Modificar Ficheros de Propiedades en Tiempo de Ejecución

Instalacion de NetBeans en Slackware


Ya tenia instalado el netbeans en debian, open solaris y pc-bsd, ahora encontre una guia sencilla para la instalacion sobre slackware.

desde circolinux.blogspot.com

Te voy a explicar cómo instalar NetBeans en Slackware. ¿ No sabés lo que es NetBeans ?, se trata de un IDE. Así que si no lo conocés, mirálo.

La instalación es simple, pero en Slackware hay que dar un paso más y es instalar el Java SDK, que creo que Slackware no lo instala por defecto, y solo te instala jre ( de ahí la confusión que me generó a mi y a otra gente según ví ).

Necesitás el Java SDK, además de JRE. Entrá acá y bajate la versión más nueva que es Java SDK 6 update 3, que es la primera.

Lo bajás y lo instalás – si querés en tu usuario – o bien globalmente :

$ chmod +x jdk-6u3-linux-i586.bin
$ ./jdk-6u3-linux-i586.bin

Si lo querés globalmente, copialo a /usr/lib o donde tengas ganas.

Luego bajás netbeans de acá. Y la instalación es similar :

$ chmod +x netbeans-5_5_1-linux.bin
$ ./netbeans-5_5_1-linux.bin

Ahora tenés que pasearte por algunas preguntas, y le das para adelante hasta que llegués a la parte que te pide Java SDK, ahí elegís el directorio en donde lo instalaste. Si lo instalás como root lo va a encontrar solo si está en algun path que el sistema maneje.

Luego elegís donde instalarlo y le das para adelante a todas las preguntas y lo tenés instalado. La instalación ocupa unos 200 y pico Mb.

Disfrutá de NetBeans!