feed twitter facebook LinkedIn facebook

Java » Bloquear un fichero con Java

septiembre 16, 2012 por Víctor Cuervo 1 Comentario Imprimir Imprimir

Si estamos trabajando con ficheros en Java es posible que tengamos la necesidad de mantener consistente la información que contiene alguno de ellos. Para ello, una solución puede pasar por realizar un bloqueo lógico de un fichero. Es decir, marcar al fichero como bloqueado, para que el resto de procesos sepan que no deben tocar su contenido para mantenerlo consistente. Así que vamos a ver cómo podemos bloquear un fichero con Java.

Lo primero que haremos para bloquear un fichero con Java será obtener una referencia sobre el fichero mediante una clase File:

  1. File file = new File("test.txt");

Para acceder al fichero vamos a utilizar la clase RandomAccessFile en formato lectura y escritura. Y sobre ese objeto vamos a recuperar su canal de acceso mediante el método .getChannel().

  1. FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

Lo que manejamos en este momento es un objeto del tipo FileChannel. Un canal en Java es la evolución de un Stream normal de datos. El caso del FileChannel se representa una conexión abierta sobre un recurso sobre la cual se pueden realizar múltiples operaciones. Una de las operaciones que podemos realizar sobre el canal es bloquearlo o liberarlo.

Así, si queremos bloquear un fichero con Java, lo que hacemos es bloquear el canal mediante el método .lock().

  1. FileLock lock = channel.lock();

Lo que obtenemos en este caso es un objeto FileLock. Este objeto será el que nos sirva para chequear el estado del canal/fichero antes de acceder a él. Si queremos ver si el fichero está bloqueado utilizamos el método tryLock() que devolverá una excepción OverlappingFileLockException en el caso de que haya un bloqueo.

  1. try {
  2. lock = channel.tryLock();
  3. } catch (OverlappingFileLockException e) { }

También tenemos que saber que para liberar el bloqueo del fichero tenemos el método .release()

  1. lock.release();

Lo último que deberemos de hacer a la hora de bloquear un fichero con Java es cerrar el canal sobre el fichero con el método .close()

  1. channel.close();

Con estas pequeñas líneas de código hemos podido bloquear un fichero con Java..

Java » Hola Mundo con Java ME y un TextBox

septiembre 13, 2012 por Víctor Cuervo 1 Comentario Imprimir Imprimir

En un anterior ejemplo vimos como con Java ME podíamos crear una aplicación Hola Mundo. En ese caso utilizamos un Canvas sobre el que volcábamos una cadena de texto con el "Hola Mundo". En este segundo ejemplo vamos a ver como podemos crear un primer ejemplo de Hola Mundo con Java ME, pero en este caso gestionaremos la salida mediante un TextBox.

Lo primero será definir nuestra clase Display que es la que, al fin y al cabo, representa la pantalla del dispositivo móvil. De igual manera definiremos la clase TextBox que será la caja de texto en la que insertaremos nuestro Hola Mundo.

  1. private Display display;
  2. TextBox textbox = new TextBox("Mi ejemplo","Hola Mundo",20,0);

Ya vemos que cuando creamos el TextBox estamos indicando su título "Mi ejemplo" y su contenido". Así como su tamaño y restricciones.

Lo siguiente será recordar los tres métodos de los que se compone un MIDLet: startApp, pauseApp y destroyApp.

  1. protected void destroyApp(boolean unconditional)
  2. throws MIDletStateChangeException { }
  3. protected void pauseApp() { }
  4. protected void startApp() throws MIDletStateChangeException { }

Será el método de inicialización o startApp() en el que instanciemos nuestro display. Para instanciar el Display utilizamos la propia factoría Display y su método .getDisplay()

  1. display = Display.getDisplay(this);

Ya solo nos quedará añadir el TextBox a nuestro display. Para ello utilizamos el método .setCurrent() sobre el Display, pasándole la caja de texto o TextBox.

  1. display.setCurrent(textbox);

El método startApp() nos quedará de la siguiente forma:

  1. protected void startApp() throws MIDletStateChangeException {
  2. display = Display.getDisplay(this);
  3. display.setCurrent(textbox);
  4. }

Con estos sencillos pasos tenemos creados nuestro Hola Mundo con Java ME y un TextBox. Y nuestro resultado:

Java » Hola Mundo con Java ME

agosto 6, 2012 por Emmanuel Ramos 1 Comentario Imprimir Imprimir

Java ME (Java Micro Edition) es una tecnología que esta enfocada no solo a teléfonos móviles si no a todo dispositivo que funcione con Java. En ese grupo podemos encontrar decodificadores de TV, lectores de tarjeta y demás.

En este primer artículo vamos a realizar un código sencillo que nos muestre un Hola Mundo con Java ME Mediante este codigo lo podras probar mas facilmente en un IDE el cual sea de tu preferencia ya sea Netbeans o Eclipse. Este codigo esta enfocado a telefonos móviles los cuales tienen una cierta configuracion y perfil.

