Вы находитесь на странице: 1из 30

Introduccion a componentes Swing

H. Tejeda

Mayo 2016

Indice

1. Introduccion 1

2. Clase JFrame 2

3. Clase JLabel 6

4. Manejador de diseno 9

5. Extension de la clase JFrame 11

6. Clases de entrada 13

7. Programacion de manejo de eventos 17

8. Receptores de eventos 21

9. Clases para seleccion 23

1. Introduccion

Las aplicaciones son mas amigables al usuario cuando estas contienen componentes interfaz de
usuario o UI (User Interface). Los componentes UI son botones, campos de texto, y otros con
los cuales el usuario puede interactuar. Los creadores de Java han empacado una cantidad de
componentes preescritos en el paquete Swing. Los componentes Swing son elementos UI tales
como cuadros de dialogo y botones; se reconocen porque sus nombres inician con J.

Nota. Los componentes Swing fueron nombrados por un estilo musical que fue popular alla en 1940.
El nombre implica que los componentes tienen estilo y dinamismo. Las clases Swing son parte de un

1
conjunto mas general de capacidades de programacion UI que son llamadas las clases de fundacion
Java o JFC (Java Foundation Classes). JFC incluye las clases componentes Swing y algunas clases
del paquete java.awt.

Nota. En las primeras versiones de Java, los componentes tenan nombres simples, tales como Frame
y Button. Los componentes no tenan una apariencia consistente cuando se usaban con diferentes
navegadores y sistemas operativos. Cuando los programadores de Java disenaron clases nuevas y
mejoradas necesitaron nuevos nombres para las clases, as que usaron una J precediendo cada nuevo
nombre de clase. Por lo tanto, los componentes Swing tienen nombres como JFrame, JButton,
JScrollbar, JOptionPane, etc.

Los componentes UI son tambien llamados controles o widgets (reproductores). Cada componente
Swing es un descendiente de un JComponent, el cual a su vez hereda desde la clase java.awt.Con-
tainer. Para usar los componentes UI Swing y sus metodos se debe insertar la sentencia import
javax.swing.* al inicio del programa, de esta forma se importa el paquete. La x en el nombre del
paquete representa la extension de las especificaciones del lenguaje Java original.

Nota. Casi todos los componentes Swing se dice que son componentes peso ligero porque estan
escritos completamente en Java y no descansan en el codigo del sistema operativo local. Esto significa
que los componentes no son sobrecargados teniendo que interactuar con el sistema operativo.
Algunos componentes Swing, como JFrame, se conocen como componentes peso pesado porque
requieren interactuar con el sistema operativo local. Un componente ligero reusa la ventana nativa
de su ancestro mas cercano peso pesado; un componente peso pesado tiene su propia ventana nativa
opaca. Los unicos componentes peso pesado usados en Swing son JFrame, JDialog, JWindow,
JApplet, awt.Component, awt.Container, y JComponent.

Cuando se usan componentes Swing estos son puestos, generalmente, en contenedores. Un con-
tenedor es un tipo de componente que guarda otros componentes para que este grupo pueda ser
tratado como una sola entidad. Los contenedores estan definidos en la clase Container. Frecuen-
temente, un contenedor toma la forma de una ventana que puede ser arrastrada, redimensionada,
minimizada, restaurada, y cerrada.

La clase Component es una hija de la clase Object, y la clase Container es una hija de la clase
Component. Por lo tanto, cada objeto Container es un Component, y cada objeto Component
es un Object. La clase Window es una hija de Container. Los programadores de Java usan poco
los objetos Window porque la subclase Frame de Window y su subclase JFrame componente Swing,
permiten crear objetos mas utiles. Los objetos Window no tienen barra de ttulo, ni bordes.

2. Clase JFrame

Se crea un JFrame para poner otros objetos dentro para ser mostrados. Enseguida se muestra el
arbol de herencia de la clase JFrame para mostrar la relacion con sus ancestros.

java.lang.Object

2
|
+--java.awt.Component
|
+---java.awt.Container
|
+---java.awt.Window
|
+---java.awt.Frame
|
+---javax.swing.JFrame

La clase JFrame tiene cuatro constructores:

JFrame() construye un nuevo marco que inicialmente es invisible y no tiene ttulo.

JFrame(String ttulo) crea un nuevo JFrame inicialmente invisible con el ttulo indicado.

JFrame(GraphicsConfiguration gc) crea un JFrame en el GraphicsConfiguration de un


dispositivo de pantalla sin ttulo.

JFrame(String ttulo, GraphicsConfiguration gc) crea un JFrame con el ttulo especi-


ficado y el GraphicsConfiguration dado de una pantalla.

Se construye un JFrame como cualquier otro objeto, usando el nombre de la clase, un identificador, el
operador de asignacion, el operador new, y una llamada al constructor. Las siguientes dos sentencias
construyen dos JFrame: uno con el ttulo Hola y otro sin ttulo.

JFrame primerMarco = new JFrame("Hola");


JFrame segundoMarco = new JFrame();

Ya teniendo los objetos JFrame creados, se pueden usar algunos de los metodos utiles dados en el
cuadro 1.

Suponiendo que se ha declarado un JFrame llamado primerMarco, se pueden usar las siguientes
sentencias para poner el tamano del objeto primerMarco a 250 pxeles horizontalmente por 100
verticalmente y pone el ttulo del JFrame para mostrar un argumento String. Los pxeles son
los elementos de imagen, o pequenos puntos de luz, que hacen la imagen en el monitor de la
computadora.

primerMarco.setSize(250, 100);
primerMarco.setTitle("Mi marco");

Cuando se pone el tamano de un JFrame, no se tiene el area completa disponible para usarla porque
parte del area es usada por la barra de ttulo y los bordes del JFrame.

La aplicacion JFrame1, codigo 1, muestra una aplicacion que crea un JFrame pequeno y vaco.

3
Metodo Descripcion
void setTitle(String) Pone el ttulo del JFrame usando el argumento
String.
void setSize(int, int) Fija el tamano de un JFrame en pxeles con el ancho
y alto como argumento.
void setSize(Dimension) Fija el tamano de un JFrame usando un objeto
Dimension; el constructor Dimension(int, int)
crea un objeto que representa un ancho y una al-
tura.
String getTitle() Regresa el ttulo de un JFrame.
void setResizable(boolean) Pone el JFrame para que sea redimensionable pa-
sando true al metodo, con false es no redimen-
sionable.
boolean isResizable() Regresa true o false para indicar si el JFrame es
redimensionable.
void setVisible(boolean) Hace un JFrame visible usando el argumento boo-
leano true e invisible usando el argumento false.
void setBounds(int, int, int, Sobreescribe el comportamiento por defecto para
int) que el JFrame sea posicionado en la esquina su-
perior izquierda en la pantalla del escritorio de la
computadora; los primeros dos argumentos son las
posiciones horizontal y vertical de la esquina supe-
rior izquierda del JFrame en el escritorio, y los dos
argumentos finales fijan el ancho y la altura.

Cuadro 1: Metodos utiles heredados por la clase JFrame.

4
1 import j a v a x . swing . ;
2 public c l a s s JFrame1 {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 JFrame unMarco = new JFrame ( Primer Marco ) ;
5 unMarco . s e t S i z e ( 2 5 0 , 1 0 0 ) ;
6 unMarco . s e t V i s i b l e ( true ) ;
7 }
8 }

Codigo 1: Aplicacion JFrame1.

La aplicacion JFrame1, codigo 1, crea un JFrame. Este se parece a marcos que se han visto cuando
se usan programas UI diferentes. La razon para usar objetos marco similares es porque los usuarios
ya estan familiarizados con el ambiente de marcos. Cuando los usuarios ven marcos esperan ver una
barra de ttulo en la cima con informacion de texto. Tambien esperan ver los botones de minimizar,
maximizar o restaurar, y cerrar en alguna de la esquinas superiores del marco. Muchos usuarios
suponen que pueden cambiar el tamano del marco arrastrando sus bordes o reposicionar la ventana
en la pantalla arrastrando la barra de titulo de la ventana a una nueva localidad.

En la aplicacion del codigo 1, las tres sentencias en el metodo main() son importantes. Despues de
instancia unMarco, se necesita hacer setVisible(true) para poder ver el JFrame, y tambien poner
su tamano ya que de otra forma solo la barra de ttulo del JFrame es visible porque el tamano de este
es 0 x 0 por defecto. Una razon por la cual el JFrame es invisible es porque este se podra construir
en segundo plano mientras otras acciones estan ocurriendo y quizas se deseara hacer visible mas
tarde. Algunos programadores usan el metodo show() en vez del metodo setVisible().

