Mostrando entradas con la etiqueta Java. Mostrar todas las entradas
Mostrando entradas con la etiqueta Java. Mostrar todas las entradas

miércoles, 26 de marzo de 2008

Ejercicio 1: Diseño de la ventana

Descripción



Desarrollar un programa que muestre una secuencia de numeros determinada (1, 2, 3, 4, 5, 7) de manera constante e infinita (después de mostrar un 7 deberá mostrar un 1, 2, 3). Los datos deben mostrarse en una ventana en el centro de la misma como un texto grande y poseer un botón para detener el conteo y la secuencia.

Solución propuesta



Comenzemos por la parte más aburrida desde mi punto de vista: Crear la interfaz, para esto yo se que hay herramientas pero prefiero hacerlo a mano. Para esto necesitamos una ventana, un texto grande y un botón, así que usaremos un JFrame, un JLabel y un JButton.


public class Exercise1 extends JFrame {
private JLabel numberLabel = null;
private JButton stopButton = null;

//Sobreescribimos el constructor para darle un titulo al frame
public Exercise1() {
super("Ejercicio 1");

numberLabel = new JLabel(" ");
stopButton = new JButton("Detener");
}
}


Ahora continuemos con la apariencia de la etiqueta, necesitamos que sea un texto grande


//Recuperamos la fuente de la etiqueta
Font font = numberLabel.getFont();
//Recreamos la fuente con un tamaño de 32 puntos
font = font.deriveFont(32.0);
//Establecemos la fuente nueva de la etiqueta
numberLabel.setFont(font);


Ordenamos los elementos dentro de la ventana. A mi me parece un modelo muy aplicable a un BorderLayout


this.setLayout(new BorderLayout());
this.add(numberLabel, BorderLayout.CENTER);
this.add(stopButton, BorderLayout.PAGE_START);


Y finalmente mostramos el contenido de la ventana


//Ajustamos la ventana para el tamaño de los componentes
this.pack();
//Mostramos la ventana
this.setVisible(true);

Ejercicio 1: Contador infinito

Descripción



Desarrollar un programa que muestre una secuencia de numeros determinada (1, 2, 3, 4, 5, 7) de manera constante e infinita (después de mostrar un 7 deberá mostrar un 1, 2, 3). Los datos deben mostrarse en una ventana en el centro de la misma como un texto grande y poseer un botón para detener el conteo y la secuencia.

jueves, 7 de febrero de 2008

Gráficas con rangos variables HSSF - POI

Recientemente comence a utilizar Apache POI para crear archivos de Excel desde Java y me encontre con un problema que podría calificar de trivial pero que me quito algo de tiempo.

Supongamos que queremos crear una gráfica que muestre los valores anuales desde una fecha determinada hasta el día de hoy. La solución puede sonar simple: creamos una gráfica en un archivo y listo, posteriormente escribimos los valores mediante POI en otro archivo tomando como base el primero. Cuando el número de años entre la fecha actual y la de inicio cambia (el tiempo pasa) el problema deja de ser trivial.

La principal razón por la que esto sucede es por el simple hecho de que POI no incluye soporte para gráficas, entonces, no es posible crearla o alterarla de manera directa. La solución que yo encontre es un poco rebuscada pero funciona.


  1. Crear el archivo con la gráfica en Excel con datos de muestra.

  2. Crear un rango nombrado que cuente el numero de valores que pueden cubrir nuestros datos.

    1. En el menú Insert > Name > Define...

    2. En la parte inferior crear una formula para seleccionar el rango:

      =OFFSET(Hoja!$B$1, 1, 0, COUNTA(Hoja!$B:$B) - 1, 1)


      OFFSET selecciona un rango a partir de la celda pasada como primer parametro con el numero de filas indicado (el primer uno), el numero de columnas (el cero), y un alto igual al tercer parametro con un ancho del cuarto parametro.

      COUNTA cuenta las celdas no vacias de el rango pasado como parámetro.



  3. Crear la gráfica hasta el paso donde se seleccionan los datos de origen.

  4. Una vez en este paso dar clic en la pestaña de series

  5. Dentro de la pestaña series cambiar el valor de valores y etiquetas por los nombres definidos previamente

  6. Ahora pueden agregarse datos en la fila por debajo de la ultima con datos y estos se agregaran a la gráfica.

  7. El resto es sencillo con POI