Cuando hablamos de configuracion nos referimos a que debido a las diferentes capacidades de procesamiento de los telefonos móviles, el API de Java, se reduce dejando solo las funcionalidades básicas de dicho dispositivo.

En cuanto al perfil nos referimos a que diferentes móviles pueden tener diferentes caracteristicas, las cuales podrían ser una camara integrada o una pantalla tactil es en esto en las caracteristicas extra o especificas de los móviles.

Este código de Hola Mundo con Java ME vamos a realizarlo con un Perfil MIDP 2.0 y una configuracion CLDC 1.0 , el cual solo nos imprimirá en la pantalla de nuestro móvil el mensaje HOLA MUNDO.

Descargando Java ME

Lo primero que tienes que hacer antes de empezar a desarrollar el código Hola Mundo con Java ME es el descargarte la librería Java ME.

Así que lo primero que tenemos que hacer es descargarnos el Kit de Desarrollo de Java ME desde la página de Oracle.

En este Kit encontraremos, entre otras cosas, las definiciones de los dispositivos y los perfiles y configuraciones a los que hemos hecho mención anteriormente.

Empezando a codificar el Hola Mundo con Java ME

Lo primero que tenemos que saber es que las clases que construyamos para Java ME extenderán de la clase MIDlet. Esta clase MIDlet es la que nos proporcionara los metdos para el ciclo de vida de la aplicacion

  1. public class HolaMundo extends MIDlet {...}

Como la clase MIDlet es abstracta necesitamos sobreescribir sus metodos.

Las librerías que necesitaremos de Java ME serán:

  1. import javax.microedition.lcdui.Canvas;
  2. import javax.microedition.lcdui.Display;
  3. import javax.microedition.lcdui.Graphics;
  4. import javax.microedition.midlet.*;

Por lo cual tendremos que importarlas antes de nuestro código.

Definiremos dos variables que nos servirán para mostrar en pantalla mi mensaje. Por un lado Display es sencillamente mi pantalla en el móvil, la variable mycanvas es en la que nostros dibujamos nuestro mensaje.

  1. private Display display;
  2. private MyCanvas mycanvas;

El inicio de la aplicación: strarApp()

En el inicio de la aplicación lo que haremos será, en primer lugar obtener acceso a la pantalla, es decir, al Display.

  1. this.display = Display.getDisplay(this);

Instanciamos nuestro Canvas. Ahora veremos que tiene el Canvas y como inserta el texto.

  1. this.mycanvas = new MyCanvas();

Y por último añadimos el Canvas a la pantalla mediante el método .setCurrent()

  1. display.setCurrent(mycanvas);

El código completo de startApp() quedará de la siguiente forma:

  1. protected void startApp() throws MIDletStateChangeException {
  2. display = Display.getDisplay(this);
  3. this.mycanvas = new MyCanvas();
  4. display.setCurrent(mycanvas);
  5. }

El Canvas y la cadena Hola Mundo

Como hemos visto antes, la gestión de insertar la cadena se la hemos dejado a nuestra clase MyCanvas. La clase MyCanvas extiende de Canvas la cual es abstracta, debemos implementar su metodo paint(Graphics).

En el método paint tenemos un objeto Graphics el cual servirá para escribir nuestro "Hola Mundo", una característica de esta clase es que cuando se hace una instacia de ella, se llama al metodo paint para que dibuje lo que nosotros pusimos dentro del método.

  1. class MyCanvas extends Canvas {
  2. protected void paint(Graphics g) {
  3. g.setColor(255,255,255);
  4. g.drawString("HOLA MUNDO", this.getWidth()/2, this.getHeight()/2,
  5. Graphics.BASELINE|Graphics.HCENTER);
  6. }
  7. }

También hemos añadido el método .setColor, el cual indica que el texto a insertar es blanco. Esto lo necesitamos ya que el fondo del Canvas es negro y no se verían las letras.

Probando la aplicación en emulador

Si probais la aplicación en el emulador que viene con el Kit de desarrollo de Java ME de Oracle obtendréis un resultado como el que se a continuación:

Pues con este código tenemos nuestra primera aplicación Hola Mundo con Java ME. Espero que os haya gustado.

Java » Guía Completa Javamelody: Monitoreo de aplicaciones web

julio 31, 2012 por Emmanuel Sio Sin Comentarios Imprimir Imprimir

Javamelody es una herramienta destinada a monitorear servidores de aplicación Java o Java EE en ambientes de QA y producción. Es importante tener en cuenta que no es una herramienta para simular pedidos de usuarios, sino que se debe utilizar para medir y calcular estadísticas que surgen de la operatoria de la aplicación por todos los usuarios.

Requisitos de Javamelody

Se requiere tener instaladas las siguientes versiones de Java:

  • 1.5 como mínimo
  • 1.6 o 1.7 para las siguientes funciones: heap dump, memory histogram, stack traces and system load average
  • JDK o JRE de Sun o JRockit de Oracle/BEA o J9 de IBM

Versiones de Servidor:

  • JavaEE 1.4
  • Tomcat 5.5, 6 o 7
  • GlassFish v2 o v3
  • JBoss 4, 5, 6 o 7
  • Jonas 4 o 5
  • Jetty 6 o 7
  • WebLogic 9, 10, 11

