Está en la página 1de 16

----~

Interfaces grficas de usuario con Swing

Problemas resueltos

INTERFACES

GRFICAS DE USUARIO

Ejercicio 10.1:
Escriba una aplicacin con interfa: grfica en la que se construya una ventana con ttulo y marco que tenga
los controles bsicos (iconizar; maximizar; cerrar) y que al pulsar sobre el aspa de la ventana (cerrar) se
salga completamente de la aplicacin. La ventana contendr una etiqueta y el usuario debe poder cambiar su
tamao.

Planteamiento:
a)

Como hay que crear una ventana con marco lo mas adecuado es crear una clase que extienda o especialice
la clase JFrame. Esta clase ya tiene marco y los controles bsicos.
S610 hay que configurar el comportamiento del control de cierre (el aspa) de la ventana. Para hacerla
simplemente se fija la propiedad correspondiente mediante la instruccin setDefaultCl
oseOperati on
CJFrame.EXIT_ON_CLOSE).
Hay que crear una etiqueta de tipo JLabel y aadirla a la ventana.
Se configuran el resto de propiedades de la ventana, como son su ttulo, que se pueda modificar su
tamao, que su tamao inicial se ajuste al tamao preferido de los componentes que contiene y que sea
visible.

b)

e)
d)

Solucin:
import
public

j avax. swi

ns. *; ..,.(;-------------------[

Se importanlos elementosgrficos.]1

class EjemploJFrameCerrable
extends JFrame
public
EjemploJFrameCerrableC){
setDefaultCloseOperationCJFrame.
EXIT_ON_CLOSEl;
JLabel

etiqueta

addCet i queta) ;
setTitleC"Prueba
setResizableCtrue);

new JLabel("Ventana

Se termina la aplicacinal pulsar


el botn en cruz del sistema.

+--_ .....

redimensionable

y cerrable");

JFrame");

packO;
setVisibleCtrue);

public

static
void mainCString
EjemploJFrameCerrable

Se crea un objeto del tipo ventana


que se ha definido.
args[])
ventana

{
=

new EjemploJFrameCerrableO;

+-

--J

}
/ / Ejemp7oJFrameCerrab7e
.- .
__

._ _

_ _,

_,

,0-.

~ __

Figura 10.1. Captura de la ventana generada inicialmente

V-j

'

L;]~~

,;j Prueba JFrame

Ventana redimensionable

...
_,._

y cerrable

y una vez redimensionada

por el usuario.

----

Programacin

en Java 2

Comentario: El comportamiento de cierre de la aplicacin se podra haber proporcionado mediante un gestor


de eventos de ventana (un oyente WindowLi stener) que implemente el mtodo wi ndowClosi ng() en el cual se
ejecutara la operacin de salida de la aplicacin (System. exi t (O.
Aviso: En versiones de lava anteriores a la 1.4 los componentes grficos no se podan aadir directamente la
etiqueta a la ventana mediante add(etiqueta).
Haba que hacerlo expresamente a su panel de contenido mediante getContentPane() . add(eti queta).
Ejercicio 10.2:
Escriba una aplicacin grfica con una ventana que tenga una etiqueta y dos botones de operacin. El
comportamiento de la aplicacin debe reflejar en el texto de la etiqueta cul es el ltimo botn en el que el
usuario ha hecho dic.
Planteamiento: Primero se construye la ventana principal de la aplicacin que contiene al resto de los componentes grficos, es decir, la etiqueta y los dos botones. Por simplicidad se agrupa la etiqueta y los botones en un
panel que es el que finalmente se aade a la ventana.
En este caso hay que proporcionar un comportamiento a la interfaz grfica que d respuesta a las interacciones
de los usuarios, en concreto a los botones, y por tanto hay que incluir un manejador o gestor de eventos. Con el
gestor se va a escuchar y responder al evento de alto nivel de accin que se genera al hacer clic sobre cada
botn.
Este oyente se lleva a cabo como una clase interna que implementa la interfaz Act i onL i stener y proporciona el mtodo act i onPerformed ( ). Este es el mtodo que se ejecuta cuando se produce el evento (se hace
clic en el botn) y en l se determina el origen del evento y, en funcin de cul se haya pulsado, se modifica
la etiqueta.
Solucin:

import javax.swing.*:
import java.awt.event.*;

+----------------

public class BotonesEtiquetaOyente


private JLabel etiqueta;
private JButton botonUno;
private JButton botonDos;
private JPanel panel;
public BotonesEtiquetaOyente()

extends JFrame {

etiqueta = new JLabel("No se ha pulsado ningn botn") ;


botonUno =new JButton("Boton Uno");
botonDos

= new JButton("Boton Dos");

panel = new JPanel();


panel.add(etiqueta);
panel.add(botonUno);
panel.add(botonDos);
add(panel) ;
OyenteAccion oyenteBoton = new OyenteAccion(); ..,..J,..botonUno.addActionListener(oyenteBoton);
botonDos .addActi onL istener( oyenteBoton) ;+-----,\

Se aaden los objetos grficos al


panel y el panel a la ventana.

-II

Se crea un objeto oyente


de acciones.

Se asigna el mismo oyente a

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Ventana con interaccin");
pack() ;

los dos botones de interaccin.

----

Interfaces grficas de usuario con Swing

setVisibleCtrue):
}

public static void mainCString[] args) {


BotonesEtiquetaOyente ventana = new BotonesEtiquetaOyenteC):

