0% encontró este documento útil (0 votos)
45 vistas

14.sesión Java - GUI

Este documento presenta la decimocuarta secuencia de aprendizaje sobre programación en Java. Se centra en las interfaces gráficas de usuario (GUI) en Java, comparando las tecnologías AWT, Swing y JavaFX. Explica que Swing es independiente de la plataforma y sigue el patrón MVC. Incluye ejemplos de código para crear ventanas, botones, etiquetas y campos de texto usando Swing.

Cargado por

mrnovoa
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
45 vistas

14.sesión Java - GUI

Este documento presenta la decimocuarta secuencia de aprendizaje sobre programación en Java. Se centra en las interfaces gráficas de usuario (GUI) en Java, comparando las tecnologías AWT, Swing y JavaFX. Explica que Swing es independiente de la plataforma y sigue el patrón MVC. Incluye ejemplos de código para crear ventanas, botones, etiquetas y campos de texto usando Swing.

Cargado por

mrnovoa
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 22

PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

JAVA: SECUENCIA DE APRENDIZAJE nº 14 (Interf. Gráfica Usuario)

RESULTADOS Y COMPETENCIAS PERSEGUIDOS


En consonancia a los resultados de aprendizaje y competencias que el alumno debe
completar cursando este módulo, la secuencia de aprendizaje contribuye a conseguir los siguientes:
R5) Realiza operaciones de entrada y salida de información, utilizando procedimientos específicos
del lenguaje y librerías de clases. (Criterios f, g y h)

C2) El trabajo regular y la constancia.


C3) El aprendizaje con los demás.
C4) El aprendizaje por sí mismo.
C5) La autonomía responsable.
C7) El dominio de las herramientas de desarrollo de aplicaciones.

En esta secuencia de aprendizaje vamos a vestirnos de gala. Ya se sabe que la apariencia, y


más en esta época del devenir de la Humanidad, ha adquirido una importancia capital. Sobre todo
cuando hay que vender mejor cualquier cosa. Ya lo dice Prudencio: "el cliente no tiene ni idea de lo
que yo sé de Informática pero se fija en que yo he dejado los ordenadores bien alineados, con su
teclado y ratón bien puestos además de lo limpia que ha quedado la sala".

Las aplicaciones informáticas no están al margen de esto y hay que reconocer que una buena
presencia de la misma (intuitiva, accesible, ágil, etc...) hace que la experiencia de usuario sea más
satisfactoria. Botones, ventanas, listas desplegables, cajas de texto, etc..., forman parte del arsenal
piezas con las que armar un buen interfaz que haga cómodo el manejo de una aplicación.

Y concretamente en Java, el camino recorrido hasta ahora en esta materia ha tenido sus más
y sus menos. Todo por un detalle que es cara a veces y cruz las otras: la JVM. La
cuasiindependencia que disfruta Java para ofrecer multiplataformidad, tiene sus peajes. Por eso, al
abordar la implementación de un interfaz gráfico de usuario (GUI), hay que tener claro que está
condicionado por la interacción del sistema operativo en el que corra el programa. Porque este SO
es el que marca cómo se van a ver los componentes (ventanas, botones, listas desplegables, cajas de texto, etc..) en
pantalla, al margen del trajín que comporta "molestar" al SO para esas labores.

De hecho, a lo largo del tiempo han ido saliendo


tecnologías a este respecto como AWT, Swing y últimamente
Java FX que han intentado solventar algunos problemas que
la anterior no era capaz de gestionar.

Es más, Swing no reconstruyó sus componentes


básicos sino que aprovechó el trabajo realizado con AWT
para generar no pocos componentes. Todos los componentes
Swing derivan de la clase abstracta JComponent que es hija
de Component. Sirva como ejemplo la ilustración de la
derecha.

Ciclo Formativo Superior DAM 1 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

En esta secuencia nos centraremos en la tecnología Swing, dejando JavaFX para que sea
abrodado desde el módulo de Entornos de Desarrollo.

AWT Swing JavaFX

componentes con código componentes sin código componentes sin código


nativo, muy dependiente de nativo, pero sólo apto para nativo, misma calidad para
la plataforma (SO) aplicaciones de escritorio aplicaciones web y móviles

En el fondo, y hasta la llegada de JavaFX, el problema radicaba en que si la empresa que


encargaba el desarrollo de una aplicación en Java, se encontraba con que los componentes
presentados en pantalla rompían con el "look" de la marca de dicha empresa y los ponía en función
del SO de turno. En Swing al final, se llegó a pagar por diseñar looks de Java personalizados, lo que
ha sido un buen negocio para muchos durante una temporada. Ahora con JavaFX, las posibilidades
de apariencia son mucho mayores y fácilmente modificables.

Quede aquí un cuadro resumen con sus diferencias más acusadas:

AWT SWING JAVAFX


Dependiente de la Plataforma Independiente de la Plataforma Independiente y Multidispositivo
No sigue el patrón MVC Sigue el patrón MVC No sigue del todo el patrón MVC
Lesser Components Componentes más potentes Componentes más potentes y versátiles
"Look&Feel" dependiente del SO "Look&Feel" multiplataforma sustituibles "Apariencias" (themes) tuneables con CSS
Ejecución pesada Ejecución ligera Ejecución muy ligera

Swing

Swing es el nombre que se le quedó a esta tecnología, aunque en realidad es como se llamó
al proyecto dedicado a la construcción de componentes gráficos para Java casi finalizando el siglo
XX. La tecnología fue denominada inicialmente como JFC (Java Foundation Classes) siendo los
componentes Swing GUI una parte de las características de esa JFC. Su filosofía se basa en poner a
disposición del desarrollador contenedores y componentes gráficos así como un modelo de eventos
para gestionar la interactividad entre ellos y el usuario. Todo ello en forma de clases, interfaces y
adaptadores.