domingo, 6 de enero de 2008

Selenium Server + JUnit

Selenium no solamente puede utilizarse de la manera que se menciono en el post anterior, sino que puede usarse de manera practicamente automatizada con varios lenguajes de programación, obviamente uno de ellos es Java.

Utilizando Selenium Server podemos desarrollar nuestras pruebas en el lenguaje ya conocido, Java, y podemos observar el comportamiento en el navegador real. Este post explica a groso modo la manera de comenzar con este proceso.

Nota: Para el ejemplo se asume que se utilizara Firefox y por ende, que este se encuentra instalado en la computadora donde se realizaran las pruebas, si desea utilizar IE en lugar de Firefox sustituya la cadena "*firefox" por "*iexplore".

Iniciar Selenium Server




  1. Primeramente es necesario descargar el software Selenium RC del site de Selenium.

  2. Extraer el contenido del archivo descargado

  3. Abrir una consola (cmd o terminal) y moverse al directorio donde se extrajo Selenium RC

  4. Cambiar a la carpeta selenium-server-x.x. Dependiendo el numero de la versión usada

  5. Dentro de esta carpeta teclear java -jar selenium-server.jar. Como resultado debera aparecer la consola del servidor indicando que esta escuchando en el puerto 4444.



Desarrollo de la prueba



El proceso de desarrollo llegará a escribir un simple TestCase que abra la página de Google. El código será parecido al siguiente (JUnit 3.8).


package selenium.test.sample;

import junit.framework.TestCase;

import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;

public class TestInicial extends TestCase {
private Selenium selenium;

protected void setUp() {
selenium = new DefaultSelenium("localhost", 4444,
"*firefox", "http://www.google.com.mx");;
selenium.start();
}

public void test1() {
selenium.open("http://www.google.com.mx/");
assertNotNull(selenium.getTitle());
}

protected void tearDown() {
selenium.stop();
}
}


Para poder compilar el test es necesario agregar al CLASSPATH actual las librerias que estan dentro de la carpeta selenium-java-client-x.x de la distribución de Selenium RC.

Una vez desarrollado el test procedemos a ejecutarlo, como resultado del mismo deberíamos de ver que se abre un navegador, este carga la página de Google, y se cierra inmediatamente. A manera de ejemplo se ha agregado un pequeño test que nos dice que obtuvimos una página con titulo.

Las posibilidades de prueba van desde enlaces, tablas, etc. Para asegurarse de entender estas capacidades puede leerse la documentación de Selenium que acompaña la distribución de Selenium RC.

lunes, 12 de noviembre de 2007

lunes, 5 de noviembre de 2007

Diseño de Software Java Guiado por Pruebas

Un artículo que recien escribi y puede encontrarse en Scribd

lunes, 17 de septiembre de 2007

Material del Curso de Web Development

Resumen del material revisado en las sesiones del curso.

Revisen los requerimientos generales del mismo.

Material.

Actualización:

jueves, 13 de septiembre de 2007

JUnit

JUnit es una libreria Java que permite realizar pruebas de unidad sobre las clases que han sido desarrolladas dentro de un proyecto orientado a objetos. Por medio de JUnit podemos probar parte de la calidad del software que desarrollamos.

Las pruebas que se pueden desarrollar sobre JUnit parten de un sencillo concepto: assert, un assert en una condición que debe cumplirse para considerar que nuestra clase probada funciona de la manera esperada.

Además, los JUnits permiten realizar operaciones complejas dentro de una clase utilizando código Java para las pruebas.

Un UnitTest tiene la siguiente estructura:
  1. 1 método protegido setUp( ) que configura el entorno antes de realizar cualquier prueba.
  2. 1 método protegido tearDown( ) que destruye el entorno de pruebas.
  3. Varios métodos con el nombre test* que son cada una de las pruebas que se van a realizar.
Dentro de cualquiera de estos métodos pueden utilizarse los métodos siguientes:
  1. assertTrue(mensaje, condicion), assertTrue(condicion). Que comprueba que la condicion booleana que se le pasa como parametro sea forzosamente correcta.
  2. assertFalse. Lo mismo pero al reves.
  3. assertEquals(valor, valor), assertEquals(mensaje, valor, valor). Se asegura que los valores pasados como parametro sean iguales.
  4. assertNotEquals( );
  5. assertSame(Objeto, Objeto). Los objetos deben hacer referencia al mismo objeto, es decir, la misma direccion de memoria.
  6. assertNotSame( ).