F===============~

Se crea una clase oyente de


class OyenteAccion implements ActionListener{
acciones como clase interna.
public void actionPerformed CActionEvent evento){
JButton boton = CJButton) eventa.getSource():
etiqueta. setTextC "Botan pulsada: " + botan. getTextO):

}// OyenteAcci on
}//BotonesEtiquetaOyente
Comentario: En este caso el tratamiento de los eventos de accin generados por el clic del usuario sobre los
botones se trata mediante un nico objeto de una clase oyente interna a la clase principal de la aplicacin.
La ventaja de las clases internas es que pueden acceder directamente a todos los atributos de la clase
contenedora y adems, como son locales a ellas, se evita la proliferacin de clases. Otras opciones posibles
seran que la propia clase principal pudiera actuar como oyente de acciones, es decir, que implemente la
interfaz Acti onLi stener y proporcione el mtodo actionPerformed()
.o implementar la clase oyente como
una clase externa normal.
Aviso: Un componente grfico slo puede estar contenido en un nico elemento grfico contenedor. En este
caso los botones y la etiqueta estn contenidos en el panel y el panel est contenido en la ventana. Es decir, la
jerarqua de composicin de objetos grficos es simple y, por tanto, si se trata de aadir un componente a un
segundo contenedor, dejara de estar contenido en el primer contenedor.
..

''

Ventana con interaccin

Nose ha pulsado ningln bot6n

I ~oton-un~

GJ

Figura 10.2. Ventana inicial de la aplicacin y resultado despus de hacer clic sobre el botn uno.

Ejercicio 10.3:
Escriba una aplicacin grfica con una ventana que tenga dos etiquetas y dos botones de operacin. El
comportamiento de la aplicacin debe reflejar en el texto de las etiqueta el nmero de veces que el usuario ha
hecho clic en cada uno de los botones.
Planteamiento: Primero se construye la ventana principal de la aplicacin que contiene al resto de los componentes grficos, es decir, las dos etiquetas y los dos botones. Por simplicidad se agrupan estos elementos
grficos en un panel que es el que fmalmente se aade a la ventana.
Para proporcionar un comportamiento a la interfaz grfica que d respuesta a las interacciones de los
usuarios, en concreto a los botones, hay que incluir un gestor de eventos que responda al evento de la accin
que se genera al hacer clic sobre cada botn.

----

Programacin

en Java 2

Solucin:

import javax.swing.*;
import java.awt.event.*:
publicO class BotonesEtiquetasOyenteExterno
private JLabel etiquetaUno;
private JLabel etiquetaDos;
private JButton botonUno;
private JButton botonDos;
private JPanel panel;

extends JFrame {

public BotonesEtiquetasOyenteExterno()
{
etiquetaUno = new JLabel("Boton Uno: O veces");
etiquetaDos = new JLabel("Boton Dos: O veces");
botonUno = new JButton( "Boton Uno");
botonDos = new JButton( "Boton Dos");
panel = new JPanel();
Los componentes se presentan
en elpanelen elordenen el
panel.add(etiquetaUno);
que se aaden.
panel.add(botonUno);
panel.add(etiquetaDos);
panel.add(botonDos);
add(panel) ;
OyenteExternoAccion oyenteBotonUno = new OyenteExternoAccion(etiquetaUno);~
OyenteExternoAccion oyenteBotonDos = new OyenteExternoAccion(etiquetaDos);
botonUno.addActionListener(oyenteBotonUno);
botonDos.addActionListener(oyenteBotonDos);
En estecaso se creandos objetos
oyentesy se lespasa como parmetro
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
laetiquetacorrespondiente.
setTit;le("Ventana con interaccin");
setSize(300,lOO);
setVisible(true);
}

public static void main(String[]


BotonesEtiquetasOyenteExterno

args) {
ventana

new BotonesEtiquetasOyenteExterno();

}
} / /BotonesEtiquetasOyenteExterno
,Lr---------------------il

..
public class OyenteExternoAccion
private int numVeces;
private JLabel etiqueta;

