<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>{francho(lab)} &#187; Java</title>
	<atom:link href="http://francho.org/lab/category/programacion/java/&#038;lang=es_es/feed/" rel="self" type="application/rss+xml" />
	<link>http://francho.org/lab</link>
	<description>forjando ideicas</description>
	<lastBuildDate>Fri, 20 Aug 2010 10:56:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Jugando con Java y el API de Twitter</title>
		<link>http://francho.org/lab/529/jugando-con-java-y-el-api-de-twitter/</link>
		<comments>http://francho.org/lab/529/jugando-con-java-y-el-api-de-twitter/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 17:38:00 +0000</pubDate>
		<dc:creator>francho</dc:creator>
				<category><![CDATA[Banco de pruebas]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://francho.org/lab/?p=529</guid>
		<description><![CDATA[Twitter tiene un API muy completa que nos permite interactuar con su servicio desde nuestras aplicaciones. Esta tarde he estado enredando un poco con ella y la verdad es que se me ocurren un montón de aplicaciones prácticas(logueos, análisis automáticos, integración en servicios de noticias, estadísticas, seguimiento de usuarios, actualizaciones automáticas del perfil, etc&#8230;)
Existen librerías [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://apiwiki.twitter.com/">Twitter tiene un API</a> muy completa que nos permite interactuar con su servicio desde nuestras aplicaciones. Esta tarde he estado enredando un poco con ella y la verdad es que se me ocurren un montón de aplicaciones prácticas(logueos, análisis automáticos, integración en servicios de noticias, estadísticas, seguimiento de usuarios, actualizaciones automáticas del perfil, etc&#8230;)</p>
<p>Existen librerías en un montón de lenguajes que facilitan aún mas su uso. Pero en este caso yo he preferido programar un servicio desde cero (lo cual, gracias a la <a href="http://apiwiki.twitter.com/Twitter-API-Documentation">documentación del API</a> no ha sido nada complicado).</p>
<p>El siguiente ejemplo es una aproximación sencilla que permite actualizar nuestro estado (enviar un post) desde aplicación Java.</p>
<pre class="brush: java;">
/*
 *   http://creativecommons.org/licenses/by-nc/3.0/deed.es
 */

package org.francho.java.twitter;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
// http://commons.apache.org/codec/
import org.apache.commons.codec.binary.Base64;

/**
 *
 * @author francho - http://francho.org/lab/
 */
public class Twitter {

    private String username;
    private String pass;
    private String response;

    Twitter(String username, String pass) {
        setCredentials(username, pass);
    }

    /**
     * Ejemplo de acción implementada.
     *
     * Actualiza el estado de Twitter con el texto que recibe
     *
     * @param status
     */
    public void statusesUpdate(String status) {
        try {
            URL url = new URL(&quot;http://twitter.com/statuses/update.xml&quot;);
            status = URLEncoder.encode(status, &quot;UTF-8&quot;);
            String parametros = &quot;status=&quot; + status;
            doTwitterRequest(url, parametros);
        } catch (MalformedURLException ex) {
            Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Se encarga de la conexión con Twitter.
     * Necesita tener precargada los datos de autentificación (constructor), la url y los parámetros
     */
    private void doTwitterRequest(URL url, String parametros) {
        response = &quot;&quot;;
        try {
            // Creamos una conexión
            URLConnection conn;
            conn = url.openConnection();
            conn.setAllowUserInteraction(false);
            conn.setDoOutput(true);

            // Configuramos la autentificación (sencilla basada en HTTP)
            conn.setRequestProperty(&quot;Authorization&quot;, &quot;Basic &quot; + getBasicCredentials());

            // Preparamos la conexión con el servidor (vamos a mandar un formulario por post)
            conn.setRequestProperty(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;);
            // Abrimos el canal de comunicación de envío
            DataOutputStream out = new DataOutputStream(conn.getOutputStream());
            // Mandamos los parámetros de la acción que (los ha tenido que precargar el método correspondiente)
            out.writeBytes(parametros.toString());
            // Nos aseguramos de que todo se envíe
            out.flush();
            // Ya hemos dicho lo que teníamos que decir, así que cerramos la conexión de envio
            out.close();

            // Capturamos la respuesta
            BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            String l = &quot;&quot;;
            while ((l = input.readLine()) != null) {
                response += l + &quot;\n&quot;;
            }

        } catch (IOException ex) {
            Logger.getLogger(Twitter.class.getName()).log(Level.SEVERE, null, ex);

        }

    }

    public void setCredentials(String username, String pass) {
        this.username = username;
        this.pass = pass;
    }

    public String getBasicCredentials() {
        byte[] credentialsBytes = (username + &quot;:&quot; + pass).getBytes();
        byte[] encodedBytes = Base64.encodeBase64(credentialsBytes);
        return new String(encodedBytes);
    }

    public String getResponse() {
        return response;
    }
}
</pre>
<p>Este sería un ejemplo de uso de nuestra clase:</p>
<pre class="brush: java;">
/*
 *   http://creativecommons.org/licenses/by-nc/3.0/deed.es
 */

package org.francho.java.twitter;

import java.util.Date;

/**
 *
 * @author francho - http://francho.org/lab/
 */
public class Test {
    public static void main(String[] args) {
        Twitter twitter = new Twitter(&quot;yoEnTwitter&quot;, &quot;miclave&quot;);

        Date ahora = new Date();

        twitter.statusesUpdate(&quot;Jugando con Java y el API de Twitter &quot; + ahora);
        System.out.println(twitter.getResponse());
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://francho.org/lab/529/jugando-con-java-y-el-api-de-twitter/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Java: Ejemplo de uso de tipos enumerados (enum)</title>
		<link>http://francho.org/lab/519/java-ejemplo-de-uso-de-tipos-enumerados-enum/</link>
		<comments>http://francho.org/lab/519/java-ejemplo-de-uso-de-tipos-enumerados-enum/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 18:57:14 +0000</pubDate>
		<dc:creator>francho</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[ejemplos]]></category>
		<category><![CDATA[enum]]></category>

		<guid isPermaLink="false">http://francho.org/lab/?p=519</guid>
		<description><![CDATA[Los tipos enumerados sirven para restringir el contenido de una variable a una serie de valores predefinidos. Esto suele ayudar a reducir los errores en nuestro código.
A partir de Java SE 5.0 se incluyo una modalidad de tipos enumerados que mantiene la seguridad de los tipos. En la práctica viene a ser como si definiéramos [...]]]></description>
			<content:encoded><![CDATA[<p>Los tipos enumerados sirven para restringir el contenido de una variable a una serie de valores predefinidos. Esto suele ayudar a reducir los errores en nuestro código.</p>
<p>A partir de Java SE 5.0 se incluyo una modalidad de <a href="http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html">tipos enumerados</a> que mantiene la seguridad de los tipos. En la práctica viene a ser como si definiéramos nuestros propios tipos de variables.</p>
<p>En Java, los tipos enumerados se pueden definir fuera o dentro de una clase. Otra ventaja que traen los tipos enum de Java es que al ser una &#8220;especie de clase&#8221; podemos añadirles métodos, variables de instancia, constructores, etc&#8230; lo que los hace muy potentes.</p>
<p>A continuación os dejo un pequeño ejemplo que ilustra todos estos conceptos.</p>
<pre class="brush: java;">
/*
 *   http://creativecommons.org/licenses/by-nc/3.0/deed.es
 */
package org.francho.java.ejemplos;

/*
 *
 * @author francho - http://francho.org/lab/
 */

/*
 * Un tipo enumerado &quot;complejo&quot;, tiene sus propios métodos y constructor
 */

enum Vaso {
    // Tipos de vaso disponibles. Pasan al constructor su capacidad en cc.
    JARRA(500), TUBO(250), TERCIO(333), CAÑA(200);

    private int cc; // Variable interna donde almacenaremos la capacidad

    // Nuestro constructor nos fuerza a pasar parámetros al definir un nuevo tipo
    Vaso(int cc) {
        this.cc = cc;
    }

    // Devuelve la capacidad del vaso
    public int getCentimetrosCubicos() {
        return cc;
    }
}

/*
 * Definimos un tipo de bebida
 */

class BebidaCerveza {
    enum MarcaCerveza { AMBAR, GUINNESS, HEINEKEN } // Tipos enumerados sencillos. Solo tenemos estas marcas

    private Vaso vaso;
    private MarcaCerveza marca;

    BebidaCerveza(MarcaCerveza marca, Vaso vaso) {
        this.marca = marca;
        this.vaso = vaso;
    }

    public void servir() {
        System.out.println(&quot;Sirviendo &quot; + vaso.getCentimetrosCubicos() + &quot;cc. de cerveza &quot; + marca);
    }
}

/*
 * Clase pública que prueba todo esto
 */

public class PruebaEnum {
    public static void main(String[] args) {
        BebidaCerveza birra = new BebidaCerveza(BebidaCerveza.MarcaCerveza.AMBAR, Vaso.JARRA);

        birra.servir();
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://francho.org/lab/519/java-ejemplo-de-uso-de-tipos-enumerados-enum/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Códigos QR</title>
		<link>http://francho.org/lab/256/codigos-qr/</link>
		<comments>http://francho.org/lab/256/codigos-qr/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 09:45:08 +0000</pubDate>
		<dc:creator>francho</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[códigos de barras]]></category>
		<category><![CDATA[códigos QR]]></category>
		<category><![CDATA[librerías]]></category>
		<category><![CDATA[utilidades]]></category>

		<guid isPermaLink="false">http://francho.org/lab/?p=256</guid>
		<description><![CDATA[Los códigos QR son códigos de barras bidimensionales pensados para que las máquinas puedan leer datos rápidamente.
Se caracterizan por tener tres cuadrados en las esquinas, que sirven para que los escáneres puedan centrarlos, y la información codificada dibujando píxeles. Es un estándar de código abierto, muy popular en Japón que gracias a los móviles se [...]]]></description>
			<content:encoded><![CDATA[<p>Los <a title="Códigos QR en la Wikipedia" href="http://es.wikipedia.org/wiki/Codigo_QR" target="_blank">códigos QR</a> son códigos de barras bidimensionales pensados para que las máquinas puedan leer datos rápidamente.</p>
<p>Se caracterizan por tener tres cuadrados en las esquinas, que sirven para que los escáneres puedan centrarlos, y la información codificada dibujando píxeles.<img class="aligncenter size-medium wp-image-257" title="Tarjeta de visita de Francho" src="http://francho.org/lab/wp-content/uploads/2009/07/QR_francho-300x300.png" alt="Tarjeta de visita de Francho" width="300" height="300" /> Es un estándar de código abierto, muy popular en Japón que gracias a los móviles se está empezando a popularizar en nuestro país. Por ejemplo muchas páginas incluyen imágenes con el código QR con URLs de descarga para que con solo enfocar con el móvil se inicie la descarga.</p>
<p>En Android para leerlos podemos usar, entre otras, Barcode Scanner, una herramienta gratuita que se puede encontrar en el <a href="http://www.android.com/market/">Android Market</a>.</p>
<p>A nivel técnico, si queremos programar un lector en Java podemos usar las librerías <a href="http://code.google.com/p/zxing/">Zxing</a> disponibles bajo licencia Apache2. Estas librerías nos permiten trabajar con códigos de barras de una (los de toda la vida) y dos dimensiones.</p>
<p>Si lo que queremos es generar una imagen QR con nuestra propia información podemos usar un <a title="Generador de código QR" href="http://zxing.appspot.com/generator/">generador QR online</a>. La imagen que ilustra el artículo por ejemplo es mi tarjeta de visita <img src='http://francho.org/lab/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://francho.org/lab/256/codigos-qr/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java: vectores dinámicos sincronizados</title>
		<link>http://francho.org/lab/67/java-vectores-dinamicos-sincronizados/</link>
		<comments>http://francho.org/lab/67/java-vectores-dinamicos-sincronizados/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 07:41:53 +0000</pubDate>
		<dc:creator>francho</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[ejrcicios]]></category>

		<guid isPermaLink="false">http://francho.org/lab/?p=67</guid>
		<description><![CDATA[Este es un ejemplo que implementa un vector dinámico sincronizado programado en java (sin usar las clases que ya existen ya que se trata de un ejercicio   )
Para probar su funcionamiento lanzaremos varios threads que intentarán añadir y borrar elementos al vector de forma simultanea.

Main.java

/*
 * Crear una implementación sincronizada de un vector [...]]]></description>
			<content:encoded><![CDATA[<p>Este es un ejemplo que implementa un vector dinámico sincronizado programado en java (sin usar las clases que ya existen ya que se trata de un ejercicio <img src='http://francho.org/lab/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  )</p>
<p>Para probar su funcionamiento lanzaremos varios threads que intentarán añadir y borrar elementos al vector de forma simultanea.<br />
<span id="more-67"></span><br />
Main.java</p>
<pre class="brush: java;">
/*
 * Crear una implementación sincronizada de un vector dinámico
 *
 * Métodos:
 *  - añadir(elemento)
 *  - añadirEn(elemento, posicion)
 *  - borrar(elemento)
 *  - borrar(posicion)
 */
package ejerciciovectordinamico;

/**
 *
 * @author: $Author: franchux $
 * @version: $Rev: 100 $
 * @date: $Date: 2009-04-21 09:38:58 +0200 (mar 21 de abr de 2009) $
 * $Id: Main.java 100 2009-04-21 07:38:58Z franchux $
 */
public class Main
{

    public static final int HILOS = 8;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        VectorDinamicoSincronizado vector = new VectorDinamicoSincronizado();

        // Este array nos permitirá controlar los hilos que creemos
        //Thread[] manejador = new Thread[HILOS];

        // Creamos los hilos que intentarán modificar posiciones del vector con valores aleatorios
        for (int i = 0; i &lt; HILOS; i++) {
            TestVectorDinamicoRunnable r = new TestVectorDinamicoRunnable(vector);
            Thread t = new Thread(r);
            t.start();
        //manejador[i] = new Thread(r);
        //manejador[i].start();
        }

        // Ahora llenamos el vector para que los hilos que puedan los sobreescriban
        for (int i = 0; i &lt; HILOS; i++) {
            vector.añadir(&quot;-&quot;);
        }

        // Damos un tiempo para que los hilos intenten hacer su trabajo
        espera(5000);

        // Cerramos los hilos que quedan abiertos
        int numActivas = Thread.activeCount();
        Thread[] manejador = new Thread[numActivas];
        Thread.enumerate(manejador);
        for (Thread t : manejador) {
            if (t.isAlive()) {
                t.interrupt();
            }
        }

        System.out.println(vector);

        System.out.println(&quot;Hilo principal terminado&quot;);

    }

    public static void espera(int milisegundos)
    {

        long t0, t1;

        t0 = System.currentTimeMillis();
        do {
            t1 = System.currentTimeMillis();
        } while (t1 - t0 &lt; milisegundos);
    }
}
</pre>
<p>VectorDinamicoSincronizado.java</p>
<pre class="brush: java;">
package ejerciciovectordinamico;

/**
 *
 * @author: $Author: franchux $
 * @version: $Rev: 100 $
 * @date: $Date: 2009-04-21 09:38:58 +0200 (mar 21 de abr de 2009) $
 * $Id: VectorDinamicoSincronizado.java 100 2009-04-21 07:38:58Z franchux $
 */
public class VectorDinamicoSincronizado {

    protected String[] datos;
    final static int TIMEOUT = 1000;

    public VectorDinamicoSincronizado() {
        datos = new String[0];
    }

    /**
     * Añade un número al final de la lista
     *
     * @param numero a insertar
     */
    public void añadir(String texto) {
        //insertarOrdenado(numero);
        String[] nuevo = new String[datos.length + 1];
        for (int i = 0; i &lt; datos.length; i++) {
            nuevo[i] = datos[i];
        }
        nuevo[datos.length] = texto;
        datos = nuevo;
        loguea(&quot;pongo &quot; + texto + &quot; al final&quot;);
    }

    /**
     * Añade una cadena en una determinada posicion
     *
     * @param texto a añadir
     * @param posicion posición donde colocarlo
     */
    public synchronized void añadirEn(String texto, int posicion) {

        try {  // Si la posición que intentamos insertar está fuera del vector actual
            // Esperamos a ver si hay suerte y el vector crece
            while(posicion &gt; (datos.length - 1)) {
                loguea(&quot;no puedo insertar &quot; + texto + &quot; en posicion &quot; + posicion + &quot; espero...&quot;);
                wait(TIMEOUT);
            }
            datos[posicion] = texto;
            loguea(&quot;pongo &quot; + texto + &quot; en &quot; + posicion);

        } catch (InterruptedException ex) {
            // Logger.getLogger(VectorDinamicoSincronizado.class.getName()).log(Level.SEVERE, null, ex);
            loguea(&quot;HILO TERMINADO: no puedo insertar &quot; + texto + &quot; en posicion &quot; + posicion + &quot; abandono&quot;);
        }

        notifyAll();
    }

    public synchronized void borrar(int posicion) {
        String [] nueva = new String[datos.length -1];
        int n=0;

        for(int i=0;i&lt;datos.length;i++) {
            if(i!=posicion) {
                nueva[n++] = datos[i];
            }
        }

        datos = nueva;
    }

    /**
     * Muestra por pantalla un mensaje de debug
     *
     * @param texto a mostrar
     */
    public void loguea(String texto) {
        System.out.println(Thread.currentThread().toString() + texto);
    }

    /**
     * Maqueta el contenido
     *
     * @return cadena con todos los numeros del array
     */
    @Override
    public String toString() {
        String cad = &quot;[ &quot;;
        for (String d : datos) {
            cad += &quot;&quot; + d + &quot; &quot;;
        }
        cad += &quot;]&quot;;

        return cad;
    }
}
</pre>
<p>TestVectorDinamicoSincronizadoRunnable.java</p>
<pre class="brush: java;">
package ejerciciovectordinamico;

/**
 *
 * @author: $Author: franchux $
 * @version: $Rev: 99 $
 * @date: $Date: 2009-04-21 00:49:25 +0200 (mar 21 de abr de 2009) $
 * $Id: TestVectorDinamicoRunnable.java 99 2009-04-20 22:49:25Z franchux $
 */
public class TestVectorDinamicoRunnable implements Runnable {

    VectorDinamicoSincronizado vector;

    public TestVectorDinamicoRunnable(VectorDinamicoSincronizado vector) {
        this.vector = vector;
    }

    public void run()
    {
        int num = (int) (Math.random() * 10);
        int pos;
        do {
            pos = (int) (Math.random() * 10) - 1;
        } while(pos &lt; 0);

        vector.añadirEn(&quot;&quot;+num, pos);

        //        vector.borrar((int)Math.random());
        System.out.println(Thread.currentThread() + &quot;: &quot; + vector.toString());
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://francho.org/lab/67/java-vectores-dinamicos-sincronizados/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java: Calculadora sencilla en modo gráfico</title>
		<link>http://francho.org/lab/45/java-calculadora-sencilla-en-modo-grafico/</link>
		<comments>http://francho.org/lab/45/java-calculadora-sencilla-en-modo-grafico/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 22:04:34 +0000</pubDate>
		<dc:creator>francho</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[ejercicios]]></category>

		<guid isPermaLink="false">http://francho.org/lab/?p=45</guid>
		<description><![CDATA[Esta es una calculadora sencilla en modo gráfico escrita en Java.
Implementa las operaciones básicas: sumar, restar, multiplicar y dividir

Main.java

/*
 * Ejercicio: Calculadora sencilla
 *   - Implementar la Interfaz de usuario
 *   - Implementar los métodos siguientes a través de los listeners adecuados:
 *         [...]]]></description>
			<content:encoded><![CDATA[<p>Esta es una calculadora sencilla en modo gráfico escrita en Java.</p>
<p>Implementa las operaciones básicas: sumar, restar, multiplicar y dividir</p>
<p><span id="more-45"></span><br />
<strong>Main.java</strong></p>
<pre class="brush: java;">
/*
 * Ejercicio: Calculadora sencilla
 *   - Implementar la Interfaz de usuario
 *   - Implementar los métodos siguientes a través de los listeners adecuados:
 *          - Sumar
 *          - Restar
 *          - Multiplicar
 *          - Dividir
 */

package calculadora;

/**
 *
 * @author: $Author: franchux $
 * @version: $Rev: 70 $
 * @date: $Date: 2009-04-13 13:06:00 +0200 (lun 13 de abr de 2009) $
 * $Id: Main.java 70 2009-04-13 11:06:00Z franchux $
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        VentanaCalculadora calculadora = new VentanaCalculadora();
        calculadora.setVisible(true);
    }

}
</pre>
<p><strong>VentanaCalculadora.java</strong></p>
<pre class="brush: java;">
/*
 * Interfaz para nuestra calculadora sencilla
 */
package calculadora;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

/**
 *
 * @author: $Author: franchux $
 * @version: $Rev: 75 $
 * @date: $Date: 2009-04-14 00:21:18 +0200 (mar 14 de abr de 2009) $
 * $Id: VentanaCalculadora.java 75 2009-04-13 22:21:18Z franchux $
 */
public class VentanaCalculadora extends JFrame {

    /** numero tecleado */
    JTextField pantalla;

    /** guarda el resultado de la operacion anterior o el número tecleado */
    double resultado;

    /** para guardar la operacion a realizar */
    String operacion;

    /** Los paneles donde colocaremos los botones */
    JPanel panelNumeros, panelOperaciones;

    /**  Indica si estamos iniciando o no una operación */
    boolean nuevaOperacion = true;

    /**
     * Constructor. Crea los botones y componentes de la calculadora
     */
    public VentanaCalculadora() {
        super();
        setSize(250, 300);
        setTitle(&quot;Calculadora Simple&quot;);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        // Vamos a dibujar sobre el panel
        JPanel panel = (JPanel) this.getContentPane();
        panel.setLayout(new BorderLayout());

        pantalla = new JTextField(&quot;0&quot;, 20);
        pantalla.setBorder(new EmptyBorder(4, 4, 4, 4));
        pantalla.setFont(new Font(&quot;Arial&quot;, Font.BOLD, 25));
        pantalla.setHorizontalAlignment(JTextField.RIGHT);
        pantalla.setEditable(false);
        pantalla.setBackground(Color.WHITE);
        panel.add(&quot;North&quot;, pantalla);

        panelNumeros = new JPanel();
        panelNumeros.setLayout(new GridLayout(4, 3));
        panelNumeros.setBorder(new EmptyBorder(4, 4, 4, 4));

        for (int n = 9; n &gt;= 0; n--) {
            nuevoBotonNumerico(&quot;&quot; + n);
        }

        nuevoBotonNumerico(&quot;.&quot;);

        panel.add(&quot;Center&quot;, panelNumeros);

        panelOperaciones = new JPanel();
        panelOperaciones.setLayout(new GridLayout(6, 1));
        panelOperaciones.setBorder(new EmptyBorder(4, 4, 4, 4));

        nuevoBotonOperacion(&quot;+&quot;);
        nuevoBotonOperacion(&quot;-&quot;);
        nuevoBotonOperacion(&quot;*&quot;);
        nuevoBotonOperacion(&quot;/&quot;);
        nuevoBotonOperacion(&quot;=&quot;);
        nuevoBotonOperacion(&quot;CE&quot;);

        panel.add(&quot;East&quot;, panelOperaciones);

        validate();
    }

    /**
     * Crea un boton del teclado numérico y enlaza sus eventos con el listener correspondiente
     *
     * @param digito boton a crear
     */
    private void nuevoBotonNumerico(String digito) {
            JButton btn = new JButton();
            btn.setText(digito);
            btn.addMouseListener(
                    new MouseAdapter() {

                        @Override
                        public void mouseReleased(MouseEvent evt) {
                            JButton btn = (JButton) evt.getSource();
                            numeroPulsado(btn.getText());
                        }
                    });

            panelNumeros.add(btn);

    }

    /**
     * Crea un botón de operacion y lo enlaza con sus eventos.
     *
     * @param operacion
     */
    private void nuevoBotonOperacion(String operacion) {
        JButton btn = new JButton(operacion);
        btn.setForeground(Color.RED);

        btn.addMouseListener(
                new MouseAdapter() {

                    @Override
                    public void mouseReleased(MouseEvent evt) {
                        JButton btn = (JButton) evt.getSource();
                        operacionPulsado(btn.getText());
                    }
                });

        panelOperaciones.add(btn);
    }

    /**
     * Gestiona las pulsaciones de teclas numéricas
     *
     * @param digito tecla pulsada
     */
    private void numeroPulsado(String digito) {
        if (pantalla.getText().equals(&quot;0&quot;) || nuevaOperacion) {
            pantalla.setText(digito);
        } else {
            pantalla.setText(pantalla.getText() + digito);
        }
        nuevaOperacion = false;
    }

    /**
     * Gestiona el gestiona las pulsaciones de teclas de operación
     * @param tecla
     */
    private void operacionPulsado(String tecla) {
        if (tecla.equals(&quot;=&quot;)) {
            calcularResultado();
        } else if(tecla.equals(&quot;CE&quot;)) {
            resultado = 0;
            pantalla.setText(&quot;&quot;);
            nuevaOperacion = true;
        } else {
            operacion = tecla;
            if((resultado &gt; 0) &amp;&amp; !nuevaOperacion) {
                calcularResultado();
            } else {
                resultado = new Double(pantalla.getText());
            }
        }

        nuevaOperacion = true;
    }

    /**
     * Calcula el resultado y lo muestra por pantalla
     */
    private void calcularResultado() {
        if (operacion.equals(&quot;+&quot;)) {
            resultado += new Double(pantalla.getText());
        } else if (operacion.equals(&quot;-&quot;)) {
            resultado -= new Double(pantalla.getText());
        } else if (operacion.equals(&quot;/&quot;)) {
            resultado /= new Double(pantalla.getText());
        } else if (operacion.equals(&quot;*&quot;)) {
            resultado *= new Double(pantalla.getText());
        }

        pantalla.setText(&quot;&quot; + resultado);
        operacion = &quot;&quot;;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://francho.org/lab/45/java-calculadora-sencilla-en-modo-grafico/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