martes, 11 de septiembre de 2007

JSF's... va...

Los JSF's estan bastante mas avanzados que Struts, creo que si, por lo menos he escuchado bastantes comentarios en Web sobre la extensibilidad de los componentes de JSF, además de que el modelo de transferencia no es tan complicado. Pero:

  1. JSF se centra en los componentes, no en las funciones.
  2. Pesa un buen como tecnología
  3. Los tiempos de respuesta son algo complicados
  4. La mayoria de implementaciones son $$$
  5. El MyFaces es lento
  6. Los componentes o UI de JSF con AJAX dependen de terceros
Regularmente estaria de acuerdo en usar un estandar, pero para ahorrar recursos y librerias extensivas prefiero el Struts...

domingo, 9 de septiembre de 2007

Conceptos para Web

Una lista de los conceptos generales para crear aplicaciones en Web y lo que hace falta, primero el Software:
Las tecnologías vamos a revisarlas poco a poco y con calma, por lo pronto por lo menos debería de instalar el JDK, Eclipse y Tomcat. El resto podemos irlo haciendo poco a poco.

martes, 21 de agosto de 2007

Algunos materiales para el SCJA

Pues aunque no deberian ir necesariamente en este blog vamos a poner algunos materiales que bien podrian servir para medio guiarte en las obscuras profundidades del SCJA:

  1. El site oficial del exámen.
  2. Una guía rápida del UML que deberías conocer.
  3. Preguntas de prueba generadas por personas que ya tomaron la certificación.
  4. Un site con algunos recursos interesantes.
  5. Preguntas de ejemplo desde Alemania. Clic en la izquierda para entrar a cada sección.
  6. Mas mocks Cafe4Java.
  7. Mock de JavaGuru.
  8. Todo junto en JavaRanch.
De vez en cuando voy a poner algunos tópicos sobre esos detalles del SCJA, pero no prometo en realidad nada y no olviden que el detalle es que estudien.

martes, 7 de agosto de 2007

Algo de JTables pa' variar

Bueno, los JTables pueden llegar a se un poco enigmaticos, y hacer que las cosas pasen con ellos a veces resulta un poco díficil, pero con un poco de práctica podemos hacer un buen de cosas con el. Para empezar vamos a ver una manera sencilla de crear un mapeo entre una clase POJO (Plan Old Java Object, Objeto Java Sencillo y Jodido), y lo utilizamos para mostrarlo desde una base de datos a un JTable. Es algo sencillo en realidad. Pero para lograrlo necesitamos una nuevla clase del conjunto Swing, esta clase se llama TableModel y es una interfaz que permite decirle a un JTable que presentar en una tabla. Vamos por ejemplo.


//AbstractTableModel implementa TableModel y la mayoría de sus métodos
class TModelo extends AbstractTableModel {
private ArrayList lista;

//Cargamos los datos a una lista de POJO's
public TModelo(ResultSet rs) {
try {
rs.first();
do {
POJO pojo = new POJO();
pojo.campo1 = rs.getString(1);
pojo.campo2 = rs.getInteger(2);
pojo.campo3 = rs.getString(3);

lista.add(pojo);
} while(rs.next());
} catch(Exception e) { ; }
}

//Indicar cuantas filas va a tener la tabla
public int getRowCount() { return lista.size(); }
//Indicar cuantas columnas va a tener la tabla. El numero de campos en este caso
public int getColumnCount() { return 3; }
//Objeto en cada celda
public Object getValueAt(int fila, int columna) {
try {
POJO pojo = (POJO) lista.get(fila);
if(columna == 0)
return pojo.campo1;
if(columna == 1)
return new Integer(pojo.campo2);
if(columna == 2)
return pojo.campo3;
} catch(Exception e) {
//Regresamos un valor vacio por si las moscas
return "";
}
}
//nombre de las columnas
public String getColumnName(int col) {
if(columna == 0) return "Campo 1";
if(columna == 1) return "Campo 2";
if(columna == 2) return "Campo 3";
}
//Indicamos si determinada celda es editable
public boolean isCellEditable(int f, int c) {
return false;
}
}

