<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Programadores nocturnos</title>
	<atom:link href="http://programadoresnocturnos.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://programadoresnocturnos.wordpress.com</link>
	<description>El conocimiento es como el agua: se pudre si se estanca</description>
	<lastBuildDate>Tue, 22 Nov 2011 06:51:59 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='programadoresnocturnos.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Programadores nocturnos</title>
		<link>http://programadoresnocturnos.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://programadoresnocturnos.wordpress.com/osd.xml" title="Programadores nocturnos" />
	<atom:link rel='hub' href='http://programadoresnocturnos.wordpress.com/?pushpress=hub'/>
		<item>
		<title>GUI con Java y AWT: Menu</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/10/gui-con-java-y-awt-menu/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/10/gui-con-java-y-awt-menu/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 15:49:51 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=51</guid>
		<description><![CDATA[Saludos! En el presente tutorial, seguiremos explorando la creación de GUI con la biblioteca AWT de Java, esta vez con la incorporación de un menú en nuestra ventana. Para el caso del menú, la idea es la siguiente: en cada ventana puedes definir una barra de menu (MenuBar), que es el menú que vemos en [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=51&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Saludos!</p>
<p>En el presente tutorial, seguiremos explorando la creación de GUI con la biblioteca AWT de Java, esta vez con la incorporación de un menú en nuestra ventana.</p>
<p>Para el caso del menú, la idea es la siguiente: en cada ventana puedes definir una barra de menu (MenuBar), que es el menú que vemos en la pare superior de la misma (el que tiene las clásicas entradas &#8220;Archivo&#8221;, &#8220;Ayuda&#8221;, &#8220;Acerca de&#8221;). Dentro de ese menú principal, puedes tener varias opciones (o itemes de menú), y alguna de estas puede ser un menú también, es decir, puede ser un submenú.</p>
<p><span id="more-51"></span></p>
<p>Pero no tantas palabras, y más acción.</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaMenu{
	private Frame ventana;

	public PruebaMenu(){
		ventana = new Frame(&quot;Prueba de menu&quot;);
		MenuBar principal = new MenuBar();

		//crearemos un menú clásico para que se entienda la idea
		Menu archivo = new Menu(&quot;Archivo&quot;);
		MenuItem archivo_abrir = new MenuItem(&quot;Abrir&quot;);
		MenuItem archivo_guardar = new MenuItem(&quot;Guardar&quot;);
		MenuItem archivo_guardarComo = new MenuItem(&quot;Guardar como...&quot;);
		MenuItem archivo_salir = new MenuItem(&quot;Salir&quot;);

		//ahora, agregamos los elementos del menú archivo.
		archivo.add(archivo_abrir);
		archivo.add(archivo_guardar);
		archivo.add(archivo_guardarComo);
		archivo.addSeparator(); //agrega línea divisoria
		archivo.add(archivo_salir);

		//agregar el listener para los elementos del menú
		EscuchaItemMenu eim = new EscuchaItemMenu();
		archivo_abrir.addActionListener(eim);
		archivo_guardar.addActionListener(eim);
		archivo_guardarComo.addActionListener(eim);
		archivo_salir.addActionListener(eim);

		//ahora, indicamos que el menú &quot;archivo&quot; forma parte de la barra de menú
		principal.add(archivo);

		//Por último, le decimos a la ventana cuál es su barra de menu
		ventana.setMenuBar(principal);

		ventana.setSize(300, 300);
		ventana.setResizable(false);
		ventana.addWindowListener(new WindowListener(){
			public void windowOpened(WindowEvent e){}
			public void windowActivated(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				ventana.setVisible(false);
				ventana.dispose();
			}
		});
		ventana.setVisible(true);
	}

	class EscuchaItemMenu implements ActionListener{
		public void actionPerformed(ActionEvent e){
			MenuItem item = (MenuItem)e.getSource();
			String texto = item.getLabel();
			System.out.println(&quot;Opcion seleccionada: &quot; + texto);
			if (texto.equals(&quot;Salir&quot;)){
				ventana.setVisible(false);
				ventana.dispose();
			}
		}
	}

	public static void main(String[] args){
		PruebaMenu pm = new PruebaMenu();
	}
}
</pre></p>
<ul>
<li><em><strong>MenuBar principal = new MenuBar()</strong></em> crea la barra de menú que usaremos en la ventana.</li>
<li><em><strong>Menu archivo = new Menu(&#8220;Archivo&#8221;)</strong></em> crea el menú &#8220;Archivo que irá dentro del menú principal.</li>
<li><strong><em>MenuItem archivo_abrir = new MenuItem(&#8220;Abrir&#8221;)</em></strong> crea cada uno de los itemes que irán dentro de archivo.</li>
<li><em><strong>archivo.add(archivo_abrir)</strong></em> con este método estamos agregando los itemes como parte del menú archivo.</li>
<li><strong><em>principal.add(archivo)</em></strong> agrega el menú Archivo a la barra de menú.</li>
<li><em><strong>ventana.setMenuBar(principal)</strong></em> asigna la barra de menú a la ventana. Sin este paso, no se ve ningún menú en la ventana.</li>
</ul>
<p>Otro punto ventajoso para nosotros es que el Listener de cada item de menú es el ActionListener, que ya conocemos; como nota al margen, se puede agregar un ActionListener al menú (en este caso, a Archivo)&#8230; busca en la API de Java la clase java.awt.Menu para ver más detalles.</p>
<p>Otra cosa importante: además del MenuItem, existe el CheckboxMenuItem, que es un item que puede estar seleccionado o no (el típico elemento de menú al que le aparece un &#8216;visto bueno&#8217; al lado).</p>
<p>También es importante indicar que se pueden anidar los elementos, es decir, puedo poner un menú dentro de un menú para ir haciendo un submenú&#8230; como en el siguiente código.</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaMenu{
	private Frame ventana;

	public PruebaMenu(){
		ventana = new Frame(&quot;Prueba de menu&quot;);
		MenuBar principal = new MenuBar();

		//crearemos un menú clásico para que se entienda la idea
		Menu archivo = new Menu(&quot;Archivo&quot;);
		MenuItem archivo_abrir = new MenuItem(&quot;Abrir&quot;);
		MenuItem archivo_guardar = new MenuItem(&quot;Guardar&quot;);
		MenuItem archivo_guardarComo = new MenuItem(&quot;Guardar como...&quot;);
		Menu importar = new Menu(&quot;Importar&quot;);
		MenuItem archivo_salir = new MenuItem(&quot;Salir&quot;);

		//ahora, agregamos los elementos del menú archivo.
		archivo.add(archivo_abrir);
		archivo.add(archivo_guardar);
		archivo.add(archivo_guardarComo);
		archivo.addSeparator(); //agrega línea divisoria
		archivo.add(importar);
		archivo.add(archivo_salir);

		//los elementos del menú importar
		MenuItem importar_imagen = new MenuItem(&quot;Importar desde imagen&quot;);
		MenuItem importar_odf = new MenuItem(&quot;Importar desde ODF&quot;);
		MenuItem importar_html = new MenuItem(&quot;Importar desde HTML&quot;);
		MenuItem importar_pdf = new MenuItem(&quot;Importar desde HTML&quot;);
		CheckboxMenuItem importar_repetidos = new CheckboxMenuItem(&quot;Importar elementos repetidos&quot;, true);
		importar.add(importar_imagen);
		importar.add(importar_odf);
		importar.add(importar_html);
		importar.add(importar_pdf);
		importar.addSeparator();
		importar.add(importar_repetidos);

		//agregar el listener para los elementos del menú
		EscuchaItemMenu eim = new EscuchaItemMenu();
		archivo_abrir.addActionListener(eim);
		archivo_guardar.addActionListener(eim);
		archivo_guardarComo.addActionListener(eim);
		archivo_salir.addActionListener(eim);
		importar_imagen.addActionListener(eim);
		importar_odf.addActionListener(eim);
		importar_html.addActionListener(eim);
		importar_pdf.addActionListener(eim);
		importar_repetidos.addItemListener(new ItemListener(){
			public void itemStateChanged(ItemEvent e){
				System.out.println(&quot;  Importar repetidos: &quot; + (e.getStateChange() == ItemEvent.SELECTED));
			}
		});

		//ahora, indicamos que el menú &quot;archivo&quot; forma parte de la barra de menú
		principal.add(archivo);

		//Por último, le decimos a la ventana cuál es su barra de menu
		ventana.setMenuBar(principal);

		ventana.setSize(300, 300);
		ventana.setResizable(false);
		ventana.addWindowListener(new WindowListener(){
			public void windowOpened(WindowEvent e){}
			public void windowActivated(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				ventana.setVisible(false);
				ventana.dispose();
			}
		});
		ventana.setVisible(true);
	}

	class EscuchaItemMenu implements ActionListener{
		public void actionPerformed(ActionEvent e){
			MenuItem item = (MenuItem)e.getSource();
			String texto = item.getLabel();
			System.out.println(&quot;Opcion seleccionada: &quot; + texto);
			if (texto.equals(&quot;Salir&quot;)){
				ventana.setVisible(false);
				ventana.dispose();
			}
			else if (texto.equals(&quot;Importar elementos repetidos&quot;)){
				CheckboxMenuItem check = (CheckboxMenuItem)e.getSource();
				System.out.println(&quot;  Importa repetidos: &quot; + check.getState());
			}
		}
	}

	public static void main(String[] args){
		PruebaMenu pm = new PruebaMenu();
	}
}
</pre></p>
<p>Nota que el listener para el CheckboxMenuItem es el ItemListener, y no el ActionListener; si quieres, puedes probar agregando ambos listener al CheckboxMenuItem para ver cuál es el que se activa.</p>
<p>Para finalizar, sólo señalar que se pueden agregar varios elementos Menu al MenuBar (esta vez sólo agregué uno para no complicar el ejemplo), y que se pueden generar submenues de la profundidad que necesites (es decir, puedes poner menú dentro de menú tanto como sea necesario).</p>
<p>Bien, eso ha sido todo por este tutorial.</p>
<p>Como siempre, si quieres aprender más detalles, revisa la API de Java y practica, practica, practica.</p>
<p>Hasta la próxima!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/51/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=51&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/10/gui-con-java-y-awt-menu/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>
	</item>
		<item>
		<title>GUI con Java IV: layouts</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-iv-layouts/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-iv-layouts/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 14:08:49 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=45</guid>
		<description><![CDATA[Saludos! En este tutorial, veremos cómo se pueden acomodar dos o mas widgets dentro de una ventana. Para poder poner más de un widget en una ventana, se debe cambiar su diseño o layout. Java nos proporciona varios layouts, pero presentaré acá los más comunes para dejar las nociones de uso de layouts, y el [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=45&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Saludos!</p>
<p>En este tutorial, veremos cómo se pueden acomodar dos o mas <em>widgets</em> dentro de una ventana.</p>
<p>Para poder poner más de un widget en una ventana, se debe cambiar su diseño o <em>layout</em>. Java nos proporciona varios layouts, pero presentaré acá los más comunes para dejar las nociones de uso de layouts, y el resto queda a investigación del lector; no olvidar que una excelente forma de aprender Java es tener la documentación de la API a mano.</p>
<p><span id="more-45"></span></p>
<h2>FlowLayout</h2>
<p>Este es el layout más fácil de usar, y el más básico. La idea es que los elementos se ubicarán dentro de la ventana en el mismo orden en que los fui añadiendo. Así de simple. Además, ese orden se acomoda dependiendo de los tamaños de la ventana&#8230; pero eso queda -como siempre- más claro con un pequeño ejemplito:</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaFlowLayout{
	public PruebaFlowLayout(){
		//crear la ventana
		Frame ventana = new Frame(&quot;Flow Layout&quot;);
		ventana.setLayout(new FlowLayout());
		//ventana.setSize(300, 100);
		ventana.setSize(100, 300);
		ventana.addWindowListener(new WindowListener(){
			public void windowActivated(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowOpened(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				System.out.println(&quot;Cerrando ventana...&quot;);
				e.getWindow().dispose();
			}
		});

		//agregar los botones
		ListenerBoton lb = new ListenerBoton();
		for(int i = 1; i &amp;lt;= 4; i++){
			Button boton = new Button(&quot;Boton &quot; + i);
			boton.addActionListener(lb);
			ventana.add(boton);
		}

		//mostrar la ventana
		ventana.setVisible(true);
	}

	//listener para los botones
	class ListenerBoton implements ActionListener{
		public void actionPerformed(ActionEvent e){
			String texto = ((Button)e.getSource()).getLabel();
			System.out.println(&quot;Boton presionado: &quot; + texto);
		}
	}

	//main
	public static void main(String[] args){
		PruebaFlowLayout pfl = new PruebaFlowLayout();
	}
}
</pre></p>
<p>EL resultado sería algo similar a lo siguiente:</p>
<p><img title="flow.png" src="http://bligoo.com/media/users/1/83958/images/public/17155/flow.png?v=1252966510862" alt="" /></p>
<p>Mucho del código acá mostrado ya es conocido, así que sólo me quedo con las novedades.</p>
<ul>
<li><em><strong>ventana.setLayout()</strong></em> es el método que nos permite asignar un layout o diseño a la ventana. El parámetro para este método debe ser uno de los layouts que existen en el paquete java.awt; para este ejemplo, pasé como parámetro un nuevo <em>FlowLayout</em>.</li>
</ul>
<p>Tambien nota que utilizo un ciclo for para agregar cuatro botones a nuestra ventana.</p>
<p>Fíjate lo que pasa cuando cambias el tamaño de la ventana. Prueba lo siguiente: haz la ventana más alta que ancha, y fíjate lo que pasa con la distribución de los botones&#8230; sigue siendo ordenada según agregué los botones a la ventana, pero el orden cambia de horizontal a vertical dependiendo del tamaño de la ventana.</p>
<h2>BorderLayout</h2>
<p>Otro layout que normalmente se utiliza es el BorderLayout. La idea de este layout es posicionar los componentes según los puntos cardinales&#8230; veamos cómo queda el código asociado:</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaBorderLayout{
	public PruebaBorderLayout(){
		//crear la ventana
		Frame ventana = new Frame(&quot;Border Layout&quot;);
		ventana.setLayout(new BorderLayout());
		ventana.setSize(300, 250);
		ventana.addWindowListener(new WindowListener(){
			public void windowActivated(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowOpened(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				System.out.println(&quot;Cerrando ventana...&quot;);
				e.getWindow().dispose();
			}
		});

		//agregar los botones
		ListenerBoton lb = new ListenerBoton();
		Button boton = new Button(&quot;Norte&quot;);
		boton.addActionListener(lb);
		ventana.add(boton, BorderLayout.NORTH);
		boton = new Button(&quot;Sur&quot;);
		boton.addActionListener(lb);
		ventana.add(boton, BorderLayout.SOUTH);
		boton = new Button(&quot;Este&quot;);
		boton.addActionListener(lb);
		ventana.add(boton, BorderLayout.EAST);
		boton = new Button(&quot;Oeste&quot;);
		boton.addActionListener(lb);
		ventana.add(boton, BorderLayout.WEST);
		boton = new Button(&quot;Centro&quot;);
		boton.addActionListener(lb);
		ventana.add(boton, BorderLayout.CENTER);

		//mostrar la ventana
		ventana.setVisible(true);
	}

	//listener para los botones
	class ListenerBoton implements ActionListener{
		public void actionPerformed(ActionEvent e){
			String texto = ((Button)e.getSource()).getLabel();
			System.out.println(&quot;Boton presionado: &quot; + texto);
		}
	}

	//main
	public static void main(String[] args){
		PruebaBorderLayout pbl = new PruebaBorderLayout();
	}
}
</pre></p>
<p>Y nuestro programa se vería más o menos así:</p>
<p><img title="border.png" src="http://bligoo.com/media/users/1/83958/images/public/17155/border.png?v=1252966661494" alt="" /></p>
<p>Nuevamente, me centro en los cambios:</p>
<ul>
<li><em><strong>ventana.setLayout(new BorderLayout())</strong></em> define el layout de la ventana como BorderLayout.</li>
<li><em><strong>ventana.add(boton, BorderLayout.X)</strong></em> define en qué posición se agrega el widget. En este caso, lo que se estaba agregando era un botón, y X puede tomar los valores NORTH, SOUTH, EAST, WEST o CENTER según se requiera.</li>
</ul>
<p>Prueba esta vez a cambiar el tamaño de la ventana, y cómo se modifican los botones dentro de ella.</p>
<h2>GridLayout</h2>
<p>La idea del GridLayout es poner los widgets en grilla, es decir, en una malla. Es tan sencillo como &#8220;cuadricular&#8221; la ventana para poner los componentes que se desee. Vamos al ejemplo:</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaGridLayout{
	public PruebaGridLayout(){
		//crear la ventana
		Frame ventana = new Frame(&quot;Grid Layout&quot;);
		ventana.setLayout(new GridLayout(2, 2));
		ventana.setSize(300, 250);
		ventana.addWindowListener(new WindowListener(){
			public void windowActivated(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowOpened(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				System.out.println(&quot;Cerrando ventana...&quot;);
				e.getWindow().dispose();
			}
		});

		//agregar los botones
		ListenerBoton lb = new ListenerBoton();
		for(int i = 1; i &amp;lt;= 4; i++){
			Button b = new Button(&quot;Boton &quot; + i);
			b.addActionListener(lb);
			ventana.add(b);
		}

		//mostrar la ventana
		ventana.setVisible(true);
	}

	//listener para los botones
	class ListenerBoton implements ActionListener{
		public void actionPerformed(ActionEvent e){
			String texto = ((Button)e.getSource()).getLabel();
			System.out.println(&quot;Boton presionado: &quot; + texto);
		}
	}

	//main
	public static void main(String[] args){
		PruebaGridLayout pbl = new PruebaGridLayout();
	}
}
</pre></p>
<p>Y nuestra ventana se vería más o menos así:</p>
<p><img title="grid.png" src="http://bligoo.com/media/users/1/83958/images/public/17155/grid.png?v=1252966784052" alt="" /></p>
<p>Entonces, lo importante está en ventana.setLayout(new GridLayout(2,2))&#8230; ¿qué significan esos 2 que están ahí? Pues simple: el numéro de filas y columnas (respectivamente) en los que será dividida la ventana; prueba cambiar los números para ver lo que ocurre.</p>
<p>Otra cosa importante de destacar es el orden en que los botones se agregan: fíjate que van desde la primera fila (desde arriba hacia abajo), y desde la primera columna (de izquiera a derecha).</p>
<p>Interfaces más complejas: paneles y layouts anidados</p>
<p>Si bien no hemos visto todos los layouts, tenemos herramientas suficientes para crear interfaces de usuario relativamente complejas. Para esto, debes saber que los layouts se pueden anidar, es decir, yo podría poner -por ejemplo- un GridLayout al norte de un BorderLayout, y otras mezclas. Para lograr eso, el layout anidado se pone dentro de un Panel (java.awt), que es un widget no visible que actúa como contenedor (igual que la ventana), así que a un Panel se le puede asignar un layout.</p>
<p>¿Cómo combino entonces los layouts? Depende exclusivamente de lo que me interesa hacer, nada más.</p>
<p>Para muestra, un último ejemplo:</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class Anidados{
	public Anidados(){
		//crear la ventana
		Frame ventana = new Frame(&quot;Layouts y paneles&quot;);
		ventana.setLayout(new BorderLayout());
		ventana.setSize(450, 400);
		ventana.addWindowListener(new WindowListener(){
			public void windowActivated(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowOpened(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				System.out.println(&quot;Cerrando ventana...&quot;);
				e.getWindow().dispose();
			}
		});

		ListenerBoton lb = new ListenerBoton();
		Button b = null;

		Panel p1 = new Panel(new FlowLayout());
		for(int i = 1; i &amp;lt;= 5; i++){
			b = new Button(&quot;Boton p1-&quot; + i);
			b.addActionListener(lb);
			p1.add(b);
		}
		ventana.add(p1, BorderLayout.SOUTH);

		Panel p2 = new Panel(new GridLayout(3,3));
		for(int i = 1; i &amp;lt;= 9; i++){
			b = new Button(&quot;Boton p2-&quot; + i);
			b.addActionListener(lb);
			p2.add(b);
		}
		ventana.add(p2, BorderLayout.CENTER);

		b = new Button(&quot;Norte&quot;);
		b.addActionListener(lb);
		ventana.add(b, BorderLayout.NORTH);

		b = new Button(&quot;Oeste&quot;);
		b.addActionListener(lb);
		ventana.add(b, BorderLayout.WEST);

		b = new Button(&quot;Este&quot;);
		b.addActionListener(lb);
		ventana.add(b, BorderLayout.EAST);

		//mostrar la ventana
		ventana.setVisible(true);
	}

	//listener para los botones
	class ListenerBoton implements ActionListener{
		public void actionPerformed(ActionEvent e){
			String texto = ((Button)e.getSource()).getLabel();
			System.out.println(&quot;Boton presionado: &quot; + texto);
		}
	}

	//main
	public static void main(String[] args){
		Anidados a = new Anidados();
	}
}
</pre></p>
<p><img title="anidados.png" src="http://bligoo.com/media/users/1/83958/images/public/17155/anidados.png?v=1252967802313" alt="" /></p>
<p>Esto es sólo un ejemplo de lo que podría hacer; de aquí en adelante, la creatividad de cada uno es fundamental para llegar al layout que necesito para mi aplicación.</p>
<p>Bueno, eso es todo por este tutorial.</p>
<p>Pronto, tutoriales con más widgets para Java y AWT.</p>
<p>Hasta la próxima!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=45&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-iv-layouts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>

		<media:content url="http://bligoo.com/media/users/1/83958/images/public/17155/flow.png?v=1252966510862" medium="image">
			<media:title type="html">flow.png</media:title>
		</media:content>

		<media:content url="http://bligoo.com/media/users/1/83958/images/public/17155/border.png?v=1252966661494" medium="image">
			<media:title type="html">border.png</media:title>
		</media:content>

		<media:content url="http://bligoo.com/media/users/1/83958/images/public/17155/grid.png?v=1252966784052" medium="image">
			<media:title type="html">grid.png</media:title>
		</media:content>

		<media:content url="http://bligoo.com/media/users/1/83958/images/public/17155/anidados.png?v=1252967802313" medium="image">
			<media:title type="html">anidados.png</media:title>
		</media:content>
	</item>
		<item>
		<title>GUI con Java III: Button y ActionListener</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-iii-button-y-actionlistener/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-iii-button-y-actionlistener/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 14:02:04 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=42</guid>
		<description><![CDATA[Saludos! Siguiendo con los tutoriales de GUI en Java, esta vez veremos cómo se crean botones en nuestras GUI, y cómo programar código asociado a los mismos. En Java, el botón es la clase Button del paquete java.awt. El listener asociado es el ActionListener, que -como casi todos los listener- pertenece a java.awt.event. En el [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=42&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Saludos!</p>
<p>Siguiendo con los tutoriales de GUI en Java, esta vez veremos cómo se crean botones en nuestras GUI, y cómo programar código asociado a los mismos.</p>
<p><span id="more-42"></span></p>
<p>En Java, el botón es la clase Button del paquete java.awt. El listener asociado es el ActionListener, que -como casi todos los listener- pertenece a java.awt.event.</p>
<p>En el tutorial anterior, vimos ya cómo crear una ventana con Java. Ahora, lo que haremos será crear, además de la ventana, un botón dentro de ella. En fin, creo que se aprende mejor con un ejemplo, así que vamos a ello:</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaBoton{
	private Frame ventana;

	public PruebaBoton(){
		ventana = new Frame(&quot;Probando Button&quot;);
		ventana.setSize(120, 80);
		ventana.addWindowListener(new WindowListener(){
			public void windowOpened(WindowEvent e){}
			public void windowActivated(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				ventana.dispose();
			}
		});
		Button boton = new Button(&quot;Mi botón&quot;);
		ventana.add(boton);
		ventana.setVisible(true);
	}

	public static void main(String[] args){
		PruebaBoton pb = new PruebaBoton();
	}
}
</pre></p>
<p>Mucho del código anterior ya es conocido, así que me voy a las novedades:</p>
<ul>
<li><em><strong>Button boton = new Button(&#8220;Mi botón&#8221;)</strong></em> es lo que crea un nuevo botón. El texto que tendrá el botón es lo que pasamos como parámetro al constructor.</li>
<li><em><strong>ventana.add(boton)</strong></em> es lo que agrega el botón a la ventana.</li>
</ul>
<p>Si te fijas bien, ahora se entiende la ventaja de que una ventana no sea visible inmediatamente: podemos configurar toda la interfaz (es decir, agregar los widgets que sean necesarios) antes de mostrarla.</p>
<p>Ok, tenemos botón&#8230; pero no responde. Nuevamente, hay que agregar un listener, y ese es el famoso ActionListener. Así que retocamos el código anterior para ponerle un poco de acción a nuestra interfaz:</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaBoton{
	private Frame ventana;

	public PruebaBoton(){
		ventana = new Frame(&quot;Probando Button&quot;);
		ventana.setSize(120, 80);
		ventana.addWindowListener(new WindowListener(){
			public void windowOpened(WindowEvent e){}
			public void windowActivated(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				ventana.dispose();
			}
		});
		Button boton = new Button(&quot;Mi botón&quot;);
		boton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				System.out.println(&quot;Boton presionado&quot;);
			}
		});
		ventana.add(boton);
		ventana.setVisible(true);
	}

	public static void main(String[] args){
		PruebaBoton pb = new PruebaBoton();
	}
}
</pre></p>
<p><em>(Nota: debes ejecutar desde una consola/terminal/símbolo de sistema para poder ver lo que hace el botón)</em></p>
<p>Como puedes ver, la única novedad es que hemos agregado el ActionListener al botón; a diferencia del WindowListener, en ActionListener sólo tenemos un método, que recibe un ActionEvent como argumento.</p>
<p>A quienes les gusta meter mano en los ejemplos, se estarán preguntando: ¿y para poner más de un botón? Bueno, ahí la cosa no es tan simple, ya que hay que distribuir los botones dentro de la ventana para que se vean.</p>
<p>¿Y debería poner un ActionListener para cada botón? No necesariamente: si programo una clase que implemente a ActionListener podría agregar la misma instancia a más de un botón, pero tendré que detectar primero de qué botón viene la acción. Sin entrar en los detalles de la distribución de los botones (y widgets en general, que veremos en un próximo tutorial), veamos un ejemplo al respecto:</p>
<p><pre class="brush: java;">
import java.awt.*;
import java.awt.event.*;

public class PruebaBoton{
	private Frame ventana;
	private Button boton1;
	private Button boton2;

	public PruebaBoton(){
		ventana = new Frame(&quot;Probando Button&quot;);
		ventana.setSize(120, 80);
		ventana.addWindowListener(new WindowListener(){
			public void windowOpened(WindowEvent e){}
			public void windowActivated(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				ventana.dispose();
			}
		});
		boton1 = new Button(&quot;Boton 1&quot;);
		boton2 = new Button(&quot;Boton 2&quot;);
		EscuchaBoton eb = new EscuchaBoton();
		boton1.addActionListener(eb);
		boton2.addActionListener(eb);
		ventana.setLayout(new FlowLayout());
		ventana.add(boton1);
		ventana.add(boton2);
		ventana.setVisible(true);
	}

	class EscuchaBoton implements ActionListener{
		public void actionPerformed(ActionEvent e){
			Button b = (Button)e.getSource();
			System.out.println(&quot;Boton presionado: &quot; + b.getLabel());
			if (b == boton1)
				System.out.println(&quot;\tSI, definitivamente es el boton1&quot;);
			else if (b == boton2)
				System.out.println(&quot;\tSI, definitivamente es el boton2&quot;);
		}
	}

	public static void main(String[] args){
		PruebaBoton pb = new PruebaBoton();
	}
}
</pre></p>
<p>Como ves, acá creo una clase que implementa a ActionListener, y el mismo listener se agrega a los dos botones. Con el método e.getSource() en el listener obtenemos el origen del evento, es decir, qué objeto es el que cambió su estado. Este método retorna un Object, por eso se hace el cast a un botón&#8230; y el método getLabel() de Button nos permite obtener el texto de un botón.</p>
<p>Bueno, eso es todo por este tutorial. En el próximo, veremos cómo se pueden distribuir widgets dentro de una ventana, para luego ir avanzando con otros widgets de uso común.</p>
<p>Hasta la próxima!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/42/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=42&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-iii-button-y-actionlistener/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>
	</item>
		<item>
		<title>GUI con Java II: Frame y WindowListener</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-ii-frame-y-windowlistener/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-ii-frame-y-windowlistener/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:21:05 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=34</guid>
		<description><![CDATA[Saludos! Ahora que hemos visto un poquito de la teoría de las GUI con Java, podemos dar el siguiente paso: nuestra primera ventana y el respectivo listener para responder a sus eventos. Esta vez, como es lógico, nos &#8220;ensuciaremos las manos&#8221; con un poco de código, para irnos acostumbrando hasta llegar a GUI un poco [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=34&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Saludos!</p>
<p>Ahora que hemos visto un poquito de la teoría de las GUI con Java, podemos dar el siguiente paso: nuestra primera ventana y el respectivo listener para responder a sus eventos. Esta vez, como es lógico, nos &#8220;ensuciaremos las manos&#8221; con un poco de código, para irnos acostumbrando hasta llegar a GUI un poco más complejas.</p>
<p><span id="more-34"></span></p>
<p>En Java, la ventana (llamada también Form en algunos toolkits), es llamada Frame, y forma parte del paquete java.awt. Por su parte, WindowListener forma parte de java.awt.event.</p>
<p>Veamos algunos métodos de Frame con un pequeño ejemplo.</p>
<p><pre class="brush: java;">
import java.awt.Frame;

public class WinListener{
	private Frame ventana;

	public WinListener(){
		ventana = new Frame(&quot;Muestra WindowListener&quot;);
		ventana.setSize(640, 480);
		ventana.setVisible(true);
	}

	public static void main(String[] args){
		WinListener w = new WinListener();
	}
}
</pre></p>
<p>Como ves, el código es relativamente corto.</p>
<p>Fíjate que la clase fue declarada como public, asi que el código anterior debe estar en un archivo llamado WinListener.java o no compilará.</p>
<p>Veamos de a poco.</p>
<ul>
<li><strong><em>ventana = new Frame(&#8220;Muestra WindowListener&#8221;)</em></strong> crea un nuevo Frame o ventana, con el título indicado. Este es uno de los constructores de Frame.</li>
<li><strong><em>ventana.setSize(640, 480)</em></strong> da tamaño a la ventana. El primer número es su ancho, el segundo el alto; ambos números se refieren a pixeles.</li>
<li><em><strong>ventana.setVisible(true)</strong></em> hace visible la ventana. En Java, crear una ventana no la hace visible inmediatamente. En próximos tutoriales veremos las ventajas de aquello.</li>
</ul>
<p>Si ejecutas el código, te vas a encontrar con algo más o menos así:</p>
<p><img title="Frame1.png" src="http://bligoo.com/media/users/1/83958/images/public/17155/Frame1.png?v=1252730166101" alt="" /></p>
<p>También puedes notar que minimizar/maximizar la ventana funciona sin problemas, pero cerrar no produce absolutamente nada. ¿Qué es lo que pasa ahí? Pues simple: no hay un listener que haga algo con el evento <em>cerrar ventana</em>.</p>
<p>Ahora hace su entrada magistral el primer listener que estudiaremos: <em>WindowListener</em>. Como es una interfaz, debemos hacer una clase que lo implemente, es decir, que ponga código a los métodos que declara; WindowListener declara cinco métodos&#8230; pero basta de palabrerías. ¡Vamos al código!</p>
<p><pre class="brush: java;">
import java.awt.Frame;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;

public class WinListener{
	private Frame ventana;

	public WinListener(){
		ventana = new Frame(&quot;Muestra WindowListener&quot;);
		ventana.setSize(640, 480);
		ventana.setVisible(true);
		ventana.addWindowListener(new EscuchaVentana());
	}

	class EscuchaVentana implements WindowListener{
		public void windowActivated(WindowEvent e){
			System.out.println(&quot;windowActivated&quot;);
		}

		public void windowClosed(WindowEvent e){
			System.out.println(&quot;windowClosed&quot;);
		}

		public void windowClosing(WindowEvent e){
			System.out.println(&quot;windowClosing&quot;);
			ventana.dispose();
		}

		public void windowDeactivated(WindowEvent e){
			System.out.println(&quot;windowDeactivated&quot;);
		}

		public void windowDeiconified(WindowEvent e){
			System.out.println(&quot;windowDeiconified&quot;);
		}

		public void windowIconified(WindowEvent e){
			System.out.println(&quot;windowIconified&quot;);
		}

		public void windowOpened(WindowEvent e){
			System.out.println(&quot;windowOpened&quot;);
		}

	}

	public static void main(String[] args){
		WinListener w = new WinListener();
	}
}
</pre></p>
<p>El código de nuestro constructor no tiene modificaciones mayores, salvo su última línea: <strong><em>ventana.addWindowListener(new EscuchaVentana());</em></strong></p>
<p>En esa línea es donde estamos registrando el WindowListener, es decir, lo estamos asociando con la ventana. Si te fijas, poco más abajo tenemos una clase llamada EscuchaVentana, que es una implementación del WindowListener y que nos permitirá realizar alguna operación en cada evento que se genere.</p>
<p>Para cada método, sólo he puesto código para que escriba en consola el nombre del método/evento generado, así que te recomiendo ejecutar tu código desde una consola/terminal/símbolo de sistema para que puedas apreciar lo que pasa con la ventana.</p>
<p>Y ahora si, nuestra ventana está totalmente operativa.</p>
<p>La clave para que se cierre está en el método windowClosing del listener. windowClosing es el evento que se genera cuando se intenta cerrar la ventana, es decir, cuando el usuario presiona la X de la esquina. Para que la ventana se cierre, esta debe ser liberada, es decir, llamar al método <em>dispose()</em> de la misma; si no se hace esto, el evento se genera, pero la ventana no se cierra.</p>
<p>Para los más avanzados en programación, habrán notado que EscuchaVentana es una clase contenida en WinListener, por lo que EscuchaVentana tiene acceso a los atributos de WinListener. ¿Y qué hubiera pasado si WinListener hubiera heredado de Frame? No podía haber dicho <em>this.dispose()</em> en <em>windowClosing()</em>, puesto que en ese contexto, this habría sido instancia de EscuchaVentana&#8230; Una forma alternativa de obtener la ventana sobre la que se generó el evento es con el método <em>getWindow()</em> de <em>WindowEvent</em> (fíjate que el parámetro de todos los métodos de <em>WindowListener</em> es un <em>WindowEvent</em>). Así que en el código podrías reemplazar perfectamente</p>
<p><strong><em>ventana.dispose()</em></strong></p>
<p>En el método windowClosing(), por&#8230;</p>
<p><em><strong>e.getWindow().dispose()</strong></em></p>
<p>obteniendo el mismo resultado en ambos casos.</p>
<p>Quienes tengan conocimientos más avanzados de Java, de seguro conocerán las <em>clases anónimas</em>, que es una clase que sólo tiene alcance dentro del ámbito en el cual se define. Son relativamente habituales justamente para implementar listener de GUI, y el código con una clase anónima quedaría más o menos así:</p>
<p><pre class="brush: java;">
import java.awt.Frame;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;

public class WinListener{
	private Frame ventana;

	public WinListener(){
		ventana = new Frame(&quot;Muestra WindowListener&quot;);
		ventana.setSize(640, 480);
		ventana.setVisible(true);
		ventana.addWindowListener(new WindowListener(){
			public void windowActivated(WindowEvent e){}
			public void windowClosed(WindowEvent e){}
			public void windowDeactivated(WindowEvent e){}
			public void windowDeiconified(WindowEvent e){}
			public void windowIconified(WindowEvent e){}
			public void windowOpened(WindowEvent e){}
			public void windowClosing(WindowEvent e){
				System.out.println(&quot;Cerrando ventana...&quot;);
				e.getWindow().dispose();
			}
		});
	}

	public static void main(String[] args){
		WinListener w = new WinListener();
	}
}
</pre></p>
<p>En este caso, se está creando una implementación de WindowListener <em>al vuelo</em>, lo que te ahorra tener que crear una clase nueva exclusivamente para eso. También nota que ahora sólo puse código para el método <em>windowClosing()</em>, puesto que es el único que me interesa controlar para este ejemplo; el resto de métodos se queda sin cuerpo.</p>
<p>Es importante destacar en este punto que una clase anónima sólo tiene alcance en el punto donde se declara y que los métodos que implementa no son una <em>expresión lambda</em> (o <em>closure</em>), así que no caigas en la tentación. De todas maneras, una clase anónima siempre es una clase anidada, es decir, puede acceder a los atributos de la clase que la contiene.</p>
<p>Bueno, eso es todo por este pequeño tutorial. Pronto veremos widgets que podemos ir agregando a nuestra ventana para construir aplicaciones más complejas e interesantes.</p>
<p>Si quieres profundizar e investigar, revisa la famosa API de Java en la cual encontrarás más detalles acerca de WindowEvent y de WindowListener.</p>
<p>¡Hasta la próxima!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/34/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=34&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-ii-frame-y-windowlistener/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>

		<media:content url="http://bligoo.com/media/users/1/83958/images/public/17155/Frame1.png?v=1252730166101" medium="image">
			<media:title type="html">Frame1.png</media:title>
		</media:content>
	</item>
		<item>
		<title>GUI con Java I: widgets, señales, eventos</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-i-widgets-senales-eventos/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-i-widgets-senales-eventos/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:15:28 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=28</guid>
		<description><![CDATA[Saludos! Veremos ahora la teoría necesaria para entender el desarrollo de GUI (graphical user interfaces, interfaces gráficas de usuarios); la teoría que veremos ahora es aplicable no sólo a Java, sino que a cualquier desarrollo con GUI que realicen, independiente de que cada biblioteca de GUI o lenguaje de programación utilice términos ligeramente diferentes. Objetos [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=28&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Saludos!</p>
<p>Veremos ahora la teoría necesaria para entender el desarrollo de GUI (<em>graphical user interfaces</em>, interfaces gráficas de usuarios); la teoría que veremos ahora es aplicable no sólo a Java, sino que a cualquier desarrollo con GUI que realicen, independiente de que cada biblioteca de GUI o lenguaje de programación utilice términos ligeramente diferentes.</p>
<p><span id="more-28"></span></p>
<h2>Objetos y eventos</h2>
<p>Como probablemente ya sepamos, Java es un lenguaje orientado a objetos, es decir, cuando ejecutamos una aplicación tenemos un conjunto de objetos interactuando entre si. Esto significa que la unidad mínima de programación es la <em>clase</em>, la definición abstracta de un objeto.</p>
<p>Cuando programamos una GUI (piensen en cualquier aplicación que usen comunmente, como el mismo navegador web), nos damos cuenta que esa interfaz responde a eventos como hacer click en un menú, poner cursor sobre cierto punto, hacer click en un botón, etcétera. Esto significa que cuando yo -como usuario- genero un evento -como el click en un botón-, en ese momento mi aplicación responde al evento ejecutando una porción del programa.</p>
<p><img title="click.png" src="http://bligoo.com/media/users/1/83958/images/public/17155/click.png?v=1252694502352" alt="" /></p>
<p>Para muchos, la relación está medianamente clara: entonces la GUI podría ser una clase, y los eventos podrían ser métodos. Y si, esa es una buena aproximación, pero no es exactamente lo que hace Java.</p>
<h2>Los <em>listeners</em></h2>
<p>La aproximación que utiliza Java es también una orientada a objetos, y esta es utilizar el patrón observador (observer); es curioso que siendo el patrón observer, Java los haya llamado listeners (y después dicen que los informáticos no tenemos sentido del humor xD).</p>
<p>La idea es la siguiente: yo puedo poner <em>listeners</em> a cada objeto de una GUI, y cada <em>listener</em> estará pendiente de un determinado cambio en el objeto de GUI. Cuando este cambio suceda, el <em>listener</em> ejecutará una acción determinada. ¿Sencillo, verdad?</p>
<p>Para los más avanzados en conceptos de POO, los <em>listeners</em> son meras interfaces que debemos implementar y registrar o agregar al objeto que nos interesa escuchar. En la imagen que está más arriba, si yo no agrego el listener correspondiente al botón Cancelar, cuando haga click sobre él no pasará absolutamente nada.</p>
<p>Como observación, en otros toolkits de GUI (como gtk y qt), no se trabaja en base a <em>listeners</em>, sino que en base a señales y manejadores. Si bien la idea es similar, un manejador (o <em>handler</em>) puede ser simplemente un método/función, y no un objeto. En .net se ocupa esta misma idea, utilizado para ello los <em>delegates</em> (delegados).</p>
<h2>Los <em>widgets</em></h2>
<p>En la mayoría de la documentación que puedan encontrar por la web, se referirán a los objetos de GUI como <em>widgets</em>. Yo no pretendo ir contra ese esquema, así que también les llamaré widgets&#8230; además que widgets es mucho más breve que objeto de GUI xD; cabe señalar que en la jerarquía de clases de Java, se les llama componentes y no wdgets.</p>
<h2>Cada evento con su listener</h2>
<p>Como podrán imaginar, un widget no está obligado a generar sólo un evento particular, sino que puede generar muchos. Por ejemplo, podría ser un evento poner el cursor sobre el objeto, sacarlo del objeto también es un evento, hacer click, hacer click derecho, presionar una tecla, arrastrar, etcétera. Según su naturaleza, cada widget generará los eventos que corresponden.</p>
<p>Cada evento, como es de suponer, tiene naturaleza distinta. Por ejemplo, presionar una tecla y hacer click no son lo mismo, puesto que hacer click es sólo hacer click en determido botón del mouse, mientras que presionar una tecla puede ser cualquiera, puedo haberla presionado junto con control, con alt, con shift, con control y alt&#8230;</p>
<p>Pensando en esto, en Java tenemos diferentes listeners para cada tipo de evento: para los click en un botón tenemos el ActionListener, para saber cuando se quiere maximizar/minimizar/cerrar una ventana tenemos el WindowListener y el WindowStateListener, para saber si recibe el foco tenemos WindowFocusListener, y así para cada widget.</p>
<p>Al principio puede parecer confuso, ya que habría que recordar cada evento, el listener asociado, implementarlo, agregarlo al widget. Claro que no es evidente a la primera, pero con un poco de práctica, ya no es tan sufrido hacer una GUI. Junto con esto, también tenemos la documentación de la API de Java, que te muestra la jerarquía de paquetes, clases, los métodos y parámetros de cada método, y a veces algunas explicaciones breves de cómo usar un determinado método.</p>
<p>Por ahora, los insto a investigar un poco acerca de los diversos widgets disponibles (paquetes java.awt y javax.swing, respectivamente), y de los listeners que tenemos disponibles para implementar (principalmente en el paquete java.awt.event). Los nombres de las clases  métodos sugieren mucho para qué sirve cada cosa, así que no será tan complejo.</p>
<p>En el próximo tutorial, veremos nuestro primer código de GUI: una ventana y los eventos que podemos usar con ella.</p>
<p>Gracias por leer!!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=28&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/02/gui-con-java-i-widgets-senales-eventos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>

		<media:content url="http://bligoo.com/media/users/1/83958/images/public/17155/click.png?v=1252694502352" medium="image">
			<media:title type="html">click.png</media:title>
		</media:content>
	</item>
		<item>
		<title>Python y listas</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/02/python-y-listas/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/02/python-y-listas/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:10:24 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=25</guid>
		<description><![CDATA[Una de las características de Python que me ha llamado mucho la atención es el manejo de listas, y la potencia que estas tienen. Quisiera en este artículo mostrarles un poco de lo que he visto y aprendido de las listas en Python. Pero, para quienes no hayan trabajado con listas antes, partamos desde las [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=25&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Una de las características de Python que me ha llamado mucho la atención es el manejo de listas, y la potencia que estas tienen. Quisiera en este artículo mostrarles un poco de lo que he visto y aprendido de las listas en Python.</p>
<p><span id="more-25"></span></p>
<p>Pero, para quienes no hayan trabajado con listas antes, partamos desde las bases:</p>
<p><pre class="brush: python;">
lista = [&quot;cero&quot;, &quot;uno&quot;, &quot;dos&quot;, &quot;tres&quot;, &quot;cuatro&quot;, &quot;cinco&quot;]
print lista
print lista[0]
print lista[3:]
print lista[-2]
print lista[:4]
</pre></p>
<p>Quienes hayan trabajado con arreglos en lenguajes de tipo C, entenderán rápidamente la idea: una vez declarada la lista, puedo acceder a un elemento en particular indicando su índice (posición) entre corchetes (la primera posición es <strong>cero</strong>).</p>
<p>Python también permite obtener partes (<em>slices</em>) de una lista. Cuando se dice <strong>lista[3:]</strong>, se está obteniendo una parte de sublista, que comienza desde el elemento 3 en adelante. De manera similar, al decir <strong>lista[:3]</strong> son los elementos de lista hasta el tercero. ¿Y los índices negativos? Muy simple: <em>es contando desde el último hacia el primero</em>. Eso significa en el ejemplo que <strong>lista[-2]</strong> referencia al <em>penúltimo elemento</em>.</p>
<p>Ahora, para los más avanzados en programación, las listas de Python son objetos, por lo que tienen algunos métodos interesantes para probar:</p>
<p><pre class="brush: python;">
def mostrarLista(nombreLista, lista):
	for elemento in lista:
		print nombreLista + &quot;:&quot; + elemento
	print

autos = [&quot;ferrari&quot;, &quot;porsche&quot;, &quot;audi&quot;, &quot;bmw&quot;]
frutas = [&quot;pera&quot;, &quot;manzana&quot;, &quot;frutilla&quot;, &quot;naranja&quot;, &quot;ciruela&quot;]

print &quot;Autos con el Lamborghini&quot;
autos.insert(2, &quot;lamborghini&quot;)
mostrarLista(&quot;Autos&quot;, autos)

print &quot;Autos con el lada&quot;
autos.append(&quot;lada&quot;)
mostrarLista(&quot;Autos&quot;, autos)

print &quot;Frutas sin frutilla&quot;
frutas.remove(&quot;frutilla&quot;)
mostrarLista(&quot;Frutas&quot;, frutas)

jeeps = [&quot;musso&quot;, &quot;land rover&quot;]
autos.extend(jeeps)
print &quot;Autos y jeeps&quot;
mostrarLista(&quot;Autos&quot;, autos)

autos.remove(&quot;musso&quot;)
autos.remove(&quot;land rover&quot;)

#autos no contiene a los jeeps ahora
#pero, por si no me crees...
print &quot;Jeeps eliminados de los autos&quot;
mostrarLista(&quot;Autos&quot;, autos)
mostrarLista(&quot;Autos y jeeps&quot;, autos + jeeps)
autos += jeeps
#si... se pueden concatenar
mostrarLista(&quot;Autos y jeeps&quot;, autos)

print &quot;El lada esta en esta posicion:&quot;, autos.index(&quot;lada&quot;)

print &quot;Para terminar, muuuuuuuuuuchas fruuuuuuuuuuuuutas&quot;
mostrarLista(&quot;MUCHAS FRUTAS&quot;, frutas * 5)
</pre></p>
<p>Hay que tener cuidado con los métodos <strong>append()</strong> y <strong>extend()</strong>: ambos agregan elementos, pero lo hacen de manera diferente. Si paso como parámetro una lista a append(), esa lista será agregada como un único elemento, mientras que extend() agrega cada elemento de la lista pasada como parámetro al final de la otra.</p>
<p>Para terminar con las listas, una característica que me llamó la atención por su potencial: <em>inyección de listas</em>. Esto simplemente significa que puedo crear una nueva lista a partir de una existente, pero aplicando alguna función a los elementos de la lista existente. Por ejemplo:</p>
<p><pre class="brush: python;">
class Clase:
	def metodo(self):
		return &quot;Soy el resultado de un metodo&quot;

def mostrarLista(nombreLista, lista):
	for elemento in lista:
		print nombreLista + &quot;:&quot; + elemento
	print

instancias = []
for i in range(10):
	instancias.append(Clase())

valores = [elem.metodo() for elem in instancias]
mostrarLista(&quot;Valores&quot;, valores)
</pre></p>
<p>Lo que se hace acá es crear una lista de clases, para luego generar una segunda lista a partir de los valores obtenidos de invocar un método de cada elemento de la lista de clases. La sentencia <strong>valores = [elem.metodo() for elem in instancias]</strong> conviene leerla al revés: sabemos que <strong>for elem in instancias</strong> es una forma de recorrer toda la lista instancias, llamando elem al elemento actual. Luego, la lista <strong>valores</strong> se crea al llamar al <strong>metodo</strong> de cada <strong>elem</strong> en <strong>instancias</strong>.</p>
<p>Con estos pequeños ejemplos de listas me despido, no sin antes mencionar que Python posee también otros tipos de datos interesantes como tuplas (listas inmutables) y diccionarios, que también pueden facilitar mucho la programación de cierto tipo de aplicaciones. Espero pronto poder desarrollar algún proyecto pequeño que muestre las ventajas de estos tipos de datos.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/25/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=25&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/02/python-y-listas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>
	</item>
		<item>
		<title>SQLite y JDBC</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/02/sqlite-y-jdbc/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/02/sqlite-y-jdbc/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:04:28 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=21</guid>
		<description><![CDATA[Para continuar un poco con SQLite, te mostraré un breve ejemplo de cómo conectar a una base de datos SQLite con Java, utilizando JDBC. En primer lugar, JDBC es el Java Database Connectivity, una API de java que permite el acceso a bases de datos abstrayéndose de detalles como el motor en específico al que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=21&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Para continuar un poco con SQLite, te mostraré un breve ejemplo de cómo conectar a una base de datos SQLite con Java, utilizando JDBC.</p>
<p>En primer lugar, JDBC es el Java Database Connectivity, una API de java que permite el acceso a bases de datos abstrayéndose de detalles como el motor en específico al que estás conectando, el sistema operativo sobre el que se ejecuta, etcétera. Esto se traduce en que dispones de un conjunto de interfaces y clases que permiten el acceso a datos, y que el esquema de conexión y consulta es practicamente igual para varios DBMS (espero, más adelante, publicar otro artículo donde te muestre eso en detalle). Eso si, para poder conectar a un DBMS específico necesitas el driver JDBC, así que eso es lo primero que debes buscar para este artículo: el driver JDBC para SQLite, que se puede descargar desde <a href="http://www.zentus.com/sqlitejdbc/">acá</a>.</p>
<p>Para tener continuidad, partiré con la base de datos creada en el artículo <a href="http://programadoresnocturnos.bligoo.com/content/view/437406/Uso_de_SQLite.html">Uso de SQLite</a>. Ahora, simplemente nos conectaremos a esos datos para hacer consultas e inserciones.</p>
<p><span id="more-21"></span></p>
<p>Lo primero es lo primero: necesitamos importar el paquete java.sql en nuestro código, que es la API de JDBC. Luego, debemos realizar la conexión, y una vez establecida, crear un Statement que nos permitirá operar sobre la base de datos. Si, si&#8230; si el ejemplo viene ahora, simplemente estoy clarificando lo que debemos hacer. Al código:</p>
<p><pre class="brush: java;">
import java.sql.*;

public class EjemploJDBC
{
public static void main(String args[])
   throws ClassNotFoundException, SQLException
   {
      Class.forName(&quot;org.sqlite.JDBC&quot;);
      Statement stmt;

      Connection con = DriverManager.getConnection(&quot;jdbc:sqlite:ejemplo.sqlite&quot;);
      Statement stmt = conexion.createStatement();
      ResultSet resultado = stmt.executeQuery(&quot;select * from buses&quot;);
      while(resultado.next())
      {
         int id = resultado.getInt(1);
         String matricula = resultado.getString(2);
         int ano = resultado.getInt(3);
         int capacidad = resultado.getInt(4);
         System.out.println(&quot;Datos de bus&quot;);
         System.out.println(&quot;ID       :&quot; + id);
         System.out.println(&quot;Matricula:&quot; + matricula);
         System.out.println(&quot;Ano      :&quot; + ano);
         System.out.println(&quot;Capacidad:&quot; + capacidad);
         System.out.println();
      }
      System.out.println(&quot;Datos de buses leidos&quot;);
   }
}
</pre></p>
<p>¿Y qué significa todo esto? Vamos por partes:</p>
<ul>
<li><strong>Class.forName(&#8220;org.sqlite.JDBC&#8221;)</strong> carga el driver de sqlite.</li>
<li><strong>DriverManager.getConnection(&#8220;jdbc:sqlite:ejemplo.sqlite&#8221;)</strong> crea una conexión (Connection) hacia la base de datos. El string que se le pasa como parámetro es &#8220;jdbc:sqlite:&#8221;</li>
<li><strong>conexion.createStatement()</strong> crea el Statement, que nos permite ejecutar código SQL.</li>
<li>El método <strong>executeQuery()</strong> nos permite ejecutar una consulta. Entrega un ResultSet (un conjunto de resultados).</li>
<li>El ResultSet se puede trabajar casi como un iterador: mientras pueda ir al siguiente elemento, los leo; el ResultSet tiene tuplas (filas) de resultado.</li>
<li>Los <strong>métodos getYYY()</strong> <strong>de ResultSet</strong> me permiten leer un dato de la tupla actualmente activa en el ResultSet. Hay métodos para obtener enteros, enteros largos, booleanos, Strings, Fechas, etcétera. El parámetro pasado (un número, en este caso) indica la columna dentro de esa fila de donde se están sacando los datos (partiendo desde 1). Para más detalles de eso, habría que mirar el esquema de la base de datos. Es importante mencionar que los métos getYYY() están sobercargados, pudiendo pasarles también un String: el nombre de la columna.</li>
</ul>
<p>Como ves, el código es relativamente sencillo. Muchos de estos métodos lanzan excepciones, así que debes estar atento a la API de Java para capturarlas adecuadamente.</p>
<p>Para poder ejecutar este código, debes incluir el driver JDBC de SQLite en el classpath. Esto se traduce en español a:</p>
<pre><em>java -cp .;sqlitejdbc-v052.jar EjemploJDBC</em>
</pre>
<p>(Si estás probando desde Linux, cambia el ; por : )</p>
<p>Con esa invocación, estás diciendo a la JVM <em>mira, las clases que vas a ocupar están en el directorio actual </em>(por eso el .)<em> y en este archivo .jar </em>(el driver SQLite)<em>.</em></p>
<p>Una observación importante es que puedes también indicar el driver JDBC a utilizar desde la línea de comandos, en lugar de hacerlo desde el código Java. Eso significa que puedes eliminar (o comentar) la linea que llama a Class.forName(), pero ejecutar el programa de esta forma:</p>
<pre><em>java -cp.;sqlitejdbc-v052.jar -Djdbc.drivers=org.sqlite.JDBC EjemploJDBC</em>
</pre>
<p>(Nuevamente, reemplaza ; por : si están en linux)</p>
<p>¿Y si quisiera portar los datos de SQLite a MySQL o PostgreSQL? Pues simple: necesito el driver para el DBMS que voy a utilizar, cambiar los parámetros pasados a Class.forName() y DriverManager.getConnection()&#8230; y el resto queda igual (si es que al portar, ocupo datos compatibles en el DBMS). Como puedes ver, el esquema JDBC facilita enormemente cambiar de un DBMS a otro.</p>
<p>Junto con esto, si tienes un buen diseño, minimizas aún más el impacto de cambiar el DBMS. Usualmente se utiliza el patrón DAO, que puedes buscar más detalladamente en Wikipedia. Ahora, si quieres una excelente explicación, Huilén a puesto <a href="http://sherekan.com.ar/blog/2008/04/03/data-access-object-i/">acá</a> un muy buen tutorial de patrón DAO con Java, el que después continúa en un <a href="http://sherekan.com.ar/blog/2008/05/09/data-access-object-ii-dao-singleton/">segundo artículo</a> donde utiliza otro patrón de diseño (singleton) para mejorar el diseño.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/21/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=21&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/02/sqlite-y-jdbc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>
	</item>
		<item>
		<title>Uso de SQLite</title>
		<link>http://programadoresnocturnos.wordpress.com/2010/01/02/uso-de-sqlite/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2010/01/02/uso-de-sqlite/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:00:56 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=15</guid>
		<description><![CDATA[Quiero comentar acerca de SQLite. SQLite es un pequeño &#8216;sistema&#8217; de base de datos: es una biblioteca que sobre un archivo almacena el esquema de la base de datos y los datos propiamente tal. En términos generales presenta un buen rendimiento, y está aconsejada para quienes requieren almacenar un volumen medio de datos en sus [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=15&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Quiero comentar acerca de SQLite.</p>
<p>SQLite es un pequeño &#8216;sistema&#8217; de base de datos: es una biblioteca que sobre un archivo almacena el esquema de la base de datos y los datos propiamente tal. En términos generales presenta un buen rendimiento, y está aconsejada para quienes requieren almacenar un volumen medio de datos en sus aplicaciones, utilizando un esquema relacional.</p>
<p><span id="more-15"></span></p>
<p>En el caso de querer incluir la API SQLite en tu proyecto de programación, puedes incluir en tu programa C/C++ a sqlite.h, compilar a sqlite.c y listo.</p>
<p>Dentro de lo que podemos llamar una desventaja de SQLite es que no implementa la integridad referencial, es decir, no disponemos de claves foráneas (puedes declararlas, pero el intérprete ignorará tu declaración). De todas formas, SQLite si implementa triggers, así que hay algunas formas de implementar la integridad referencial de esa forma.</p>
<p>¿Un ejemplo? Pero con mucho gusto&#8230; de todas maneras, el ejemplo está pensado solo para mostrar las características de SQLite, así que no esperes un buen diseño ni nada por el estilo&#8230;</p>
<p>Por ejemplo, imagínese una pequeña empresa de buses que requiere almacenar información acerca de sus viajes. Para ello, supongamos que tenemos la tabla buses (con información de los buses), viaje (con los datos de un viaje) y pasajero (con los datos de un pasajero). Una propuesta entonces podría ser la siguiente:</p>
<p><pre class="brush: sql;">
create table buses(
  id integer primary key not null autoincrement,
  matricula text not null,
  ano integer not null,
  capacidad integer not null);

create table pasajero(
  cedula text primary key not null,
  nacimiento date not null);

create table viaje(
  id_bus integer not null,
  cedula text not null);
</pre></p>
<p>Bueno, hay algunas cosas por explicar de acá:</p>
<ul>
<li>SQLite implementa el incremento automático de un campo (autoincrement), el que perfectamente pude indicarse para el primary key.</li>
<li>Las claves foráneas, como ya mencioné, no están implementadas aún en SQLite, así que no las agrego.</li>
<li>La primary key de la tabla viaje será su OID.</li>
</ul>
<p>SQLite, para almacenar una tupla en una tabla, utiliza el sistema de OID, es decir, asigna secretamente un identificador para cada tupla, que facilita su búsqueda en el arbol B (la estructura de datos usada por SQLite para almacenar los datos en archivo). No necesito declarar el OID, pero puedo consultarlo en cualquier tabla; pronto un ejemplo de eso.</p>
<p>Ahora, insertemos algunos datos, para hacer las pruebas.</p>
<p><pre class="brush: sql;">
insert into buses values(null, 'ABCD-01', 2008, 40);
insert into buses values(null, 'JANO-05', 2007, 27);
insert into buses values(null, 'INSQ-35', 2007, 20);
insert into pasajero values('123ASD-K', 1980-05-23);
insert into pasajero values('237QSD-3', 1970-03-28);
insert into pasajero values('135QTW-3', 1989-08-05);
</pre></p>
<p>Con esos datos, podemos ver en acción el sistema de los OID:</p>
<pre>sqlite&gt;select oid,* from buses;
1|1|ABCD-01|2008|40
2|2|JANO-05|2007|27
3|3|INSQ-35|2007|20</pre>
<pre>sqlite&gt;select oid,* from pasajero;
1|123ASD-K|1980-05-23
2|135QTW-3|1989-08-05
3|237QSD-3|1970-03-28</pre>
<p>Puede parecer extraño lo que ocurre con la tabla buses, puesto que ya existe su primary key, y esta se autoincrementa. Bien, pues de todas formas se genera un OID&#8230; pero cuando se define una primary key autoincrementable de tipo integer, el OID tendrá el mismo valor que dicha clave. No ocurre lo mismo en la tabla pasajero, puesto que su primary key es un texto, y no un entero. Nota también que en los campos que se autoincrementan, el siguiente valor se genera insertando un null.</p>
<p>Gracias a esta característica es que he definido la tabla viajes sin primary key: confío en el OID (lo que no es recomendado, por cierto).</p>
<p>Ahora, la parte artística: ¿y las claves foraneas? Como mencioné, para eso disponemos de los triggers&#8230;</p>
<p><pre class="brush: sql;">
create trigger fki_viaje_buses
before insert on viaje
for each row
begin
  select raise
     (rollback,
     'Inserción en viaje viola restricción fki_viaje_buses')
  where
     (select id from buses where id=new.id_bus) is null;
end;
</pre></p>
<p>Luego de eso, intentemos insertar un viaje para un bus no válido:</p>
<pre>sqlite&gt; insert into viaje values(5, '123ASD-K');
SQL error: Inserción en viaje viola restricción fki_viaje_buses</pre>
<p>El trigger para la actualización (update) es exactamente igual, pero en el caso de la eliminación tenemos un problema: si quiero eliminar un bus ¿qué hago con los viajes? Por como se definió la base de datos, no se pueden eliminar buses o pasajeros mientras hayan viajes, así que manos al trigger:</p>
<p><pre class="brush: sql;">
create trigger fkd_viaje buses
before delete on buses
for each row
  begin
    select raise(rollback, 'No se puede eliminar bus')
    where
       (select id_bus from viaje where old.id = id_bus)
    is not null;
end;
</pre></p>
<p>Ahora, si yo he insertado los siguientes datos de viaje</p>
<p><pre class="brush: sql;">
insert into viaje values(1, '135QTW-3');
insert into viaje values(1, '123ASD-K');
</pre></p>
<p>el trigger impedirá que eliminemos un bus, lo que generaría un estado inconsistente en la base de datos</p>
<pre>sqlite&gt; delete from buses where id = 1;
SQL Error: No se puede eliminar bus</pre>
<p>Como se puede apreciar, SQLite es una alternativa interesante cuando se necesita un acceso a datos rápido y sencillo. Aunque me parece que SQLite es muy bueno, no me atrevería aún a usarlo en un entorno más de producción&#8230; aunque en la medida que lo voy usando, más me convence.</p>
<p>También cabe destacar que hay soporte de SQLite para PHP, .Net, Java (JDBC) y otros.</p>
<p>Información más detallada y descargas de SQLite, en su página oficial: <a href="http://www.sqlite.org">www.sqlite.org</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=15&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2010/01/02/uso-de-sqlite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>
	</item>
		<item>
		<title>¿Por qué cambié a wordpress?</title>
		<link>http://programadoresnocturnos.wordpress.com/2009/12/30/%c2%bfpor-que-cambie-a-wordpress/</link>
		<comments>http://programadoresnocturnos.wordpress.com/2009/12/30/%c2%bfpor-que-cambie-a-wordpress/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 15:08:40 +0000</pubDate>
		<dc:creator>programadoresnocturnos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programadoresnocturnos.wordpress.com/?p=4</guid>
		<description><![CDATA[Veamos un código: Acá se puede postear código fuente actionscript3, bash, coldfusion, cpp, csharp, css, delphi, erlang, fsharp, diff, groovy, javascript, java, javafx, mathlab, objc, perl, php, powershell, python, ruby, scala, sql, vb y xml&#8230; nice! ¿Se entiende por qué cambié?<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=4&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Veamos un código:</p>
<p class="Java">
<p><pre class="brush: java;">
public class Clase{
 int atr1;
 int atr2;

 public Clase(){
 atr1 = 10;
 atr2 = 20;
}
</pre></p>
<p>Acá se puede postear código fuente actionscript3, bash, coldfusion, cpp, csharp, css, delphi, erlang, fsharp, diff, groovy, javascript, java, javafx, mathlab, objc, perl, php, powershell, python, ruby, scala, sql, vb y xml&#8230; nice!</p>
<p><pre class="brush: cpp;">
int main(void){
   int var;
   printf(&quot;Hola, mundo!&quot;);
   scanf(&quot;%d&quot;, &amp;var);
}
</pre></p>
<p>¿Se entiende por qué cambié?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programadoresnocturnos.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programadoresnocturnos.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programadoresnocturnos.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programadoresnocturnos.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programadoresnocturnos.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programadoresnocturnos.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programadoresnocturnos.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programadoresnocturnos.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programadoresnocturnos.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programadoresnocturnos.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programadoresnocturnos.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programadoresnocturnos.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programadoresnocturnos.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programadoresnocturnos.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programadoresnocturnos.wordpress.com&amp;blog=11168419&amp;post=4&amp;subd=programadoresnocturnos&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programadoresnocturnos.wordpress.com/2009/12/30/%c2%bfpor-que-cambie-a-wordpress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/af464ceb3deb21877cb9e370dc95bc52?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">programadoresnocturnos</media:title>
		</media:content>
	</item>
	</channel>
</rss>