Cuando un usuario cierra un JFrame pulsando en el boton cerrar en alguna de la esquinas supe-
riores, el comportamiento por defecto para el JFrame es ocultarse y para la aplicacion continuar
ejecutandose. Esto tiene sentido cuando hay otras tareas por completar para el programa despues
de que el marco principal fue cerradopor ejemplo, mostrar marcos adicionales, cerrar archivos
abiertos de datos, o imprimir un reporte de actividad. Cuando un JFrame sirve como una aplicacion
de Swing se quiere que el programa termine cuando el usuario pulsa el boton cerrar. Para cambiar el
comportamiento se puede llamar al metodo setDefaultCloseOperation() de JFrame con alguno
de los siguientes cuatro valores como argumento:

JFrame.EXIT ON CLOSE termina el programa cuando el JFrame es cerrado.

WindowConstants.DISPOSE ON CLOSE cierra el marco, dispone el objeto JFrame, y mantiene


en ejecucion la aplicacion.

WindowConstants.DO NOTHING ON CLOSE mantiene el JFrame abierto y continua ejecutando-


se. En otras palabras, deshabilita el boton cerrar.

WindowConstants.HIDE ON CLOSE cierra el JFrame y continua ejecutandose; este es el com-


portamiento por defecto.

Cuando se ejecuta una aplicacion en cual se ha olvidado salir cuando el JFrame es cerrado, se puede
terminar el programa tecleando CTRL+C.

5
Personalizacion de la apariencia de un JFrame

La apariencia de un JFrame es dada por el sistema operativo en el cual el programa este eje-
cutandose. El diseno de los elementos que controlan el marco se parecen y se comportan como lo
hace cualquier otra aplicacion grafica. Los botones y el cono, en el caso de que se muestre, son
conocidos como decoraciones ventana; por defecto las decoraciones ventana son proporcionadas
por el sistema operativo. Se puede pedir que el mirar y sentir de Java de las decoraciones para un
marco. Un mirar y sentir es la apariencia y comportamiento por defecto de cualquier interfaz de
usuario.

Opcionalmente, se puede poner el mirar y sentir de un JFrame usando el metodo setDefaultLook-


AndFeelDecorated(). La aplicacion JFrame2, codigo 2, hace una llamada a este metodo en la lnea
4.
1 import j a v a x . swing . ;
2 public c l a s s JFrame2 {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 JFrame . s e t D e f a u l t L o o k A n d F e e l D e c o r a t e d ( true ) ;
5 JFrame unMarco = new JFrame ( Segundo Marco ) ;
6 unMarco . s e t S i z e ( 2 5 0 , 1 0 0 ) ;
7 unMarco . s e t V i s i b l e ( true ) ;
8 }
9 }

Codigo 2: La clase JFrame2.

Puede ser que al usar el metodo setDefaultLookAndFeelDecorated() el sistema operativo impida


modificar su apariencia, como en Mac OS X.

Actividad 1. Escribir una aplicacion grafica que muestre en el ttulo de la ventana su nombre y
tenga un tamano cuadrado. Ademas la aplicacion debe terminar cuando se cierre el marco.

3. Clase JLabel

Uno de los componentes que se podra poner en un JFrame es un JLabel. JLabel es una clase Swing
incorporada que tiene texto que se quiere mostrar. La jerarqua de herencia de la clase JLabel se
muestra enseguida:

java.lang.Object
|
+--java.awt.Component
|
+---java.awt.Container
|
+---javax.swing.JComponent
|
+---javax.swing.JLabel

6
Los constructores para la clase JLabel incluyen los siguientes:

JLabel() crea una instancia JLabel sin imagen con una cadena vaca para el ttulo.

JLabel(Icon imagen) crea una instancia JLabel con la imagen especificada.

JLabel(Icon imagen, int alineacionHorizontal) crea una instancia JLabel con la ima-
gen especificada y la alineacion horizontal.

JLabel(String texto) crea una instancia JLabel con el texto especificado.

JLabel(String texto, Icon imagen, int alineacionHorizontal) crea una instancia J-


Label con el texto, la imagen, y la alineacion horizontal especificados.

JLabel(String texto, int alineacionHorizontal) crea una instancia JLabel con el tex-
to y la alineacion horizontal indicados.

Se puede crear un JLabel llamado saludo que tenga las palabras Buen da con la siguiente
sentencia:

JLabel saludo = new JLabel("Buen da");

Para agregar el objeto saludo al objeto JFrame llamado unMarco usando el metodo add() como
sigue:

unMarco.add(saludo);

La aplicacion JFrame3, codigo 3, muestra la creacion de JFrame al que enseguida se le pone su


tamano y la operacion de cierre. Luego un JLabel es creado y agregado al JFrame.

1 import j a v a x . swing . ;
2 public c l a s s JFrame3 {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 f i n a l int ANCHO MARCO = 2 5 0 ;
5 f i n a l int ALTO MARCO = 1 0 0 ;
6 JFrame unMarco = new JFrame ( T e r c e r Marco ) ;
7 unMarco . s e t S i z e (ANCHO MARCO, ALTO MARCO) ;
8 unMarco . s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
9 JLabel s a l u d o = new JLabel ( Buen da ) ;
10 unMarco . add ( s a l u d o ) ;
11 unMarco . s e t V i s i b l e ( true ) ;
12 }
13 }

Codigo 3: La clase JFrame3.

La contraparte del metodo add() es el metodo remove(). La siguiente sentencia quita saludo de
unMarco:

7
unMarco.remove(saludo);

Si se agrega, o quita un componente de un contenedor despues de que este se hizo visible, se debera
tambien llamar los metodos invalidate(), validate() y repaint() para ver los resultados de
las acciones. Cada uno realiza funciones ligeramente diferentes pero las tres juntas garantizan que
el resultado de cambios en el diseno tomaran efecto. Los metodos invalidate() y validate() son
parte de la clase Container, y repaint() es parte de la clase Component.

Nota. Si se agrega o quita un componente en un objeto JFrame durante la construccion, no se


tiene que llamar al metodo repaint() si despues se modifica el componente, como por ejemplo,
cambiando el texto. Solo se necesita llamar a repaint() si se agrega o quita un componente despues
de la construccion.

Se puede cambiar el texto en un JLabel usando el metodo setText() de la clase Component con
el objeto JLabel y pasandole un String. El siguiente codigo cambia el valor mostrado en el JLabel
saludo:

saludo.setText("Suerte");

Se puede recuperar el texto en un JLabel, o cualquier otro Component, usando el metodo getText(),
el cual regresa el String guardado actualmente.

Cambiar la fuente de un JLabel

Java proporciona una clase Font para crear un objeto que guarde el tipo de fuente, y la informacion
del estilo y del tamano de la fuente. El metodo setFont() requiere un argumento objeto Font.
Para construir un objeto Font, se necesitan tres argumentos: tipo de fuente, estilo, y tamano en
puntos.

El argumento tipo de fuente para el constructor Font es un String representando una


fuente. Las fuentes comunes tienen nombres como Arial, Century, Monospaced, y Times New
Roman. El argumento tipo de fuente es solo una peticion; el sistema operativo en el cual el
programa se ejecuta podra no tener acceso, y si es necesario, este lo sustituye con una fuente
por defecto.

El argumento estilo aplica un atributo al texto mostrado y es uno de tres valores: Font.PLAIN,
Font.BOLD, o Font.ITALIC.

El argumento tamano en puntos es un entero que representa aproximadamente 1/72 de


una pulgada. El texto impreso es generalmente de 12 puntos; una cabecera podra ser de 30
puntos.

Nota. En impresion, el tamano de punto define una medida entre lneas de texto en un docu-
mento de texto con interlineado simple. Java adopta la convencion de que un punto en una
pantalla es equivalente a una unidad en las coordenadas del usuario.

8
Para dar a un objeto JLabel una nueva fuente, se puede crear un objeto Font, como en el siguiente:

Font fuenteCabecera = new Font("Monospaced", Font.BOLD, 36);

Luego se usa el metodo setFont() para asignar el objeto Font al objeto JLabel con una sentencia
como la siguiente:

saludo.setFont(fuenteCabecera);

La aplicacion JFrame4, codigo 4, muestra en las lneas 2, 3, 7, 8, y 12 los cambios que se hicieron
a JFrame3 para usar otro tipo de fuente con diferente tamano y apariencia.