//Una clase POJO muy sencilla
//Esto no deberia hacerse, deberiamos usar geters y seters
class POJO {
public String campo1;
public int campo2;
public String campo3;
}


Una vez que tenemos un TableModel podemos crear una Tabla con los datos que tiene el modelo mismo.


JTable tabla = new JTable(new TModelo(rs));

JFrame fra = new JFrame();
//Si se agrega la tabla de manera directa entonces no se muestran los encabezados
fra.add(new JScrollPane(tabla));


Ahora, un TableModel puede servir para hacer muchas cosas, por ejemplo, podemos filtrar los datos de uno de ellos por medio de otro, a esto se le conoce como Decorator.


class FilterModel extends AbstractModel {
private TableModel original;
private ArrayList pasan = new ArrayList();

public FilterModel(TableModel tm) {
original = tm;
}

//Implementamos un filtro sencillo para un solo campo sobre el modelo anterior
public void filtra(String valor) {
//Quitamos todo
pasan.clear();

//Filtramos cada valor y ponemos los que coinciden con el valor
for(int i = 0; i < original.getRowCount(); i++)
if(("" + original.getValueAt(i, 1)).indexOf(valor) != -1)
pasan.add(new Integer(i));
}

public String getColumnName(int c) { return original.getColumnName(c); }
public int getColumnCount() { return original.getColumnCount(); }
public int getRowCount() { return pasan.size(); }
public Object getValueAt(int f, int c) {
int real = ((Integer) pasan.get(f)).intValue();
return original.getValueAt(real, c);
}
}


Una forma sencilla de hacer las cosas.

Chaito sres...

miércoles, 1 de agosto de 2007

Haciendo Frames Internos

En Java lo más parecido que hay a un formulario MDI son los Frames Internos, estos son miniventanas que se pegan a una ventana marcada como JDesktopPane como contenedor principal, y deben agregarse a estos.

Vamos a ver como funcionan de manera general estas cosas raras:


JFrame padre = new JFrame("Varios Frames internos");

JDesktopPane jdp = new JDesktopPane();

padre.setContentPane(jdp);

//Crea un Frame interno que no puede cambiar su tamaño, puede cerrarse, no puede
//maximizarse y puede minimizarse. Los parametros son aleatorios y en ese orden.
JInternalFrame jif = new JInternalFrame("Titulo", false, true, false, true);
jif.pack();
jif.setVisible();

//Después ponemos el elemento en el frame
jdp.add(jif);


Ahora, algunas veces puedes querer que un InternalFrame no pueda cerrarse o dejarse mientras estemos usandolo. Esto en realidad no se puede hacer de manera sencilla; pero usando listeners podemos equilibrar las cosas. Vamos a ver como crear un JInternalFrame que funciona de cierta manera como una ventan modal:


JInternalFrame jif = new JInternalFrame();
jif.addInternalFrameListener(new InternalFrameAdapter() {
public void internalFrameIconified(InternalFrameEvent e) {
((JInternalFrame) e.getSource()).setVisible(true);
}

public void internalFrameDeactivated(InternalFrameEvent e) {
((JInternalFrame) e.getSource()).setVisible(true);
}
});


Esa es una forma rápida de hacer que las cosas funcionen de la manera que no deberían hacerlo. Si lo que estan buscando es una forma de mostrar dialogos Internos no hay más que reemplazar los métodos showXXXXDialog de JOptionPane por showInternalXXXXDialog.

martes, 31 de julio de 2007

Herramientas para Java