implements ActionL istener{

public OyenteExternoAccion(JLabel
numVeces = O;
this.etiqueta = etiqueta;

etiqueta){

+-----------11

public void actionPerformed (ActionEvent evento){


numVeces++;
JButton boton = (JButton) evento.getSource();
etiqueta.setText(boton.getText()+":
"+ numVeces+ " veces");
}
}//

OyenteExternoAccion

La claseoyentees una clasepblica


externaa laclaseen laque se
generanloseventos.
'<=",===========dI

Eloyentetieneun constructor
que
recibecomo parmetrolaetiqueta
a modificar.

---

Interfaces grficas de usuario con Swing

Comentario: Aunque las etiquetas son atributos privados de la ventana principal y el oyente de eventos es una
clase externa a dicha ventana, no es necesario hacer un mtodo de acceso ya que el constructor del oyente
recibe como parmetro la etiqueta que tiene que modificar.
__

~~

_~

.~~_

-"'_

._

_.-

_~_

Boton Uno: Oveces


Boton Dos: Oveces

I
I

. Ventana con interaccin

L;J

. Ventcma con interaccin

~~'!!I~

Boton Uno: 2 veces

Boton.Dos

Boton Dos: 4 veces [ ~ot~ll.~sJ

Boton Uno.

ilEJ

Figura 10.3. Ventana inicial de la aplicacin y despus de hacer clic dos veces sobre el botn uno
y 4 veces sobre el botn dos.

Ejercicio 10.4:
Escriba una aplicacin grfica con una ventana que tenga una etiqueta y un rea de texto. La aplicacin
debe reflejar en el rea de texto todos los eventos de ventana que se produzcan por la creacin de la ventana
o por las interacciones del usuario.
Planteamiento:
Primero se construye la ventana principal de la aplicacin que contiene un panel en el que se
incluyen la etiqueta y el rea de texto. Para poder reflejar todos los eventos de la ventana se hace que la propia
ventana implemente la interfaz de oyente de ventana y se proporcionan los siete mtodos correspondientes de
esta interfaz que aaden al rea de texto una lnea de texto indicando el evento producido.
Solucin:
import
import

javax.swing.*;
java.awt.event.WindowListener;

import

java.awt.event.WindowEvent;

public

class

private
private
private
private
public

VentanaOyente

extends

La propia ventana grfica es oyentede


eventos de ventanaya que implementa
la interfaz WindowLi stener.

JFrame implements

WindowListener

{+-

--II

JTextArea areaTexto;
JLabel etiqueta;
JPanel panel;
final
S~ring FIN ~"\n";

VentanaOyente()
{
etiqueta
~ new JLabel("Eventos");
areaTexto ~ new JTextArea(lO,
30): ....-----------11
areaTexto.setText("Texto
panel ~ new JPanel();

panel.add(etiqueta):
panel.add(areaTexto);
add(panel) ;
addWindowL i stener(thi

inicial

del area de texto");

s); .... -----------------11

setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setTitl e( "Ventana oyente");
setVisible(true);
pack() ;

Se crea un rea de texto con 10filas


y 30 columnasy se le asocia una
cadena de texto inicial.

Con thi s es la propiaventanala


que se registra a s mismacomo
oyente de eventosde ventana.

----

Programacin en Java 2

public void windowOpenedCWindowEvent


e) {
areaTexto. appendCFIN + "Ventana abi erta") ;.
,----------11

Se proporcionanlosmtodos
correspondientesa lainteriaz
WindowL istener.

public void windowClosingCWindowEvent


e) {
areaTexto.appendCFIN
+ "Ventana cerrandose");
}

public void windowClosedCWindowEvent


e) {
areaTexto.appendCFIN
+ "Ventana cerrada");
}

public void windowlconifiedCWindowEvent


e) {
areaTexto.appendCFIN
+ "Ventana iconizada");
}

public void windowDeiconifiedCWindowEvent


e) {
areaTexto.appendCFIN
+ "Ventana desiconizada");

..
~----tl

En losmtodos de lainteriaz
WindowL istener se aade una lnea
alcontenidodelreade textocon la
indicacindeleventoproducido.

public void windowActivatedCWindowEvent


e) {
areaTexto.appendCFIN
+ "Ventana activada");
}

public void windowDeactivatedCWindowEvent


e) {
areaTexto.appendCFIN
+ "Ventana desactivada");
}

public static void mainCString[] args) {


VentanaOyente ventana = new VentanaOyenteC);
}
} / / VentanaOyente

Comentario: En este caso se estn tratando los eventos de ventana que reflejan cualquier cambio de estado.
Estos eventos son de bajo nivel. Siempre que sea posible, es preferible hacer el tratamiento de eventos de alto
nivelo semnticos que hacerlo de sus eventos equivalentes de bajo nivel.
Aviso: Como se ha modificado el comportamiento del control de cierre de la ventana para que no haga nada y
se pueda comprobar ese evento mediante su escritura en el rea de texto, no se podr cerrar la ventana de forma
normal. Habr que hacerlo cerrando la ventana de la consola Java o desde el administrador de tareas.
~- .,

Ventana oyente
Texto inicial del area de texto
Ventana actvada
Ventana abierta

Eventos

;]@[g)

-.

",' Ventana oyente


/fexto inicial del area de texto
Ventana activada
Ventana abierta
Ventana lean Izada

Eventos ventana desactlvada


Ventana deslccmzada
Ventana activada

Figura 10.4. Ventana inicial de la aplicacin y despus de pasarla a icono y devolverla a su tamao original.

Ejercicio 10.5:
Escriba una aplicacin grfica con una ventana que tenga un botn y un rea de texto. La aplicacin debe
reflejar en el rea de texto los principales eventos de ratn que se produzcan sobre dicha rea por las
interacciones del usuario. Haciendo clic en el botn se limpiar el contenido del rea de texto.