1 import j a v a x . swing . ;
2 import j a v a . awt . ;
3 public c l a s s JFrame4 {
4 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
5 f i n a l int ANCHO MARCO = 2 5 0 ;
6 f i n a l int ALTO MARCO = 1 0 0 ;
7 Font f u e n t e = new Font ( A r i a l , Font .BOLD, 3 6 ) ;
8 JFrame unMarco = new JFrame ( Cuarta Ventana ) ;
9 unMarco . s e t S i z e (ANCHO MARCO, ALTO MARCO) ;
10 unMarco . s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
11 JLabel s a l u d o = new JLabel ( Buen da ) ;
12 saludo . setFont ( fuente ) ;
13 unMarco . add ( s a l u d o ) ;
14 unMarco . s e t V i s i b l e ( true ) ;
15 }
16 }

Codigo 4: La clase JFrame4.

No es obligatorio proporcionar un identificador para un objeto Font. Se pudo omitir la lnea 7 en el


codigo 4 y poner la fuente en saludo con la siguiente sentencia, la cual usa un objeto Font anonimo:

saludo.setFont(new Font("Arial", Font.BOLD, 36));

Despues de crear un objeto Font, se puede crear un nuevo objeto con un tipo y tamano diferente
usando el metodo deriveFont() con los argumentos apropiados. Por ejemplo, las siguientes dos
sentencias crean el objeto fuenteCabecera y el fuenteCuerpoTexto que esta basado en el primer
objeto:

Font fuenteCabecera = new Font("Arial", Font.BOLD, 36);


Font fuenteCuerpoTexto = fuenteCabecera.deriveFont(Font.PLAIN, 14);

4. Manejador de diseno

Cuando se quiere agregar multiples componentes a un JFrame u otro contenedor, usualmente se re-
quiere proporcionar instrucciones para la colocacion de los componentes. En la aplicacion JFrame5,

9
codigo 5, dos JLabel son creados y agregados a un JFrame en las sentencias de las lneas 1112.

1 import j a v a x . swing . ;
2 public c l a s s JFrame5 {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 f i n a l int ANCHO MARCO = 2 5 0 ;
5 f i n a l int ALTO MARCO = 1 0 0 ;
6 JFrame unMarco = new JFrame ( Quinta Ventana ) ;
7 unMarco . s e t S i z e (ANCHO MARCO, ALTO MARCO) ;
8 unMarco . s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
9 JLabel s a l u d o = new JLabel ( Hola ) ;
10 JLabel s a l u d o 2 = new JLabel ( Quien e r e s ? ) ;
11 unMarco . add ( s a l u d o ) ;
12 unMarco . add ( s a l u d o 2 ) ;
13 unMarco . s e t V i s i b l e ( true ) ;
14 }
15 }

Codigo 5: La clase JFrame5.

Cuando se ejecuta la aplicacion JFrame5 solo la ultima JLabel que fue agregada es visible, a pesar
de que se agregaron dos etiquetas al marco. La segunda JLabel fue puesta encima de la primera,
tapandola completamente. Si se continuan agregando mas JLabel en el programa, solo la ultima
agregada al JFrame sera visible.

Para colocar multiples componentes en posiciones especificadas en un contenedor de tal forma que
no se oculten entre ellas, se debe usar explcitamente un manejador de diseno, una clase que
controla el posicionamiento de componentes. El comportamiento por defecto de un JFrame es dado
por un manejador llamado BorderLayout. Un manejador BorderLayout divide un contenedor en
regiones. Cuando no se indica una region en la cual un componente se coloca, este se coloca siempre
en el centro, y si estaba otro componente, lo tapa.

Al agregar componentes usando el manejador FlowLayout, estos son colocados en un renglon, y


cuando el renglon se llena, los componentes automaticamente se ponen en el siguiente renglon.

Tres constantes estan definidas en la clase FlowLayout para indicar como los componentes son
posicionados en cada renglon de su contenedor. Estas son FlowLayout.LEFT, FlowLayout.RIGHT,
y FlowLayout.CENTER. Para crear un manejador de diseno llamado flujo que posicione los com-
ponentes a la derecha, se usa la siguiente sentencia:

FlowLayout flujo = new FlowLayout(FlowLayout.RIGHT);

En caso de no indicar como los componentes son distribuidos, por defecto estos son centrados en
cada renglon.

Una vez que el manejador de diseno ha sido creado entonces puede ser puesto al objeto JFrame
haciendo lo siguiente:

unMarco.setLayout(flujo);

Se puede compactar el codigo usando un objeto FlowLayout anonimo con:

10
unMarco.setLayout(new FlowLayout(FlowLayout.RIGHT));

La aplicacion JFrame6, codigo 6, ha puesto el manejador de diseno del JFrame para que componentes
multiples sean visibles.

1 import j a v a x . swing . ;
2 import j a v a . awt . ;
3 public c l a s s JFrame6 {
4 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
5 f i n a l int ANCHO MARCO = 2 5 0 ;
6 f i n a l int ALTO MARCO = 1 0 0 ;
7 JFrame unMarco = new JFrame ( Sexta Ventana ) ;
8 unMarco . s e t S i z e (ANCHO MARCO, ALTO MARCO) ;
9 unMarco . s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
10 JLabel s a l u d o = new JLabel ( Hola ) ;
11 JLabel s a l u d o 2 = new JLabel ( Quien e r e s ? ) ;
12 unMarco . s e t L a y o u t (new FlowLayout ( FlowLayout . RIGHT ) ) ;
13 unMarco . add ( s a l u d o ) ;
14 unMarco . add ( s a l u d o 2 ) ;
15 unMarco . s e t V i s i b l e ( true ) ;
16 }
17 }

Codigo 6: La clase JFrame6.

Al ejecutar la aplicacion JFrame6 se deben ver los dos JLabel, uno al lado del otro porque se usa
un FlowLayout. Si hubiera mas JLabel u otros componentes, estos seran colocados continuamente
lado por lado a traves del JFrame hasta que no haya mas espacio.

5. Extension de la clase JFrame

Se puede instanciar un objeto JFrame simple dentro del metodo main() de una aplicacion o en
cualquier otro metodo de cualquier clase que sea escrita. Alternativamente, se puede crear su
propia clase que descienda de la clase JFrame. La ventaja de crear una clase hija desde JFrame es
la posibilidad de poder poner las propiedades del JFrame dentro del constructor de objetos; luego,
cuando se crea su objeto hijo JFrame, este es dotado automaticamente con las caractersticas que
se hayan especificado, tales como el tamano, el ttulo, y la operacion de cierre por defecto.

Para crear una clase hija se usa la palabra reservada extends en la cabecera de la clase, seguido por
el nombre de la clase padre. Para llamar el constructor de la clase padre se usa la palabra reservada
super(), y debera ser la primera sentencia en el constructor de la clase hija.

La clase JMiMarco, codigo 7, extiende a JFrame. En el constructor de JMiMarco, el constructor


super() JFrame es llamado; este acepta un argumento String para usarlo como el ttulo del JFrame.
El constructor de JMiMarco tambien fija el tamano, la operacion de cierre por defecto y la visibilidad
para cada JMiMarco. Cada uno de los metodossetSize(), setDefaultCloseOperation(), y
setVisibleaparecen en el constructor sin un objeto, porque el objeto es el JMiMarco actual
siendo construido.

11
1 import j a v a x . swing . ;
2 public c l a s s JMiMarco extends JFrame {
3 f i n a l int ANCHO = 2 0 0 ;
4 f i n a l int ALTO = 1 2 0 ;
5 public JMiMarco ( ) {
6 super ( Mi marco ) ;
7 s e t S i z e (ANCHO, ALTO) ;
8 s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
9 s e t V i s i b l e ( true ) ;
10 }
11 }

Codigo 7: La clase JMiMarco.

Cuando se ejecuta la aplicacion CrearDosObjetosMiMarco, codigo 8, los dos objetos JMiMarco son
mostrados con el segundo encima del primero. Para ver el primer marco se debe arrastrar el segundo
marco.
1 public c l a s s CrearDosObjetosMiMarco {
2 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
3 JMiMarco miMarco = new JMiMarco ( ) ;
4 JMiMarco miSegundoMarco = new JMiMarco ( ) ;
5 }
6 }

Codigo 8: La aplicacion CrearDosObjetosMiMarco.

