Aplicaciones+Graficas

1.1 Introducción
El objetivo de este tema es enseñar a diseñar pequeñas interfaces gráficas empleando para ello las librerías gráficas Swing. Una interfaz es lo que le permite a un usuario comunicarse con un programa, una interfaz es lo que nosotros vemos al arrancar, por ejemplo, un navegador de internet: un conjunto de menús, botones, barras.... que nos permiten activar un código que es el que realmente nos llevará a una página web, salvará la imagen en el disco duro....

Las librerías gráficas que usaremos vienen a sustituir a las antiguas AWT. Las nuevas librerías a parte de tener una mayor cantidad de opciones sobre los componentes (como distintas apariencias, control sobre el focus, mayor número de campos que modifican su aspecto, mayor facilidad para pintar al hacer el buffering transparente al usuario....) se diferencian de las anteriores radicalmente en su implementación.

En AWT cuando añadíamos un botón, por ejemplo, a nuestro diseño el compilador generaba código que le pedía al sistema operativo la creación de un botón en un determinado sitio con unas determinadas propiedades; en Swing ya no se pide al sistema operativo nada: se dibuja el botón sobre la ventana en la que lo queríamos. Con esto se eliminaron muchos problemas que existían antes con los códigos de las interfaces gráficas, que debido a depender del sistema operativo para obtener sus componentes gráficos, era necesario testar los programas en distintos sistemas operativos, pudiendo tener distintos bugs en cada uno de ellos. Esto evidentemente iba en contra de la filosofía de Java, supuestamente un lenguaje que no dependía de la plataforma. Con Swing se mejoró bastante este aspecto: lo único que se pide al sistema operativo es una ventana, una vez que tenemos la ventana dibujamos botones, listas, scroll-bars... y todo lo que necesitemos sobre ella.

Evidentemente esta aproximación gana mucho en lo que a independencia de la plataforma se refiere. Además el hecho de que el botón no sea un botón del S.O. sino un botón pintado por Java nos da un mayor control sobre su apariencia.

1.2 JFRAME
 Graduación de herencia de JFrame 1

Es el contenedor que emplearemos para situar en él todos los demás componentes que necesitemos para el desarrollo de la interface de nuestro programa. En el gráfico 1 se muestra la jerarquía de herencia de este componente desde Object, que como ya dijimos es el padre de todas las clases de Java. Los métodos de este componente estarán repartidos a lo largo de todos sus ascendientes, cosa que hemos de tener en cuenta cuando consultemos la ayuda on-line de esta clase. Así por ejemplo resulta intuitivo que debiera haber un método para cambiar el color de fondo del frame, pero él no tiene ningún método para ello, lo tiene Component. Veamos el código necesario para crear un Jframe:

Importamos una librería, un package

import javax.swing.*; Nuestra clse frame extiende a JFrame