----

Interfaces grficas de usuario con Swing

Planteamiento: Primero se construye la ventana principal de la aplicacin que contiene un panel en el que se
incluyen el botn y el rea de texto.
Para poder reflejar algunos de los eventos del ratn se crea una clase oyente de ratn que implemente la
interfaz MouseInputL istener. Esta interfaz incluye siete mtodos y para no tener que implementarlos todos se
hace que la clase oyente extienda de la clase adaptadora MouselnputAdapter. Esta clase adaptadora proporciona defmiciones vacas de los siete mtodos de modo que slo se necesita implementar los mtodos que resulten
interesantes.
Solucin:

import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;+----------------il
public class VentanaOyenteAdaptador extends JFrame (
private JTextArea areaTexto;
public VentanaOyenteAdaptador() (
JButton boton = new JButton("Limpiar");
areaTexto = new JTextArea(12. 30);
JPanel panel = new JPanel();
panel.add(boton);
panel.add(areaTexto);
add( pane 1) ;
ActionListener oyenteBoton= new OyenteAccion();
boton.addActionListener(oyenteBoton);
MouseL istener oyenteRaton= new OyenteRaton(); +-----;1
areaTexto.addMouseListener(oyenteRaton);

Tambin hay que importarloseventos


de swingya que es aqudonde se
defineMouse 1nputAdapter.

Se creaun oyentede ratnque se


asociaalreade texto.

class OyenteRaton extends MouselnputAdapter (+--------------,I


public void mouseClicked(MouseEvent e) (
areaTexto.append("Se ha hecho clic \n");
areaTexto.append(" Posicion X: "+e.getX());
El oyentede ratnse creaextendiendola
areaTexto. append(" Posi cion y: "+e.getY()) ;
claseadaptadoraMouselnputAdapter.
}

public void mousePressed(MouseEvent e) (


if e.getModifiers() & InputEvent.BUTTON3_MASK) != O)
areaTexto.append ("El botn pulsado es el de la derecha \n");
areaTexto.append("Se ha pulsado el botn del ratn \n");
}

public void mouseReleased(MouseEvent e) (


areaTexto.append("Se ha soltado el botn del ratn \n");
}

public void mouseEntered(MouseEvent e) (


areaTexto.append("El ratn ha entrado en el componente \n");
}

public void mouseExited(MouseEvent e) (


areaTexto.append("El ratn ha salido del componente \n");

class OyenteAccion implements ActionListener{ +---------11


public void actionPerformed (ActionEvent evento){
areaTexto.setText("");

Oyente de accionesque limpia


elcontenidodelreade texto.

..

----

Programacin en Java 2

publC statc vod man(Strng[] args) (


VentanaOyenteAdaptador ventana = new VentanaOyenteAdaptador():
ventana. setT t1e( "Eventos de ratn"): +-----------11
ventana.pack():
ventana.setVsble(true):

En este caso las propiedades de la


ventana de la aplicacin se
establecen en el programa principal.

}//VentanaOyenteAdaptador
Comentario: En este caso se estn tratando los eventos de ratn a bajo nivel. El uso de la clase adaptadora ha
evitado tener que proporcionar tambin la implementacin de los mtodos mouseOragged() y mouseMoved() ya
que en este caso no se deseaba tener su funcionalidad.

El ratn ha entrado en el componente


El ratn ha salido del componente
El ratn ha entrado en el componente
El botn pulsado es el de la derecha
Se ha pulsado el botn del ratn
r-;:um.;=im=p=3rl=r-
Se ha soltado el botn del ratn
.
Se ha hecho cllc
Poslcion X: 42 Pcsiclcn y: S8

El ratn ha entrado en el componente


Se ha putsado el botn del ratn
El ratn ha salido del componente
Se ha sonado el botn del ratn

Limpiar

Figura 10.5. A la izquierda la ventana de la aplicacin despus de haber entrado, salido y vuelto a entrar en el rea
de texto donde se ha hecho clic con el botn derecho. A la derecha el ratn ha entrado en el rea de texto, se ha
pulsado el ratn y antes de soltarse se ha salido del componente de modo que no se ha producido el clic.

Ejercicio 10.6:
Escriba una aplicacin grfica que permita calcular el ndice de masa corporal. Este ndice se obtiene
dividiendo el peso en kilos de una persona por el cuadrado de su altura en metros.
Planteamiento: Primero se construye la ventana principal de la aplicacin que contiene un panel en el que se
incluyen dos campos de texto con sus etiquetas identificativas para la obtencin del peso y de la altura, un
botn para realizar el clculo y el campo de texto donde se muestra el resultado (este ltimo campo no debe ser
editable por el usuario). Los campos de texto que se necesitan para tomar datos o mostrar resultados, es decir,
que sern posteriormente accedidos, se declaran como atributos de la clase. El resto de componentes grficos
se declaran como variables locales, o incluso annimas.
Solucin:

mport javax.swng.*:
mport java.awt.event.*:
publc class IndiceMasaCorporal extends JFrame {
prvate JTextField campoAltura:
prvate JTextField campoPeso:
prvate JTextField campoIMC:

Interfaces grficas de usuario con Swing

----

public IndiceMasaCorporalC) (
JLabel etiquetaAltura = new JLabel("Altura Cmetros)");
JLabel etiquetaPeso = new JLabel("Peso Ckg)");
JLabel etiquetaIMC = new JLabel("Indice Masa Corporal");
JButton calcular
= new JButtonC"Calcular
IMC");
campoAltura = new JTextField(6); +------------11
campo Peso = new JTextField(6);
campoIMC
= new JTextField(6);
campoIMC.setEditableCfalse);
JPanel panel = new JPanelC);

Se creanloscampos de alturay peso


donde elusuariointroducir
losdatos.

panel.addCetiquetaAltura);
panel.addCcampoAltura);
panel.addCetiquetaPeso);
panel.addCcampoPeso);
panel.addCcalcular);
panel.addCetiquetaIMC);
panel.addCcampoIMC);
addCpanel);
Albotnde calcularse leasocia
ca 1 cu 1 ar .addActi onL istenerC +---------------ll
un oyentede accionesmediante
una claseannima.
new ActionListenerC) (
public void actionPerformed CActlonEvent evento){
Double peso = Double.parseDoubleCcampoPeso.getTextC;
Double altura = Double.parseDoubleCcampoAltura.getTextC;
Double imc = peso / Caltura * altura);
String cadena = String.formatC"%6.2f". tmc) :
campoIMC.setTextCcadena);
11
Alresultadose leda formatocon dos
~----I
decimalesy se muestraen elcampoIMC.
}
); / / addActionLi stener
} l/constructor
public static void mainCStringe] args) (
IndiceMasaCorporal ventana = new IndiceMasaCorporalC);
ventana .setTitleC"Indice de Masa Corporal");
ventana.setDefaultCloseOperationCJFrame.EXIT_ON_CLOSE);
ventana.setSizeC400. 100);
ventana.setVisibleCtrue);