Nota. Se podra usar el metodo setBounds() con uno de los objetos JMiMarco para no tener
que arrastrar uno de los objetos JMiMarco para ver el otro. La clase Objeto incluye el metodo
setLocation() que se puede usar con un JFrame. Para usar este metodo, se deben dar valores para
las posiciones horizontal y vertical como argumentos del metodo.

Nota. Se termina la aplicacion cuando se pulsa en el boton cerrar de alguno de los dos objetos
JMiMarco. Cada objeto tiene la misma operacion de cierre por defecto porque cada uno usa el mismo
constructor que indica esa operacion. Para permitir que solo un JMiMarco controle la terminacion
del programa, se podra usar el metodo setDefaultCloseOperation() con alguno de los objetos
en la aplicacion para cambiar su comportamiento de cierre, quizas usando DISPOSE ON CLOSE para
descartar uno de los marcos pero manteniendo la aplicacion en ejecucion.

Cuando se extiende un JFrame para crear una clase nueva personalizada, se debe recordar tomar
decisiones con los atributos que se quieren fijar dentro de la clase y los que se quieren dejar a las
aplicaciones que usaran la clase. Por ejemplo, se puede poner la sentencia setVisible() dentro del
constructor de la clase hija JFrame, o se puede permitir a la aplicacion usar el metodo setVisible()
precedido por el nombre de un objeto instanciado seguido de un punto. Cualquiera trabaja, pero
si no se hace ninguna, el marco no sera visible.

Nota. Algunos programadores ponen un metodo main() dentro de una clase como JMiMarco. Luego
la clase da la opcion para ser usada para instanciar objetos, como en la aplicacion CrearDosObjetosMiMarco,
o para ser usada ejecutandose como un programa que crea un objeto.

12
6. Clases de entrada

Un JFrame tambien contiene otras caractersticas de ventana, tales como JTextField, JButton, e
informacion sobre herramientas (tool tips).

Clase JTextField

Un JTextField es un componente en el cual un usuario puede teclear una lnea de texto. El texto
comprende cualquier caracter que se pueda meter del teclado o aplicacion, incluyendo numeros y
signos de puntuacion. La siguiente figura muestra la jerarqua de herencia de la clase JTextField.

java.lang.Object
|
+--java.awt.Component
|
+---java.awt.Container
|
+---javax.swing.JComponent
|
+---javax.swing.text.JTextComponent
|
+---javax.swing.JTextField

En un JTextField un usuario teclea una lnea de texto y luego presiona la tecla Intro o pulsa un
boton con el raton para meter los datos. Se puede construir un objeto JTextField usando uno de
los varios constructores:

JTextField() construye un nuevo JTextField.

JTextField(int columnas) construye un nuevo JTextField vaco con la cantidad indicada


de columnas.

JTextField(String texto) construye un nuevo JTextField inicializado con el texto espe-


cificado.

JTextField(String texto, int columnas) construye un nuevo JTextField inicializado


con el texto dado y la cantidad de columnas indicada.

Por ejemplo, para tener un JTextField que tenga suficiente espacio para que un usuario puede
meter 10 caracteres, se puede codificar lo siguiente:

JTextField respuesta = new JTextField(10);

Para agregar el JTextField llamado respuesta a un JFrame llamado marco, se indica con:

13
marco.add(respuesta);

La cantidad de caracteres que un JTextField puede mostrar depende de la fuente usada y los
caracteres tecleados. En la mayora de las fuentes, m es mas ancha que i, as un JTextField de
tamano 10 usando la fuente Arial puede mostrar 24 caracteres i, pero solo 8 caracteres m.

Se debe intentar anticipar cuanto caracteres los usuarios podran ingresar cuando se crea un
JTextField. El usuario puede meter mas caracteres que aquellos que son mostrados, pero los
caracteres extra se desplazan fuera de la vista. Puede ser desconcertante intentar meter datos en
un campo que no es lo suficientemente grande, as que es mejor sobreestimar que subestimar el
tamano de un campo de texto.

Otros metodos estan disponibles para ser usados con objetos JTextField. El metodo setText()
permite cambiar el texto en un JTextField, u otro Componet, que ha sido creado, como se muestra
enseguida:

respuesta.setText("Gracias");

Despues de que el usuario ingreso texto en un JTextField, se puede limpiar con una sentencia
como la siguiente, la cual asigna una cadena vaca al texto:

respuesta.setText("");

El metodo getText() permite recuperar el String de texto en un JTextField, u otro Component,


como en:

String entradaUsuario = respuesta.getText();

Cuando un JTextField tiene la capacidad de aceptar pulsaciones de teclas, el JTextField es


editable. Un JTextField por defecto es editable. Si no se quierer que el usuario pueda ingresar
datos en un JTextField, se puede mandar un valor booleano al metodo setEditable() para
cambiar el estado editable de un JTextField. Por ejemplo, si se quiere dar al usuario una cantidad
limitada de oportunidades de contestar una pregunta correctamente, se pueden contar los intentos
de entrada de datos y entonces prevenir al usuario de reemplazar o editar los caracteres en el
JTextField usando una sentencia como:

if (intentos > LIMITE)


respuesta.setEditable(false );

Clase JButton

Un JButton es un Component en el cual el usuario puede pulsar con el raton para hacer una
seleccion. Hay cinco constructores JButton y son:

14
JButton() crea un boton sin texto.

JButton(Icon cono) crea un boton con un cono de tipo Icon o ImageIcon.

JButton(String texto) crea un boton con texto.

JButton(String texto, Icon icon) crea un boton con el texto inicial y un cono del tipo
Icon o ImageIcon.

JButton(Action a) crea un boton en el cual sus propiedades son tomadas de la Action


proporcionada.

La jerarqua de herencia de la clase JButton es la siguiente:

java.lang.Object
|
+--java.awt.Component
|
+---java.awt.Container
|
+---javax.swing.JComponent
|
+---javax.swing.AbstractButton
|
+---javax.swing.JButton

Para crear un JButton con la etiqueta Pulsar cuando este listo, se puede escribir lo siguiente:

JButton botonListo = new JButton("Pulsar cuando este listo");

Se puede agregar un JButton a un JFrame usando el metodo add(). Se puede cambiar la etiqueta
de un JButton con el metodo setText(), como en:

botonListo.setText("No me presiones nuevamente!");

Se puede recuperar el texto de un JButton y asignarlo a un objeto String con el metodo getText(),
usando:

String queEstaEnJButton = botonListo.getText();

La clase JFrameConMuchosComponentes, codigo 9, extiende JFrame y guarda varios componentes.


Como los componentes, dos JLabel, un JTextField y un JButton son agregados al marco, estos
son puestos de izquierda a derecha en renglones horizontales en la superficie del JFrame.

15
1 import j a v a x . swing . ;
2 import j a v a . awt . ;
3 public c l a s s JFrameConMuchosComponentes extends JFrame {
4 f i n a l int ANCHO = 3 5 0 ;
5 f i n a l int ALTO = 1 5 0 ;
6 public JFrameConMuchosComponentes ( ) {
7 super ( Mostrar muchos componentes ) ;
8 s e t S i z e (ANCHO, ALTO) ;
9 s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
10 JLabel c a b e c e r a = new JLabel ( Este marco t i e n e v a r i o s componentes ) ;
11 c a b e c e r a . s e t F o n t (new Font ( A r i a l , Font .BOLD, 1 6 ) ) ;
12 JLabel mensajeNombre = new JLabel ( I n g r e s a r su nombre : ) ;
13 J T e x t F i e l d campoNombre = new J T e x t F i e l d ( 1 2 ) ;
14 JButton boton = new JButton ( P u l s a r para c o n t i n u a r ) ;
15 s e t L a y o u t (new FlowLayout ( ) ) ;
16 add ( c a b e c e r a ) ;
17 add ( mensajeNombre ) ;
18 add ( campoNombre ) ;
19 add ( boton ) ;
20 }
21 }

Codigo 9: La clase JFrameConMuchosComponentes.

La aplicacion DemoComponentes, codigo 10, instancia un objeto del tipo JFrameConMuchosComponentes.

1 public c l a s s DemoComponentes {
2 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
3 JFrameConMuchosComponentes marco =
4 new JFrameConMuchosComponentes ( ) ;
5 marco . s e t V i s i b l e ( true ) ;
6 }
7 }

Codigo 10: Aplicacion DemoComponentes.