class frame extends JFrame { el constuctor public frame{ Este es uno de los métodos que nuestra clase frame ha <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">heredado de JFrame. Pone un título a la ventana <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">setTitle("Hola!!!"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Igual que el anterior, pero le esta vez le da un tamaño <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">setSize(300,200); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}/~

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Esta es la clase auxiliar, tiene el main de la aplicación

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public class ejemplo13{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public static void main (String[] args){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Creamos un objeto de tipo frame <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">JFrame frame = new frame;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">invoco sobre este objeto uno de los métodos que ha heredado <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">de JFrame: show. Los frames por defecto son “invisibles”, <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">este método los hace visibles.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">frame.show; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} ///:~

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Si embargo nuestro código anterior tiene un problema: no podemos cerrar la ventana. La única forma de acabar con ella será mediante ^c si hemos ejecutado el programa desde una consola o con Control-Alt-Supr y eliminando su tarea correspondiente si lo ejecutamos desde windows.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">¿Por qué no se cierra la ventana? porque no hemos escrito el código necesario para ello. Para que se cierre nuestro frame hemos de escribir un código que escuche los eventos de ventana, y que ante el evento de intentar cerrar la ventana reaccione cerrándose esta. A continuación y <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">antes de seguir con componentes de la librería Swing veamos que es un evento y como gestionarlos.

<span style="color: #0020ff; font-family: Verdana,Geneva,sans-serif;">1.3 Eventos
<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">El sistema de gestión de eventos de Java 1.2 es el mismo que Java 1.1 y por lo tanto el mismo que para las librerías AWT. Aunque los desarrolladores de Java considerasen que para mejorar el lenguaje se necesitaba dejar a un lado las librerías AWT e introducir las Swing no sintieron lo mismo del sistema de gestión de eventos, consideraron que era lo suficientemente bueno.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Realmente este sistema de gestión de eventos es bastante elegante y sencillo, sobre todo si se compara con el sistema de gestión de eventos de Java 1.0, mucho más engorroso de usar y menos elegante.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">¿Qué es un evento?

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Todos los sistemas operativos están constantemente atendiendo a los eventos generados por los usuarios. Estos eventos pueden ser pulsar una tecla, mover el ratón, hacer clic con el ratón, pulsar el ratón sobre un botón o menú (Java distingue entre simplemente pulsar el ratón en un sitio cualquiera o hacerlo, por ejemplo, en un botón). El sistema operativo notifica a las aplicaciones que están ocurriendo estos eventos, y ellas deciden si han de responder o no de algún modo a este evento.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">El modelo de delegación de eventos

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">El modelo de Java se basa en la delegación de eventos: el evento se produce en un determinado componente, por ejemplo un scroll. Dónde se produce el evento se denomina “fuente del evento”. A continuación el evento se transmite a un ”manejador de eventos” (event listener) que este asignado al componente en el que se produjo el evento. El objeto que escucha los eventos es el que se encargará de responder a ellos adecuadamente. Esta separación de código entre generación del evento y actuación respecto a él facilita la labor del programador y da una mayor claridad a los códigos.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Gestión de eventos en Java.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">A la fuente del evento, en este caso un botón, le indicamos quién será su manejador de eventos, manejador que ha de extender la clase Adapter correspondiente o implementar la interfaz Listener (interfaz ActionLitener en este caso). Cuando el usuario genere el evento deseado (en este caso pulse el botón), el objeto fuente empaqueta información a cerca del evento generando un objeto de tipo Event (ActionEvent en este caso) e invoca el método correspondiente del manejador (actionPerformed(actionEvent)) pasándole como información el objeto de tipo Event generado.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Es responsabilidad del manejador, y no de la fuente, responder al evento, por ello se dice que la fuente delega la gestión del evento en el manejador. Lo que la fuente de eventos le pasa al objeto encargado de escuchar los eventos es, como no, otro objeto. Es un objeto tipo Event. En este objeto va toda la información necesaria para la correcta gestión del evento por parte del objeto que escucha los eventos.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">El objeto que escucha los eventos ha de implementar para ello una interface. El nombre de esta interface es siempre el nombre del evento más “Listener”: para que un objeto escuche eventos de ratón ha de implementar la interface MouseListener, para que escuche eventos de teclado KeyListener.....

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Para hacer que un objeto escuche los eventos de otro objeto se emplea el método add[nombre_evento]Listener, así si tuviésemos un Jframe llamado “frame” y quisiésemos que el objeto llamado “manejador” escuchase los eventos de ratón de “frame” lo haríamos del siguiente modo:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">frame.addMouseListener(manejador);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">manejador ha de pertenecer a una clase que implemente la interface MouseListener, que tiene un total de 7 métodos que ha de implementar.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">A continuación en la siguiente tabla mostramos los eventos más comunes, junto a la interface que debe implementar el objeto que escuche esos eventos y el método para asociar un objeto para escuchar dichos eventos. En la columna de la derecha se presentarán diversos componentes que pueden generar dichos eventos.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Cabe preguntarse ahora por que métodos tiene cada interface, ya que hemos de implementar todos ellos, incluso aunque no los usemos, sino la clase que se encargaría de escuchar los eventos sería abstracta y no podríamos crear ningún objeto de ella. Parece un poco estúpido <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> implementar métodos que no hagan nada sólo porque la interface de la que heredamos los tenga. Así por ejemplo si estamos interesados en escuchar clics de ratón hemos de crear una clase que implemente MouseListener, pero nosotros sólo estaremos interesados en un método de dicha interfase: mouseClicked.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Los creadores de Java también pensaron en esto y por ello para cada interface que tiene más de un método crearon una clase llamada [nombre_evento]Adapter (MouseAdapter), que lo que hace es implementar todos los métodos de la interface sin hacer nada en ellos. Nosotros lo único que tendremos que hacer es que nuestra clase que escuche eventos extienda esta clase y sobrescriba los métodos que nos interesen.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> A continuación en la siguiente tabla damos un listado de las principales interfaces junto a sus respectivas clases “Adapter” y los métodos que poseen:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Un frame que se cierra

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Pongamos en práctica lo que hemos visto haciendo un frame que se pueda cerrar:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import javax.swing.*; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import java.awt.event.*;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> class frame extends JFrame { <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> public frame{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> setTitle("Hola!!!"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> setSize(300,200);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Le indicamos al frame quien será su manejador de eventos de <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> ventana: un objeto de tipo manejador que creamos en esta misma línea

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">addWindowListener (new manejador); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">/*Clase manejadora de eventos de ventana. Implementa el <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">*inteface WindowListener, por lo que ha de sobreescribir <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">*todos sus métodos*/

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">class manejador implements WindowListener{

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowClosing(WindowEvent e){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">System.out.println("sali"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Esta sentencia termina la máquina virtual <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">System.exit(0); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Métodos que no hacen nada,pero que he de sobreescribir por <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">implementar el interface

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowOpened(WindowEvent e){} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowClosed(WindowEvent e){} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowActivated(WindowEvent e){} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowDeactivated(WindowEvent e){} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowIconified(WindowEvent e){} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowDeiconified(WindowEvent e){} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public class ejemplo15{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public static void main (String[] args){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">JFrame frame = new frame; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">frame.show; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">/:~

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Aquí se ve como al hacer que la clase manejador implemente la interface MouseListener hemos de implementar sus siete métodos aunque sólo nos interesa el que está relacionado con el cierre de la ventana. A continuación rescribimos el ejemplo pero aprovechando las ventajas de las clases Adapter:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import javax.swing.*; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import java.awt.event.*;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> class frame extends JFrame {

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> public frame{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> setTitle("Hola!!!"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> setSize(300,200); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Igual que antes le indico a la ventana quién será su <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> manejador de eventos de ventana. <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">addWindowListener (new manejador); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">/**Esta vez la clase manejador extiende la clase adapter, por <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">*lo que sólo tengo que sobrescribir el método en el que <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">*estoy interesado*/

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">class manejador extends WindowAdapter{

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowClosing(WindowEvent e){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">System.out.println("sali"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">System.exit(0); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public class ejemplo16{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public static void main (String[] args){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">JFrame frame = new frame; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">frame.show;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} ///:~

<span style="color: #0020ff; font-family: Verdana,Geneva,sans-serif;">1.4 JPANEL
<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Ahora ya sabemos hacer una ventana (frame) que se cierra. Podríamos empezar a añadirle <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> botones, scrolls, campos de texto ... y todo lo que necesitemos, pero no es considerado una buena práctica de programación añadir componentes directamente sobre un contenedor de “pesado” (frames y applets por lo que a nosotros respecta). Lo correcto es añadir a este uno o varios paneles y añadir sobre los paneles lo que necesitemos.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Una de las ventajas de añadir paneles sobre nuestro frame es que los paneles al derivar de <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> JComponent poseen el método paintComponent que permite dibujar y escribir texto sobre el <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> panel de modo sencillo.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Para añadir un JPanel a nuestro frame primero obtenemos uno de los objetos que forman el <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> frame: el “panel contenedor” (content pane). Para ello invocaremos al método getContentPane de nuestro JFrame. El objeto que nos devuelve será de tipo Container:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Container [nombre_del_contentpane] = frame.getContentPane;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> A continuación invocamos al método add del Container obtenido para añadir el panel, pasándole el propio panel al método:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> [nombre_del_contentpane].add(nombre_del_panel);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Añadámosle un JPanel a nuestro frame: <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import javax.swing.*; import java.awt.event.*; import java.awt.*; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> class frame extends JFrame { <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public frame{ setTitle("Hola!!!"); setSize(300,200); addWindowListener (new manejador); Le pido al frame su objeto contenedor Container contentpane = getContentPane;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Creo un objeto de tipo JPanel <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">JPanel panel = new JPanel; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">ado el panel en el objeto contenedor del framecontentpane.add(panel); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> ngo el color de fondo del panel de color rojo <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">panel.setBackground(Color.red);}}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">class manejador extends WindowAdapter{public void windowClosing(WindowEvent e){System.out.println("sali");System.exit(0);}} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public class ejemplo17{public static void main (String[] args){JFrame frame = new frame;frame.show;}} /:~

<span style="color: #0020ff; font-family: Verdana,Geneva,sans-serif;">1.5 LAYAOUT
<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Ya ha llegado casi el momento de empezar a añadir cosas a nuestra ventana, sólo una cosa queda pendiente: como controlar dónde añadimos los objetos. Por ejemplo como decirle a nuestro panel dónde tiene que colocar un botón, por ejemplo.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Una solución sería indicarle dónde colocar la esquina izquierda de arriba del botón y luego indicando el alto y ancho del botón. Esto es precisamente lo que hace el método setBounds(int,int,int,int) de la clase Component. Parece, en principio, una buena solución.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Hagámoslo:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import javax.swing.*; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import java.awt.event.*; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import java.awt.*;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> class frame extends JFrame { <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> public frame{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> setTitle("Hola!!!"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> setSize(500,400); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> addWindowListener (new manejador); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Container contentpane = getContentPane; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> JPanel panel = new JPanel;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">imino el gestor de layouts del panel <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> panel.setLayout(null);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Creo un objeto de tipo JButton (un botón) <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> JButton boton = new JButton; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Mediante este método le indico al botón que se sitúe en las coordenadas 300,300 del panel, con un tamaño de 50x50 <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> boton.setBounds(300,300,50,50);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Añado el botón al panel

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">panel.add(boton); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">contentpane.add(panel); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">panel.setBackground(Color.red); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public static void main (String[] args){ JFrame frame = new frame; frame.show; } } /:~

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Si con este código probamos a cambiar de tamaño la ventana podremos ver como el botón no se mueve, desapareciendo si la ventana se hace muy pequeña y cambiando su posición relativa a los bordes de la ventana. Esto, en una aplicación real, desorientaría al usuario que nunca sabría dónde irlo a buscar al cambiar el tamaño de la ventana.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Para solucionar este inconveniente se crearon los Layout Maneger: con ellos se especifican unas posiciones determinadas en un panel, frame o applet donde añadiremos nuestros componentes o un nuevo panel, al que también le podremos añadir un layout en cuyas posiciones podremos añadir componentes o más panels con layouts....

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> La posibilidad de añadir varios panels a un layout y fijar a estos nuevos layouts da un gran dinamismo a la hora de colocar los componentes.


 * //<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> FlowLayout //**

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Es el que tienen los paneles por defecto. Los objetos se van colocando en filas en el mismo orden en que se añadieron al contenedor. Cuando se llena una fila se pasa a la siguiente.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Tiene tres posibles constructores:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> FlowLayout; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Crea el layout sin añadirle los componentes, con los bordes de unos pegados a otros.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> FlowLayout(FlowLayout.LEFT[RIGTH][CENTER]); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Indica la alineación de los componentes: a la izquierda, derecha o centro.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> FlowLayout(FlowLayout.LEFT, gap_horizontal, gap_vertical);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Además de la alineación de los componentes indica un espaciado (gap) entre los distintos componentes, de tal modo que no aparecen unos pegados a otros.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> He aquí un ejemplo del uso de FlowLayout:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> import javax.swing.*; import java.awt.*; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> class panel extends JFrame{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> public panel { <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> setSize(300,200); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Container container = this.getContentPane; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 5,10); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> container.setLayout(fl); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> for (int i=0; i<4; i++) { <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> JButton button = new JButton("Button"+(i+1)); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> button.setPreferredSize(new Dimension(100,25)); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> container.add(button); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> } <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> } <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> } <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> public class ejemplo19{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> public static void main (String[] args){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> panel t = new panel; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> t.show; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> } <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> } <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">/:~

<span style="color: #0020ff; font-family: Verdana,Geneva,sans-serif;">1.6 JButton
<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Ha llegado el momento de introducir un componente que no sea un mero contenedor. Empecemos por un botón. Crear un botón es tan sencillo como: <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Button boton = new JButton; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Si queremos que el botón aparezca con una etiqueta de texto:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">JButton boton = new JButton(“texto va aquí”);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Veamos como añadirle funcionalidad a nuestro botón. Cada vez que hacemos clic sobre el botón se genera un evento del tipo ActionEvent. Para poder escuchar dichos eventos necesitaremos una clase que implemete la interface ActionListener, interface que tiene un solo <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">método actionPerformed (ActionEvent). Haremos, por ejemplo que al hacer un clic sobre nuestro botón cambie el color de fondo de un <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">panel. Le pondremos un BorderLayout y haremos que el panel sea quien escuche los eventos del botón; para ello ha de implementar la interface ActionListener. Cuando se llame al método actionPerformed invocaremos al método setBackground del panel para cambiarlo a azul. Por otro lado hemos de indicar que va a ser el frame el que escuche los eventos del botón:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">boton.addActionListener(this);

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">El código resultante será:

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">import java.awt.*;import javax.swing.*;import java.awt.event.*; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Ahora la clase frame implementa el interface <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> ActionListener, para poder gestionar eventos de tipo ActionEvent <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">class frame extends JFrame implements ActionListener{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Ahora el panel lo he definido como una variable de la clase no ocal de un método. De este modo podré acceder a ella en cualquier <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> todo de la clase.

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">JPanel panel = new JPanel; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public frame{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">setTitle("Hola!!!"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">setSize(500,400); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">addWindowListener (new manejador); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Container contentpane = getContentPane;

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Le pongo al panel un BorderLayour

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> panel.setLayout(new BorderLayout); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> JButton boton = new JButton("Azul"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Le indico al botón quien será su gestor de eventos de <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">ventana: este propio objeto (this), es decir el frame <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> boton.addActionListener(this); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Creo un objeto de tipo dimensión, un objeto que contiene un <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">par de valores enteros <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Dimension d = new Dimension; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> Inicializo ese par de valores enteros <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">d.height = 40; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">d.width = 100; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Le pongo al botón un tamaño preferido, empleando para ello <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> el objeto dimensión que he creado. El BorderLayout <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">respetará el alto preferido del botón al estar éste en su <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> campo sur. <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">boton.setPreferredSize(d); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">añado el layout al campo sur del panel <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> panel.add(boton,BorderLayout.SOUTH); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> contentpane.add(panel); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> panel.setBackground(Color.red); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> }

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;"> La clase frame ha de sobreescribir este método, ya que implementa la interface ActionListener <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void actionPerformed (ActionEvent e){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">panel.setBackground(Color.blue); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">}

<span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">class manejador extends WindowAdapter{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public void windowClosing(WindowEvent e){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">System.out.println("sali"); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">System.exit(0); <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">Java2, tutorial de javahispano (http://javahispano.org). Página 78 de 119 <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public class ejemplo22{ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">public static void main (String[] args){ <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">JFrame frame = new frame; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">frame.show; <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} <span style="display: block; font-family: Verdana,Geneva,sans-serif; text-align: justify;">} ///:~