Instalación de Javamelody

La instalación es realmente sencilla. Solamente basta copiar dos archivos en la carpeta WEB-INF/lib de la aplicación que deseamos monitorear. Luego debemos editar el archivo web.xml agregando algunas pocas líneas de código.

Instalación Paso a Paso

Los siguientes pasos son los básicos, donde elegimos a Tomcat como servidor de ejemplo.

Pasos:
a) Descargar el archivo javamelody-x.x.x.zip de la web del proyecto.
b) Descomprimir el archivo zip.
c) Copiar los archivos javamelody-x.x.x.jar y jrobin.x.x.x.jar al directorio WEB-INF/lib que está dentro del directorio webapps/nuestra-aplicación.
d) Agregamos las siguientes líneas en el archivo WEB-INF/web.xml de la aplicación.

  1. <filter>
  2. <filter-name>monitoring</filter-name>
  3. <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>monitoring</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>
  9. <listener>
  10. <listener-class>net.bull.javamelody.SessionListener</listener-class>
  11. </listener>

e) Si queremos tener informes en PDF debemos copiar a WEB-INF/lib el archivo itext-2.1.7.jar. Este paso es opcional.

Si necesitan más customizaciones pueden obtenerlos del sitio de google code donde se encuentra alojado todo el proyecto de Javamelody. Pueden visitarlo aquí.

Primeros resultados

Podemos acceder a nuestra herramienta a través de:

http://<host>/<my-context>/monitoring

  • <host> : nombre del servidor donde la aplicación web está instalada, seguido posiblemente por el puerto (por ejemplo localhost:8080).
  • <my-context>: Es el nombre del contexto de la aplicación web.

Seguridad

La página de monitoreo no tiene datos como usuario y password para ser usados como login. Por ello, antes de usar Javamelody en producción puede ser necesario que deseemos restringir el acceso a esta página. Esta tarea recae en nosotros mismos, donde una de las posibilidades es realizar un login customizado. Javamelody nos ayuda dándonos la posibilidad de restringir su acceso a través de una expresión regular tomando como parámetro la dirección IP del cliente. Esto podemos lograrlo a través de allowed-addr-pattern. Por ejemplo: “192\.168\..*|123\.123\.123\.123” para permitir las IP que se encuentren en el rango “192.168.*.*” mas cualquier pc que se encuentre detrás de una puerta de enlace 123.123.123.123.
Hay que tener en cuenta que si usamos un servidor proxy http como Apache, la dirección IP del cliente será la de Apache. Por ello, no debes usar allowed-addr-pattern en este caso o, si es ese el caso, no usar Apache para acceder a esta página, o  habilitar mod_proxy_ajp para que el servidor monitoreado sepa las direcciones IP de los clientes.

Ejemplo de httpd conf con ajp:

  1. <location /webapp>
  2. ProxyPass ajp://localhost:8080/webapp
  3. </location>

Otra opción que tenemos es la utilización de roles. Si en nuestro archivo web.xml ya hemos definido roles, entonces podemos habilitarlos para que solo ellos puedan acceder a la página de monitoring.

Ejemplo utilizando roles:

  1. <login-config>
  2. <auth-method>BASIC</auth-method>
  3. <realm-name>Monitoring</realm-name>
  4. </login-config>
  5. <security-role>
  6. <role-name>monitoring</role-name>
  7. </security-role>
  8. <security-constraint>
  9. <web-resource-collection>
  10. <web-resource-name>Monitoring</web-resource-name>
  11. <url-pattern>/monitoring</url-pattern>
  12. </web-resource-collection>
  13. <auth-constraint>
  14. <role-name>monitoring</role-name>
  15. </auth-constraint>
  16. <!-- if SSL enabled (SSL and certificate must then be configured in the server)
  17.   <user-data-constraint>
  18. <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  19. </user-data-constraint>
  20. -->
  21. </security-constraint>

Los usuarios deben estar definidos en el servidor de aplicación y deben tener asignado el rol de monitoring para tener acceso a los reportes. Un ejemplo de cómo configurarlo sería del siguiente modo:

  1. <?xml version='1.0' encoding='utf-8'?>
  2. <tomcat-users>
  3. <role rolename="monitoring"/>
  4. <user username="monitoring" password="monitoring" roles="monitoring"/>
  5. </tomcat-users>

Activación consultas SQL

Si dentro de nuestra aplicación utilizamos Hibernate, entonces la siguiente línea de configuración puede ser utilizada para poder activar el rastreo de las consultas SQL realizadas.

Para ello buscamos el archivo hibernate.cfg.xml y agregamos la siguiente línea:

  1. <property name="hibernate.jdbc.factory_class">net.bull.javamelody.HibernateBatcherFactory</property>

Esto habilita que Javamelody detecte cada consulta realizada y nos muestre el tiempo total de ejecución, la cantidad de veces que se ejecutó dicha consulta, el máximo tiempo de ejecución, desviación standard y el % de error del sistema.