Al ejecutar la aplicacion DemoComponentes, el JFrame contiene todos los componentes que fueron
agregados en el constructor del marco. El usuario puede minimizar o restaurar el marca y puede
modificar su tamano arrastrando los bordes del marco. El usuario puede teclea en el JTextField
y pulsar el JButton. Cuando el boton es pulsado, este parece que fue presionado al igual que otros
botones usados en diferentes aplicaciones. Sin embargo, cuando el usuario teclea o pulsa el boton,
no ocurren acciones resultantes porque no se ha sido escrito todava codigo para manejar es eventos
iniciados por usuario.

Uso de informacion sobre herramientas

Informacion sobre herramientas (tool tips) son ventanas emergentes que pueden ayudar al
usuario a entender el proposito de los componentes en una aplicacion; la informacion aparece cuando
un usuario flota el apuntador del raton encima del componente. Se define el texto que sera mostrado
en una sugerencia usando el metodo setToolTipText() y pasandole un String apropiado. En
la clase JFrameConMuchosComponentes, codigo 9, se puede agregar una sugerencia al componente

16
boton usando la siguiente sentencia en el constructor JFrame:

boton.setToolTipText("Pulsa este boton");

Actividad 2. Crear una aplicacion Swing que muestre un JFrame que tenga un JLabel, un
JTextField, y un JButton. El diseno de esta aplicacion debera incluir una clase que extienda
a la clase JFrame, la cual tendra los componentes como campos de esta clase con la correspondien-
te asignacion de los objetos instanciados; en el constructor de la clase hija configurar el marco y
agregar los componentes. Luego escribir una aplicacion que cree un objeto de la clase hija donde se
debera fijar el tamano de la ventana en 350 de ancho y 100 de alto usando constantes.

7. Programacion de manejo de eventos

Un evento ocurre cuando un usuario realiza una accion en un componente, tal como pulsar el
raton en un objeto JButton. En un programa de manejo de eventos, el usuario podra iniciar
cualquier cantidad de eventos en cualquier orden. Si se usa un programa procesador de textos, se
tienen docenas de opciones disponibles en cualquier momento. Se puede teclear texto, seleccionar
el texto con el raton, pulsar un boton para cambiar el texto a negritas, o a italicas, escoger un
elemento del menu, etc. Con cada documento creado se escogen opciones en el orden que parece
mas apropiado en el momento. El programa procesador de textos debera estar listo para responder
cualquier evento que haya sido iniciado.

Dentro de un programa de manejo de eventos, un componente en el cual un evento es generado es


la fuente del evento. Un boton que un usuario puede pulsar es un caso de una fuente; un campo
de texto donde un usuario puede ingresar texto es otra fuente. Un objeto que esta interesado en un
evento es un receptor (listener ). No todos los objetos oyen por todos los posibles eventoscomo
en algunos programas en los cuales se pulsa en diferentes areas de la pantalla y no sucede nada. Si
se quiere que un objeto sea un receptor para un evento, se debe registrar el objeto como un receptor
de la fuente.

Un objeto fuente componente Java, como un boton, mantiene una lista de receptores registrados
y notifica a todos ellos cuando cualquier evento ocurre. Un JFrame podra querer ser notificado
de cualquier pulsacion en su superficie. Cuando un receptor recibe las noticias, un metodo de
manejo de evento contenido en el objeto receptor responde al evento.

Nota. Un objeto fuente y un objeto receptor puede ser el mismo objeto. Por ejemplo, se podra
programar un JButton para cambiar su propia etiqueta cuando un usuario lo pulse.

Para responder a eventos del usuario dentro de alguna clase creada, se debe hacer lo siguiente:

Preparar la clase para aceptar mensajes de eventos.

Indicar a la clase para que espere eventos que pasaran.

Indicar a la clase como responder a los eventos.

17
Preparar la clase para aceptar mensajes de eventos

Se prepara la clase para aceptar eventos de pulsacion del boton importando el paquete java.awt.-
event en el programa y agregando la frase implements ActionListener a la cabecera de la clase.
En el paquete java.awt.event se incluyen clases evento como ActionEvent, ComponentEvent, y
TextEvent. ActionListener es una interfazun tipo de clase con un conjunto de especificaciones
para metodos que se pueden usar. Implementar ActionListener da especificaciones estandar de
metodos de eventos que permiten al receptor trabajar con ActionEvent, el cual es el tipo de evento
que ocurre cuando se pulsa un boton.

Indicar a la clase para que espere eventos que pasaran

Se le dice a una clase que espere eventos ActionEvent con el metodo addActionListener().
Si se ha declarado un JButton llamado unBoton, y se quiere realizar una accion cuando el usua-
rio pulse unBoton, unBoton es la fuente de un mensaje, y se puede considerar a la clase como
un destino al cual se manda este. La referencia this significa este objeto actual, as el codi-
go unBoton.addActionListener(this); hace que cualquier mensaje ActionEvent (pulsar boton)
que venga de unBoton sea enviado a este objeto actual.

Nota. No todos los eventos son ActionEvent con un metodo addActionListener(). Por ejemplo,
KeyListener tiene un metodo addKeyListener, y FocusListener tiene un metodo addFocusListener.

Indicar a la clase como responder a los eventos

La interfaz ActionListener contiene la especificacion del metodo actionPerformed(ActionEvent


e). Cuando una clase, tal como un JFrame, fue registrada como un receptor para un Component,
tal como un JButton, y un usuario pulsa el JButton, el metodo actionPerformed() se ejecuta.
Se implementa el metodo actionPerformed() usando la siguiente cabecera, donde e representa
cualquier nombre que se quiera para el evento que inicio la notificacion al ActionListener, el cual
es el JFrame:

public void actionPerformed(ActionEvent e)

El cuerpo del metodo contiene cualquier sentencia que se quiera ejecutar cuando la accion ocurre. Se
podra querer realizar un calculo matematico, construir nuevos objetos, generar salida, o ejecutar
cualquier otra operacion. En la clase JVentanaHola, codigo 11, un JFrame contiene un JLabel
que pide al usuario un nombre, un JTextField en el cual el usuario puede teclear una respuesta,
un JButton para pulsar, y una segunda JLabel que muestra el nombre ingresado por el usuario.
El metodo actionPerformed() se ejecuta cuando el usuario pulsa el boton JButton; dentro del
metodo, la cadena que un usuario ha tecleado en el JTextField es recuperada y guardada en la
variable nombre. El nombre es luego usado como de un String que altera la segunda JLabel del
JFrame.

18
1 import j a v a x . swing . ;
2 import j a v a . awt . ;
3 import j a v a . awt . e v e n t . ;
4 public c l a s s JVentanaHola extends JFrame
5 implements A c t i o n L i s t e n e r {
6 JLabel p r e g u n t a = new JLabel ( Cua l e s su nombre ? ) ;
7 Font fuenteGrande = new Font ( A r i a l , Font .BOLD, 1 6 ) ;
8 J T e x t F i e l d r e s p u e s t a = new J T e x t F i e l d ( 1 0 ) ;
9 JButton unBoton = new JButton ( Pulsa aqu ) ;
10 JLabel s a l u d o = new JLabel ( ) ;
11 f i n a l int ANCHO = 2 7 5 ;
12 f i n a l int ALTURA = 2 2 5 ;
13 public JVentanaHola ( ) {
14 super ( Ventana Hola ) ;
15 s e t S i z e (ANCHO, ALTURA) ;
16 p r e g u n t a . s e t F o n t ( fuenteGrande ) ;
17 s a l u d o . s e t F o n t ( fuenteGrande ) ;
18 s e t L a y o u t (new FlowLayout ( ) ) ;
19 add ( p r e g u n t a ) ;
20 add ( r e s p u e s t a ) ;
21 add ( unBoton ) ;
22 add ( s a l u d o ) ;
23 s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
24 unBoton . a d d A c t i o n L i s t e n e r ( t h i s ) ;
25 }
26 public void a c t i o n P e r f o r m e d ( ActionEvent e ) {
27 S t r i n g nombre = r e s p u e s t a . getText ( ) ;
28 S t r i n g mensaje = Hola + nombre ;
29 s a l u d o . s e t T e x t ( mensaje ) ;
30 }
31 }

Codigo 11: La clase JVentanaHola.

La aplicacion JDemoHola, codigo 12, instancia un objeto JVentanaHola y lo hace visible.

1 public c l a s s JDemoHola {
2 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
3 JVentanaHola ventana = new JVentanaHola ( ) ;
4 ventana . s e t V i s i b l e ( true ) ;
5 }
6 }

