Buscar
Social
Ofertas laborales ES
lunes
jul012002

Uso de ficheros de recursos


Construir un ResourceBundle con ficheros de propiedades.


Fecha de creación: 01.07.2002

Revisión 1.0.1 (01.12.2002)

Mª Ángeles Martínez
marianmr ARROBA iespana PUNTO es

Copyright (c) 2002, Mª Ángeles Martínez. Este documento puede ser distribuido solo bajo los términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en /licencias/).





Un fichero de propiedades es un simple fichero de texto que se puede crear y mantener con un sencillo editor de texto.


Siempre se debe crear un fichero de propiedades por defecto. El nombre de este fichero empieza por el nombre base y termina con el sufijo .properties. Este fichero contiene las siguientes líneas:

# Fichero.properties
campo1 = valor1
campo2 = valor2
campo3 = valor3

En este fichero las líneas de comentarios empiezan con una almohadilla (#), el resto contienen parejas de clave y valor que podrán ser usadas por nuestro programa.





Para crear ficheros de propiedades adicionales, o localizados para una región determinada, hay que entender el concepto de localidad, o Locale. Una localidad es un espacio determinado por un idioma, en ocasiones un país que especifíca aún más, e incluso, se puede indicar una variante dentro de un idioma y país.


Estas localidades determinan la forma de presentar la información (formatos de números, fechas, etc), pero tambíen determinan el fichero de propiedades a leer. Así, podremos usar es_ES para el español de España, es_MX para el de México, y es_AR para Argentina, por poner un ejemplo. Y aunque sea un poco anticuado, porque el Euro es ya la moneda oficial de España, podemos escoger la representación concreta con es_ES_EUR.


Para soportar una nueva Locale (es decir, una nueva localidad), los localizadores crearán un nuevo fichero de propiedades que contenga los valores traducidos. No se necesita cambiar el código fuente, ya que el programa referencia las claves, no los valores.


Por ejemplo, para añadir soporte para el idioma inglés, los localizadores tendrán que traducir los valores de Fichero.properties y situarlos en un fichero llamado Fichero_en_US.properties (que también termina con el sufijo .properties). Sin embargo, como el fichero se ha creado para una localidad específica, el nombre base es seguido por el código del idioma (en) y el código del país (US). El contenido de Fichero_en_US.properties es éste:

# Fichero_en_US.properties
campo1 = value1
campo2 = value2
campo3 = value3



Lanzamos, por ejemplo, tres ficheros de propiedades con el programa ProgramaProperties:

Fichero.properties
Fichero_en_US.properties
Fichero_fr.properties






En el programa ProgramaProperties hemos creado los objetos Locale de esta forma:

Locale[] supportedLocales = {
new Locale("fr","FR"),
new Locale("de","DE"),
new Locale("en","US")
}

Locale currentLocale = supportedLocales[0];

Para cada uno de estos objetos hemos específicado un código de idioma y un código de país. Esto códigos corresponden con los ficheros de propiedades creados en los pasos anteriores.





Éste es el paso que muestra como se relacionan, la localidad, los ficheros de propiedades y el ResourceBundle. Para crear el ResourceBundle, llamamos al método getBundle, especificando el nombre base (Fichero) y la localidad:

ResourceBundle labels = ResourceBundle.getBundle("Fichero",currentLocale);



El método getBundle primero busca un fichero de clase que corresponda con el nombre base. Si no puede encontrar el fichero de clase, comprueba los ficheros de propiedades. En el programa ProgramaProperties, hemos constituido el ResourceBundle con ficheros de propiedades en vez de ficheros de clases. Cuando el método getBundle localiza el fichero de propiedades correcto, devuelve un objeto PropertyResourceBundle cargado con las parejas clave-valor del fichero de propiedades.


Si no existe un fichero de propiedades para la localidad específicada, getBundle selecciona el fichero de propiedades con la correspondencia más cercana (es decir, si buscamos en_US y no lo encuentra, pero sí el en, nos devolverá este último). La siguiente tabla identifica los ficheros de propiedades que buscará el programa ProgramaProperties para cada localidad:























Parámetros Locale


fichero de propiedades

Explicación


en US



Fichero_en_US.properties


Correspondencia exacta.


fr FR



Fichero_fr.properties



Fichero.properties_fr_FR no existe, esta es la correspondencia más cercana


de DE



Fichero.properties


Se selecciona el fichero por defecto porque los parámetros de la localidad no existen.


En lugar de llamar a getBundle, podríamos haber creado el objeto PropertyResourceBundle llamando a su constructor, que acepta un InputStream como argumento. Para crear el InputStream debemos específicar el nombre exacto del fichero de propiedades en la llamada al constructor de FileInputStream. Crear el PropertyResourceBundle llamando al método getBundle es más flexible, porque buscará los ficheros de propiedades con la correspondencia más cercana a la localidad específicada.





Para recuperar los valores traducidos desde el ResourceBundle, llamamos al método getString:

String value  = labels.getString(key);

El String devuelto por getString corresponde con la clave que hemos especificado. El String está en el idioma apropiado, proporcionado por un fichero de propiedades existente para la localidad específicada. Como las claves no cambian, los localizadores añaden ficheros de propiedades adicionales posteriormente. Nuestra llamada a getString no necesita cambiar.





Si queremos recuperar los valores para todas las claves de un ResourceBundle, necesitamos llamar al método getKeys. Este método devuelve una Enumeration con todas las claves de un ResourceBundle. Se puede iterar a través de la Enumeration y recuperar cada valor con el método getString. Las siguientes líneas de código del programa ProgramaProperties, muestran como se hace esto:

ResourceBundle labels = ResourceBundle.getBundle("Fichero",currentLocale);

Enumeration bundleKeys = labels.getKeys();

while (bundleKeys.hasMoreElements()) {
String key = (String)bundleKeys.nextElement();
String value = labels.getString(key);
System.out.println("key = " + key + ", " +
"value = " + value);
}







// Clase BdConfig.java

import java.util.*;

public final class BdConfig {

private static ResourceBundle bundle =
ResourceBundle.getBundle("bdconfig");

public static String getValue(String key) {
return bundle.getString(key);
}

public static int getIntValue(String key) {
return Integer.parseInt(bundle.getString(key));
}
}




// Fichero de propiedades bdconfig.properties

jdbc_driver = xxxxxxxx
jdbc_url = yyyyyyy
jdbc_user = zzzzzz
jdbc_password = ****




//Y desde el programa que crea las conexiones, los datos se cogen así:

BdConfig.getValue("jdbc_driver");
BdConfig.getValue("jdbc_url");
BdConfig.getValue("jdbc_user");
BdConfig.getValue("jdbc_password");





Recursos

Acerca del autor

Mª Ángeles Martínez
Mª Ángeles Martínez es una licenciada en Química (especialidad de Bioquímica y Biología Molecular) a la que le entró el gusanillo por la programación a través de algunos cursos que hizo durante su carrera, hasta el punto de llevarla a estudiar Ingeniería Técnica en Informática de Gestión y ganarse la vida como técnica de desarrollo en Java
En los pocos ratos libres que le deja el trabajo le gusta ir al cine, al campo, de fiesta, y con su novio, supongo que a los tres sitios.

lunes
jul012002

Imprimir desde código Java


Impresión desde Java mediante ejemplos




Más información en:


PrinterJob (http://www.javacommerce.com/articles/printing.html)

Printing in JDK 1.4 Part 1 (http://www-106.ibm.com/developerworks/library/j-mer0322/)

Printing in JDK 1.4 Part 2 (http://www-106.ibm.com/developerworks/library/j-mer0424.html)

PrintService (http://java.sun.com/j2se/1.4/docs/api/javax/print/PrintService.html)




Objeto PrinterJob



Para usar el objeto PrinterJob deberemos tener un objeto Printable que será el que contendrá lo que queremos imprimir.
Este objeto debe contener la función print donde indicaremos la información que nos interesa imprimir.
Esta información será dibujada sobre un objeto Graphics (que luego pasaremos a Graphics2D) o Graphics2D (la impresión en Java, al menos versones anteriores es un trabajo gráfico, de ahí su lentitud).
Después crearemos el objeto PrinterJob,
mediante setPrintable(objeto_a_imprimir) haremos que se dibuje la página a mandar a la impresora.
Llamaremos o no, a la ventana de configuración de impresión, y por último imprimiremos.




Impresión mediante un objeto PrinterJob(JDK1.2+) para imprimir gráficos.



//Impresión en Java2 mediante PrinterJob
import java.awt.*;
import java.awt.print.*;
import java.awt.geom.*;

//La clase debe de implementar la impresión implements Printable
class ObjetoAImprimir implements Printable
{
public int print (Graphics g, PageFormat f, int pageIndex)
{
//Creamos un objeto 2D para dibujar en el
Graphics2D g2 = (Graphics2D) g;
//Este código imprime 2 páginas una con un cuadrado o marco
//y una segunda con un circulo en la esquina superior izquierda

//Creamos el rectángulo
//getImagebleX() coge la parte de la hoja donde podemos
//imprimir quitando los bordes. Si no hiciesemos
//esto así y tuviesemos bordes definidos en la impresión
//lo que dibujasemos fuera de los bordes no lo
//imprimiría aunque cupiese en la hoja físicamente.
Rectangle2D rect = new Rectangle2D.Double(f.getImageableX(),
f.getImageableY(),
f.getImageableWidth(),
f.getImageableHeight());

//Creamos la circunferencia
Ellipse2D circle = new Ellipse2D.Double(100,100,100,100);

//pageIndex indica el número de la página que se imprime
//cuando es 0 primera página a imprimir, es un rectángulo
//cuando es 1 segunda página a imprimir, es una circunferencia
//En otro caso se devulve que no hay más páginas a imprimir
switch (pageIndex)
{
case 0 : //Página 1: Dibujamos sobre g y luego lo pasamos a g2
g.setColor(Color.black);
g.fillRect(110,120,30,5);
g.setColor(Color.pink);
g.drawLine(0,0,200,200);
g2 = (Graphics2D) g;
return PAGE_EXISTS; //La página 1 existe y se imprimirá
case 1 : //Página 2: Circunferencia y rectángulo
g2.setColor(Color.red);
g2.draw(circle);
g2.draw(rect);
return PAGE_EXISTS; //La página 2 existe y se imprimirá
default: return NO_SUCH_PAGE; //No se imprimirán más páginas
}
}
}

//clase pública que se ejecuta donde debe de estar el main que llama a la
//otra clase.
public class Imprime
{
public static void main (String[] args)
{
// Creamos un objeto de impresión.
PrinterJob job = PrinterJob.getPrinterJob();

// Hacemos imprimible el objeto ObjetoAImprimir
job.setPrintable(new ObjetoAImprimir());
//Pondrá algo tipo Información job: sun.awt.windows.WPrinterJob@4a5ab2
System.out.println("Información job: " + job.toString());

//Abre el cuadro de diálogo de la impresora, si queremos que imprima
//directamente sin cuadro de diálogo quitamos el if...
if (job.printDialog())
{
//Imprime, llama a la función print del objeto a imprimir
//en nuestro caso el Objeto ObjetoAImprimir
try { job.print(); }
catch (PrinterException e) { System.out.println("Error de impresión: " + e); }
}
}
}



Objeto FileOutputStream



Este objeto es usado habitualmente para crear ficheros.
Como el Stream lo podemos redireccionar, en este caso lo enviamos a la impresora, ya sea indicando la ubicación en red, como el puerto en el que está, y a partir de aquí sólo hay que mandar el fujo de datos para que lo reciba la impresora.
Se debe tener en cuenta que en este caso deberemos saber de antemano la ubicación de la impresora y que no será un código portable a otra estación de trabajo ya que puede no tener acceso a la impresora indicada.



Impresión mediante un objeto FileOutputStream para imprimir texto.



//Impresión en Java2 mediante FileOutputStream
import java.awt.print.*;
import java.util.*;
import java.io.*;

//La clase debe de implementar la impresión implements Printable

//clase pública que se ejecuta donde debe de estar el main que
// llama a laotra clase.
public class ImprimeTexto
{
public static void main (String[] args)
{

try {

//Esto saldría en la consola de java o en la consola de sistema operatico
System.out.println("Probando, probando la impresión.");

//enviar a imprimir en pantalla.
//FileDescriptor fd = FileDescriptor.out;
//FileOutputStream os = new FileOutputStream(fd);

//enviar a imprimir a la impresora en red, debemos conocer el nombre de la
//impresora.
//Desde windows se puede poner ...new FileOutputStream("//Au-4022/hp1100");

//Formato UNIX
//FileOutputStream os = new FileOutputStream("\\\\Au-4022\\hp1100");

//Si tuviesemos la impresora en el puerto paralelo
//FileOutputStream os = new FileOutputStream("LPT1:");
//Si tuviesemos la impresora en el puerto serie
//FileOutputStream os = new FileOutputStream("COM1:");

//Enviar a un archivo de texto.
FileOutputStream os = new FileOutputStream("nombre_archivo.txt");
PrintStream ps = new PrintStream(os);
ps.println("prueba de impresión realizada");
ps.close();

}
catch(Exception e){
System.out.println("Error: "+e.getMessage());
}
}
}


Objeto PrintService.



Es un objeto de la versión 1.4 del JDK.
Si se soporta este objeto, es la mejor opción ya que es la más depurada.



Un servicio de impresión puede ser cualquier impresora instalada en la máquina tanto local como en red.
Tras crear el objeto de servicio de impresión y asignar una en concreto, crearemos un objeto documento Doc.
que contendrá lo que vamos a imprimir.
Este documento puede contener texto, gráficos, etc... simplemente mediante el objeto DocFlavor indicaremos al objeto PrintService que tipo de datos contiene el documento.
aunque deberemos comprobar que el servicio de impresión accepte ese tipo de datos (el DocFlavor).
Una vez creado el documento, definido el tipo de datos y rellenados estos datos, se mandará a imprimir.



Impresión mediante un objeto PrintService(JDK1.4+) para imprimir texto.



//Cogemos el servicio de impresión por defecto (impresora por defecto)
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
//Le decimos el tipo de datos que vamos a enviar a la impresora
//Tipo: bytes Subtipo: autodetectado
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
//Creamos un trabajo de impresión
DocPrintJob pj = service.createPrintJob();
//Nuestro trabajo de impresión envía una cadena de texto
String ss=new String("Aquí lo que vamos a imprimir.");
byte[] bytes;
//Transformamos el texto a bytes que es lo que soporta la impresora
bytes=ss.getBytes();
//Creamos un documento (Como si fuese una hoja de Word para imprimir)
Doc doc=new SimpleDoc(bytes,flavor,null);

//Obligado coger la excepción PrintException
try {
//Mandamos a impremir el documento
pj.print(doc, null);
}
catch (PrintException e) {
System.out.println("Error al imprimir: "+e.getMessage());
}



Impresión mediante un objeto PrintService(JDK1.4+) para imprimir un objeto printable como con PrinterJob.



Usaremos la clase ObjetoAImprimir como en el ejemplo con PrinterObject.


ObjetoAImprimir puede ser cualquier objeto que implemente Printable (Applets, Panels,Objetos propios,?)




PrintService service = PrintServiceLookup.lookupDefaultPrintService();
//Indicamos que lo que vamos a imprimir es un objeto imprimible
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
DocPrintJob pj = service.createPrintJob();
//Creamos el documento a imprimir que contendrá el objeto
Doc doc=new SimpleDoc(new ObjetoAImprimir(),flavor,null);

try {
pj.print(doc, null);
}
catch (PrintException e) {
System.out.println("Error al imprimir: "+e.getMessage());
}



Información del objeto PrintService.



//Coger impresora por defecto
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
System.out.println("Nombre impresora por defecto: "+service.getName());

//Coger todas las impresoras instaladas (tanto en local como en red)
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
//Tendremos un array con todas las impresoras instaladas
//con length podemos saber el nº de impresoras
System.out.println("Número de impresoras configuradas en el sistema: "
+ services.length);

if (services.length > 0) {
//Recorre el array de impresoras (o servicios de impresión)
for(int i=0;iSystem.out.println("Impresora "+(i+1)+":"+services[i].getName());
}
}

//BYTE_ARRAY indica el tipo y AUTOSENSE el subtipo
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
//Comprobar si el tipo está soportado por la impresión
System.out.println("Flavor soportado?:"
+ service.isDocFlavorSupported(flavor)); //true o false
System.out.println("Flavor mime type:"+flavor.getMimeType());
//Listar los tipos soportados
DocFlavor[] flavs=service.getSupportedDocFlavors();
for(int c=0;cSystem.out.println("Tipo soportado: " +
flavs[c].getMimeType() +" " + flavs[c].toString());
}

//Listar todos los servicios que soportan un tipo de impresión,
//en este caso impresión en color
aset = new HashAttributeSet(); //Creamos grupo de atributos
aset.add(ColorSupported.SUPPORTED); //Añadimos atributo
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, aset);
System.out.println("Número de impresoras en color: "+services.length);
//Si hay alguna impresora que cumple la condición
if (services.length > 0) {
for(int i=0;iSystem.out.println("Impresora en color " + (i+1) + ":"
+ services[i].getName()); //Muestra el nombre
}
}
















FaNK.




Para cualquier duda o tirón de orejas, e-mail a:
barf_ak_ARROBA_yahoo.es









viernes
jun282002

Nueva web oficial de Java

Parece que la gente de Sun por fin se ha dado cuenta de que la web oficial de Java en http://java.sun.com era demasiado compleja y no permitía encontrar lo que uno buscaba fácilmente, y la han rediseñado totalmente, poniendo las cosas más comunes al alcance de un click de ratón y haciéndola mucho más intuituva y agradable de navegar.

Ahora, por ejemplo, desde la portada podremos dirigirnos fácilmente a las secciones de J2SE, J2EE y J2ME, ir a las páginas de download del J2SDK 1.4, del tutorial de Java, visitar la documentación, entrar en la Developer Connection, etc...
jueves
jun272002

PalmOS apuesta fuerte por Java

PalmSource no se quiere quedar atrás en la carrera tecnolýgica y ha anunciado un acuerdo de colaboracrión con Insignia Solutions cuyo objetivo es integrar Insignia Mobile Foundation, una JVM, con PalmOS.


Está JVM para Palm está basada en el PDA Profile que está a punto de salir. Además Palm ha anunciado su interýs por la ttecnología Java para competir con rivales como Microsoft o QualComm.


Desde luego incluir una JVM con toda Palm es un nuevo avance espectacular para toda la comunidad Java, sobre todo para los desarrolladores que podrýn explotar más todavía la filosofýa WORA. Podéis ver la noticia reflejada aquí
jueves
jun272002

Sun Certified Programmer for Java2 1.4

Acaban de salir los objetivos del nuevo examen de certificación como programador Java para la versión 1.4, examen disponible a partir de Agosto.


Las novedades más llamativas son la eliminación de las partes dedicadas a IO y AWT (desfasado, y Swing es demasiado grande para meterlo ahí), y la inclusión de las aserciones como tema.


En definitiva, nueve secciones para el nuevo examen, cuyos objetivos se encuentran aquí