martes, 30 de octubre de 2012

Cómo usar JSON con Java

JSON (JavaScript Object Notation) es un formato sencillo utilizado para el intercambio de datos. Es completamente independiente del lenguaje y una buena alternativa para quienes no gustan del XML. En este post les voy a mostrar la manera de cómo utilizar este popular formato para aplicaciones Java. Si bien es cierto que existen muchas implementaciones, en este post voy a usar la que, a mi parecer, es la más ligera, clara y accesible manera de utilizar JSON en aplicaciones Java. Existe una implementación hecha por Google muy buena pero si queremos utilizarla con applets por ejemplo, vamos a tener problemas.

Bien, lo primero que necesitamos es descargarnos 5 clases: JSONArray, JSONException, JSONObject, JSONString y JSONTokener de json.org y agregarlas a nuestro proyecto de Java de tal manera que nos quede así:
Fig. 1 Árbol de clases del paquete JSON
Hecho esto, podemos crear un bean por ejemplo al que le agregaremos algunos atributos. Este bean podría ser una entidad que haga referencia a una tabla de base de datos por ejemplo. Para este ejemplo vamos a crear un bean Vendedor y un bean Cliente tal como se muestra a continuación:

Creamos la clase Vendedor.
package com.demo.bean;

import java.util.List;

/**
 *
 * @author Rolando
 */
public class Vendedor {

    private int edad;
    private String nombre;
    private String apellido;
    private List<Cliente> clientes;

    public String getApellido() {
        return apellido;
    }

    public void setApellido(String apellido) {
        this.apellido = apellido;
    }

    public List<Cliente> getClientes() {
        return clientes;
    }

    public void setClientes(List<Cliente> clientes) {
        this.clientes = clientes;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
}
Y ahora la clase Cliente:
package com.demo.bean;

/**
 *
 * @author Rolando
 */
public class Cliente {

    private String dirección;
    private String nombre;
    private String telefono;

    public String getDirección() {
        return dirección;
    }