Generación de reportes PDF

Para generar reportes en PDF como también en HTML, debemos agregar la librería iText v2.1.x. Para ello buscamos el archivo iText-2.x.x.jar, ubicado en src/test/test-webapp/WEB-INF/ lib dentro de javamelody.zip y copiarlo dentro del directorio WEB-INF/lib .

Suplementos en web.xml

Para evitar monitorear algunas url determinadas podemos usar url-pattern dentro del archivo web.xml.

Por ejemplo, usamos filter-mappings y url-patterns para monitorear solamente urls como /servlet1/* y /servlet2/* pero no otras como /static/*

  1. <filter>
  2. <filter-name>monitoring</filter-name>
  3. <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>monitoring</filter-name>
  7. <url-pattern>/servlet1/*</url-pattern>
  8. </filter-mapping>
  9. <filter-mapping>
  10. <filter-name>monitoring</filter-name>
  11. <url-pattern>/servlet2/*</url-pattern>
  12. </filter-mapping>
  13. <filter-mapping>
  14. <filter-name>monitoring</filter-name>
  15. <url-pattern>/monitoring</url-pattern>
  16. </filter-mapping>
  17. <listener>
  18. <listener-class>net.bull.javamelody.SessionListener</listener-class>
  19. </listener>

Es importante tener en cuenta que url-pattern debe contener la url /monitoring para tener reportes.
Como alternativa, se puede usar un único /* url-pattern y un parámetro de filtro con una expresión regular antes del tag .

Por ejemplo:

  1. <filter>
  2. <filter-name>monitoring</filter-name>
  3. <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
  4. <init-param>
  5. <param-name>url-exclude-pattern</param-name>
  6. <param-value>/static/.*</param-value>
  7. </init-param>
  8. </filter>
  9.  
  10. <filter-mapping>
  11. <filter-name>monitoring</filter-name>
  12. <url-pattern>/*</url-pattern>
  13. </filter-mapping>
  14.  
  15. <listener>
  16. <listener-class>net.bull.javamelody.SessionListener</listener-class>
  17. </listener>

Esto ha sido todo sobre la instalación de JavaMelody. Esperamos que les sea útil a la hora de tener una guía completa para su instalación.

Java » Comprobar conexión a Internet con Java

Hace algún tiempo necesitaba una aplicación que cada determinado tiempo compruebe el estado de la conexión, entonces desarrolle una aplicación en Java muy simple que cada cierto tiempo verifique el estado de conexión. Lo que voy a exponer aquí solo es la parte de código Java que se encarga de la comprobar la conexión, nada más. Luego podrá usted incluirlo en una aplicación más grande y con sus propios fines si le parece útil el pequeño código expuesto.

Para este sencillo programa Java vamos a utilizar la clase Socket, así que veamos lo necesario de ella para los fines de la aplicación. También es necesario trabajar con excepciones pero creo que a este tema le corresponde un post por sí solo.

Clase Socket de Java: Es un conector TCP/IP diseñado para conectarse a servidores e iniciar intercambios bajo protocolo. La creación de un objeto Socket establece implícitamente una conexión entre cliente y servidor. Ahora pasemos al código:

Antes que nada importamos el paquete java.net y ponemos los comentarios de documentación habituales:

  1. import java.net.Socket;
  2. /**
  3. * @(#)ComprobarConexionJava.java
  4. *
  5. * ComprobarConexionJava application
  6. *
  7. * @author Christian G. Gimenez
  8. * @version 1.00 2012/6/27
  9. */