Y tan importante como conocer las clases que soportan los componentes GUI, es aprender la
técnica de construcción de los interfaces gráficos.

Ahora al principio jugaremos un poco con interfaces simples que nos servirán para
familiarizarnos con algunos componentes, dejando sentada la idea de que el año que viene, en el
módulo de Desarrollo de Interfaces, se implementarán GUIs más profesionales.

Ciclo Formativo Superior DAM 2 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Manos a la obra

import javax.swing.*; //Importando el paquete de los controles Swing


class GuiSwing1 {
public static void main(String[] args) {
JFrame marco = new JFrame("Mi primer interfaz GUI");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setSize(300, 300);
JButton boton1 = new JButton("Pulsa");
marco.add(boton1);
marco.setVisible(true);
}
}

¿Cómo entender este código?

1) JFrame marco = new JFrame("Mi primer interfaz GUI"); con esta instancia de JFrame, generas la ventana
principal de la aplicación (que viene con sus botones de minimizar, ampliar y cerrar) a la que se le puede añadir
un título en la barra superior.

2) marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); con esto asocias que al pulsar el botón de


cierre de la ventana principal (arriba derecha), la aplicación termine de ejecutarse. Lo que para ti es
evidente, no lo es para la interfaz. Prueba a quitarlo a ver qué pasa.

3) marco.setSize(300, 300); con esto estableces el tamaño que tendrá la ventana principal de la
aplicación. Prueba a modificarlo como te parezca.

4) JButton boton1 = new JButton("Pulsa"); con esta instancia de JButton generas un botón, añadiéndole el
letrerito que irá por delante. Prueba a modificar el letrerito.

5) marco.add(boton1); de esta forma, una de las que existen, el botón se añade a la ventana como si lo
pincháramos en un tablón de anuncios. Lo sitúa en medio por defecto.

6) marco.setVisible(true); de esta forma toda la preparación realizada pasa a visualizarse en pantalla.

Nota: el fondo color metálico degradado que observas en la captura de su ejecución es


porque el botón ocupa todo el marco.

Ahora trata de crear un segundo botón con letrerito diferente y observa qué ocurre. ¡Vaya!
¿Qué ha pasado? Todavía es pronto para conocer los bajos fondos que operan en una interfaz con
Swing, pero quédate con la copla que, así a pelo, jugar con varios componentes tiene sus problemas.
Ello requerirá de más conocimientos que iremos adquiriendo al ir de ejercicio en ejercicio como las
abejas arrastran el polen de las flores por donde se posan. Porque entre esto y lo de que el botón ha
ocupado todo el marco, ya empiezan los misterios.

De ahí que ahora pasemos a un segundo ejercicio que nos pueda aclarar alguno de estos
contratiempos.

Ciclo Formativo Superior DAM 3 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

import java.awt.*;
import javax.swing.*;
class GuiSwing2 {
public static void main(String[] args) {
JFrame marco = new JFrame("Mi segundo interfaz GUI");
marco.setSize(400, 300);
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setLayout(new FlowLayout());
JLabel etiqueta = new JLabel("Nombre: ");
JTextField texto = new JTextField(20);
JButton boton = new JButton("Saludar");
marco.add(etiqueta);
marco.add(texto);
marco.add(boton);
marco.setVisible(true);
}
}

¿Cómo entender este código?

Apenas se ha hecho nada diferente con respecto al código anterior. Pero ahora hemos
incluido tres componentes (etiqueta, campo de texto y botón), y han aparecido los tres. Observando
detenidamente este código caemos en la cuenta de que:

1) JLabel etiqueta = new JLabel("Nombre: "); no sólo de botones viva la interfaz. También existen etiquetas
y esta la forma de generarlacon el texto que se le quiera poner (en este caso "Nombre:").

2) JTextField texto = new JTextField(20); y así se instancia un campo de texto. En este caso con una
limitación de tamaño en pantalla 20 caracteres. Aunque se pueden teclear más de 20 caracteres,
puesto que sólo es una limitación visual. Puedes probar a ponerle sólo 10 caracteres.

3) marco.setLayout(new FlowLayout()); con el método setLayout() se le indica al marco la forma en la que


ha de ir colocando los componentes que se le vayan incorporando. En este caso FlowLayout (hay
varios más), opera bajo la premisa "te los iré poniendo uno al lado del otro en la misma línea (de
izquierda a derecha), hasta que ésta se acabe y entonces te los pondré en la siguiente línea".

4) import java.awt.*; los acomodadores como FlowLayout vienen de herencia del AWT, de ahí que se
ponga esta sentencia en el código. Prueba a comentar este import, a ver qué pasa.

Prueba ahora a estrechar el marco con el ratón. ¿Entiendes mejor lo de FlowLayout? Pues
comenta ahora la línea de código donde se establece este FlowLayout. ¿Qué ocurre ahora? Me temo
que lo mismo que pasó al añadir el segundo botón a GuiSwing1. Prueba entonces de nuevo a
incorporar dos botones a GuiSwing1 pero esta vez añadiendo la línea de código que activa el
FlowLayout.

Nota: por cierto, ahora ya no hay fondo de color metálico degradado. El fondo se quedó
blanco y le he puesto un borde negro a la captura para destacarlo.

Nota: ahora se ve el botón más ajustado a lo que suele verse en cualquier interfaz gráfico.
Eso sí, el botón es meramente decorativo puesto que por mucho que se pulse sobre él, no
realizará ninguna acción.

Ciclo Formativo Superior DAM 4 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Seguimos entonces destripando misterios y, probablemente, adquiriendo nuevos:

import javax.swing.*;
class GuiSwing3 {
public static void main(String[] args) {
JFrame marco = new JFrame("Campo, botón y etiqueta");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel etiqueta = new JLabel("No tienen actividad");
JPanel panel = new JPanel();
JButton boton = new JButton("Enviar");
JTextField campotexto = new JTextField(16);
panel.add(campotexto);
panel.add(boton);
panel.add(etiqueta);
marco.add(panel);
marco.setSize(300, 300);
marco.setVisible(true);
}
}

¿Cómo entender este código?

De nuevo poco cambio respecto al código anterior. No obstante, hay un actor nuevo en el
partido: exacto, un JPanel. ¿Y eso paqué? Si nos fijamos bien en el código, vemos que una vez
creado el JPanel, los tres componentes han sido incluidos en dicho contenedor. Pero lo más curioso
es que posteriormente, dicho panel se adhiere al marco. Lo que significa que el panel (JPanel) hace
las veces de intermediario con el propósito simplificar el posicionamiento de componentes. En
realidad, alguno estará pensando que no hacía falta porque los componentes ya se las entendían
solos con el marco. A medida que aumente la complejidad de los interfaces se entenderá mejor el
porqué de los paneles. Mientras, vayamos practicando con ellos.

1) JPanel panel = new JPanel(); instancia un panel para recoger componentes en su interior. Pregunta:
¿y cómo puede ser que sin aplicarle al panel ningún Layout haya colocado los componentes uno al
lado del otro y si falta sitio en la línea siguiente? De hecho es la aplicación de un FlowLayout lo
que se observa. Pausa para la intuición... Efectivamente, un JPanel viene dotado por defecto con
un acomodador de componentes tipo FlowLayout.

2) JTextField texto = new JTextField("Texto por defecto", 16); prueba una segunda posibilidad del constructor
del componente JTextField para que aparezca texto en el campo. Advertencia: no machaca al
comenzar a escribir sobre él.
Nota: si un JPanel trae de serie un acomodador FlowLayout, ¿un marco JFrame qué
acomodador tiene asignado por defecto? Eso te toca a ti investigarlo y sacar las
conclusiones de porqué se comportó en GuiSwing1 como se comportó.

Nota: tal como indica la cadena de la etiqueta, los componentes campo de texto y botón no
tienen actividad. Aunque se inserte texto y se pulse el botón, nada sucede.

Prueba a comentar la sentencia marco.setSize(300, 300); y escribe la siguiente marco.pack();.


Observarás un leve cambio y es porque el método pack() aplicado al marco, calcula el espacio
necesario para mostrar la información que contiene. El tiempo te llevará a usar dicho método.

Ciclo Formativo Superior DAM 5 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

En algunos interfaces gráficos de ususario se suelen ver botones en los que en vez de texto
aparecen iconos representativos. Pues Swing también sabe hacer eso:

import javax.swing.*;
class GuiSwing4 {
public static void main(String[] args) {
JFrame marco = new JFrame("Mi botón iconizado");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setSize(300, 300);
Icon icono = new ImageIcon("src/icono.jpg");
JButton boton1 = new JButton(icono);
marco.setLayout(new FlowLayout());
boton1.setPreferredSize(new Dimension(80, 40));
marco.getContentPane().add(boton1);
marco.setVisible(true);
}
}

¿Cómo entender este código?

Las líneas que llaman la atención en el código son:

1) Icon icono = new ImageIcon("src/icono.jpg"); instancia un elemento ImageIcon pasándole el nombre del
fichero que contiene la imagen que se va a superponer en el botón. En nuestro caso se ha puesto
una imagen con fondo blanco pero puedes añadir una con fondo transparente. Eso sí, habrá que
indicarle en qué carpeta del proyecto IntelliJ IDEA está almacenada.

2) boton1.setPreferredSize(new Dimension(80, 40)); por si en algún


momento viene bien personalizar el tamaño de un botón,
Swing permite hacer esto con esa sentencia. Pero
cuidado, no siempre funciona. ¿Cómo? Si se le quita
FlowLayout, es muy probable que no dimensione al gusto
y lo establezca por defecto.

3) marco.getContentPane().add(boton1); si te fijas no se ha
utilizado un JPanel para adherir el botón. Es por ello que
el botón se adhiere a una especie de panel que los
JFrames tienen incorporados por defecto como pse puede
ver en lal ilustración. Si no se pone, el botón se adhiere por defecto al mismo.

Por cierto, no quería dejar pasar la ocasión para indicar que el tercer contenedor (ya hemos visto
JFrame y JPanel) que Swing tiene en cartera es JWindow. Como muestra sirva el siguiente código que
visualiza en pantalla un marco y una ventana para que se puedan observar sus diferencias (no pongo
captura; fíjate cuando lo ejecutes):

Ciclo Formativo Superior DAM 6 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

import javax.swing.*;
class GuiSwingCont {
public static void main(String[] args) {
JFrame marco = new JFrame("El marco");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setSize(300, 300);
marco.setLocation(100, 100);
JWindow ventana = new JWindow();
ventana.setSize(300, 300);
ventana.setLocation(500, 100);
marco.setVisible(true);
ventana.setVisible(true);
}
}

Ahora hablaremos de los acomodadores (también se les puede llamar organizadores) de componentes.
Dijimos hace un rato que no sólo existía FlowLayout, que era el que tenía por defecto un
contenedor como JPanel. Si investigaste bien, encontrarías que los marcos tenían el suyo de serie
denominado BorderLayout. Cada uno de su padre y de su madre, de ahí que tengan distribución
organizativa y comportamientos diferentes. Y por si fuera poco, se pueden cambiar como ya pudiste
comprobar en el código GuiSwing2 en la sentencia marco.setLayout(new FlowLayout());. Ahora ya sabes
que un marco tiene predeterminados el acomodador BorderLayout y lo que hacía dicha sentencia
era sustituirlo por FlowLayout.

