Java construye las interfaces gráficas del usuario mediante awt
1. PRACTICA
UN
EJERCICIO
PARA
UILIZAR
LA
INTERFASE
GRAFICA
JAVA
construye
las
interfaces
gráficas
del
usuario
mediante
AWT.
Para
crear
una
interfaz
gráfica
de
usuario
hace
falta
un
contenedor
que
es
la
ventana
donde
se
situarán
los
componentes
(como
botones,
cajas
de
texto,
etiquetas,
entre
otros)
y
donde
se
realizarán
los
dibujos.
Lo
podemos
relacionar
con
los
formularios,
los
componentes
como
tal
y
el
modelo
de
eventos,
que
son
las
respuestas
a
las
acciones
como
presionar
un
botón
o
hacer
un
click
de
ratón.
Cuando
el
usuario
realiza
una
determinada
acción,
se
produce
el
evento
correspondiente
que
el
SO
transmite
al
AWT,
este
crea
un
objeto
de
una
determinada
clase
de
evento
derivada
de
AWTEvent
y
el
evento
es
trasmitido
a
un
determinado
método
(procedimiento
o
función
de
la
clase)
para
que
lo
gestione.
El
componente
u
objeto
que
recibe
el
evento
debe
indicar
previamente
que
objeto
se
va
a
hacer
cargo
de
gestionar
el
evento.
El
modelo
de
eventos
de
JAVA
Está
basado
en
que
los
objetos
sobre
los
que
se
producen
los
eventos
o
event
sources
registran
los
objetos
que
los
gestionarán
(event
listener),
para
lo
cual
los
event
listener
habrán
de
2. disponer
de
los
métodos
adecuados.
Esos
métodos
se
llamarán
automáticamente
cuando
se
produzca
el
evento,
la
forma
de
garantizar
que
los
event
listener
disponen
de
los
métodos
apropidos
para
gestionar
los
eventos
es
obligarles
a
implementar
una
determinada
interface
Listener,
estas
interfaces
se
corresponden
con
los
tipo
oris
de
eventos
que
se
pueden
producir.
Proceso
para
crear
una
aplicación
interactiva
orientada
a
eventos
con
interfase
gráfica
de
usuario.
Determinar
los
componentes
que
van
a
constituir
la
interfase
de
usuario,
como
botones,
cajas
de
texto,
menús,
etc.
Crear
una
clase
para
la
aplicaci;on
que
contenga
la
función
main().
Crear
una
clase
Ventana,
sub
clase
de
Frame,
que
corresponda
al
evento
WindowClosing().
La
función
main()
deberá
crear
un
objeto
de
la
clase
ventana
para
colocar
los
componentes
y
mostrarla
por
pantalla
con
el
tamaño
y
la
posición
adecuados.
Añadir
al
objeto
Ventana
todos
los
componentes
y
menús
que
deba
contener.
Se
puede
hacer
un
constructor
de
la
Ventana
o
en
el
propio
método
main().
3. Definir
los
objetos
listener
(aquellos
que
respondan
a
eventos
cuyas
clases
implementarán
las
distintas
interfases
Listener
)
para
cada
uno
de
los
eventos
que
deban
estar
soportados.
En
aplicaciones
pequeñas,
el
propio
objeto
ventana
se
puede
ocupar
de
responder
a
los
eventos
de
sus
componentes.
En
programas
mas
grandes
se
puede
crear
uno
o
mas
objetos
de
clases
especiales
para
ocuparse
de
los
eventos.
Finalmente,
se
deben
implementar
los
métodos
de
las
interfases
listener
que
se
vayan
a
hacer
cargo
de
la
gestión
de
los
eventos.
Como
ejemplo
vamos
a
realizar
un
programa
en
JAVA
que
sirva
de
juego
para,
en
una
ventana
contenedora
de
botones
amarillos
y
rojos,
al
clickear
sobre
uno
de
ellos
aparezca
el
color
del
botón
seleccionado.
En
NetBeans
vamos
a
abrir
un
proyecto
identificándolo
con
el
nombre
Juego
y
lo
vamos
a
colocar
en
el
escritorio.
A
la
carpeta
SRC
le
vamos
a
añadir
dos
clases
adicionales
a
la
principal.
Una
clase
se
va
a
llamar
Botonera
y
la
otra
OyenteAcciones.
Vamos
a
importar
las
siguientes
librerías
Javax.swing.*
4. Java.awt.*
Java.awt.event.*
La
clase
Botonera
la
vamos
a
llenar
de
botones
amarillos
y
rojos.
Esta
clase
va
a
heredar
los
atributos
y
métodos
de
la
clase
JPanel
(por
lo
que
hay
que
colocar
que
la
clase
Botonera
extends
JPanel.
Podemos
entonces
declarar
Public
Botonera
(int
tamaño)
{
para
colocar
JButton
[][]
botones:
y
así
crear
una
matriz
de
botones,
se
instancia
botones
con
new
JButton
[tamaño][tamaño].
Se
crea
un
oyente
de
acciones
para
los
eventos
con
la
otra
clase
que
creamos
en
el
proyecto,
OyenteAcciones
oyente
=
new
OyenteAcciones(this):.
Con
un
doble
ciclo
se
crean
los
objetos
botones
For
(int
i=0;i<botones.length;i++){
For
(int
j=0;j<botones[i].length;i++){
Dentro
del
doble
ciclo
codificamos
botones[i][j]=new
JButton();
botones[i][j].setPreferredSize(newDimension(5
0,50));
if
((i+j+1)%2==0)
{
botones[i][j].setBackground(Color.BLACK);
}
5. De
esta
manera
coloreamos
los
botones
en
negro
de
manera
intercalada
con
el
color
por
defecto,
que
sería
el
blanco.
Fuera
del
doble
ciclo
codificamos
setLayout(new
GridLayout
(tamano,tamano));
En
java,
cuando
hacemos
ventanas,
la
clase
que
decide
cómo
se
reparten
los
botones
(Y
demás
controles)
dentro
de
la
ventana
se
llama
Layout.
Esta
clase
es
la
que
decide
en
qué
posición
van
los
botones
y
demás
componentes,
si
van
alineados,
en
forma
de
matriz,
cuáles
se
hacen
grandes
al
agrandar
la
ventana,
etc.
Otra
cosa
importante
que
decide
el
Layout
es
qué
tamaño
es
el
ideal
para
la
ventana
en
función
de
los
componentes
que
lleva
dentro.
Con
un
layout
adecuado,
el
método
pack()
de
la
ventana
hará
que
coja
el
tamaño
necesario
para
que
se
vea
todo
lo
que
tiene
dentro.
Este
pone
los
componentes
en
forma
de
matriz
(cuadrícula),
estirándolos
para
que
tengan
todos
el
mismo
tamaño.
El
GridLayout
es
adecuado
para
hacer
tableros,
calculadoras
en
que
todos
los
botones
son
iguales,
etc.
//
Creación
de
los
botones
JButton
boton[]
=
new
JButton[9];
for
(int
i=0;i<9;i++)
boton[i]
=
new
JButton(Integer.toString(i));
//
Colocación
en
el
contenedor
contenedor.setLayout
(new
6. GridLayout
(3,3));
//
3
filas
y
3
columnas
for
(int
i=0;i<9;i++)
contenedor.add
(boton[i]);
//
Añade
los
botones
de
1
en
1.
Terminamos
la
clase
con
private
Dimension
newDimension(int
i,
int
i0)
{
return
null;
}
Aquí
creamos
una
Dimension
cuya
anchura
y
altura
son
las
que
se
especifican
en
los
argumentos.
En
la
clase
OyenteAcciones
implementamos
un
oidor,
ya
que
tenemos
el
evento
que
va
a
activar
a
una
caja
de
mensajes
para
indicar
el
color
del
botón.
public
class
OyenteAcciones
implements
ActionListener
{
private
JPanel
panel;
public
OyenteAcciones(JPanel
panel){
this.panel=panel;
}
public
void
actionPerformed(ActionEvent
evento)
{
7.
JButton
boton=(JButton)
evento.getSource();
String
color="BLANCO";
if
(boton.getBackground()==Color.BLACK)
color="NEGRO";
JOptionPane.showMessageDialog(panel,
"Se
ha
pulsado
un
boton
de
color
"+
color,
"Boton
Pulsado",
JOptionPane.INFORMATION_MESSAGE);
}
}
Por
último,
en
el
main
java
creamos
la
botonera
y
ps
colocamos
en
la
ventana
contenedora
public
static
void
main(String[]
args)
{
JFrame
ventana=new
JFrame("BOTONERA");
Botonera
botonera
=
new
Botonera(18);
8.
ventana.add(botonera);
ventana.pack();
ventana.setVisible(true);
}
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
Contenedores
y
gestión
de
los
layout
En
la
lección
anterior
hemos
visto
como
introducir
en
nuestras
aplicaciones
y
en
nuestros
apliques
unas
etiquetas
y
unos
botones.
Para
hacerlo
hemos
utilizado
unos
contenedores
y
unos
layout
sin
saber
cómo
funcionaban.
En
este
lección
analizeremos
sus
funcionamientos
y
cómo
aprovecharlos
para
mejorar
nuestras
interfaces.
Empezamos
con
describir
la
clase
Container
del
paquete
java.awt.
Es
una
extensión
de
la
clase
Component
de
la
que
proceden
todos
los
componentes
GUI
y,
en
realidad,
éste
mismo
es
un
componente
GUI.
9.
Un
Container
es
un
contenedor
para
los
objetos
GUI
y,
por
lo
tanto,
también
para
los
demás
container.
Se
utiliza
junto
a
un
Layout
Manager
y
permite
que
abarquen
más
de
un
GUI
(y
Contenedores),
permitiendo
que
aparezcan
varios
objetos
en
nuestras
interfaces.
Vemos
qué
contiene
la
clase.
Container()
,
es
el
único
constructor
de
la
clase.
Unos
métodos:
Component
add(Component
comp),
añade
el
componente
al
final
del
contenedor.
Component
add(Component
comp,
int
index),
añade
el
componente
en
la
posición
indicada
por
el
contenedor.
void
add(Component
comp,
Object
constraints)
e
void
add(Component
comp,
Object
constraints,
int
index)
,
como
antes,
lo
único
es
que
especifica
unas
constantes
para
el
componente
que
se
ha
introducido.
Component
add(String
name,
Component
comp),
añade
al
contenedor
el
componente
y
le
da
un
nombre.
10. void
addContainerListener(ContainerListener
l),
ajusta
el
ContainerListener
que
escuchará
los
sucesos
que
han
ocurrido
en
el
contenedor.
void
doLayout(),
provoca
la
disposición
de
los
componentes
en
el
contenedor.
Component
findComponentAt(int
x,
int
y),
devuelve
el
componente
que
se
encuentra
en
la
posición
especificada
del
contenedor
(posición
gráfica).
Component
findComponentAt(Point
p)
,
devuelve
el
componente
que
se
encuentra
en
la
posición
especificada
del
contenedor
(posición
gráfica).
float
getAlignmentX(),
devuelve
el
ajuste
de
líneas
a
lo
largo
del
eje
X
del
contenedor.
float
getAlignmentY(),
devuelve
el
ajuste
de
líneas
a
lo
largo
del
eje
Y
del
contenedor.
Component
getComponent(int
n),
devuelve
el
enésimo
componente
introducido
en
el
contenedor.
Component
getComponentAt(int
x,
int
y),
devuelve
el
componente
que
se
encuentra
en
la
posición
especificada
del
contenedor
(posición
gráfica).
Component
getComponentAt(Point
p),
devuelve
el
componente
que
se
encuentra
en
la
posición
especificada
del
contenedor
(posición
gráfica).
int
getComponentCount()
,
da
el
número
de
componentes
introducidos
en
el
contenedor.
11. Component[]
getComponents(),
da
todos
los
componentes
introducidos
en
el
contenedor.
Insets
getInsets(),
da
un
objeto
Insets
para
el
contenedor.
Este
objeto
representa
el
tamaño
(gráfico=
del
contenedor.
LayoutManager
getLayout(),
devuelve
el
LayuotManager
asociado
al
contenedor.
EventListener[]
getListeners(Class
listenerType),
devuelve
todos
los
oyentes
de
sucesos
al
contenedor.
Dimension
getMaximumSize(),
devuelve
el
tamaño
máximo
que
puede
tener
el
contenedor.
Dimension
getMinimumSize(),
devuelve
el
tamaño
mínimo
que
puede
tener
el
contenedor.
Dimension
getPreferredSize(),
devuelve
el
tamaño
preferido
por
el
contenedor.
void
list(PrintStream
out,
int
indent),
imprime
el
listado
de
los
componentes
introducidos
en
el
contenedor,
sobre
un
stream
de
output.
void
list(PrintWriter
out,
int
indent),
imprime
en
una
impresora
los
componentes
introducidos
en
el
contenedor.
void
paint(Graphics
g),
dibuja
el
contenedor.
La
paint
es
una
función
muy
importante.
Veremos
cómo
definirla
para
dibujar
en
una
ventana.
void
paintComponents(Graphics
g).
dibuja
todos
los
componentes
del
contenedor.
void
print(Graphics
g),
imprime
el
contenedor
(el
aspecto
gráfico).
12. void
printComponents(Graphics
g),
imprime
todos
los
componentes
introducidos
en
el
contenedor
(sus
aspectos
gráficos).
void
remove(Component
comp),
elimina
el
componente
especificado
por
el
contenedor.
void
remove(int
index),
aparta
el
componente
que
se
encuentra
en
la
posición
especificada
en
el
contenedor.
void
removeAll(),
aparta
todos
los
componentes
introducidos
en
el
contenedor.
void
removeContainerListener(ContainerListener
l),
elimina
el
oyente
de
sucesos
para
containers
de
este
container.
void
setFont(Font
f),
ajusta
las
Font
utilizadas
por
el
texto
en
el
contenedor.
void
setLayout(LayoutManager
mgr),
asocia
al
contenedor
un
gestor
de
layout.
void
update(Graphics
g),
vuelve
a
dibujar
el
contenedor.
void
validate(),
anula
el
contenedor
y
sus
componentes.
Introduciendo
componentes
en
el
contenedor,
como
en
el
ejemplo
sucesivo,
nos
damos
cuenta
de
que
sólo
el
último
será
visualizado.
Esto
ocurre
porque
no
hemos
dado
gestor
de
Layout.
En
el
caso
de
applet,
en
cambio,
el
LayoutManager
de
default
es
el
FlowLayout.
13. import
java.awt.*;
public
class
Contenedor
extends
Frame
{
Label
l1=new
Label("Etiqueta1");
Label
l2=new
Label("Etiqueta2");
Label
l3=new
Label("Etiqueta3");
Label
l4=new
Label("Etiqueta4");
Label
l5=new
Label("Etiqueta5");
public
Contenedor()
{
//
uso
add,
porque
el
Frame
es
una
extensión
de
Window,
que
a
su
//
vez
amplía
Container.
add(l1);
add(l2);
add(l3);
add(l4);
add(l5);
doLayout();
pack();
show();
}
public
static
void
main(String
[]
arg)
{
14.
new
Contenedor();
}
}
Por
lo
tanto,
vemos
cómo
introducir
un
gestor
de
Layout
en
el
contenedor.
El
método
de
la
clase
container
que
lo
permite
es
void
setLayout(LayoutManager
mgr).
No
nos
queda
que
ver
cómo
es
el
objeto
de
tipo
LayoutManager.
LayoutManager
es
una
interfaz.
De
las
clases
que
la
implementan
analizaremos
GridLayout,
FlowLayout.
Hay
otra
interfaz
llamada
LayoutManager2,
que
amplía
ésta
y
que
tiene
otras
clases
que
la
implementan.
De
éstas
veremos:
CardLayout,
BorderLayout,
GridBagLayout,
BoxLayout,
OverlayLayout.
Por
lo
tanto,
en
el
método
setLayout
(…)
podemos
utilizar
como
parámetro
un
objeto
de
estas
clases.
Llegados
a
este
punto,
tenemos
que
comprender
qué
diferencia
hay
entre
los
layout
manager.
El
FlowLayout
deja
colocar
los
componentes
de
un
contenedor
de
la
izquierda
hacia
la
derecha
15. en
una
sóla
línea.
Para
utilizar
el
LayoutManager
FlowLayout
del
ejemplo
precedente
basta
con
invocar
el
método
setLayout
con
parámetro
new
FlowLayout(),
y
después
los
componentes
se
introducen
automáticamente,
de
la
add
de
la
derecha
hacia
la
izquierda
en
la
misma
línea.
import
java.awt.*;
public
class
ContEFL
extends
Frame
{
Label
l1=new
Label("Etiqueta1");
Label
l2=new
Label("Etiqueta2");
Label
l3=new
Label("Etiqueta3");
Label
l4=new
Label("Etiqueta4");
Label
l5=new
Label("Etiqueta5");
public
ContEFL()
16. {
//
uso
add,
porque
el
Frame
es
una
extensión
de
Window,
que
a
su
//
vez
amplía
Container.
setLayout(new
FlowLayout());
add(l1);
add(l2);
add(l3);
add(l4);
add(l5);
pack();
show();
}
public
static
void
main(String
[]
arg)
{
new
ContEFL();
}
}
La
ventana
que
sale
es:
17.
El
GridLayout
permite
colocar
los
componentes
en
un
contenedor
como
si
se
dispusieran
en
una
plantilla.
Todos
los
componentes
tendrán
el
mismo
tamaño.
La
clase
tiene
tres
constructores,
uno
sin
parámetros
que
crea
una
planilla
con
1
línea,
prácticamente
un
FlowLayout,
y
otros
dos
que
permiten
especificar
el
tamaño
de
la
planilla.
El
ejemplo
anterior
cambia
de
esta
forma:
import
java.awt.*;
18.
public
class
ContEGL
extends
Frame
{
Label
l1=new
Label("Etiqueta1");
Label
l2=new
Label("Etiqueta2");
Label
l3=new
Label("Etiqueta3");
Label
l4=new
Label("Etiqueta4");
Label
l5=new
Label("Etiqueta5");
public
ContEGL()
{
//
uso
add,
poruqe
el
Frame
es
una
extensión
de
Window,
que
a
su
//
vez
amplía
Container.
setLayout(new
GridLayout(2,3));
add(l1);
add(l2);
add(l3);
add(l4);
add(l5);
pack();
show();
}
19. public
static
void
main(String
[]
arg)
{
new
ContEGL();
}
}
La
ventana
es
la
siguiente:
El
LayoutManager
CardLayout
permite
visualizar
los
componentes
diferentes
en
plazos
de
tiempo
diferentes,
es
decir,
que
visualiza
sólo
un
componente
a
la
vez.
Sin
embargo
el
componete
visualizado
se
puede
cambiar.
Hay
aquí
un
ejemplo
del
uso
de
CardLayout
import
java.awt.*;
import
java.awt.event.*;
public
class
ContECL
extends
Frame
{
22.
new
ContECL();
}
}
El
resultado
de
los
ejemplos
son
las
siguientes
ventanas:
23.
Muestran
como
las
cinco
etiquetas
aparecen
en
la
misma
posición
en
plazos
de
tiempo
diferentes.
Notad
que
en
el
ejemplo
no
se
han
utilizado
los
demás
gestores
de
Layout
para
que
se
puedan
introducir
los
botones
Próximo
y
Anterior.
BorderLayout
es
uno
de
los
gestores
de
Layout
más
utilizados.
Permite
introducir
en
un
contenedor
cinco
componentes,
uno
al
Norte,
uno
al
Sur,
uno
al
Este,
uno
al
Oeste
y
otro
al
Centro.
El
tamaño
del
contenedor
lo
establecerá
el
componente
central.
Las
cinco
posiciones
están
indicadas
por
los
contenedores
de
la
clase:
BorderLayout.NORTH
BorderLayout.SOUTH
24. BorderLayout.EAST
BorderLayout.WEST
BorderLayout.CENTER
hay
aquí
un
ejemplo
del
uso
de
BorderLayout.
He
cambiado
los
colores
de
fondo
de
las
etiquetas
para
que
se
vea
el
componente
entero.
import
java.awt.*;
public
class
ContEBL
extends
Frame
{
Label
l1=new
Label("Etiqueta
al
Norte",Label.CENTER);
Label
l2=new
Label("Etiqueta
al
Sur",Label.CENTER);
Label
l3=new
Label("Etiqueta
al
Este",Label.CENTER);
Label
l4=new
Label("Etiqueta
al
Oeste",Label.CENTER);
Label
l5=new
Label("Etiqueta
al
Centro",Label.CENTER);
public
ContEBL()
{
//
uso
add
porque
el
Frame
es
una
extensión
de
Window,
que
a
su
//
vez
amplía
Container.
26.
El
resultado
es:
Hay
también
otros
gestores
de
Layout,
que
no
analizaremos,
y
que,
sin
embargo,
podéis
estudiar
junto
a
éstos
en
la
documentación
oficial
de
las
Java
Development
Kit.