Codigo 12: Aplicacion JDemoHola.

Cuando se ejecuta la aplicacion JDemoHola, la cual instancia un objeto JVentanaHola, despues de


que el usuario ingresa un nombre, el programa lo saluda con el nombre despues de que el usuario
pulsa el boton.

Cuando mas de un componente es agregado y registrado a un JFrame, podra ser necesario de-
terminar cual componente fue usado para iniciar un evento. En la clase JVentanaHola, codigo
jventanahola, se podra querer que el usuario pueda ver el mensaje despues de pulsar el boton o
de presionar la tecla Intro en el JTextField. En ese caso, se podra designar a ambos como fuentes

19
de mensaje usando el metodo addActionListener() con cada uno, como sigue:

unBoton.addActionListener(this);
respuesta.addActionListener(this);

Estas dos sentencias hacen que el JFrame (this) el receptor de cualquier objeto. El JFrame tiene un
solo metodo actionPerformed(), as que este es el metodo que se ejecuta cuando el boton unBoton
mande un mensaje o el campo de texto respuesta.

Si se quiere que acciones diferentes ocurran dependiendo del generador del evento, se debe de-
terminar la fuente del evento. Dentro del metodo actionPerformed(), se puede usar el metodo
getSource() del objeto enviado para determinar cual componente genero el evento. Por ejemplo,
dentro de un metodo con la cabecera public void actionPerformed(ActionEvent e), e es un
ActionEvent. ActionEvent y otras clases evento son parte del paquete java.awt.event y son
subclases de la clase EventObject. Para determinar cual objeto genero el ActionEvent, se usa la
siguiente sentencia:

Object fuente = e.getSource();

Por ejemplo, si un JFrame contiene dos JButton llamados opcion1 y opcion2, se puede usar la
estructura de decision en el siguiente metodo para tomar diferentes acciones dependiendo del boton
pulsado. Si una fuente de evento es un JButton, JTextField, u otro Component, este puede ser
asignado a un Object porque todos los componentes descienden de Object.

public void actionPerformed(ActionEvent e) {


Object fuente = e.getSource();
if (fuente == opcion1)
// ejecutar estas sentencias cuando el usuario pulse opcion1
else
// ejecutar estas sentencias cuando el usuario pulse opcion2
}

Alternativamente, se puede tambien usar la palabra reservada instanceof para determinar la


fuente del evento. instanceof es usada cuando es necesario conocer solo el tipo del componente,
en vez del componente que disparo el evento. Por ejemplo, si se quiere tomar alguna accion cuando
un usuario ingresa datos en cualquier JTextField, pero no cuando un evento es generado por un
tipo diferente de Component, se usa el formato de metodo mostrado enseguida:

void actionPerformed(ActionEvent e) {
Object fuente = e.getSource();
if (fuente instanceof JTextField) {
// ejecutar las sentencias cuando cualquier
// JTextField genera el evento, pero no cuando
// un JButton u otro Component lo hace.
}
}

20
Metodo setEnabled()

Cuando se usan aplicaciones hay ocasiones en las cuales un componente se deshabilita o deja de ser
usable. Por ejemplo, un JButton podra oscurecerse y deja de responder cuando el programador
no quiera que se tenga acceso a este. Los componentes estan habilitados por defecto, pero se puede
usar el metodo setEnabled() para hacer un componente disponible o no pasando true o false a
este, respectivamente.

Actividad 3. Agregar funcionalidad al JButton y al JTextField de la actividad 6. Al pulsar el


boton o presionar la tecla Intro se debera cambiar el texto de la etiqueta para que muestre un
mensaje de agradecimiento y para que el boton muestre la cadena Hecho.

Actividad 4. Repetir la actividad anterior pero ahora solo se modificara el texto de la etiqueta
para que indique quien fue la fuente del evento, si el boton o el campo de texto.

8. Receptores de eventos

Varios tipos de receptores existen en Java, y cada uno de estos puede manejar un tipo de evento
especfico. Una clase puede implementar tantos receptores como ocupepor ejemplo, una clase
podra requerir responder a la pulsacion de un boton del raton y a un teclazo, as que se deberan
implementar las interfaces ActionListener y KeyListener. El cuadro 2 lista algunos receptores
de eventos y los tipos de eventos para los cuales son usados.

Receptor Tipos de eventos Ejemplo


ActionListener Eventos de accion Pulsar boton
AdjustmentListener Eventos de ajuste Mover barra de desplaza-
miento
ChangeListener Eventos de cambio Reposicionar deslizador
FocusListener Eventos del foco del teclado Gana o pierde el foco un
campo de texto
ItemListener Eventos de elementos Cambiar estado de casilla
de verificacion
KeyListener Eventos del teclado Ingresar texto
MouseListener Eventos del raton Pulsar boton del raton
MouseMotionListener Eventos de movimiento del Mover raton
raton
WindowListener Eventos de la ventana Cerrar ventana

Cuadro 2: Lista de algunos receptores de eventos

Un evento ocurre cada vez que un usuario teclea o pulsa un boton del raton. Cualquier objeto puede
ser notificado de un evento siempre y cuando este implemente la interfaz apropiada y sea registrado
como un receptor de eventos en la fuente de eventos apropiada. Previamente, en la seccion 6, se ha
mostrado como establecer una relacion entre un JButton y un JFrame que lo contiene usando el
metodo addActionListener(). De igual forma, se pueden crear relaciones entre otros componentes
Swing y las clases que reaccionan a las manipulaciones de usuarios de ellos. En el cuadro 3, cada
componente listado en la columna izquierda esta asociado con un metodo de la columna derecha.

21
Por ejemplo, cuando se quiere que un JCheckBox responda a las pulsaciones del usuario, se puede
usar el metodo addItemListener() para registrar el JCheckBox como el tipo de objeto que puede
crear un evento ItemEvent. El argumento que se pone dentro de los parentesis de la llamda al
metodo addItemListener() es el objeto que debera responder al eventoquizas un JFrame que
contiene el JCheckBox generador del evento. El formato es:

laFuenteDelEvento.addListenerMetodo(laClaseQueDeberaResponder);

Componente(s) Metodo(s) registradores-


receptores asociados
JButton, JCheckBox, JComboBox, JText- addActionListener()
Field, y JRadioButton.
JScrollBar addAdjustmentListener()
Todos los componentes Swing. addFocusListener(), addKeyListener(),
addMouseListener(), y addMouseMotion-
Listener()
JButton, JCheckBox, JComboBox, y addItemListener()
JRadioButton.
Todos los componentes JWindow y JFrame. addWindowListener()
JSlider y JCheckBox. addChangeListener()

Cuadro 3: Algunos componentes Swing y su metodos registradores-receptores asociados

Nota. Cualquier fuente de eventos puede tener multipes receptores registrados en este.Es decir,
una sola instancia de JCheckBox podra generar eventos ItemEvent y FocusEvent, y una sola
instancia de la clase JFrame podra responder a los ActionEvent generados por el JButton y a los
ItemEvents generados por el JCheckBox.

La clase del objeto que responde a un evento debe contener un metodo que acepte el objeto evento
creado por la accion del usuario. Un metodo que se ejecuta porque es llamado automaticamente
cuando un evento apropiado ocurre es un manejador de evento. Es decir, cuando se registra un
componente, tal como un JFrame, para ser un receptor para eventos generados por otro componente,
como un JCheckBox, se debe escribir un metodo manejador de evento. No se puede escoger un
nombre propio para los manejadores de eventoidentificadores de metodos especficos reaccionan
a tipos especficos de eventos. En el cuadro 4 se listan algunos de los metodos que reaccionan a
eventos.

Receptor Metodo
ActionListener actionPerformed(ActionEvent)
AdjustmentListener adjustmentValueChanged(AdjustmentEvent)
FocusListener focusGained(FocusEvent) y focusLost-
(FocusEvent)
ItemListener itemStateChanged(ItemEvent)

Cuadro 4: Metodos seleccionados que responden a eventos.

Las siguientes tareas se deben realizar cuando se declara una clase que maneja un evento:

22
La clase que maneja un evento debera implementar una interfaz receptora o extender una
clase que implemente una interfaz receptora. Por ejemplo, si un JFrame llamado MiMarco
necesita responder a pulsaciones del usuario en un JCheckBox, se podra escribir la siguiente
cabecera de clase:

public class MiMarco extends JFrame implements ItemListener

Si despues se declara una clase que extienda MiMarco, no se necesita incluir implements
ItemListener en su cabecera. La nueva clase hereda la implementacion.