Bien pues ha llegado el momento de conocer los más útiles para nosotros, no sin dejar claro
que la elección del o los acomodadores es una faceta delicada a la hora de construir una interfaz
gráfica. De ahí que haya que conocerlos meridianamente bien porque sino difícilmente se consigue
posicionar los componentes donde uno quiere.

Empezamos por FlowLayout. Es del que más noticias tenemos y cuyo lema tenemos
fresquito: "te los iré poniendo uno al lado del otro en la misma línea (de izquierda a derecha), hasta que
ésta se acabe y entonces te los pondré en la siguiente línea". Por lo que dependerá del tamaño del
marco, la disposición de los componentes. Este ejemplo te lo deja claro:

import javax.swing.*;
class GuiSwingFlow {
public static void main(String[] args) {
JFrame marco = new JFrame("Conociendo FlowLayout");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
for(int i = 0; i < 10; i++) {
panel.add(new JLabel("Etiqueta " + i));
}
marco.add(panel);
marco.setSize(300, 300);
marco.setVisible(true);
}
}

Ciclo Formativo Superior DAM 7 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

¿Qué puedes hacer para aprender con este código? Estrechar o ensanchar el marco, cambiar
alguna etiqueta por botón. Sustituir el método setSize() por el método pack(). Cómo cambiar la
alineación del panel, por defecto centrada: panel.setLayout(new FlowLayout(FlowLayout.LEFT));. Esto lo pone
a la izquierda como ya imaginas. También conocer como modificar los 5 píxeles de separación
(horizontal y vertical) por defecto entre componentes: panel.setLayout(new FlowLayout(FlowLayout.LEFT, 15, 15)); .
El resto de posibilidades te las dejo a ti, ahora que ya tienes las nociones básicas.

Pasemos ahora a BorderLayout. Sólo sabíamos de éste que era la organización que traía de
serie un marco. Pero desconocíamos cuál es su representación real en pantalla. Consiste en dividir
el contenedor al que se le aplique en cinco zonas: arriba, abajo, izquierda, derecha y centro.

Como puede observarse en el siguiente código, se ha colocado un botón en cada zona y estos
han acabado ocupando todo el espacio, como ya ocurrió en el primer código de esta secuencia. Por
último, resaltar la manera en la que se han establecido las separaciones, horizontal (5) y vertical
(10), en este acomodador de componentes: marco.setLayout(new BorderLayout(5, 10));.

import java.awt.*;
import javax.swing.*;
class GuiSwingBorder {
public static void main(String[] args) {
JFrame marco = new JFrame("Conociendo Border Layout");
marco.setLayout(new BorderLayout(5, 10));
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton boton1, boton2, boton3, boton4, boton5;
boton1 = new JButton("Arriba (NORTH)");
boton2 = new JButton("Abajo (SOUTH)");
boton3 = new JButton("Derecha (EAST)");
boton4 = new JButton("Izquierda (WEST)");
boton5 = new JButton("Enmedio (CENTER)");
marco.add(boton1, BorderLayout.NORTH);
marco.add(boton2, BorderLayout.SOUTH);
marco.add(boton3, BorderLayout.EAST);
marco.add(boton4, BorderLayout.WEST);
marco.add(boton5, BorderLayout.CENTER);
marco.setSize(425, 350);
marco.setVisible(true);
}
}

¿Qué puedes hacer para aprender con este código? Estrechar o ensanchar el marco, cambiar
algún botón por campo de texto. Sustituir el método setSize() por el método pack(). También
conocer como modificar los píxeles de separación (horizontal y vertical) por defecto entre zonas. El resto
de posibilidades te las dejo a ti, ahora que ya tienes las nociones básicas.

Por ahora vamos a dejarlo con el tercer acomodador denominado GridLayout, porque sino
podríamos echar la peonada. A este no lo quiere nadie de inicio, aunque la venganza la sirve fría
puesto que al final la gran mayoría de los interfaces gráficos acaban recurriendo a este acomodador.
Su característica organizacional reside en una rejilla en forma de tabla con tantas filas y columnas
como se le diga.

Ciclo Formativo Superior DAM 8 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

import java.awt.*;
import javax.swing.*;
class GuiSwingGrid {
public static void main(String[] args) {
JFrame marco = new JFrame("Conociendo GridLayout");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 4, 10, 5));
for(int i = 0; i < 12; i++) {
panel.add(new JButton("Botón " + i));
}
marco.add(panel);
marco.setSize(400, 300);
marco.setVisible(true);
}
}

¿Qué puedes hacer para aprender con este código? Pues lo mismo que vienes haciendo con
los anteriores.

Sólo queda decir que una de las cosas que se acaba aprendiendo a medida que se va
implementando un interfaz detrás de otro es que, por ejemplo, partiendo de un marco con
acomodador BorderLayout, la zona NORTH puede contener varios componentes acomodados por
un FlowLayout y en la zona CENTER sus componentes estén regidos por un GridLayout. Así que
como ves, acaba convirtiéndose en todo un arte lo de construir interfaces.

Aunque sólo hemos conocido por ahora una manera de asociar el cierre de un
marco a una acción, existe alguna más como se puede ver:
JFrame.EXIT_ON_CLOSE: Abandona aplicación
JFrame.DISPOSE_ON_CLOSE: Libera los recursos asociados a la ventana
JFrame.DO_NOTHING_ON_CLOSE: No hace nada
JFrame.HIDE_ON_CLOSE: Cierra la ventana, sin liberar sus recursos

Ahora que empezamos a conocer algunas interioridades de la implementación de GUIs y


habiéndonos ejercitado con algunas simples, todo lo visto no tiene ningún sentido si los
componentes mostrados en pantalla no ofrecen al usuario una interactividad que satisfaga su
experiencia con la aplicación.