Generalmente el manejo de aplicaciones Java es simplemente considerado plano, sin embargo, los desarrollos Java estan plagados de opciones de trabajo que permiten simplificar el desarrollo, distribución, y mantenimiento de las aplicaciones; existen multiples herramientas que pueden hacer más sencillo el trabajo de Java en entornos de trabajo, vamos a revisar algunas de ellas.
  • Eclipse: Es un IDE que permite desarrollar aplicaciones Java de una manera intuitiva. Es completamente gratuito y puede extenderse de manera casi ilimitada con plugins para realizar diferentes tareas además de las que contiene originalmente. En lo personal me encanta su soporte para integrar muchas de las demás herramientas que aquí se mencionan. Pueden encontrar diversas versiones del IDE, opción personal TFTP y Callipso

  • BlueJ: Cuando no requerimos de todo el poder y las gracias que nos ofrece Eclipse, BlueJ es una buena opción, ofrece poco soporte para herramientas avanzadas, pero nos permite desarrollar aplicaciones sencillas, depurarlas de una manera intuitiva y verlas como dibujos. Cualquier cosa seria no cabe en BlueJ pero es ligero y fácil de usar para cuestiones didacticas

  • Ant: Es una herramienta que permite automatizar muchas de las tareas latosas y repetitivas que se realizan en Java, probablemente no entiendan que hacer con Ant y les parezca una forma fastidiosa de escribir XML pero cuando hablemos de Deploy y estrategías de pruebas automatizadas.

  • JUnit: Es una librería realizada completamente en Java que nos permite automatizar las pruebas y condiciones que deben ejecutarse en cada elemento del programa de manera separada o bien de manera integrada, es una forma de saber que las cosas trabajan antes de ponerlas en producción.

  • HttpUnit: Es algo que pegas con el anterior para probar interfaces Web

  • JavaDoc: Parte de la suite Java del SDK que permite generar documentación parecida a la oficial de la API sobre los elementos de los programas que nosotros desarrollemos
Si bien no es indispensable dominar todas estas tecnologías para utilizar Java te pueden hacer la vida bastante fácil.

Listeners

La plataforma Swing se basa primordialmente para el manejo de eventos en el concepto de escucha o Listener; la teoría general establece que existe un objeto al que llamaremos disparador que realiza alguna acción sobre otro objeto reactivo. El objeto entonces informa a varios Listener de que algo ha ocurrido en el disparador. Entonces cada uno de los listeners puede realizar alguna acción en base al evento que ocurrió.

La metáfora que utilizaremos para comprender el concepto es mas o menos el siguiente: Imagina que tenemos un sistema que mide la temperatura del ambiente, este sistema puede conectarse con multiples sistemas independientes; imaginemos entonces que podemos conectar un aparato que pite cada que la temperatura rebase cierto limite, además podemos conectar otro aparato que actualize la temperatura en un sitio Web cada que esta cambie, y podemos conectar más aparatos que realizen funciones diferentes, siempre y cuando sean capaces de saber cuando la temperatura cambia.

Entre los componentes Swing hay una amplia gama de Listener's que se implementan como Interfaces, si queremos que determinada clase responda a los eventos de un objeto es necesario que este implemente la interface Listener adecuada y que se registre con el objeto que genera los reportes de evento. El ejemplo más sencillo es el de los botones comunes y la interfaz ActionListener.


JButton boton = new JButton("El boton");

//ActionListener es la clase encargada de escuchar eventos de acción
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.out.println("Se ha hecho click en el botón");
}
}

boton.addActionListener(al);

//Registramos el nuevo objeto como escucha del botón
JButton boton2 = new JButton("Otro boton");
//Podemos agregar un Listener a varios elementos
boton2.addActionListener(al);
//E igualmente podemos registrar mas de un listener por objeto
boton.addActionListener(otro_listener);

//Borramos el registro de escucha cuando deja de interesarnos
boton.removeActionListener(al);


Algunos elementos pueden llegar a tener multiples interfaces para utilizar Listeners, como el caso de los JFrame's, que permiten recibir WindowListener, FrameListener, PropertyChangeListener, MouseListener, MouseMotionListener entre otros. En la documentación de Java pueden encontrarse bastantes referencias a los listeners que acepta cada uno de los componente Swing.

Existen casos de Listeners que declaran muchos métodos, como el caso del WindowListener que implementa windowClosed, windowClosing, windowIconofied, y otros muchos, estos métodos deben cubrirse completamente en cualquier clase que implemente la interfaz, pero para facilitar las cosas por cada una de estas clases existe una clase Adapter que implementa una funcionalidad vacia en todos estos métodos.


//Usando el adapter nos evitamos escribir todos los métodos
WindowListener wl = new WindowAdapter() {
public void windowClosed(WindowEvent we) {
System.out.println("Se cerro la ventana");
}
}

lunes, 30 de julio de 2007

Look And Feel

Java ofrece funcionalidades para cambiar la forma en la que se muestran las ventanas que conforman un sistema, cada parte del sistema completo puede verse como si se encontrara en otro sistema operativo o bien con un esquema gráfico diferente. Por medio de esta herramienta podemos hacer que los desarrollos Java luzcan visualmente como si se hubieran realizado en un lenguaje común, como VB; o ejecutado desde un sistema operativo cualquiera y verse como un Mac o un Windows.