Comentario: Normalmente en las aplicaciones grficas slo se declaran como atributos aquellos elementos grficos a los que hay que acceder posteriormente (aunque en este caso no sera necesario). Respecto a la funcionalidad
de la aplicacin, en este caso se proporciona mediante un oyente de acciones asociado al botn de operacin que se
implementa como una clase annima. Hay que tener cuidado con esta prctica ya que, aunque es cmodo debido
a que no hay que crear nuevas clases, puede dificultar la lectura del cdigo. Por tanto slo se debe usar cuando el
cdigo del oyente sea suficientemente sencillo como para no interferir con la legibilidad del programa.
Aviso: No se ha introducido control de errores en la entrada proporcionada por el usuario, de modo que si el
formato numrico no fuera correcto, se producira una excepcin y la correspondiente terminacin anmala
del programa. Si se introduce cero en la altura en el ndice de masa corporal se muestra Infinity
(infinito) ya
que se ha realizado una divisin por cero.

1------

Programacin en Java 2
-

Indice de Masa Corporal

GJLQ]I~

I Peso (kg) 1102


I
Indice Masa Corporal i_i7,96~' ~

Altura (metros) 11.91

~alcular IMg

Figura 10.6. Captura de la ventana de la aplicacin-despus de haber introducido datos y haber hecho clic
en el botn Calcular !MC.

Ejercicio 10.7:
Escriba una aplicacin grfica que permita de forma sencilla realizar el cambio de pesetas a euros y viceversa. La tasa de cambio que se aplica es 1 euro igual a 166,386 pesetas. En todo momento el usuario debe estar
informado de la conversin que se est realizando.
Planteamiento: En este caso se hace que la clase especialice a un panel (JPanel) en el que se incluyen los dos
campos de texto con sus correspondientes etiquetas para obtener la cantidad a cambiar y mostrar el resultado.
Tambin se incluye un botn de operacin para realizar el cambio y un botn conmutador que determinar la
conversin que se est realizando en ese momento. Cuando se pulse el botn conmutador se cambiar la
conversin a realizar y su texto identificativo para que el usuario conozca el sentido de dicha conversin,
pesetas a euros o euros a pesetas.
En el programa principal se construye y se fijan las caractersticas de la ventana principal de la aplicacin
a la que se aade un objeto de la clase que especializa el panel.
Solucin:
import

jqvax.swing.*:

import

java.awt.event.*:

public

class

private

CalculadoraEurosPesetas
final

double

extends

prvate

double

prvate

JTextField

campoCantidad:

private

JTextField

campoResultado:

public

cambioEfectivo

= TASACAMBIO:

CalculadoraEurosPesetas()