Es por eso, que debemos adentrarnos ahora en el mundillo de los eventos, que es como se
denomina por el territorio Java a las acciones que el usuario propicia al interactuar con los
elementos de una GUI. Podrás comprender que para ello Java ha puesto a disposición de los
desarrolladores, herramientas (clases e interfaces) que dotan de capacidad de respuesta a la aplicación
ante estos eventos que genera dicho usuario.

Estas herramientas se denominan Listeners y Adapters, aunque con el tiempo los Adapters
han ido perdiendo fuelle quedando en la actualidad los Listeners como herramienta principal para
estos menesteres. ¿Y qué es un Listener? Pues el objeto que a modo de controlador aéreo, está
pendiente de que en la aplicación alguien pueda pulsar sobre un botón, elegir una opción de una
lista desplegable o de un grupo de botones de radio. Y claro estar pendiente para luego decirle al
desarrollador, aquí te dejo un espacio para que cuando yo detecte movimiento escribas el código
que entiendes oportuno para lo sucedido.

Ciclo Formativo Superior DAM 9 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Para una primera idea rápida sobre eventos y Listeners:


https://es.slideshare.net/laurafolgadogalache/eventos-y-listeners-en-java-swing

En las aplicaciones Java que vinimos desarrollando hasta ahora (teclado y pantalla), el método
main() era el que indicaba el orden de ejecución de las operaciones de nuestro programa. Pero
hemos de caer en la cuenta de que en las aplicaciones GUI, el orden en el que se ejecutan las
operaciones dependerá de las acciones que realice el usuario. Gracias a Java, el desarrollador sólo
ha de responsabilizarse en el conocimiento de las acciones que ha de realizar la aplicación, cuándo
se producirán y definir/programar los pertinentes manejadores de eventos, que serán activados
automáticamente cuando sus eventos asociados tengan lugar.

Antes de nada, debes saber que los eventos también son herencia de AWT, por lo que las
aplicaciones que se desarrollen con estas características han de encabezarse con este import:

import java.awt.event.*;

Como bien puedes ver en el siguiente código que muestra un botón, que al ser pulsado,
muestra un mensaje que aparecerá en la ventana de ejecución del entorno donde estés trabajando:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class GuiSwingAct1 {
public static void main(String[] args) {
JFrame marco = new JFrame("Swing con Actividad");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setLayout(new FlowLayout());
JLabel etiqueta = new JLabel("Pulsa el botón");
JButton botonPal = new JButton("Palante");
botonPal.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Pulsaste el botón");
}
});
marco.add(etiqueta);
marco.add(botonPal);
marco.pack();
marco.setVisible(true);
}
}

¡Jo, qué cutre, ¿no?! Pues ya podría mostrarlo en el mismo interfaz, ¿verdad? Pues la verdad
es que quedaría más profesional. Pues podemos aplicarnos el cuento y modificar el código de
manera que el mensaje lo muestre mediante una etiqueta. Y ya puestos a trabajar poco, que
aproveche la misma etiqueta que muestra la leyenda "Pulsa el botón" para indicar que se ha pulsado
el botón.

Ciclo Formativo Superior DAM 10 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class GuiSwingAct2 {
public static void main(String[] args) {
JFrame marco = new JFrame("Swing con Actividad");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setLayout(new FlowLayout());
JLabel etiqueta = new JLabel("Pulsa el botón");
JButton btnPal = new JButton("Palante");
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
etiqueta.setText("Botón Palante pulsado");
}
};
btnPal.addActionListener(actionListener);
marco.add(etiqueta);
marco.add(btnPal);
marco.pack();
marco.setVisible(true);
}
}

¿Lo podríamos hacer con dos botones? Pues eso, ¡con DOS BOTONES!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class GuiSwingAct3 {
public static void main(String[] args) {
JFrame marco = new JFrame("Swing con Actividad");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setLayout(new FlowLayout());
JLabel etiqueta = new JLabel("Pulsa en cualquier botón");
JButton btnPal = new JButton("Palante");
JButton btnCancel = new JButton("Cancelar");
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnPal)
etiqueta.setText("Botón Palante pulsado");
else
etiqueta.setText("Botón Cancelar pulsado");
}
};
btnPal.addActionListener(actionListener);
btnCancel.addActionListener(actionListener);
marco.add(etiqueta);
marco.add(btnPal);
marco.add(btnCancel);
marco.pack();
marco.setVisible(true);
}
}

Pero como no todo van a ser botones, vamos a ser más listos trabajando con las listas. En
este caso, las desplegables desde las que vamos a seleccionar un tipo de letra y dicha acción
provoque la aparición de una etiqueta escrita con el tipo de letra seleccionado.

Ciclo Formativo Superior DAM 11 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class GuiSwingAct4 {
public static void main(String[] args) {
JFrame marco = new JFrame("Swing Lista Fuentes");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel etiqSalida = new JLabel("Texto del tipo de letra");
JPanel listaPan = new JPanel();
JLabel etiqueta = new JLabel("Elige fuente:");
JComboBox fuente = new JComboBox();
fuente.setEditable(false);
fuente.addItem("Serif");
fuente.addItem("SansSerif");
fuente.addItem("Monospaced");
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String tipo = (String) fuente.getSelectedItem();
int estilo = Font.BOLD; int tam = 20;
Font tipoFuente = new Font ( tipo, estilo, tam);
etiqSalida.setFont(tipoFuente);
marco.repaint();
}
};
fuente.addActionListener(actionListener);
listaPan.add(etiqueta);
listaPan.add(fuente);
marco.add(listaPan, "South");
marco.add(etiqSalida, "Center");
marco.setSize(275,150);
marco.setVisible(true);
}
}

Reto

Curioso, ¿verdad? Pues te reto a que este mismo ejercicio lo realices pero en vez de utilizar
una lista desplegable, implementes un grupo de botones de radio que permitan elegir la fuente con
la que se quiere representar la etiqueta. Se trata de que investigues cuál es el componente que Swing
ha prefabricado para presentar un grupo de botones de radio, de forma que solo una opción pueda
ser seleccionada.