Se debe registrar cada instancia de la clase manejadora de eventos como un receptor para uno
o mas componentes. Por ejemplo, si MiMarco contiene un JCheckBox llamado miCheckBox,
entonces dentro de la clase MiMarco se podra codificar:

miCheckBox.addItemListener(this);

La referencia this es a la clase en la cual miCheckBox esta declaradoen este caso, MiMarco.

Se debe escribir un metodo manejador de eventos con un identificador apropiado, como se


muestra en el cuadro 4, que acepte el evento generado y reaccione a este.

9. Clases para seleccion

Otros componentes permiten al usuario hacer selecciones en un ambiente interfaz de usuario, como
JCheckBox, ButtonGroup, y JComboBox.

Clase JCheckBox

Un JCheckBox es una casilla de verificacion que consiste de una etiqueta puesta a un lado de un
cuadro; se puede pulsar el cuadro para mostrar una palomita o quitarla. Se usa un JCheckBox para
permitir al usuario prender o apagar una opcion. La aplicacion DemoCheckBox, codigo 13, muestra
el uso de cuatro JCheckBox.

23
1 import j a v a . awt . ;
2 import j a v a x . swing . ;
3 import j a v a . awt . e v e n t . ;
4 public c l a s s DemoCheckBox
5 extends JFrame implements I t e m L i s t e n e r {
6 JLabel e t i q u e t a = new JLabel ( Que d e s e a s tomar ? ) ;
7 JCheckBox c a f e = new JCheckBox ( Cafe , f a l s e ) ;
8 JCheckBox c o l a = new JCheckBox ( Cola , f a l s e ) ;
9 JCheckBox l e c h e = new JCheckBox ( Leche , f a l s e ) ;
10 JCheckBox agua = new JCheckBox ( Agua , f a l s e ) ;
11 JLabel e s t a d o = new JLabel ( ) ;
12 public DemoCheckBox ( ) {
13 super ( Demostracion CheckBox ) ;
14 s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE ) ;
15 s e t L a y o u t (new FlowLayout ( ) ) ;
16 e t i q u e t a . s e t F o n t (new Font ( A r i a l , Font . ITALIC , 2 2 ) ) ;
17 c a f e . addItemListener ( this ) ;
18 cola . addItemListener ( this ) ;
19 leche . addItemListener ( this ) ;
20 agua . a d d I t e m L i s t e n e r ( t h i s ) ;
21 add ( e t i q u e t a ) ;
22 add ( c a f e ) ;
23 add ( c o l a ) ;
24 add ( l e c h e ) ;
25 add ( agua ) ;
26 add ( e s t a d o ) ;
27 }
28 public void itemStateChanged ( ItemEvent e ) {
29 Object f u e n t e = e . g e t I t e m ( ) ;
30 JCheckBox cb = ( JCheckBox ) f u e n t e ;
31 int s e l e c c i o n = e . g e t S t a t e C h a n g e ( ) ;
32 i f ( s e l e c c i o n == ItemEvent .SELECTED)
33 e s t a d o . s e t T e x t ( Se ha s e l e c c i o n a d o +cb . getText ()+ ! ) ;
34 else
35 e s t a d o . s e t T e x t ( Se ha q u i t a d o l a s e l e c c i on +cb . getText ()+ ! ) ;
36 }
37 public s t a t i c void main ( S t r i n g [ ] arguments ) {
38 f i n a l int FRAME WIDTH = 3 5 0 ;
39 f i n a l int FRAME HEIGHT = 1 2 0 ;
40 DemoCheckBox ventana = new DemoCheckBox ( ) ;
41 ventana . s e t S i z e (FRAME WIDTH, FRAME HEIGHT ) ;
42 ventana . s e t V i s i b l e ( true ) ;
43 }
44 }

Codigo 13: Aplicacion DemoCheckBox.

La jerarqua de herencia de la clase JCheckBox se muestra enseguida. Los metodos mas frecuente-
mente usados aparacen en el cuadro 5.

java.lang.Object
|
+--java.awt.Component

24
|
+---java.awt.Container
|
+---javax.swing.JComponent
|
+---javax.swing.AbstractButton
|
+---javax.swing.JToggleButton
|
+---javax.swing.JCheckBox

Metodo Proposito
void setText(String) pone el texto para el JCheckBox.
String getText() regresa el texto JCheckBox.
void setSelected(boolean) pone el estado del JCheckBox a true para seleccio-
nado o false para no seleccionado.
boolean isSelected() obtiene el estado actual (marcado o desmarcado)
del JCheckBox.

Cuadro 5: Metodos JCheckBox usados frecuentemente.

Varios constructores pueden ser usados con JCheckBox. Cuando se construye un JCheckBox, se
puede escoger si se le asigna una etiqueta; si el JCheckBox aparece seleccionado, por defecto un
JCheckBox no esta seleccionado. Las siguientes sentencias crean cuatro objetos JCheckBox:

Sin etiqueta y sin seleccion.

JCheckBox casilla1 = new JCheckBox();

Con etiqueta y sin seleccion.

JCheckBox casilla2 = new JCheckBox("Marcar aqu");

Con etiqueta y sin seleccion.

JCheckBox casilla3 = new JCheckBox("Marcar aqu", false );

Con etiqueta y seleccionado.

JCheckBox casilla4 = new JCheckBox("Marcar aqu", true );

Si no se quiere inicializar un JCheckBox con una etiqueta y se quiere asignar despues, o si se quiere
cambiar una etiqueta existente, se puede usar el metodo setText(), como sigue:

casilla1.setText("Marcar esta casilla ahora);

25
Se puede poner el estado de un JCheckBox con el metodo setSelected(); por ejemplo, se puede
usar la siguiente sentencia para asegurar que casilla1 no este seleccionada:

casilla1.setSelected(false );

El metodo isSelected() es mas util en expresiones booleanas, como en el siguiente ejemplo, la


cual agrega uno a una variable contadorVotos si casilla2 esta actualmente marcada.

if (casilla2.isSelected())
++contadorVotos;

Cuando el estado de un JCheckBox cambia de marcado a no marcado, o viceversa, un evento


ItemEvent es generado, y el metodo itemStateChanged() es ejecutado. Se puede usar el meto-
do getItem() para determinar cual objeto genero el evento y metodo getStateChange() para
determinar si el evento fue una seleccion o no.

El metodo getStateChange() devuelve un entero que es igual a una de las dos constantes de
claseItemEvent.SELECTED o ItemEvent.DESELECTED. En el siguiente extracto de codigo el meto-
do itemStateChanged() llama al metodo getItem(), el cual regresa el objeto llamado fuente.
Luego, el valor de fuente es probado con una sentencia if para determinar si este es equivalente
a un objeto JCheckBox llamado casilla. Si las dos referencias son al mismo objeto, el codigo
determina si la casilla fue seleccionada o no, y en cada caso las acciones apropiadas son hechas.

public void itemStateChanged(ItemEvent e) {


Object fuente = e.getItem();
if (fuente == casilla) {
int seleccion = e.getStateChange():
if (seleccion == ItemEvent.SELECTED)
// sentencias que se ejecutan cuando la casilla esta seleccionada
else
// sentencias que se ejecutan cuando la casilla NO esta seleccionada
}
else {
// sentencias que se ejecutan cuando la fuente del evento es otro
// componente diferente a casilla
}
}

Clase ButtonGroup

Cuando se quieren opciones mutuamente exclusivas, es decir, se quiere que el usuario solo pueda
seleccionar una opcion de varias, se debe crear un ButtonGroup para agrupar varios componentes,
tales como los JCheckBox. Cuando se agrupan objetos JCheckBox y el usuario selecciona cual-
quiera de las casillas, el resto de las casillas queda sin seleccion. La clase ButtonGroup desciende
directamente de la clase Object y tambien es parte del paquete javax.swing.

26
Nota. Un grupo de JCheckBox en el cual un usuario puede seleccionar uno a la vez actua como un
conjunto de botones de radio, los cuales se pueden crear usando la clase JRadioButton. La clase
JRadioButton es similar a la clase JCheckBox, y se debe preferir su uso cuando se tiene una lista
de opciones de usuario mutuamente excluyente.

Para crear un ButtonGroup en un JFrame y luego agregar un JCheckBox, se deben realizar los
siguientes cuatro pasos:

1. Crear un ButtonGroup, tal como:

ButtonGroup unGrupo = new ButtonGroup();

2. Crear un JCheckBox

JCheckBox unaCasilla = new JCheckBox();

3. Agregar unaCasilla a unGrupo

unGrupo.add(unaCasilla);

4. Agregar unaCasilla al JFrame

add(unaCasilla);

Se puede crear un ButtonGroup y luego crear los objetos individuales JCheckBox, o tambien invir-
tiendo el orden. Si se crea un ButtonGroup pero se olvida agregar cualquier objeto JCheckBox a
este, entonces los JCheckBox actuan como casillas individuales no exclusivas.

Un usuario puede marcar uno de los JCheckBox de un grupo pulsando con el raton en este, o
con codigo puede seleccionar un JCheckBox dentro de un ButtonGroup con una sentencia como la
siguiente:

unGrupo.setSelected(unaCasilla);

Solo un JCheckBox puede ser seleccionado dentro de un grupo. Si se asigna el estado selected a
un JCheckBox dentro de un grupo, cualquier asignacion previa es dejada sin marca.

Se puede determinar cual, si hay, de los JCheckBox en un ButtonGroup esta seleccionado con el
metodo isSelected().

No se puede limpiar la casilla para todos los elementos que son miembros de un ButtonGroup. Se
podra hacer que todos los JCheckBox en un ButtonGroup inicialmente se muestren sin seleccion
agregando un JCheckBox que no sea visible, usando en este el metodo setVisible(). Luego, se
podra usar el metodo setSelected() para marcar el JCheckBox no visible, y el resto se muestre
sin marca.

27
Clase JComboBox

Un JComboBox es un componente que combina dos caractersticas: una area de visualizacion mos-
trando una opcion por defecto y un cuadro de lista que contiene opciones adicionales alternas. El
area de visualizacion contiene un boton que el usuario puede pulsar o un campo editable en el cual
el usuario puede teclear. Cuando un JComboBox se muestra, la opcion por defecto es mostrada.
Cuando el usuario pulsa el JComboBox, una lista de elementos alternativos cae; si el usuario selec-
ciona alguno, este reemplaza el elemento del cuadro mostrado. Los usuario esperan ver las opciones
de un JComboBox en orden alfabetico. Otras formas razonables son poner las opciones en algun
otro orden logico, como pequeno, mediano, y grande, o poniendo a los mas frecuentemente
seleccionados primero.

La jerarqua de herencia de la clase JComboBox se muestra a continuacion.

java.lang.Object
|
+--java.awt.Component
|
+---java.awt.Container
|
+---javax.swing.JComponent
|
+---javax.swing.JComboBox

Se puede construir un JComboBox usando un constructor sin argumentos y luego agregando elemen-
tos, por ejemplo, String a la lista con el metodo addItem(). Las siguientes sentencias crean un
JComboBox llamado opcionPrincipal que contiene tres opciones de las cuales un usuario puede
escoger:

JComboBox<String> opcionPrincipal = new JComboBox<String>();


opcionPrincipal.addItem("Ingles");
opcionPrincipal.addItem("Matematicas");
opcionPrincipal.addItem("Sociologa");

En la declaracion del JComboBox del ejemplo previo, se usa <String> seguido del nombre de la clase.
Por defecto, un JComboBox espera elementos que los elementos agregados sean del tipo Object.
Usando String encerrado entre parentesis angulares se notifica al compilador que los elementos
esperados en el JComboBox son String y se permite que el compilador revise por errores si elementos
invalidos son agregados. Cuando no se indica un tipo de dato para un JComboBox, el programa
compila, pero un mensaje de advertencia es marcado con cada llamada al metodo addItem(). Se
dice que la clase JComboBox usa genericos. La programacion con genericos es una caracterstica
de los lenguajes modernos que permiten que tipos de datos multiples sean usados de forma segura
con metodos.

Otra forma de construir un JComboBox es usando un arreglo de Object como argumento para el
constructor; los elementos en el arreglo se convierten en la lista de elementos dentro del JComboBox.
El siguiente codigo crea el mismo JComboBox opcionPrincipal como en el codigo precedente:

28
String[] arregloPrincipal = {"Ingles","Matematicas","Sociologa"};
JComboBox opcionPrincipal = new JComboBox(arregloPrincipal);

El cuadro 6 lista algunos metodos que se pueden usar con un objeto JComboBox. Por ejemplo,
se puede usar el metodo setSelectedItem() o setSelectedIndex() para escoger uno de los
elementos en un JComboBox para que sea el elemento seleccionado inicialmente. Se puede usar el
metodo getSelectedItem() o getSelectedIndex() para saber cual elemento esta actualmente
seleccionado.

Metodo Proposito
void addItem(Object) Agrega un elemento a la lista.
void removeItem(Object) Quita un elemento de la lista.
void removeAllItems() Quita todos los elementos de la lista.
Object getItemAt(int) Regresa el elemento de la lista en la posicion indi-
cada por el ndice entero.
int getItemCount() Devuelve la cantidad de elementos en la lista.
int getMaximumRowCount() Regresa la cantidad maxima de elementos que el
cuadro lista puede desplegar sin una barra de des-
plazamiento.
int getSelectedIndex() Da la posicion del elemento seleccionado actual-
mente.
Object getSelectedItem() Da el elemento seleccionado actualmente.
Object[] getSelectedObjects() Devuelve un arreglo conteniendo los Object selec-
cionados.
void setEditable(boolean) Pone el campo para que sea editable o no.
void setMaximumRowCount(int) Pone la cantidad de renglones en el cuadro de lista
que pueden ser mostrados a la vez.
void setSelectedIndex(int) Pone el ndice en la posicion indicada por el argu-
mento.
void setSelectedItem(Object) Pone el elemento seleccionado en el area de visua-
lizacion.

Cuadro 6: Metodos JComboBox usados frecuentemente.

Se puede tratar una lista de elementos en un objeto JComboBox como un arreglo; el primer ele-
mento esta en la posicion cero, el segundo en la posicion uno, etc. Es adecuado usar el metodo
getSelectedIndex() para determinar la posicion en la lista del elemento actualmente seleccio-
nado; luego se puede usar el ndice para acceder la informacion correspondiente guardada en un
arreglo paralelo. Por ejemplo, si un JComboBox llamado opcionesHistoria ha sido llenado con
una lista de eventos historicos, tales como Declaracion de Independencia, Batalla de Puebla,
y Expropiacion Petrolera se puede codificar lo siguiente para recuperar la opcion del usuario:

int posicionSeleccion = opcionesHistoria.getSelectedIndex();

La variable posicionSeleccion guarda la posicion del elemento seleccionado, y se puede usar la


variable para acceder un arreglo de fechas para poder mostrar la fecha que corresponde al evento.
Por ejemplo, si se declara lo siguiente, entondces fechas[posicionSeleccion] tiene el ano para
el evento historico seleccionado:

29
int fechas = {1810,1862,1938};

Nota. Un JComboBox no tiene que guardar los elementos declarados como String; puede guardar
un arreglo de Object y mostrar los resultados del metodo toString() usados con esos objetos. Es
decir, en vez de usar arreglos paralelos para guardar eventos historicos y fechas, se podra designar
una clase EventoHistorico que encapsule String para el evento e int para la fecha.

Ademas de un JComboBox para el cual el usuario pulse sobre elementos presentados en una lista,
se puede crear un JComboBox en el cual el usuario pueda teclear texto. Para hacer esto, se usa
el metodo setEditable(). Una desventaja de usar un JComboBox es que el texto que el usuario
ingresa debe ser exactamente igual a un elemento en el cuadro de lista. Si el usuario introduce
incorrectamente la seleccion o el uso de mayusculas/minusculas, no devuelve un valor valido la
llamada del metodo getSelectedIndex(). Se puede usar una sentencia if para probar el valor
regresado de getSelectedIndex(); si este es negativo, la seleccion no aparea ningun elemento en
el JComboBox, y se puede generar un mensaje de error apropiado.

Actividad 5. Crea una aplicacion interactiva para un hotel incluyendo JCheckBox para las dife-
rentes selecciones. El precio base para un cuarto es $2000, y un huesped puede escoger de varias
opciones. Reservar un cuarto para un fin de semana agrega $1000 al precio, incluir desayuno agrega
$200, e incluir un viaje en lancha agrega $750. Un huesped puede seleccionar ninguna, alguna u
todos estos servicios. Cada vez que el usuario cambia la opciones del paquete, el precio es recalcu-
lado.

30

Вам также может понравиться