    public void setDirección(String dirección) {
        this.dirección = dirección;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getTelefono() {
        return telefono;
    }

    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }
}
Ahora creamos nuestro método principal en donde instanciamos un objeto Vendedor al que se le asocia dos clientes y creamos el objeto JSON a partir de ello.
public static void main(String[] args) {
    Vendedor v1 = new Vendedor();
    v1.setNombre("Juan");
    v1.setApellido("Perez");
    v1.setEdad(10);
    Cliente c1 = new Cliente();
    c1.setNombre("HIVYMAR");
    c1.setDirección("Victor Emilio Estrada 204");
    c1.setTelefono("5020800");
    Cliente c2 = new Cliente();
    c2.setNombre("PROMESA");
    c2.setDirección("Via. Daule KM 5.5");
    c2.setTelefono("5013604");
    List<Cliente> clientes = new ArrayList<Cliente>();
    clientes.add(c1);
    clientes.add(c2);
    v1.setClientes(clientes);
    //CREAMOS EL OBJETO JSON
    JSONObject obj = new JSONObject(v1);
    System.out.println(obj);
}
Al imprimir en consola el resultado podremos ver en la Fig. 2 que no es lo que esperabamos.
Fig 2. Objeto JSON simple
Para eso justamente utilizamos otra de las clases que nos hemos descargado: JSONArray. Para mostrar el funcionamiento de esta clase voy a implementar un segundo métood main, de tal manera que podamos reflejar a través de un objeto JSON a nuestro objeto Vendedor con sus respectivos clientes.
public static void main(String[] args) {
    Vendedor v1 = new Vendedor();
    v1.setNombre("Juan");
    v1.setApellido("Perez");
    v1.setEdad(10);
    Cliente c1 = new Cliente();
    c1.setNombre("HIVYMAR");
    c1.setDirección("Victor Emilio Estrada 204");
    c1.setTelefono("5020800");
    Cliente c2 = new Cliente();
    c2.setNombre("PROMESA");
    c2.setDirección("Via. Daule KM 5.5");
    c2.setTelefono("5013604");
    List<Cliente> clientes = new ArrayList<Cliente>();
    clientes.add(c1);
    clientes.add(c2);
    //CREAMOS EL OBJETO JSON
    JSONObject objVendedor = new JSONObject(v1);
    JSONArray objClientes = new JSONArray();
    try {
        for (Cliente cliente : clientes) {
            JSONObject objCliente = new JSONObject();
            objCliente.put("nombre", cliente.getNombre());
            objCliente.put("direccion", cliente.getDirección());
            objCliente.put("telefono", cliente.getTelefono());
            objClientes.put(objCliente);
        }
        JSONObject objVendedorClientes = new JSONObject();
        objVendedorClientes.put("vendedor", objVendedor);
        objVendedorClientes.put("clientes", objClientes);
        System.out.println(objVendedorClientes);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
El resultado mostrado en la Fig. 3 refleja de mejor manera lo que realmente queremos representar y a su vez, este objeto puede ser interpretado por cualquier lenguaje de programación.

Fig. 3. Resultado de la generación de ub objeto JSON que contiene listas como elementos.
Bueno, espero haber sido claro a  lo largo de este post. Nos vemos hasta una próxima oportunidad. Y no dejen de enviar sus comentarios a la página de Facebook de este Blog.

Hasta una próxima oportunidad.

miércoles, 17 de octubre de 2012

La distancia de Levenshtein

El algoritmo de la Distancia de Levenshtein es un procedimiento mediante el cuál se determina el menor número de cambios (inserción, eliminación o sustitución) que se tienen que hacer a una cadena de caracteres para poder obtener otra. Por consiguiente la entrada para este algoritmo son dos cadenas de texto, de las cuales se determinará qué tan diferentes son estas dos palabras. Los usos de este algoritmo son muy diversos, entre los que destacan correctores ortográficos, minería de datos o bioinformática.
El algoritmo, basado en programaciónn dinámica, se muestra en la figura 1, y existen implementaciones en muchísimos lenguajes de programación. Y fiel al estilo de este blog les mostraré un applet similar al publicado en esta página pero además con el código fuente disponible esperando que les sea de utilidad.

Figura 1. Algoritmo de la distancia de Levenshtein
El applet del que les mencioné es el siguiente:




Generated by NetBeans IDE

Y el código fuente está disponible en el siguiente enlace:

Descargar

Me despido hasta una próxima oportunidad y no se olviden de dejar sus comentarios.

martes, 16 de octubre de 2012

La amistad en los tiempos de facebook

En primer lugar aclarar que este no es un artículo más en donde se ataca a facebook ya que considero que, bien manejada, es una herramienta muy útil hoy en día. Y es que todos hemos sido testigos de cómo esta aplicación ha ido poco a poco cambiando nuestras vidas y hasta nos ha generado más preocupaciones y necesidades de las que ya teníamos, pero bueno... la gente de la década de los 90 para adelante estamos acostumbrados a esto (mIRC, Latinchat, Messenger, etc).

La forma en que interactuamos con la gente ha cambiado bastante en poco tiempo. Incluso la palabra "amigo" tiene otro significado pues basta con un clic para decir que una persona es tu amigo. Y es esta la razón por la cual me animé a escribir este artículo.

Hoy he tenido un pésimo día, los requerimientos y el control de cambios de un proyecto me están haciendo perder la cabeza y es ahora cuando se necesita de los amigos para conversar y compartir momentos divertidos. Pero ¿de qué amigos hablo?... ¿de amigos del facebook? - No, esos amigos no. Creo que facebook debería llamarlos de otra manera o como g+, agruparlos por categorías pues no todos nuestros contactos son necesariamente nuestros amigos, incluso hay quienes nos tienen cólera, envidía o simplemente les gusta renegar con nuestras publicaciones; y ante esta vasta diversidad una buena idea es clasificarlos y creo que la mejor manera de agruparlos es por las intenciones por las cuales te agregaron o los agregaste. La clasificación es la siguiente:

Amigos: Son aquellas personas que son de verdad tus amigos, que si se encuentran por la calle pueden pasar horas conversando, que han pasado muchas cosas juntos, que pueden ser llamados amigos hoy, el siglo pasado o de aquí a 50000 años. No necesariamente  tienes que darle un like a cada publicación que el otro hace. La interacción se da más allá de las redes de facebook y este solo es un medio más a través del cual estas personas pueden interactuar.

Seudo-espías: Son las personas que disponen de mucho tiempo sin hacer nada y que te han agregado solo porque necesitan saber de tí, de tus movimientos o tus pensamientos, ya sea por interés propio o por terceros. Este tipo de gente es la que, particularmente, detesto. A penas los identifico, los elimino, los bloqueo, los denuncio, en fin... tantas cosas que se pueden hacer.

Resentidos: Son las personas que te detestan, que te envidian y que simplemente no te eliminan porque les gusta regocijarse en su dolor al ver que las cosas te marchan bien. No entiendo las razones por las cuales esas personas no eliminan a uno si tan mal le caemos. Pero recomiendo no eliminarlos a pesar de tenerlos claramente identificados pues no hay nada más placentero que hacerles pasar malos ratos.

Desubicados: Se llama así a los contactos que te agregaron sin tener absolutamente nada en común contigo, que les da igual lo que te sucede pero que no eliminan porque le dan mucha importancia al número de contactos que tienen en facebook.

Proyectados: Creen que para algo bueno puedes servir en algún momento y como no les restas nada, pues no te borran.

Contactos: Son personas que realmente comprenden el significado de facebook, que te han agregado porque comparten actividades comunes contigo y le sacan provecho a la interacción que facebook ofrece intercambiando contigo información, críticas y comentarios. Son los más cercanos a convertirse en amigos.

Espero que este pequeño análisis les pueda servir de guía para clasificar a sus contactos y tomar mejores decisiones antes de enviar o aceptar una invitación. Hasta una próxima oportunidad.

Saludos.

lunes, 15 de octubre de 2012

Transacciones con Java y JDBC

Hay veces que uno no quiere que una sentencia sql tome efecto a menos que otras se completen. A este le llamamos transacciones. Las transacciones son un conjunto de órdenes que representan la unidad de trabajo mínima e indivisible de un gestor de base de datos. Para esto, los gestores de base de datos proveen los mecanismos necesarios para constituir una transacción, pero cuando queremos o debemos manejar este tipo acciones a nivel de aplicación Java nos provee de las herramientas para hacerlo.

El ejemplo mostrado ha sido tomado de la página oficial de tutoriales de Oracle y se han añadido algunas clases para poder hacerlo más comprensible y propenso al error para de ese modo poder apreciar a plenitud el manejo de transacciones.
El caso es el siguiente: supongamos que necesitamos que el administrador de una cafetería actualize los precios de las ventas por semana. Esto implicará que se tenga que actualizar la venta total al mismo tiempo que la venta por semana pues de no darse el caso los datos quedarían inconsistentes. Este es un típico caso de transacciones en donde dos consultas sql distintas convergen en un solo punto y la depencia hace que se vean como una sola cumpliéndose de este modo el principio de atomicidad.

Para solucionar este caso nuestro método encargado de la actualización deberá implementar transacciones y frente a cualquier error deberá dejar la base de datos en un estado consistente. El código mostrado es el encargado de esta tarea:
package com.blogspot.rolandopalermo.dao;

import com.blogspot.rolandopalermo.bean.Coffees;
import com.blogspot.rolandopalermo.util.Conexion;
import com.blogspot.rolandopalermo.util.Constantes;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author Rolando
 */
public class CoffeesDAO {

    public List<Coffees> obtenerTodos() {
        List<Coffees> coffees = new ArrayList<Coffees>();
        String sql = "SELECT * FROM " + Constantes.dbName + ".COFFEES";
        PreparedStatement getaAll = null;
        Connection con = Conexion.obtenerConexion();
        try {
            getaAll = con.prepareStatement(sql); // create a statement
            ResultSet rs = getaAll.executeQuery();
            while (rs.next()) {
                Long id = rs.getLong(1);
                String name = rs.getString(2);
                Double sales = rs.getDouble(3);
                Double total = rs.getDouble(4);
                Coffees cf = new Coffees();
                cf.setId(id);
                cf.setCof_name(name);
                cf.setSales(sales);
                cf.setTotal(total);
                coffees.add(cf);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return coffees;
    }

    public void updateCoffeeSales(HashMap<String, String> salesForWeek)
            throws SQLException {
        PreparedStatement updateSales = null;
        PreparedStatement updateTotal = null;
        String updateString =
                "update " + Constantes.dbName + ".COFFEES "
                + "set SALES = ? where COF_NAME = ?";
        String updateStatement =
                "update " + Constantes.dbName + ".COFFEES "
                + "set TOTAL = TOTAL + ? "
                + "where COF_NAME = ?";
        Connection con = Conexion.obtenerConexion();
        try {
            con.setAutoCommit(false);
            updateSales = con.prepareStatement(updateString);
            updateTotal = con.prepareStatement(updateStatement);

            for (Map.Entry<String, String> e : salesForWeek.entrySet()) {
                Double value = Double.parseDouble(e.getValue());
                updateSales.setDouble(1, value);
                updateSales.setString(2, e.getKey());
                updateSales.executeUpdate();
                updateTotal.setDouble(1, value);
                updateTotal.setString(2, e.getKey());
                updateTotal.executeUpdate();
                con.commit();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            if (con != null) {
                try {
                    System.err.print("La transacción se deshace.");
                    con.rollback();
                } catch (SQLException excep) {
                    e.printStackTrace();
                }
            }
        } finally {
            if (updateSales != null) {
                updateSales.close();
            }
            if (updateTotal != null) {
                updateTotal.close();
            }
            con.setAutoCommit(true);
        }

    }
}
Cuando registramos los datos de ventas de manera correcta, estos se actualizarán en la base de datos.



Si registramos algún dato incorrecto, entonces lanzará una excepción y regresará todos los datos al último estado que mantuvo consistencia.


Y si volvemos a cargar los datos en la tabla obtendremos esto:

Y eso no es todo, pues si vamos a la base de datos podemos apreciar que los datos relacionados a una cafetería permanecen consistentes. Si en una fila ingresamos una cantidad por semana que no representa un número, el valor total en base de datos no se verá afectada y el valor  de ventas por semana regresará a su estado anterior. De esa manera nos aseguramos que el valor total para una cafetería se actualize solo cuando se ingresa un valor correcto para las ventas por semana. Para mayor detalle adjunto el código fuente del proyecto y les dejo el script de la base de datos.
-- MySQL Administrator dump 1.4
--
-- ------------------------------------------------------
-- Server version 5.5.16


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;


--
-- Create schema coffees
--

CREATE DATABASE IF NOT EXISTS coffees;
USE coffees;

--
-- Definition of table `coffees`
--

DROP TABLE IF EXISTS `coffees`;
CREATE TABLE `coffees` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `cof_name` varchar(45) NOT NULL,
  `sales` double NOT NULL DEFAULT '0',
  `total` double NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

--
-- Dumping data for table `coffees`
--

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
Todos los archivos del proyecto los pueden descargar aquí:

 
Espero que les sea de utilidad y no se olviden de seguir este blog a través de su página de facebook.

viernes, 12 de octubre de 2012

Por qué ser blogger

Dedicar más de dos horas al día a una actividad sin esperar recibir algún tipo de retribución económica, sentarse frente a la computadora un sábado por la noche mientras los amigos se van  de fiesta o tener a la enamorada a un costado con una cara de aburrimiento y muchas ganas de querer matarte por no hacerle caso; es una actividad que hoy en día tiene nombre propio: Ser blogger. Muchas personas me han preguntado la razón por la cual he creado y mantengo este blog y pues, siempre he dado respuestas muy variadas sin embargo quiero resumirlas en este post y darles a conocer el por qué de la existencia de rolandopalermo.blogspot.com.
- A lo largo de mi carrera universitaria siempre he usado el internet como una herramienta para complementar lo aprendido y creo que todo es un juego de retroalimentación. Si el internet a través de sus blogs y foros me brinda x de conocimiento entonces yo debo devolverle x+k, ∀ kNk0. Pensar que has encontrado una página con algo "oculto" y que solo tú lo sabes es un gran error pues cientos de personas ya habrán accedido a la misma información, además si alguien la puso ahí es porque quiere que ese conocimiento se comparta y tú la estás ocultando.

- Todo lo posteado es algo que perdura en mi mente pues gracias a los comentarios de la gente y mediante la resolución de sus dudas aprendo cada día más. Es como una bitácora pues si algo no recuerdo como se hacía sencillamente reviso mi blog y veo una explicación hecha por mí mismo y que se me hace más fácil entender.

- Me permite mantenerme actualizado pues siempre debo investigar antes de postear, informarme para no brindar información errada.

- He creado una página de Facebook y ya cuento con algunos seguidores a quienes les estoy infinitamente agradecido y a pesar de no tener la acogida que tienen las páginas de memes igual me siento feliz pues se que cada like es un like pensado pues habiendo miles de blogs de tecnología la gente me ha tenido en consideración y espera recibir algo más de parte de este blog. Y es justamente el cumplimiento de esas expectativas que las personas tienen lo que impulsa a este humilde blog. La figura 1 es una captura de pantalla de las estadísticas que semana a semana entrega Facebook.

Figura 1. Estadísticas de la página en facebook de este blog.
- ¡Está bien!, acepto que existe publicidad en mi blog sin embargo como programador freelance puedo conseguir mucho más... pero dedicar tiempo a desarrollar aplicaciones por dinero no es algo que llame mi atención (Creo que ya es suficiente con el trabajo en la oficina). Es más gratificante un comentario de agradecimiento, un like en la página de facebook o un mensaje personal comentándome lo mucho que le sirvió lo posteado. No hay mejor paga que eso.

Y estoy seguro que muchas personas que mantienen algún blog comparten perspectivas similares. Por mi parte he decidido hacer crecer este blog enriqueciendo su contenido día a día pues la escencia de este blog es entregar lo que las personas esperan, allanar un poco el difícil camino de los que han decidido andar los senderos de la informática, de la computación o electrónica.

Espero poder seguir compartiendo el conocimiento con ustedes y bueno, agradecerles una vez más la consideración y gratitud que le han entregado a este blog.

Saludos y hasta una próxima oportunidad.

martes, 9 de octubre de 2012

Control de un robot móvil con Java y microcontrolador 18F4550

Siguiendo con nuestras publicaciones orientadas al uso de microcontroladores PIC, en esta oportunidad voy a mostrar la manera de como controlar la movilidad de un robot terrestre utilizando Java y la tarjeta de adquisición de datos mostrada en el artículo pasado. Para el ejemplo diseñaremos una interfaz gráfica que nos permita operar un robot móvil de una buena manera.
La interfaz que se va a usar se muestra en la figura 1. En esta se pueden apreciar 2 botones con los cuales se va a controlar un robot de 4 llantas, cada una con tracción independiente. Los movimientos que se implementaron son los dos más básicos que puede tener un robot: ir hacia adelante o hacia atrás.


El código fuente que se encarga de realizar este trabajo es el siguiente:
private void btnAdelanteMousePressed(java.awt.event.MouseEvent evt) {                                         
// TODO add your handling code here:
    byte LED = 0x55;
    if (send_command(cmd_TRACCION_P, LED)) {
        mostrarMensaje("Mover robot hacia adelante");
    }
}                                        

private void btnAdelanteMouseReleased(java.awt.event.MouseEvent evt) {                                          
// TODO add your handling code here:
    byte LED = 0x00;
    if (send_command(cmd_TRACCION_P, LED)) {
        mostrarMensaje("Detener robot");
    }
}                                         

private void btnAtrasMousePressed(java.awt.event.MouseEvent evt) {                                      
// TODO add your handling code here:
    byte LED = (byte) 0xAA;
    if (send_command(cmd_TRACCION_P, LED)) {
        mostrarMensaje("Mover robot hacia atras");
    }
}                                     

private void btnAtrasMouseReleased(java.awt.event.MouseEvent evt) {                                       
// TODO add your handling code here:
    byte LED = 0x00;
    if (send_command(cmd_TRACCION_P, LED)) {
        mostrarMensaje("Detener robot");
    }
}                                      

public boolean send_command(byte command, byte param1) {
    boolean value = false;
    try {
        byte[] out = {command, param1};
        iface.QWrite(out, 2, 1000);
        value = true;
    } catch (UnsatisfiedLinkError ex) {
        mostrarMensaje("NVerifique conexión de dispositivo.");
        value = false;
    } finally {
        return value;
    }
}
La tarjeta de adquisición de datos usada por este programa fué utilizada también en el robot Gero2. Aquí les dejo un video para que puedan apreciar su funcionamiento:


El código fuente lo encuentran disponible en el siguiente enlace:

 

Así mismo recomiendo leer este artículo para poder ejecutar el proyecto: http://rolandopalermo.blogspot.com/2012/10/java-usb-pic-conversor-analogico-digital.html

lunes, 8 de octubre de 2012

Diferencia entre Interface y Herencia

Desde que iniciamos nuestro camino en el mundo Java escuchamos decir que la herencia múltiple no está permitida, pero que para salvar este problema existen las interfaces. Entonces ¿podemos decir que las interfaces son un tipo de herencia?, ¿Ambos conceptos modelan el mismo aspecto del mundo real?... así como este par de preguntas, pueden surgir muchas más sin embargo la respuesta es sencilla y se la voy a mostrar con un sencillo ejemplo.
La herencia es un mecanismo utilizado para crear clases a partir de clases existentes y modelar comportamientos comunes, siguiendo un esquema jerárquico. Por ejemplo de la superclase Mamífero pueden extender clases como Perro, Gato y Ratón, tal como se muestra en la figura 1.

Figura 1. La herencia crea clases a partir de clases existentes.
 Por otro lado, las interfaces representan un concepto mediante el cual se puede asociar comportamientos comunes a dos clases totalmente distintas. La figura 2 ilustra mejor este concepto.
Figura 2. Las interfaces no siempre se basan en un árbol de jerarquía.
Como podemos ver, una llanta y una pelota no comparten ninguna relación de herencia pero al poseer cierto comportamiento en común (rebotar), pueden implementar una misma interfaz.

Entonces como conclusión podemos decir que Interfaz no significa herencia pues como hemos visto dos clases sin ningún esquema jerárquico en común pueden compartir una misma interfaz. Espero que esta explicación haya sido clara. Me despido hasta una próxima oportunidad.

Saludos.

domingo, 7 de octubre de 2012

Iniciándose con Struts2.0 y Netbeans

Struts2.0 es hoy en día uno de los frameworks más demandados en el mercado. La facilidad de su uso así como las prestaciones que tiene hacen que muchas veces reemplaze al muy conocido JSF2.0. En este artículo les mostraré la manera de cómo empezar a desarrollar proyectos usando este framework.

Los pasos son los siguientes:

1. Creamos un proyecto web con netbeans.


2. Establecemos el nombre de nuestro proyecto.


3. Seleccionamos glassfish como servidor de aplicaciones.


4. No marcamos ningún framework pues nosotros mismos vamos a configurar nuestro framework.


5. Ahora descargamos las librerías disponibles en el siguiente enlace: librerías de struts2.0. Y las agregamos a nuestro proyecto de tal manera que nuestro proyecto quede así:


Se recomienda copiar todos los archivos *.jar a una carpeta dentro de nuestro proyecto para no tener problemas de referencias al cambiar de entorno de trabajo.

6. Creamos el archivo de configuración web.xml




Y editamos el archivo creado de tal modo que nos quede algo así:
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
             
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>
7. Y ahora creamos el archivo de configuración de Struts.



Como nombre de archivo le ponemos struts y finalizamos el asistente.

8. Ahora editamos el archivo con el siguiente código:
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="false" />
    
    <package name="default" extends="struts-default">
        <action name="Login" class="actions.Login">
            <result>/bienvenido.jsp</result>
            <result name="input">/index.jsp</result>
        </action>
    </package>
</struts>
9. Luego creamos el paquete actions y a continuación la clase Login.





10. Editamos la clase Login.
package actions;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;

/**
 *
 * @author Java
 */
public class Login extends ActionSupport {

    private String usuario;
    private String clave;

    public String getClave() {
        return clave;
    }

    @RequiredStringValidator(message = "Campo clave es requerido", trim = true)
    @StringLengthFieldValidator(message = "Campo clave debe tener mìnimo 5 caracteres", trim = true, minLength = "5")
    public void setClave(String clave) {
        this.clave = clave;
    }

    public String getUsuario() {
        return usuario;
    }

    @RequiredStringValidator(message = "Nombre de Usuario es requerido", trim = true)
    public void setUsuario(String usuario) {
        this.usuario = usuario;
    }

    @Override
    public String execute() throws Exception {
        if (getUsuario().equals("user") && getClave().equals("123456")) {
            return SUCCESS;
        }
        return INPUT;
    }
}
11. Ahora es el turno del archivo index
<%-- 
    Document   : index
    Created on : 23-ago-2012, 19:21:55
    Author     : Java
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Primera aplicación en Struts 2</title>
    </head>
    <body>
        <h1>Login de usuario</h1>
        <s:form action="Login">
            <s:textfield name="usuario" label="Usuario"/>
            <s:password name="clave" label="Clave"/>
            <s:submit/>
        </s:form>
    </body>
</html>
12. Y también debemos crear el archivo bienvenido.jsp


 

Y editamos su contenido.
<%-- 
    Document   : bienvenido
    Created on : 23-ago-2012, 20:54:16
    Author     : Java
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Bienvenido <s:property value="usuario"/></h1>
        <h2>La clave ingresada fué <s:property value="clave"/></h2>
    </body>
</html>
Con eso sería suficiente, desplegamos nuestro proyecto y ya tenemos nuestra primera aplicación con struts2.

Saludos y hasta una próxima oportunidad.

sábado, 6 de octubre de 2012

Renderizado de un JCalendar utilizando Substance

Todos los desarrolladores quienes hemos utilizado Substance como LookAndFeel y JCalendar como componente para la selección de fecha hemos tenido el problema de la siguiente imágen.

Figura 1. Mala renderización del componente JCalendar.
La solución es simplemente una línea de código, que deberá ser incluída en nuestro método principal.
UIManager.put(SubstanceLookAndFeel.BUTTON_NO_MIN_SIZE_PROPERTY, Boolean.TRUE);
Con esto es suficiente para tener resuelto el problema, tal como se puede ver en la Figura 2.

Figura 2. Correcta renderización de componente JCalendar utilizando Substance
Espero que les sea de utilidad en sus proyectos.

Saludos.

jueves, 4 de octubre de 2012

Comunicación entre Java y microcontrolador 18F4550 vía USB

Desarrollar aplicaciones de control industrial y automatización electrónica con Java, contrariamente a lo que muchos puedan pensar, es una tarea realmente sencilla. En este artículo goo.gl/NNbvy se mostró la manera de cómo utilizar uno de los componentes más populares de JFreeChart para el control industrial.

Este artículo es el inicio de una serie de posts que se basarán en la tarjeta de adquisición de datos de la figura 1 y que mostrarán cómo desarrollar aplicaciones para el telecontrol y automatización con Java. En esta primera etapa se muestra la manera como adquirir datos analógicos utilizando Java y el microcontrolador 18F4550.

Figura 1. Tarjeta de Adquisición de Datos utilizando el PIC18F4550 y el conector JPicUSB
Para lograr la conexión entre Java y nuestra tarjeta de adquisición de datos necesitamos de un conector, el JPicUSB cuyos archivos se ecuentran adjuntos en al final del post. Así mismo es necesario agregar ciertas *.dlls a nuestro proyecto, que en este caso se encuentra desarrollado en Netbeans. La manera como establecemos la conexión es solo unas cuantas líneas. El código siguiente esquematiza la idea:
try {
    iface.load();
} catch (Exception e) {
    System.out.println(e.getMessage());
}
iface.set_vidpid("vid_04d8&pid_000b");
iface.set_instance(0);
temperaturas.start();
Para la adquisición de temperatura se utilizó el sensor LM35, siendo este fácilmente reemplazable. Entre los archivos adjuntos del proyecto también se encuentra el código fuente en lenguaje C utilizado para programar el microcontrolador. Así mismo se presenta una simulación en ISIS para poder ver en funcionamiento a esta tarjeta. Los pasos para ejecutar la aplicación son los siguientes:

1. Abrir el archivo de simulación utilizando ISIS (se recomienda la versión 7.6 SP0 y Sistema operativo Windows XP)
2. Cargar el archivo jPicUsb Led Show.hex al microcontrolador.
3. Iniciar la simulación.
4. Ejecutar el proyecto de netbeans.

También les muestro un video del funcionamiento de la tarjeta de adquisición de datos:


Ahora para ejecutar el proyecto los pasos detallados son los siguientes:

1. Abrir el ISIS Proteus.


2. Seleccionar el archivo de simulación.


3. Hacemos doble clic sobre el microcontrolador 18F4550 que se ha cargado en el workspace. Nos aparecerá la siguiente ventana:


4. Seleccionar el archivo con los códigos hexadecimales (jPicUsb Led Show.hex) a ejecutar. Dar clic en el botón "play" para iniciar la simulación.


 5. Abrir el proyecto en netbeans.


6. Ejecutar la clase  ThermometerPanel.java.


Y tendremos nuestra aplicación java comunicándose vía usb con nuestro microcontrolador 18F4550. Como comenté anteriormente este es solo el inicio de una serie de artículos, todos relacionados al uso de esta tarjeta (la cual fué parte de mi tesis para obtener el grado de Ingeniero). Espero que les sea de utilidad, y si tienen alguna duda no duden en comentarla pues la idea es hacer crecer este proyecto y el feedback que se obtenga de los comentarios será de mucha ayuda para otras personas.

Todos los archivos del proyecto los pueden descargar aquí:

 
Saludos y hasta la próxima oportunidad.