Luego tenemos la signatura de la clase y del método main de Java, toda la acción va a estar dentro del método main:

  1. public class ComprobarConexionJava {
  2. public static void main(String[] args) {

Lo siguiente que vamos a hacer es definir dos variables, de tipo String e int que contendrán una dirección web y un puerto respectivamente:

  1. String dirWeb = "www.lineadecodigo.com";
  2. int puerto = 80;

A continuación, viene algo fundamental para el funcionamiento de esta pequeña aplicación, cuando definimos una variable de tipo Socket y creamos el objeto de dicho tipo lo hacemos dentro de un bloque try, de no ser así vamos a tener problemas a la hora de compilar nuestra aplicación:

  1. try{
  2. Socket s = new Socket(dirWeb, puerto);
  3.  

Ahora utilizamos un if para llamar al método isConnected() de la clase Socket, este método devolverá un valor booleano, dependiendo de éste devolveremos un mensaje correspondiente al estado de la conexión:

  1. if(s.isConnected()){
  2. System.out.println("Conexión establecida con la dirección: " + dirWeb + " a travéz del puerto: " + puerto);
  3. }

Por último vamos a escribir el bloque catch correspondiente al bloque catch que utilizamos arriba, a este bloque lo utilizamos para comunicar el fallo al conectarse en caso que exista tal fallo.

  1.  
  2. }catch(Exception e){
  3. System.err.println("No se pudo establecer conexión con: " + dirWeb + " a travez del puerto: " + puerto);
  4. }

Eso es todo, como ven es muy simple. Espero lo encuentren útil en algún momento.

Java » Gráficos de torta y barras con JFreeChart

mayo 31, 2012 por Feffo 1 Comentario Imprimir Imprimir

El otro día veíamos como crear, de una forma sencilla, un gráfico con JFreeChart. Hoy les presento una forma muy fácil para crear y mostrar un gráfico de torta y uno de barras en Java con JFreeChart.

Recordar que lo primero es descargarse las librerías de JFreeChart. Vamos a necesitar las siguientes librerías JFreeChart y JCommon

Una vez que estén importados los respectivos .jar podremos comenzar a ver el código.

Una forma fácil que se me ocurrió para mostrarles el funcionamiento de esta librería fue crear unos 10000 números aleatorios entre 0 y 9 y llevar un registro de cuantas veces apareció cada número. Para esto tenemos el siguiente código:

  1. Random rnd = new Random(System.currentTimeMillis());
  2. // Establece una semilla para el random
  3. int[] array = new int[10];
  4. for (int i = 0; i < 10000; i++)
  5. array[rnd.nextInt(10)]++;

Cada vez que el random da un numero, se aumenta en uno la cantidad de veces que fue dado. Una vez finalizado el algoritmo tenemos un arreglo donde en cada índice se indica cuantas veces surgió ese índice del random.

Luego, procederemos a crear el gráfico de torta en base a nuestro arreglo con JFreeChart. Lo tendremos todo en el método crearGraficoTorta.

  1. private static JPanel crearGraficoTorta(int[] array) {...}

Lo primero será crear un dataset donde vamos a almacenar las distintas 'porciones' de la torta. Es por ello que utilizamos una clase DefaultPieDataSet de JFreeChart.

  1. DefaultPieDataset dataset = new DefaultPieDataset();
  2. for (int i = 0; i < array.length; i++)
  3. dataset.setValue("Valor " + i + ": " + array[i], array[i]);

Utilizamos un bucle for para agregar las 'porciones' a nuestro grafico de torta. El ultimo parametro indica el valor de la torta que ocupa cada porcion.

Luego, en base a este dataset, creamos nuestro gráfico. Utilizamos la factoría de creación de gráficos de JFreeChart, la ChartFactory.

  1. JFreeChart chart = ChartFactory.createPieChart("Repeticion de randoms",
  2. dataset, true, true, true);

Podemos hacer algunas mejoras sobre el propio gráfico con JFreeChart como añadirle un fondo o quitar la leyenda:

  1. chart.setBackgroundPaint(Color.white);
  2. chart.removeLegend();

Finalmente, retornamos un panel que contenga a esa torta.

Ahora, procederemos a crear el gráfico de barras en base a nuestro arreglo.

  1. private static JPanel crearGraficoBarras(int[] array) {...}

Volvemos a crear un dataset donde vamos a almacenar las distintas 'barras'. En este caso es un DefaultCategoryDataSet.

  1. DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  2. String serie = "Numeros";
  3. for (int i = 0; i < array.length; i++)
  4. dataset.addValue(array[i], serie, "" + i);</pre<
  5.  
  6. Vemos que <strong>los valores son añadidos al DataSet con un addValue()</strong>.
  7.  
  8. Una vez completado el dataset, se crea el grafico de barras en base a el.
  9.  
  10. <pre lang="java">JFreeChart chart = ChartFactory.createBarChart("Repeticion de randoms", null,
  11. null, dataset, PlotOrientation.HORIZONTAL, true, true, false);

Para terminar debemos agregar los gráficos a un frame para poder verlos:

  1. JFrame frame = new JFrame("CrearGraficos - LineaDeCodigo");
  2. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  3. frame.setLayout(new GridLayout(2, 1));
  4. frame.add(crearGraficoTorta(array));
  5. frame.add(crearGraficoBarras(array));
  6. frame.pack();
  7. frame.setLocationRelativeTo(null);
  8. frame.setVisible(true);

En este código hemos añadido los gráficos mediante el método .add() del JFrame. Adicionalmente hemos redimensionado el tamaño del frame, al minimo posible con el método .pack() y centrado el frame con .setLocationRelativeTo(null).

Nuestro resultado final para crear gráficos de torta y barras con JFreeChart nos quedará de la siguiente forma:

Una vez que saben como hacer uno de estos gráficos con JFreeChart, el resto (Líneas de Tiempo, Gráficos XY, etc.) son básicamente el mismo procedimiento con algunos detalles con respecto al dataset de cada tipo.

Java » Gráficos en Java con JFreeChart

mayo 30, 2012 por Pablo Ruiz 3 Comentarios Imprimir Imprimir

Mientras tanto hago el análisis de mi proyecto de título me he visto en la necesidad de buscar algunas librerías gráficas para que me faciliten el trabajo en Java, es así que he llegado a JFreeChart, librería para estadísticas gráficas. Hoy por hoy les explicaré lo sencillo que resulta crear un gráfico con JFreeChart.

Lo primero que tenemos que hacer es agregar la librerías de JFreeChart, si no las tenemos, podemos acceder a ellas desde la página de sus programadores.

Principalmente trabajaremos con dos librerías que son jcommon-1.0.16.jar y jfreechart-1.0.13.jar

Las librerías quedarán así en tu proyecto:

Una vez que hayamos agregado las librerías de JFreeChart cremos un proyecto nuevo y agregamos un JFrame. Este JFrame puede servir directamente como un gráfico, pero en éste ejemplo lo he usado para agregar un botón que hará la llamada del gráfico en un nuevo JFrame.

Nos vamos a el JFrame que ya agregamos, y añadimos sobre él un botón, el cual llamará al gráfico. Visualmente debería quedar algo así:

Lo primero será declarar un atributo JFrame dentro de nuestra clase, la cual hemos llamado GraficosJFreeChart:

  1. JFrame frame = new JFrame("Probando JFreeChart");

El constructor de JFreeChart inicializaremos el JFrame, cambiaremos su tamaño y posición en la pantalla:

  1. frame.setSize(500, 270);
  2. frame.setLocationRelativeTo(getRootPane());
  3. this.setLocationRelativeTo(getRootPane());

Cabe destacar que cuando hacemos referencia a "this" estamos haciendo referencia a la ventana de la clase principal en éste caso la primera que agregamos.

La acción de click sobre el botón será la que lance toda la ejecución y carga de los gráficos JFreeChart.

  1. private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {...}

Lo primero que haremos con los gráficos JFreeChart es crear un DataSet, que es dónde vamos a meter los datos que representaremos gráficamente. Para ello utilizamos un DefaultCategoryDataset y añadimos los valores mediante el método .addValue().

  1. DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  2. dataset.addValue(1.0, "Row 1", "Column 1");
  3. dataset.addValue(5.0, "Row 1", "Column 2");
  4. dataset.addValue(3.0, "Row 1", "Column 3");
  5. dataset.addValue(2.0, "Row 2", "Column 1");
  6. dataset.addValue(3.0, "Row 2", "Column 2");
  7. dataset.addValue(2.0, "Row 2", "Column 3");
  8. dataset.addValue(10.0,"Row 3", "Column 4");
  9. dataset.addValue(10.0,"Row 3", "Column 4");

Destaquemos que las llamadas al método addValue() se agregan un valor, un fila y una columna determinada. ¿Estas pensando en una base de datos? Sí, fácilmente podrían salir los datos de una base de datos. Quizás mas adelante lo expliquemos.

Una vez que tenemos el DataSet relleno nos dedicaremos a generar el gráfico. Los gráficos en JFreeChart se generan mediante la factoría CharFactory. En este caso, como queremos crear un gráfico de barras utilizamos el método .createBarChart().

  1. JFreeChart chart = ChartFactory.createBarChart(
  2. "Ejemplo básico para Linea de Codigo",
  3. "Categorías",
  4. "Valores",
  5. dataset,
  6. PlotOrientation.VERTICAL,
  7. true,
  8. true,
  9. true
  10. );

En la creación del gráfico al método createBarChart le pasamos el título, los valores de los textos de los ejes, si queremos que haya leyenda,... y lo más importante el DataSet con los datos.

El gráfico creado hay que mostrarlo. Para mostrar un gráfico en JFreeChart hay que ponerlo en un Panel. Así que creamos un panel con la clase ChartPanel al cual le pasamos como parámetro el gráfico que acabamos de crear. Después mostramos el panel en el JFrame.

  1. ChartPanel chartPanel = new ChartPanel(chart, false);
  2. frame.setContentPane(chartPanel);
  3. frame.setVisible(true);

Ya tenemos nuestro primer gráfico con Java y JFreeChart.

Java » Calcular el número feliz con Java

mayo 5, 2012 por Víctor Cuervo 1 Comentario Imprimir Imprimir

Ayer hablábamos en el grupo de Facebook sobre Java en Español (¿¿Qué todavía no estás apuntado???) sobre el cálculo de el número feliz con Java. Pero, ¿qué es un número feliz? Si seguimos la descripción de la wikipedia sobre el número feliz, este es aquel que, de forma iterativa, en la suma de sus dígitos acaba resultando un 1.

Es decir, para el caso del número 7, que es un número feliz, la secuencia sería la siguiente:

72 = 49
42 + 92 = 97
92 + 72 = 130
12 + 32 + 02 = 10
12 + 02 = 1

Así que nos ponemos manos a la obra para resolver este planteamiento de el número feliz con Java.

Lo primero que vemos es que hay que extraer los dígitos del número. Esto ya lo explicábamos en el artículo Dígitos de un número con Java. Así que es bueno que lo leas en detalle. Si bien, lo que hacemos es utilizar divisiones y el módulo del 10 (división y resto) para ir extrayendo los números del dígito.

  1. public static int[] digitosNumero(int iNumero){
  2.  
  3. // Creamos un array del tamaño del número de dígitos del número
  4. String x = Integer.toString(iNumero);
  5. int[] iNumeros = new int[x.length()];
  6.  
  7. // Método que devuelve los dígitos de un número
  8. int iDigito = 0;
  9. while (iNumero>0){
  10. iNumeros[iDigito] = iNumero%10;
  11. iNumero = iNumero/10;
  12. iDigito++;
  13. }
  14.  
  15. return iNumeros;
  16.  
  17. }

Al final hemos construido un método que dado un entero nos devuelve un array con los dígitos de dicho número.

Lo siguiente será, por cada dígito del número hacer la suma de los cuadrados de los dígitos. Para calcular los cuadrados utilizamos el método .pow() de la clase Math.

Recuerda que la clase Math es estática y no hace falta instanciarla.

El código de esta suma de dígitos al cuadrado sería:

  1. int[] iNumeros = digitosNumero(iNumero);
  2. iSuma = 0;
  3. for (int x=0;x<iNumeros.length;x++)
  4. iSuma += Math.pow(iNumeros[x],2);

Ahora hay que validar si la suma es un uno o si no saldremos del bucle. En el caso de que no sea un uno volvemos a llamar a la función digitosNumero para que nos vuelva a "trocear" el nuevo número.

  1. while (iSuma!=1){
  2. iSuma = 0;
  3.  
  4. for (int x=0;x<iNumeros.length;x++)
  5. iSuma += Math.pow(iNumeros[x],2);
  6.  
  7. iNumeros = digitosNumero(iSuma);
  8. }

Con esto ya tendríamos nuestro código que calcule si un número es un número feliz con Java terminado. Pero hay una cosa que se puede mejorar, y es que si el número no es feliz se mete en una secuencia infinita de calculos, ya que nunca encontrará el 1. Si bien, podemos cortar este bucle si se repite un número en la secuencia, ya que volverá a la misma secuencia.

Veamos el caso del número 2:

22 = 4
42 = 16
12 + 62 = 37
32 + 72 = 58
52 + 82 = 89
82 + 92 = 145
12 + 42 + 52 = 42
42 + 22 = 20
22 + 02 = 4

Al llegar al número 4 que ya estaba en la serie, todo se volverá a repetir de forma infinita. Es por ello que en este punto habría que cortar el cálculo.

Para implementar esto lo que hemos hecho es añadir un conjunto, es decir, un Set al programa, al cual vamos metiendo los números, siempre y cuando el número sumado no esté. Ya que si esta significará que la secuencia se vuelve a repetir y hay que salir del bucle.

Instanciamos el Set mediante una clase HashSet.

  1. Set<Integer> iCalculados = new HashSet<Integer>();

Y en mitad del bucle hacemos la comprobación o inserción en el conjunto. Para ello utilizamos los métodos .contains y .add

  1. if (iCalculados.contains(new Integer(iSuma)))
  2. bRepetido = true;
  3. else
  4. iCalculados.add(new Integer(iSuma));

Vemos que aparece una variable bRepetido y es que esta será el flag que utilicemos para salirnos del bucle. Así que finalmente nuestro bucle de cálculo quedará de la siguiente forma:

  1. while ((iSuma!=1) && !(bRepetido)){
  2. iSuma = 0;
  3. for (int x=0;x<iNumeros.length;x++)
  4. iSuma += Math.pow(iNumeros[x],2);
  5. iNumeros = digitosNumero(iSuma);
  6.  
  7. // Controlamos si ha salido un número repetido. Para no entrar en el bucle.
  8. if (iCalculados.contains(new Integer(iSuma)))
  9. bRepetido = true;
  10. else
  11. iCalculados.add(new Integer(iSuma));
  12. }

Ya solo nos quedará imprimir si el número es un número feliz o no. Esto nos lo cuenta la variable bRepetido. :-D

  1. if (bRepetido)
  2. System.out.println(iNumero + " NO es un número feliz");
  3. else
  4. System.out.println(iNumero + " SI es un número feliz");

Java » Listar ficheros ocultos de un directorio con Java

mayo 4, 2012 por Víctor Cuervo 1 Comentario Imprimir Imprimir

Estaba haciendo unas pruebas con ficheros y no había caído en que el directorio con el que estaba trabajando tenía algunos ficheros ocultos que no estaba moviendo. Y me he dicho, porqué no escribir unas pequeñas líneas de código con Java para listar los ficheros ocultos de un directorio. Y es que el programa es muy sencillo.

Te recomiendo que empieces echando un ojo al artículo que explica como listar los ficheros de un directorio con Java. Ya que la base del listado de ficheros está en ese ejemplo.

Lo siguiente será saber que el método que nos dice si un fichero es oculto o no es .isHidden(). Algo que, por otro lado, cabía esperar. Así que listemos los ficheros del directorio.

  1. String sDirectorio = "d:\\test";
  2. File f = new File(sDirectorio);
  3.  
  4. if (f.exists()){
  5. File[] ficheros = f.listFiles();
  6. for (int x=0;x<ficheros.length;x++){
  7. System.out.println(ficheros[x].getName());
  8. }
  9. } else{
  10. System.out.println("No existe ese directorio");
  11. }

Con este código hemos listado todos los ficheros. Si queremos listar los ocultos añadimos el método .isHidden() sobre el objeto File sobre el que estamos iterando.

  1. if (f.exists()){
  2. File[] ficheros = f.listFiles();
  3. for (int x=0;x<ficheros.length;x++){
  4. if (ficheros[x].isHidden())
  5. System.out.println(ficheros[x].getName());
  6. }
  7. } else{
  8. System.out.println("No existe ese directorio");
  9. }

Algo muy sencillo y útil para no dejarnos o encontrar esos ficheros ocultos.

En los siguientes artículos intentaremos hablar de todas las novedades que trae Java SE 7 sobre la gestión de ficheros.

Java » Usando las clases HashSet y HashMap

abril 11, 2012 por Emmanuel Ramos 4 Comentarios Imprimir Imprimir

Antes de iniciar a explicar el codigo, tengo que señalar que tanto la clase HashSet como la clase HashMap tienen una ventaja la cual es, que los valores que se van insertando en la coleccion internamente no tendran un orden especifico, esto se debe a que estas clases realizan un ordenamiento interno mediante el hashcode de el elemento(Objeto), por lo cual no sabremos que elemento traerá.

Esto nos da una ventaja para nosotros que es poder sobrescribir el metodo .hashCode() y .equals() para asi, si tenemos un objeto que tienen sus mismas caracteristicas y mismo hashcode no se agregue a la colección , una de las principales ventajas de este metodo es la rapidez en la insercion de los elemento si tenemos cientos de elementosque agregar, esta coleccion es la indicada para este trabajo.

El algoritmo de busqueda de un elemento en la colecion es el siguiente

  1. Encuentra el elemento (Objeto) mediante el hashcode. Imagínense varios personas en un salon con la misma edad.
  2. Ya que encontro el elemento mediante el hashcode se realiza la comparacion si el objeto es igual mediante el método .equals(). Imaginen que en ese mismo salon se esta buscando a una persona con un nombre y apellido especifico.

Lo primero será definir un objeto de tipo Alumnos.

  1. public class Alumnos {
  2. private int age;
  3. private String name;
  4.  
  5. Alumnos(String name, int age){
  6. this.name = name;
  7. this.age = age;
  8. }
  9. }

Las variables age y name serán las necesarias para que se comparen los objetos y su hashcode.

Lo siguiente que haremos será insertar los objetos Alumnos en un HashSet.

  1. Alumnos person1 = new Alumnos("Juan",18);
  2. Alumnos person2 = new Alumnos("Miguel",25);
  3. Alumnos person3 = new Alumnos("Luis",18);
  4. Alumnos person4 = new Alumnos("Luis",18);
  5.  
  6. HashSet<Alumnos> personas = new HashSet<Alumnos>();
  7. personas.add(person1);
  8. personas.add(person2);
  9. personas.add(person3);
  10. personas.add(person4);

Si verificamos el tamaño del HashSet alumnos veremos que nos devuelve "4", ya que por defecto el HashSet no realiza ninguna comparación.

  1. System.out.println(personas.size());

Ahora agregamos 4 objetos alumno a un HashMap.

  1. Map<Alumnos,String> m = new HashMap<Alumnos,String>();
  2.  
  3. m.put(person1, "valor1");
  4. m.put(person2, "valor2");
  5. m.put(person3, "valor1");
  6. m.put(person4, "mi valor");

El método .size() nos devolvera un tamaño de "4" ya que el HashMap tampoco realiza ninguna comparación. De igual manerá el método .keySet() devuelve todos los elementos del HashMap.

  1. System.out.println(m.keySet());
  2. System.out.println(m.size());

Ahora vamos a cambiar el comportamiento de la clase Alumnos para que al insertarlo en un HashMap o en un HashSet se valide si el elemento insertado ya existe.

Sobrescribimos el método .equals() de tal manera que dos objetos Alumno serán iguales si coinciden sus nombres.

  1. @Override
  2. public boolean equals(Object o) {
  3. if (o instanceof Alumnos) {
  4. Alumnos p = (Alumnos)o;
  5. return this.name.equals(p.name);
  6. } else {
  7. return false;
  8. }
  9. }

De igual manera sobrescribimos el método .hashCode(). Para generar el hascode utilizamos la variable edad y la longitud del String, consiguiendo así un entero.

  1. @Override
  2. public int hashCode() {
  3. return age * this.name.length();
  4. }

Ahora, una vez sobrescritos los métodos .hashCode() y .equals(), si verificamos el tamaño del HashSet alumnos veremos que nos devuelve "3" ya que, si hay un elemento igual, el metodo .add() devolvera false.

  1. Map<Alumnos,String> m = new HashMap<Alumnos,String>();

De igual manera el método .size() sobre el HashMap.keySet() los nombres de 3 alumnos ya que el método .put() habrá devuelto false al insertar objetos iguales.

  1. System.out.println(m.keySet());
  2. System.out.println(m.size());

Una cosa que hay que tener en cuenta es que si se sobreescribe solo uno de sus metodos ya sea .hashCode() o .equals() no tendremos el comportamiento deseado. Hay que sobrescribir los dos.