add(new

JLabel("Cantidad

campoCantidad

JPanel

TASACAMBIO = 166.386:

En botn conmutador se fija que


inicialmente no est seleccionado.
Luego se aade al panel y se le
asocia un oyente de acciones.

{
a convertir")):

= new JTextField("O.O".6):

add(campoCantidad):
add(new

JLabel(

campoResultado

"Resultado")):
= new JTextField("O.O".6):

campoResultado.setEditable(false):
add(campoResultado):
JToggleButton

moneda = new JToggleButton("Euros

a Pesetas".

false):+-------J

add(moneda) :
moneda.addActionListener(new
JButton

OyenteBotonConmutador()):

cambi ar = new JButton(

"Cambi ar"):

add(cambiar):
cambiar.addActionListener(new

class

OyenteCambio

implements

OyenteCambio()):

ActionL

istener{+----------------J

Oyente de acciones que obtiene la


cantidad a cambiar, realiza la conversin
que est seleccionado y muestra el
resultado (formateado con dos decimales).

----

Interfaces grficas de usuario con Swing

..

public void actionPerformed CActionEvent evento){


double dinero= Double.parseDoubleCcampoCantidad.getTextC));
dinero = dinero * cambioEfectivo;
String cadena = String. formatC"%6.2f". dinero);
campoResultado.setTextCcadena);
}

}// OyenteCambio
Oyente del botnconmutador
el ass OyenteBotonConmutador
imp 1ements Act ionL istener { +---------11 que cambia su etiquetay
estableceelcambio efectivo.
public void actionPerformed CActionEvent evento){
JToggleButton boton = CJToggleButton) evento.getSourceC);
if Cboton.isSelectedC)){
Es necesarioobtenerelorigen
boton.setTextC"Pesetas
a Euros");
deleventoya
que no est
cambioEfectivo = 1 / TASACAMBIO;
'--------11
directamenteaccesible.
else {
boton. setText C"Euros a Pesetas");
cambioEfectivo = TASACAMBIO;
Se crea laventana principal
de
laaplicaciny se leproporciona
}
elttuloen elconstructor.
}// OyenteBotonConmutador

public static void mainCString[] args) {


JFrame ventana = new JFrameC"Calculadora
cambio moneda") ;+-..J
CalculadoraEurosPesetas
calculadora = new CalculadoraEurosPesetasC);
ventana.addCcalculadora);
ventana.setDefaultCloseOperationCJFrame.EXIT_ON_CLOSE);
ventana.setSizeC400.
100);
ventana.setVisibleCtrue);
Se creaun objetode tipocalculadora 11
y se aade a laventana principal.
}

-----1

,,==========1)

}// Ca7cu7adoraEurosPesetas
~

- .

Cantidad a convertir

I
r

'

156.89

Euros a Pesetas

-.

I Resultaf;lo
11

8ID1biarl

.-.> ~

156.89

Pesetas a Euros

194.~~n~._.
I
.

_.

-.'

;][QJ

Calculadora cambio moneda


Cantidad a convertir

r;]r:g]

. Calculadora cambio moneda

I Resultado

~~~

__

II~I

Figura 10.7. Captura de la ventana de la aplicacin primero en la conversin de euros a pesetas y luego en la de
pesetas a euros. Obsrvese que el botn conmutador que muestra la conversin que se realiza cambia no slo en su
texto sino tambin su aspecto, ya que pasa a estar seleccionado.

Comentario: Como en este caso la clase principal no hereda de JFrame si no de JPane 1, no produce una
ventana principal en la que se muestra directamente la aplicacin. Esta ventana se crea en el programa principal y luego se le aade un objeto del tipo calculadora.

----

Programacin en Java 2

Aviso: No se ha introducido control de errores en la entrada proporcionada por el usuario de modo que si el
formato numrico no fuera correcto se producira una excepcin y la correspondiente terminacin anmala del
programa.
Ejercicio 10.8:
Mejore la aplicacin grfica que realiza el cambio de pesetas a euros y viceversa presentado en el
ejercicio anterior. Adems de las funcionalidades
anteriores se debe permitir operar con los botones
desde el teclado y hay que aadir un botn que permita borrar los campos de datos y resultado. Tambin
para darle mayor robustez se debe incluir un control de errores que avise mediante una ventana emergente si se ha introducido un nmero en formato errneo evitando que la aplicacin se detenga de forma
anmala.
Planteamiento: En este caso se hace que la clase especialice a un panel (JPane 1) en el que se incluyen los dos
campos de texto con sus correspondientes etiquetas para obtener la cantidad a cambiar y mostrar el resultado.
Tambin se incluye un botn de operacin para realizar el cambio y un botn conmutador que determinar la
conversin que se est realizando en ese momento. Cuando se pulse el botn conmutador se cambiar la
conversin a realizar y su texto identificativo para que el usuario conozca el sentido de dicha conversin
(pesetas a euros o euros a pesetas). Para que se pueda operar con los botones desde el teclado se utilizan los
rnnemnicos. Si la letra indicada en el rnnemnico aparece en el texto del botn, su primera ocurrencia
aparecer subrayada
En el programa principal se construye y se fijan las caractersticas de la ventana principal de la aplicacin
a la que se aade un objeto de la clase que especializa el panel.
Solucin:

import javax.swing.*:
import java.awt.event.*;
import java0.swing.event.*;
public class
private
private
prvate
private

CalculadoraEuroMejorada
extends JPanel
final double TASACAMBIO = 166.386:
double cambioEfectivo = TASACAMBIO;
JTextField campoCantidad;
JTextField campoResultado;

public CalculadoraEuroMejoradaC)
{
addCnew JLabel("Cantidad a convertir"));
campoCantidad = new JTextFieldC"O.O" ,6);
addCcampoCantidad);
addCnew JLabel( "Resultado"));
campoResultado = new JTextFieldC"O.O" , 6);
campoResultado.setEditableCfalse);
addCcampoResultado);
JToggleButton moneda = new JToggleButtonC"Euros a Pesetas", false);
moneda.setMnemonicCKeyEvent.VK_E);
PulsandoAL Tte se activaeste
add Cmoneda) ;
botn,Silaletra
e apareceen el
moneda.addChangeListenerCnew
Oyent eBotonConmutadorC));
textodelbotnsu
primera
JButton cambiar = new JButtonC"Cam biar") ;
ocurrenciaaparecersubrayada.
cambiar.setMnemonicCKeyEvent.VK_C)
addCcambiar);
Se creaun iconoa partir
de una
cambiar.addActionListenerCnew
Oyen teCambioC)) ;
imagen
grfica
e
n
formatogif,
I
Imagelcon icono = new ImagelconC"c ross.gif");

----

Interfaces grficas de usuario con Swing


JButton borrar = new JButtonC "Borrar". icono); +-__
borrar.setMnemonicCKeyEvent.VK_B);
addCborrar) ;
borrar. addActionL istenerC +------...,
new ActionListenerC){
public void actionPerformedCActionEvent ev)
borrarDatosC) ;

-,
Se crea un botn que adems
de un texto tiene un icono.

Se aade un oyente annimo que invoca


al mtodo privado de borrado de datos.

);

private void borrarDatosCl{ +---------------11


campoCantidad.setTextC"O.O");
campoResultado.setTextC"O.O");

Mtodo privado de la clase que permite


mejorar la estructuracin de cdigo.

class OyenteCambio implements ActionListener{


public void actionPerformed CActionEvent evento){
Se protege la lectura de datos para
double dinero= 0.0;
evitar que un error en el formato
try{+-------------------~I
numrico provoque la terminacin
dinero = Double.parseDoubleCcampoCantidad.getTextC));
anmala de la ejecucin.
catch CNumberFormatException excepcion){
JOpt ionPane. showMessageDi alogCCa1cu1adoraEuroMejorada .thi s.
"Solo se pueden introducir dgitos y el punto decimal".
"Error en el formato numrico".
Se crea una ventana emergente
JOptionPane.ERROR_MESSAGE);
con el mensaje de error y un
borrarDatosC) ;
icono que muestra dicho error.

+-------.1

dinero = dinero * cambioEfectivo;


String cadena = String. formatC"%6.2f". dinero);
campoResultado.setTextCcadena);
}

}// OyenteCambio
class OyenteBotonConmutador implements ChangeListener{
public void stateChangedCChangeEvent evento){
JToggleButton boton = CJToggleButton) evento.getSourceC);
if Cboton.isSelectedC)){
boton.setTextC"Pesetas a Euros");
cambioEfectivo = 1 / TASACAMBIO;
} else (
boton. setTextC "Euros a Pesetas");
cambioEfectivo = TASACAMBIO;
}

}// OyenteBotonConmutador
public static void mainCString[] args) (
JFrame ventana = new JFrameC"Calculadora cambio moneda");
CalculadoraEuroMejorada calculadora = new CalculadoraEuroMejoradaC);

----

Programacin en Java 2

ventana.addCcalculadora);
ventana.setDefaultCloseOperationCJFrame.EXIT_ON_CLOSE);
ventana.setSizeC400. 130);
ventana.setVisibleCtrue);
}

}// Ca7cu7adoraEuroHejorada
Comentario: La imagen grfica "cross. gif" es 'la que se incluye en las distribuciones estndar de JDK de
lava. Normalmente se puede encontrar en la ruta demo/app1ets/TicTacToe/images
a partir del directorio de
instalacin del JDK.
En este caso se ha modificado el oyente del botn conmutador a un oyente de cambios. Su comportamiento
es similar y tambin es un evento semntico o de alto nivel.
Cuando se crea el cuadro de dilogo emergente como primer argumento se debe proporcionar el componente grfico, normalmente una ventana, del que depende dicho cuadro emergente. Como el oyente es una
clase interna al panel se podra haber tratado de utilizar thi s pero en ese caso representa la instancia del
oyente, que no es un componente grfico, y por tanto hay que usar la expresin Ca1cu1 adoraEuroMejorada. this
mediante la cual se accede a la instancia actual de la clase contenedora del oyente. Tambin podra haberse
utilizado nu 11 como argumento, pero en este caso no se tiene referencia sobre dnde posicionar el cuadro de
dilogo emergente.
-

cambio moneda

Cantidad a convertir
.
I