Reto

Otro reto podría ser que ampliaras el ejercicio GuiSwingAct4 de forma que existan varias
listas desplegables en las que puedas seleccionar el tipo de letra como ya hace, pero también el
tamaño y el estilo (negrita, cursiva, subrayado). Obviamente el resultado por pantalla debe ser coherente
con los datos seleccionados en las listas desplegables.

Ciclo Formativo Superior DAM 12 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Ahora vamos a dar un golpe de calidad a nuestros


interfaces. ¿Recuerdas que en el código GuiSwing4
introdujimos algo del manejo de imágenes? Pues en el siguiente
código puedes ver una primera muestra de lo que podemos
hacer con ellas, combinando una lista desplegable e imágenes.

Nos aparece por defecto uno de los personajes y su foto


correspondiente, pero a medida que se vaya eligiendo una
nueva opción de la lista, debe modificarse correctamente la
foto.

En este caso, el código lo podrás encontrar en el aula


virtual, ya que debido a su tamaño ocuparía un par de páginas
largas y no es cuestión.

ListaAmigos.java

Reto

De nuevo te propongo rehacer el ejercicio


GuiSwingAct5 de forma que en vez de listas desplegables en
las que puedas seleccionar el personaje como ya hace, éstos se
muestren en un grupo de botones de radio que al seleccionar el
deseado provoque la aparición de la imagen correspondiente.

Ya dijimos al principio de esta secuencia que Swing había reaprovechado muchos de los
componentes de AWT, además de los "escuchadores" (Listeners). Pero la modernidad exigió a Swing
la creación de componentes que AWT no diseñó en su momento. Un ejemplo de estos nuevos
componentes es JSlider, que permite seleccionar un valor dentro de un rango moviendo un
señalador. Si nos fijamos, no aparece el import java.awt.*; que hasta ahora veníamos colocando y es
import javax.swing.event.*; el que proporciona las clases para gestionar sus eventos.

import javax.swing.*;
import javax.swing.event.*;
class GuiSwingAct5 {
public static void main(String[] args) {
JFrame marco = new JFrame("JSlider con Actividad");
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel etiqueta = new JLabel();
JPanel panel = new JPanel();
JSlider slider = new JSlider(0, 200, 100);
//Pinta y espacia la info del slider
slider.setPaintTrack(true);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setMajorTickSpacing(50);

Ciclo Formativo Superior DAM 13 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

slider.setMinorTickSpacing(5);
/* Coloca a las bravas la detección de los
cambios al mover la flecha del slider
y reemplaza el texto con su valor actual */
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent event) {
etiqueta.setText("Valor actual = " + slider.getValue());
}
});
panel.add(slider);
panel.add(etiqueta);
marco.add(panel);
//Para colocar texto inicial con el valor del JSlider
etiqueta.setText("Valor actual = " + slider.getValue());
marco.setSize(300, 300);
marco.setVisible(true);
}
}

Si te fijas, todos los códigos que se han mostrado hasta ahora se implementan dentro la clase
main(). Esto se hecho así por facilitar la adquisición de los conocimientos sobre contenedores,
componentes y eventos. Pero a nadie se le escapa, y por lo visto en secuencias anteriores, que en
Java se busca no hacer las cosas en el método main() para facilitar una reutilización profesional de
las soluciones.

En esa línea, se presenta a continuación una segunda versión de GuiSwingAct5 que se


queda a mitad de camino de lo que debe ser una solución profesional (no lo hagamos todo de golpe). Lo que
se ha hecho en primer lugar es no crear una clase anónima como se hizo en el primer
GuiSwingAct5:

slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent event) {
etiqueta.setText("Valor actual = " + slider.getValue());
}
});

¿Viste por algún lado una clase que recogía el método stateChanged()? No, ¿verdad? Por
eso se llama al constructor [new ChangeListener()] en el momento de colocarle la escucha al objeto
slider y sirve de envoltorio para justificar la sobreescritura del método stateChanged(). El hecho de
implementarlo incrustado dentro del método main() facilita que se pueda acceder al objeto slider
directamente sin tener que crear objeto ni nada.

Pero mosquea mucho ver que ChangeListener es en realidad un interfaz, lo sabemos porque
viene acompañado de la palabra reservada implements, y la teoría nos dice que un interfaz no se
instancia. Ya pero es el truco barato que cuela en Java cuando se quiere hacer todo a lo "Juan
Palomo" (dentro del mismo método), en el caso anterior main(), teniendo en cuenta que no le hemos
suministrado explícitamente la interfaz. Ahora en esta segunda versión vamos a sacar de main() el
método stateChanged() sobreescrito, dado que vamos a indicarle explícitamente el interfaz, lo que
nos permite utilizarlo como método aparte:

class GuiSwingAct5 implements ChangeListener {

Ciclo Formativo Superior DAM 14 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

import javax.swing.*;
import javax.swing.event.*; La declaración de los contenedores y componentes
class GuiSwingAct5 implements ChangeListener { se hace en forma de atributo para que los métodos
static JFrame marco; de la clase puedan acceder a ellos directamente. [Es
static JSlider slider; que ahora stateChanged() ya no está en main()]
static JLabel etiqueta;
public static void main(String[] args) {
¿Y por qué static? Por comodidad, porque sino
GuiSwingAct5 control = new GuiSwingAct5();
en main(), al haber instanciado control del tipo
marco = new JFrame("JSlider con Actividad");
GuiSwingAct5, deberíamos hacer referencia a
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cada atributo como control.marco,
etiqueta = new JLabel();
control.etiqueta, etc...
JPanel panel = new JPanel();
slider = new JSlider(0, 200, 100);
slider.setPaintTrack(true);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setMajorTickSpacing(50);
slider.setMinorTickSpacing(5);
/* Coloca la detección de cambios
en el objeto de la clase */
slider.addChangeListener(control);
panel.add(slider);
panel.add(etiqueta);
marco.add(panel);
//Para colocar texto con valor del JSlider
etiqueta.setText("Valor actual = " + slider.getValue());
marco.setSize(300, 300);
marco.setVisible(true);
}
//Acción a realizar si detecta cambio en JSlider
Aquí tenemos el método stateChanged()
public void stateChanged(ChangeEvent e) {
fuera de main()
etiqueta.setText("Valor actual = " + slider.getValue());
}
}

Puedes probarlo y verás que funciona idéntico a la primera versión. Pero hemos dicho que
todavía podemos adelgazar más el método main(). ¡Momento Jorge Blass! Para empezar sacándolo
en clase aparte al estilo de la clase Piloto utilizada en muchos códigos de nuestras secuencias. Sin
embargo, eso nos generaría ventajas y desventajas aunque más de las primeras. Nada por aquí, nada
por allí, y de repente nos sacamos de la manga el método constructor de una clase. Atentos:

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
class Igu extends JFrame implements ChangeListener {
La declaración de los componentes se hace en
JSlider slider;
forma de atributo para que los métodos de la clase
JLabel etiqueta; Igu puedan acceder a ellos directamente. Ya no
Igu() hace falta static porque en main() se instancia toda
{ la clase Igu.
//Crea y configura componentes
etiqueta = new JLabel();
slider = new JSlider(0, 200, 100); La declaración de los contenedores no existe a priori
porque directamente se ha extendido la clase
slider.setPaintTrack(true);
JFrame para que herede Igu.Ahora Igu es el marco,
slider.setPaintTicks(true); al que se le está colgando el interfaz. Dentro de este
slider.setPaintLabels(true); constructor se han creado y configurado
slider.setMajorTickSpacing(50); componentes además de colocar la escucha.
slider.setMinorTickSpacing(5);

Ciclo Formativo Superior DAM 15 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

//Coloca la detección de cambios en el JSlider


slider.addChangeListener(this);

//Para colocar texto debajo con valor del JSlider


etiqueta.setText("Valor actual = " + slider.getValue());

//Coloca componentes en el marco y lo configura


add(slider);
add(etiqueta);
setTitle("JSlider con Actividad");
setLayout(new FlowLayout()); Si nos fijamos bien, el marco no tiene
nombre explícito, porque asume que Igu
setSize(300, 150);
es un JFrame y al estar trabajando
setVisible(true); dentro no necesita identificarlo.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public void stateChanged(ChangeEvent e) {


etiqueta.setText("Valor actual = " + slider.getValue());
}
}

public class GuiSwingAct5 {


public static void main(String[] args) { ¿No queríamos el método main()
Igu aplicacion = new Igu(); delgadito para el verano? Pues mira.
}
}

Para rematar la faena, no siempre nos pedirán que los mensajes resultantes de nuestras
selecciones tengan que plasmarse en etiquetas. Swing tiene un componente denominado
JOptionPane que genera una ventana de información como las que muestra el SO Windows
cuando informa de algo o como cuando en un formulario por Internet nos quiere avisar de que se
nos ha olvidado algo o nos hemos equivocado.

import javax.swing.*;
import java.awt.event.*;
class Igu {
JRadioButton botRadio1;
JRadioButton botRadio2;
JButton boton;
ButtonGroup agrupBotRad;
JLabel etiqueta;
public Igu() {
this.setLayout(null);
botRadio1 = new JRadioButton();
botRadio2 = new JRadioButton();
boton = new JButton("Pulsa");
agrupBotRad = new ButtonGroup();
etiqueta = new JLabel("FP estudiada");
botRadio1.setText("Grado Medio");
botRadio2.setText("Grado Superior");
botRadio1.setBounds(120, 30, 120, 50);
botRadio2.setBounds(250, 30, 120, 50);
boton.setBounds(125, 90, 80, 30);
etiqueta.setBounds(20, 30, 150, 50);
this.add(botRadio1);
this.add(botRadio2);

Ciclo Formativo Superior DAM 16 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

this.add(boton);
this.add(etiqueta);
agrupBotRad.add(botRadio1);
agrupBotRad.add(botRadio2);
//Colocando escucha al grupo de botones
boton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String fpStu = " ";
if (botRadio1.isSelected()) {
fpStu = botRadio1.getText();
}
else if (botRadio2.isSelected()) {
fpStu = botRadio2.getText();
}
else {
fpStu = "Nada seleccionado";
}
// Muestra mediante ventana de diálogo la opción seleccionada
JOptionPane.showMessageDialog(Igu.this, fpStu);
}
});
}
}
class GuiSwingAct6 {
public static void main(String[] args) {
Igu marco = new Igu();
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setBounds(100, 100, 400, 200);
marco.setTitle("Botones de radio, botón y ventana");
marco.setVisible(true);
}
}

Pasos básicos en la construcción de una interfaz


1.Crear una nueva clase para nuestra ventana (o directamente instanciarJFrame)
2.Crear los componentes de nuestra interfaz
3.Crear uno o varios contenedores intermedios
4.Asociar los componentes al contenedor
5.Asociar el contenedor a la ventana
6.Hacer visible la ventana

Reto

Si te fijas en el código del ejercicio GuiSwingAct6, se ha quedado en tierra de nadie. Se ha


desgajado en dos clases. Pero no ha sacado fuera la escucha tirando del interfaz. Te propongo
entonces refactorizar manualmente dicho código en dos sentidos:
a) de forma que quede todo recogido en el método main() de una sola clase, como hacíamos al principio
b) de forma que existan dos clases, teniendo una de ellas la escucha colgada por interfaz, un constructor
dejando para la otra el método main() lo más fino posible.