Para establecer el LookAndFeel de un sistema de ventanas se usa código como el siguiente:


try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} cactch(Exception e) {
//No es posible cambiar el Look and Feel;
}


Los LookAndFeel más comunes en Java son los siguientes:






















Clase LookAndFeel
javax.swing.plaf.metal.MetalLookAndFeel LookAndFeel de Java
com.sun.java.swing.plaf.gtk.GTKLookAndFeel GTK+ (Solaris normal)
com.sun.java.swing.plaf.motif.MotifLookAndFeel Motif (Linux viejitos)
com.sun.java.swing.plaf.windows.WindowsLookAndFeel LookAndFeel normal de Windows (No lo recomiendo)


Pueden encontrarse en Internet varios LookAndFeel que pueden mejorar en gran medida nuestra aplicación de manera muy sencilla.

Una nota final: el LookAndFeel se aplica de manera general a las ventanas existentes y las futuras ventanas, y todas las ventanas que existan hasta que se cambie el LookAndFeel.

viernes, 27 de julio de 2007

Menús

El manejo de los menús en Swing se realiza por medio de las clases JMenu, JMenuBar, JCheckBoxMenuItem, JMenuItem, JRadioMenuItem y JPopupMenu. De la misma forma es necesario iniciar con el manejo de los Actions para poder reutilizar eventos a travez del sistema.

Para crear un menú regular necesitamos un objeto JFrame o JInternalFrame para poner en el el menú. Primeramente agregamos un elemento JMenuBar para poder pegar ahi el menú y dentro de el elementos JMenu, y JMenuItem o una de sus subclases en el interior.


JFrame ventana = new JFrame("Ejemplo de menus");

JMenuBar barra = new JMenuBar();
//Ponemos el menu en Vertical
barra.add(Box.createVerticalGlue());

JMenu archivo = new JMenu("Archivo");
JMenuItem guardar = new JMenuItem("Guardar");
archivo.add(archivo);
archivo.addSeparator();

ventana.setMenuBar(barra);


Bueno, esta es la teoría general de los menús, cada uno de los menús puede personalizarse en base a Actions, los actions son elementos que definen como se realiza un determinado proceso, le asignan un nombre y una imagen, lo que lo hace facilmente reutilizable en otros entornos; en este caso hablamos de un patron conocido como Comand, donde el elemento action define como se realiza una operación y puede ser establecido en multiples elementos sin problemas, por ejemplo un botón, un elémento de menú, un espacio de una barra de herramientas etc.

Para crear Actions generalmente se extiende la clase AbstractAction de una manera mas o menos así:


class SalirAction extends AbstractAtion {
public SalirAction(ImageIcon imagen) {
super("Texto", imagen);
}

public static void actionPerformed(ActionEvent ae) {
System.exit(0);
}
}

Action salir = new SalirAction(imagen);
JButton btnSalir = new JButton(salir);
JMenuItem mnuSalir = new JMenuItem(salir);


Con este modelo tanto el boton como el menu comparten el mismo texto y el mismo funcionamiento, lo que hace más fácil reutilizar esta funcionalidad en el sistema. Pero la reutilización de un Action va un poco mas alla, cuando utilizamos un action este establece más propiedades que puden visualizarse en otro elementos. Esto suele establecerse en el constructor de la clase Action por medio del método putValue(clave, valor).


public SalirAction(ImageIcon imagen) {
super("Texto", imagen);

putValue(SHORT_DESCRIPTION, "Tool Tip Text del control que contenga al action");
putValue(NAME, "Nombre del Action");
//Estableces la acción en respuesta a CTRL + A
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
putValue(LONG_DESCRIPTION_KEY, "Descripción larga");
putValue(LARGE_ICON_KEY, imagenGrande);
putValue(SMALL_ICON, imagenChica);
//Establece el nemonico del action a N
putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_N));
//Se establece el estado seleccionado del action
putValue(SELECTED_KEY, Boolean.TRUE);
}


Dependiendo del tipo de control del que se este hablando podemos reutilizar las funcionalidades de las claves anteriores.

jueves, 26 de julio de 2007

Introducción a Swing