'" Calculadora

Eurosa Pesetas

- ~--

I ResuHado
15657,12
.
---_ ---_.~-j

134
11

-.

~&l~
........

11

)(

Ilorrar

Solo se pueden introducir digitos y el punto decimal

Figura 10.8. Captura de la ventana de la aplicacin que ya incorpora el botn Borrar con el incono de la cruz roja
y donde en el texto de los botones aparecen subrayadas las letras elegidas como mnemnicos, en el botn
de seleccin del tipo de cambio se sigue subrayando la primera letra e incluso cuando se cambia de etiqueta.
En la segunda captura se muestra el cuadro de dilogo emergente donde se indica que se ha producido un error
en el formato numrico.

Ejercicio 10.9:
Escriba una aplicacin grfica que cree un tablero de tamao de ocho por ocho con cuadros blancos y negros
similar al utilizado en el juego de las damas o del ajedrez. La aplicacin debe detectar la pulsacin sobre el
tablero e informar sobre el color del cuadro pulsado.

Interfaces grficas de usuario con Swing

----

..

Planteamiento: En este caso se hace que la clase especialice a un panel (Jpane 1) en el que se incluye un array
de botones que representarn
los cuadros. Para que todos los cuadros tengan el mismo tamao se elige que su
tamao preferido sea cuadrado, mediante setPreferredSi
zeO. Para representar los cuadros negros se establece su color de fondo a dicho color (setBackground(Color.BLACK).
Por defecto, el gestor de disposicin o
administrador
de diseo, en ingls LayoutManager,
del panel es el FlowLayout que organiza los componentes
en filas segn el orden en el que se han aadido al panel. Como interesa organizar los cuadros en forma de
tablero se cambia el gestor de disposicin por defecto por el gestor Gri dLayout(fi 1as, co 1umnas) que organiza
los componentes
en una matriz de tamao dado por las filas y las columnas.
En el programa principal se construye y se fijan las caractersticas
de la ventana principal de la aplicacin
a la que se aade un objeto de la clase que especializa el panel.
Solucin:
import javax.swing.*:
import java.awt.*:
import java.awt.event.*:
public class Tablero extends JPanel
public TableroCint tamao) (
JButton[][]
botones:
botones = new JButton[tamao][tamao]:
OyenteAcciones oyente = new OyenteAccionesCthis):
+-----.,1 Se crea un oyente de acciones y se
le pasa el panel como argumento.
for Cint i = O: i< botones.length:
i++)
for Cint j = O: j<botones[i].length:
j++){
botones[i][j]=
new JButtonC):
botones[i][j].setPreferredSizeCnew
OimensionC50. 50:
if CCCi +j+ 1) % 2) == O)(
botones [i ] [j] . setBackground CCo1or . BLACK):
Se crean los botones y se establece su
tamao preferidoa 50 por 50 pxeles.
}
botones[i][j].addActionListenerCoyente):
addCbotones[i][j]):
}
setLayoutCnew GridLayoutCtamao. tamao: +---------11 Se establece el gestor de disposicin
Gri dLayout para el panel.

LIF"'=--=--=--=--=--=--=--=--=--==iI

class

OyenteAcciones implements ActionListener{


private JPanel panel:
public OyenteAccionesCJPanel
panel){
this.panel
= panel:
}
public void actionPerformed
CActionEvent evento){
JButton boton = CJButton)evento.getSource():
+-------11 Se obtiene el colordel botn pulsado. 11
String color = "blanco":
if Cboton.getBackgroundC)==
Color.BLACK)
color = "negro":
JOpt i onPane. showMessageOi al og Cpane 1 . +-------11 Se muestra un cuadro de dilogoinformativo.
"Se ha pulsado un cuadro de color"
+ color.
"Cuadro pulsado".
JOptionPane. INFORMATION_MESSAGE):
+------.,1 Eliconoque se utilizaren el cuadro
emergente es la letraide informacin.
}

/ /OyenteAcciones

.r>>----

Programacin en Java 2

public static void mainCString[] args) {


JFrame ventana = new JFrameC "Tab 1ero") ;
Tablero tablero = new Tablero(8);
ventana.addCtablero);
ventana.packC);
ventana.setVisibleCtrue);

Comentario: El oyente de acciones tiene un constructor parametrizado que recibe como parmetro el panel en
el que est incluido el botn al que se escucha.
En el clculo del tamao de la ventana mediante pack () se tiene en cuenta el tamao preferido de cada uno
de los componentes que contiene
Si hubiera interesado adems del color cules son las coordenadas del cuadro pulsado se podra haber
creado una clase que especializara un JButton y tuviera dos atributos privados coordenadaX y coordenadaY.

Figura 10.9. Captura de la ventana de la aplicacin con el tablero inicial y con el cuadro informativo que emerge
despus de haber pulsado un cuadro de color negro.

Figura 10.10. Si no se hubiera asignado expresamente el gestor de disposicin por defecto en un panel, es el
FlowLayout quien lo hara y se hubiera obtenido una presentacin similar a la de esta captura.

11I

También podría gustarte