Nota: Es tan buen ejercicio pasar un código que está todo incluido en main() a
profesional como hacerlo en sentido inverso.

Ciclo Formativo Superior DAM 17 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Y si...

...después de todo lo que llevamos programado, nos viene alguien y nos dice eso de: "pues
IntelliJ IDEA tiene un asistente gráfico para construir interfaces que de paso te genera el código
Java Swing necesario". Pues sí, confirmado. IntelliJ IDEA, al igual que el resto de entornos de
desarrollo para Java, tiene su herramienta gráfica de creación de interfaces.

En este vídeo de Youtube puedes aprender cómo en escasos 10 minutos:


https://www.youtube.com/watch?v=xqEQs0nuHnQ

En este otro vídeo de Youtube de 16 minutos también:


https://www.youtube.com/watch?v=-SmNpKskfJc

El resultado de implementar un GUI con el asistente de IntelliJ IDEA es este código que el
propio entorno ha generado:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GUIAsist1 {
private JTextField dataEntrada;
private JButton boton1;
private JPanel miPanel;
private JLabel etiqueta;
public GUIAsist1() {
boton1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
etiqueta.setText(dataEntrada.getText());
}
});
}
public static void main(String[] args) {
JFrame marco = new JFrame("GUIAsist1");
marco.setContentPane(new GUIAsist1().miPanel);
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.pack();
frame.setVisible(true);
}

// Fíjate como aquí no termina la clase


/*
Ahora IntelliJ IDEA pega todo el código
interno necesario para que funcione
*/
{
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
$$$setupUI$$$();
}

Ciclo Formativo Superior DAM 18 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

/**
* Method generated by IntelliJ IDEA GUI Designer
* >>> IMPORTANT!! <<<
* DO NOT edit this method OR call it in your code!
*
* @noinspection ALL
*/
private void $$$setupUI$$$() {
miPanel = new JPanel();
miPanel.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(3, 2, new Insets(0, 0, 0, 0), -1, -1));
dataEntrada = new JTextField();
miPanel.add(dataEntrada, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 2,
com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST,
com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL,
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW,
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false));
final com.intellij.uiDesigner.core.Spacer spacer1 = new com.intellij.uiDesigner.core.Spacer();
miPanel.add(spacer1, new com.intellij.uiDesigner.core.GridConstraints(1, 1, 2, 1,
com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER,
com.intellij.uiDesigner.core.GridConstraints.FILL_VERTICAL, 1,
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
boton1 = new JButton();
boton1.setText("Pulsa");
miPanel.add(boton1, new com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1,
com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER,
com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL,
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK |
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW,
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
etiqueta = new JLabel();
etiqueta.setText("");
miPanel.add(etiqueta, new com.intellij.uiDesigner.core.GridConstraints(2, 0, 1, 1,
com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE,
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED,
com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
}
/**
* @noinspection ALL
*/
public JComponent $$$getRootComponent$$$() {
return miPanel;
}
}

En IntelliJ IDEA se accede al asistente de interfaces gráficos creando un


proyecto pero en vez de ir a crear una nueva Java Class, en ese mismo menú
desplegable hay una opción denominada GUI Form.

Ciclo Formativo Superior DAM 19 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Prueba a transformar este código

Refactoriza manualmente este código de forma que existan dos clases, teniendo una de ellas
la escucha colgada por interfaz, un constructor dejando para la otra el método main() lo más fino
posible.

import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TransJSpinner {


public static void main(String[] args) {
JFrame v = new JFrame("Spinner y campo de texto");
JTextField tf = new JTextField(20);
JSpinner spinner = new JSpinner();
spinner.setValue(30);
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
// Ponemos el valor del JSpinner en el JTextField
tf.setText(spinner.getValue().toString());
}
});
v.getContentPane().setLayout(new FlowLayout());
v.getContentPane().add(spinner);
v.getContentPane().add(tf);
v.pack();
v.setVisible(true);
v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}

Ejercicio 1

Implementa una GUI que refleje un conversor de moneda de euro a dolar USA que solicite
la introducción de una cantidad (puede contener decimales) en un campo de texto. Mediante dos
botones de radio agrupados se eligirá si se quiere el resultado en euros o en dólares USA siendo un
botón el que desencadene la operación. Una vez calculada la cantidad equivalente, ésta deberá
reflejarse en un segundo campo de texto.

Habrá que dejar constancia en el código que se controla, mediante excepciones, la


posibilidad de que introduzcan caracteres en el campo de texto o que alguien se equivoque y utilice
las comas para establecer los decimales.

Ciclo Formativo Superior DAM 20 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Ejercicio 2

Implementa la GUI cuyas capturas se muestran a continuación, de forma que al seleccionar


el tipo de pan, el tipo de relleno y los aderezos, el pulsado del botón genere la ventana de diálogo
con el texto que corresponda a la elección realizada.

Ciclo Formativo Superior DAM 21 [email protected]


PROGRAMANDO EN JAVA Decimocuarta secuencia de Aprendizaje.

Ejercicio 3

Implementa la GUI representada en la dirección: https://www.gabilos.com/textocalculadoradccuenta.htm


que calcula los digitos de control e IBAN de una centa bancaria.

Ejercicio 4

Implementa la GUI realizada en el ejercicio 1, pero en esta ocasión utilizando el asistente de


interfaces gráficos que proporciona IntelliJ IDEA.

Autoevaluación

Te recomiendo que ahora te dirijas a la autoevaluación nº 6 para calibrar si realmente has


entendido los conceptos y manejado los procedimientos de interfaces gráficas de usuario con la
soltura debida.

Ciclo Formativo Superior DAM 22 [email protected]

También podría gustarte