El paquete más comunmente utilizado en Java para crear interfaces gráficas es el paquete Swing, este contiene una serie de controles que se puede utilizar pero Swing ws un poco más que solamente controles:
  • Controles GUI para presentación en pantalla.
  • La interfaz Java2D para dibujo en formularios.
  • Look & Feel's intercambiables.
  • Control de operaciones de transferencia (Copiar, Pegar)
  • Registro de acciones deshacibles.
  • Soporte UNICODE.
  • Accesibilidad.
En posteriores posts vamos arevisar algunos conceptos generales y avanzados de Swing más a detalle, por el momento vamos a considerar los patrones que se utilizan en Swing una y otra vez.

  • Action. Action es una clase que engloba cualquier acción que se pueda realizar en el sistema, lo que debería pasar cuando ocurre un evento. Un elémento Action se comporta de manera completamente independiente de sus contenedores, así que podemos hacer que un mismo Actión se corresponda con muchos controles.
  • Listener. El control de eventos en Java se basa en el concepto de escucha o Listener, un escucha es una clase que implementa determinada interfaz de eventos, cuando un objeto dispara un evento utiliza esta interfaz para comunicar a todos los objetos escuchas de que algo ha ocurrido en el. Utilizando los Listeners podemos crear clases de control de multiples elementos o bien tener más de un controlador de evento para un solo control.
  • Model. Un Model define la manera en la que se van a presentar los datos dentro de un control determinado. La mayoría de las funcionalidades de un Model permiten que los datos sean alterados en la manera que se visualizan sin, necesariamente, modificar los datos mismos.
En terminos generales, si queremos que algún elemento reaccione a las acciones del usuario o del sistema mismo deberíamos usar Listener's; si conocemos que esa misma acción debe ocurrir por otras causas deberiamos agregar un Action. Generalmente la idea de cambiar el comportamiento y la visualización de los datos es una responsabilidad del Model.

Recursos sobre JDBC

Algunos enlaces interesantes sobre JDBC:

  1. Curso de JDBC oficial.
  2. Curso de lo mismo pero en Español.
  3. JDBC en el JavaTutorial.

Acceso y abstracción de datos

El acceso a la base de datos suele ser un poco complicado y repetitivo, para manejar las cuestiones generales de datos podemos utilizar algunos patrones de diseño para generar clases que puedan encargarse de conectarse a las bases de datos y actualizar estas de la manera más abstracta posible, el primer paso para esto es la conexión de datos compartida.

Dado que en Java no existen variables globales, es necesario buscar otra aproximación para compartir la conexión a lo largo de toda la aplicación, el modelo Singleton puede ayudarnos en esto, en este modelo existe una clase de la que solamente puede existir un elemento en un determinado momento. Un singleton sencillo podría verse más o menos de la siguiente forma.


public class ConexionDB {
private static ConexionDB instance = null;
private Map conexiones;

//El acceso privado hace imposible instanciar directamente esta clase
private ConexionDB() {
conexiones = new LinkedHashMap();
}

//Si requerimos una instancia de la clase deberiamos llamar a este metodo
private static ConexionDB getInstance() {
//LazyInstancing. Creamos el objeto hasta que se necesita
if(instance == null)
instance = new ConexionDB();
return instance;
}

public Connection getIConnection(String driver, String uri, String user, String pass) {
try {
//Verificamos si la conexión no existe ya en Cache
if(conexiones.hasKey(uri))
return (Connection) conexiones.get(uri);

Class.forName(driver);
Connection c = DriverManager.getConnection(uri, user, pass);
conexiones.put(uri, c);

return c;
} catch(Exception e) {
return null;
}
}

//Simplificamos las llamadas para no depender del Singleton en código general
public static Connection getConnection(String driver, String uri, String u, Stirng p) {
return ConexionDB.getInstance().getIConnection(driver, uri, u, p);
}

//Generalmente siempre se usa una sola conexión a DB por default
public static Connection getDefaultConnection() {
return ConexionDB.getInstance().getIConnection("sun.jdbc.odbc.JdbcOdbcDriver",
"jdbc:odbc:osos", "sa", "admin");
}
}


Para utilizar la conexión en otra clase solamente utilizariamos código sencillo:


Connection c = ConexionDB.getConnection("driver", "uri", "user", "pass");
Connection c2 = ConexionDB.getDefaultConnection();