HTMLpointHTMLpoint HTMLpoint.com


 Las etiquetas y los botones



Empezamos este recorrido panorámico sobre los GUI. Para utilizar varios componentes en la misma ventana necesitamos uno o más contenedores. Éstos los analizaremos sucesivamente, sin embargo tendré que utilizarlos de vez en cuando en este apartado sin haberlos explicado.
Estoy seguro de que no tendréis problemas para comprender los programas porque usaré tanto los Layout como los Container de forma muy simple. Sin embargo os pido perdón si este procedimiento os puede causar algún inconveniente.
En particular, utilizaré los Panel o utilizaré unas constantes de la clase BorderLayout, que separa el Container, en este caso el Panel, en cinco zonas, NORTH, SOUTH, WEST, EAST e CENTER.
En esta lección analizaremos dos componentes, los más simples, las Label y los Botones. Las primeras no tienen ningún suceso asociado, mientras los segundos, según el tipo de botón, tienen dos tipos de sucesos asociados..

Etiquetas
Empezamos nuestra panorámica sobre los componentes analizando el primer elemento simple, la etiqueta, que, entre otras cosas, ya hemos utilizado. La etiqueta es un contenedor para un texto. Esta hace aparecer en la pantalla una simple línea de texto que el usuario no puede editar, y que, sin embargo, la aplicación puede cambiar.
La etiqueta, invocada en Java Label, se encuentra en el paquete java.awt. Por lo tanto para ser utilizada, nuestro programa tendrá que empezar una import java.awt.Label (para incluir sólo la clase Label del paquete), o import java.awt.* (para incluir todas las clases del paquete) internamente al programa que quiere utilizarla, por lo tanto, tendrá que declarar un objeto de tipo Label de la siguiente forma:

Label etiqueta = new Label();

o, si no ha sido importado el paquete java.awt:

java.awt.Label etiqueta = new Label();

La Label tiene tres constructores:

Label() , que construye una etiqueta vacía. Label(String text), que construye una etiqueta con texto Text, justificada a la izquierda. Label(String text, int alignment) , que construye una etiqueta con texto Texto, justificada con alignment. Los valores de alignment son: Label.LEFT, Label.RIGHT, y Label.CENTER.

Algunos métodos del objeto son:

int getAlignment(), da la justificación actual del objeto.
String getText() , da el texto incluido en el label.
void setAlignment(int alignment), cambia la justificación de la Label con alignment.
void setText(String text), ajusta el texto de la Label.

Además existe el método AccessibleContext getAccessibleContext(), que veremos cuando analicemos los contenedores. Realmente la Label es un contenedor de texto.
Label viene de la siguiente jerarquía:



Por lo tanto hereda los métodos de Object y los de java.awt.Component. Todos los componentes GUI se heredan de Component, por lo tanto, al final de la panorámica de los GUI hablaremos de Component que incluye métodos muy útiles para sus gestión. Por ejemplo, métodos para ajustar y obtener informaciones sobre tamaño, colores del fondo, colores del texto, bordes, etc… del componente.
A parte los métodos de Component, estamos listos para utilizar las Label en nuestos programas. Por ahora no pongo ningún ejemplo sobre el uso de las Label porque las veremos en el siguiente párrafo cuando hablemos de los botones.
El paquete swing pone a disposición una clase parecida llamada JLabel que es una extensión de Label, y que, a su vez, pone a disposición una amplia gama de funciones añadidas. Por ejemplo, es posible crear JLabel que tengan tanto un texto como una imagen.

Botones
Otro componente muy utilizado, y de simple realización es el botón. Es un poco más complicado de la Label porque puede recibir unos sucesos (Click el botón).
Los botones son de tres tipos: los normales, les Checkbox y los radiobutton. Empezamos con los primeros.
La clase que define los botones es Button java.awt y pone a disposición todos los métodos para gestionar el aspecto del botón. Los constructores de la clase son dos:

Button(), costruye un botón sin etiqueta;
Button(String txt), costruye un botón con etiqueta txt.

Algunos métodos de la clase son:

void addActionListener(ActionListener l), añade el botón a un objeto invocado.
ActionListener, que escucha los sucesos. Cuando se clique el botón, el suceso será gestionado por ActionListener.
AccessibleContext getAccessibleContext(), como para las Label, los botones son también unos contenedores.
String getActionCommand(), a cada botón se asocia una órden que devuelve el actual.
String getLabel(), devuelve la etiqueta asociada al botón.
EventListener[] getListeners(Class listenerType), da un array que incluye a todos los que escuchan sucesos establecidos por este botón.
addXXXListener(), añade un oyente de sucesos de tipo tipo XXX. En Java hay varios tipos de sucesos, los analizaremos dentro de poco. Uno de éstos es el suceso de tipo action y, en este caso, el método es addActionListener( )
void removeActionListener(ActionListener l), elimina el oyente de sucesos 1 precedentemente asociado al botón.
void setActionCommand(String command), ajusta la órden asociada al botón. Al principio la órden es la etiqueta.
void setLabel(String label), ajusta la etiqueta del botón.

Ahora podemos definir nuestro primer botón. Sólo tenemos que conseguir entender cómo capturar el suceso que resulta de la presión del mismo. Como ya dicho anteriormente, trataré de la gestión de los suceos según Java 2 porque el viejo modelo de gestion de los eventos de Java 1 es obsoleto y no funciona.
Según Java2, definido un botón, como el suceso principal del botón es el click, que pertenece a la familia de los sucesos Action, hay que asociar un ActionListener al mismo botón utilizando el método addActionListaner(ActionListener l); Lo que tenemos que hacer es crear un ActionListener especializado para nuestro botón (o para nuestros botones).
ActionListener se define en el paquete java.awt.event (que hay que incluirlo en el programa). Es una interfaz y, por lo tanto, tiene que ser implementada en la clase en la que se ha definido.
Por ejemplo, estoy haciendo un Frame llamado Tribilín que incluye un botón del que quiero escuchar el click y quiero escucharlo con un ActionListener especializado por mí llamado EscuchaTribilín. Tendré que escribir algo parecido a:

import java.awt.*;
import java.awt.event.*;
public class Tribilín extends Frame
{
Button botón=new Button("Hola");
… métodos de Tribilín, entre los que está el constructor, que incluye un botón.addActionListener(new EscuchaTribilín());

public class EscuchaTribilin implements ActionListener()
{
// Gestión del suceso
} // Fin clase EscuchaTribilín dentro de Tribilín
}//Fin clase Tribilín


En EscuchaTribilín tendré que especializar todos los métodos de la interfaz que estoy extendiendo. ActionListener tiene sólo un método:

void actionPerformed(ActionEvent e), por lo tanto, en EscuchaTribilón tendré que definir el método public void actionPerformed(ActionEvent e). Éste es el método que se invocará cuando clique el botón.
La ActionEvent que llega al método como parámetro, incluye todas las informaciones sobre el suceso, incluso la órden. EscuchaTribilín se puede asociar incluso a más botones. Su actionPerformed se invocará al click de cada uno de estos botones. Aclaremos en seguida este concepto que, a lo mejor, es un poco más difícil de las demás cosas que hemos hecho con el anterior ejemplo. Sin embargo, os aseguro que una vez asimilado el concepto, la gestión de los sucesos de Java resultará muy simple.
Creamos un Frame que tenga un botón y una Label: cada vez que se clica el botón, la etiqueta da un mensaje.

import java.awt.*;
import java.awt.event.*;

public class Botón extends Frame
{
// Constructor clase Botón

Button clícame=new Button("Clícame");

Label clicado=new Label("No me has clicado ni siquiera una vez");

public Botón()
{
clícame.addActionListener(new Oyente());
// setup comando
clícame.setActionCommand("CLIC");
// Añado un botón y la etiqueta al Frame.
// No hagáis caso a las siguientes instrucciones,
// la add sirve para añadir un componente ad
// un contenedor y el segundo parámetro
// add, es decir BorderLayout, es un gestor de Layout,
// que sirve para establecer la forma en la que los objetos
// GUI se colocan en el contenedor.

add(clícame,BorderLayout.NORTH);
add(clicado,BorderLayout.SOUTH);


// métodos de Frame
pack();
show();
}

// main

public static void main (String [] arg)
{

new Botón();

}

// Oyente de suceso Action

int Volte=2;

public class Oyente implements ActionListener
{

public void actionPerformed (ActionEvent e)
{

String Órden=e.getActionCommand();

if (Órden.compareTo("CLIC")==0)
{

clicado.setText("Me has clicado");

clícame.setLabel("Vuelve a clicarme");

clícame.setActionCommand("RECLIC");

};

if (Órden.compareTo("RECLIC")==0)
clicado.setText("Me has clicado "+(Veces++)+" veces.");

}

}// Fin Oyente

}// Fin Botón


El resultado es la siguiente ventana:





Como se ve en Oyente se gestionan dos órdenes diferentes asociados al mismo botón y éste, cuando se clica por primera vez, cambia la órden asociado al suceso clic.
Intentad cambiarlo modificando la orden para estalblecer con certeza las primeras diez veces que se clica e imprimiendo en la etiqueta "Has clicado nueve veces el botón" (la novena vez).

Resumiendo, en una interfaz gráfica, en primer lugar se programa el aspecto gráfico, es decir, se incluyen los botones, los menús, etc. Después se crean y se añaden los oyentes de los sucesos que, según el suceso, invocan uno u otro método de gestión del programa (pone al día la interfaz, calcula las funciones del programa de la que es la interfaz gráfica).
Éste es un principio general de la programación de Interfaces Gráficas, es decir, de la programación de los sucesos. Cada programa que utilizáis funciona de esta forma y cada programa que escribíss también.
El tipo de programación es un poco diferente al que un programador sobre plataforma no gráficas (tipo Dos, Linux senza X-Win) está acostumbrado y al principio puede resultar no muy simple. Sin embargo hay que acostumbrarse, después es todo igual.

El segundo tipo de botones que analizamos son las Checkbox, es decir, los botones de tipo booleano, que retienen el estado. Se utilizan para hacer opciones no exclusivas o exclusivas entre ellas (en este último caso son unos radiobutton). Por ejemplo, si hay que elegir entre unos hobbies preferidos, estos botones, una vez clicados, se quedan así y hay que volver a clicarlos para que vuelvan a la situación inicial.
Pra crear una Checkbox hay que crear un objeto que pertenece a la clase Checkbox de java.awt. Los constructores son:

Checkbox(), crea una Checkbox sin etiqueta.
Checkbox(String label), crea una Checkbox con etiqueta label.
Checkbox(String label, boolean state), crea una Checkbox con etiqueta label, y hay que clicarla o no según el valor booleano state.

En cambio para los radiobutton:

Checkbox(String label, boolean state, CheckboxGroup group), crea una Checkbox con etiqueta label introducida en una particular
CheckboxGroup, que es un contenedor de Checkbox.
Checkbox(String label, CheckboxGroup group, boolean state) crea una Checkbox con etiqueta label introducida en una particular
CheckboxGroup, y ajustada según el valor de state.

Prácticamente, entre todos los botones introducidos en el CheckboxGroup, sólo uno puede ser clicado, los demás no se tienen que clicar. Las Checkbox del primer tipo, como he dicho, se utilizan para hacer unas opciones no exclusivas como, por ejemplo, la opción de los intereses entre una lista de los intereses posibles. Mientras las Checkbox del segundo tipo, es decir, los radiobuttons sirven para hacer opciones exclusivas como, por ejemplo, la opción de la renta de una persona en las diferentes fases.

Entre los métodos de la clase Checkbox los más interesantes son:

void addItemListener(ItemListener l) , asocia un ItemListener a la Checkbox, el ItemListener gestiona los sucesos de los Checkbox y no sólo eso. Son un segundo tipo de sucesos que aprenderemos a utilizar. De todas formas, se parecen a los ActionListener, lo único es que se asocian a los objetos que tienen un estado.
CheckboxGroup getCheckboxGroup(), da el posible grupo en el que se intruduce la Checkbox.
Las ya conocidas String getLabel() e EventListener[] getListeners(Class listenerType) boolean getState(), este método dice que la Checkbox se ha clicado o no.
void removeItemListener(ItemListener l), quita el actual oyente de sucesos Item.
void setCheckboxGroup(CheckboxGroup g), ajusta un gruppo para la Checkbox.
void setLabel(String label), ajusta la etiqueta
void setState(boolean state), ajusta el estado.

Vamos a ver ahora lo que contiene un CheckboxGroup. El constructor no tiene parámetros y los métodos no declarados Deprecated son tres:

Checkbox getSelectedCheckbox(), da la Checkbox seleccionada en el grupo .
void setSelectedCheckbox(Checkbox box), ajusta la Checkbox del grupo indicado.
String toString(), da una cadena que representa el objeto.

Ahora vamos a poner un pequeño ejemplo que usa tanto Checkbox como RadioButton.

import java.awt.*;
import java.awt.event.*;

public class Check extends Frame
{
// Constructot clase Botón

Label r=new Label("Renta anual");
Label i=new Label("Intereses");

Button sale=new Button("saledela aplicación");

CheckboxGroup renta=new CheckboxGroup();

Checkbox r1=new Checkbox("De 0 a 10");
Checkbox r2=new Checkbox("De 11 a 30");
Checkbox r3=new Checkbox("De 31 a 70");
Checkbox r4=new Checkbox("De 71 a 100");
Checkbox r5=new Checkbox("De 101 a 200");
Checkbox r6=new Checkbox("De 201 a 500");
Checkbox r7=new Checkbox("Soy un ricachón");

Checkbox i1=new Checkbox("Esport");
Checkbox i2=new Checkbox("Informática");
Checkbox i3=new Checkbox("Lectura");
Checkbox i4=new Checkbox("Cine");
Checkbox i5=new Checkbox("Animales");
Checkbox i6=new Checkbox("Teveos");
Checkbox i7=new Checkbox("Loterías");
Checkbox i8=new Checkbox("Mujeres");
Checkbox i9=new Checkbox("Hombres");



public Check()
{
sale.addActionListener(new Oyente());


Panel p1=new Panel();

Panel p2=new Panel();

p1.add(r);
p1.add(r1);
p1.add(r2);
p1.add(r3);
p1.add(r4);
p1.add(r5);
p1.add(r6);
p1.add(r7);

r1.setCheckboxGroup(renta);
r2.setCheckboxGroup(renta);
r3.setCheckboxGroup(renta);
r4.setCheckboxGroup(renta);
r5.setCheckboxGroup(renta);
r6.setCheckboxGroup(renta);
r7.setCheckboxGroup(renta);



add(p1,BorderLayout.NORTH);


p2.add(i);
p2.add(i1);
p2.add(i2);
p2.add(i3);
p2.add(i4);
p2.add(i5);
p2.add(i6);
p2.add(i7);
p2.add(i8);
p2.add(i9);



add(p2,BorderLayout.CENTER);

add(sale,BorderLayout.SOUTH);

// métodos de Frame

pack();
show();

}

// main

public static void main (String [] arg)
{

new Check2();

}


// Oyentes de sucesos Action

public class Oyente implements ActionListener
{

public void actionPerformed (ActionEvent e)
{

System.out.println("afiliación al sito XXXXXXX.it");

System.out.print("ganancia anual ");
if (r1.getState()) System.out.println(r1.getLabel());
else if (r2.getState()) System.out.println(r2.getLabel());
else if (r3.getState()) System.out.println(r3.getLabel());
else if (r4.getState()) System.out.println(r4.getLabel());
else if (r5.getState()) System.out.println(r5.getLabel());
else if (r6.getState()) System.out.println(r6.getLabel());
else if (r7.getState()) System.out.println(r7.getLabel()+" (Qué suerte!)");
else System.out.println("NO DECLARADO");

System.out.println("Intereses declarados:");
if (i1.getState()) System.out.println("\t"+i1.getLabel());
if (i2.getState()) System.out.println("\t"+i2.getLabel());
if (i3.getState()) System.out.println("\t"+i3.getLabel());
if (i4.getState()) System.out.println("\t"+i4.getLabel());
if (i5.getState()) System.out.println("\t"+i5.getLabel());
if (i6.getState()) System.out.println("\t"+i6.getLabel());
if (i7.getState()) System.out.println("\t"+i7.getLabel());
if (i8.getState()) System.out.println("\t"+i8.getLabel());
if (i9.getState()) System.out.println("\t"+i9.getLabel());

System.exit(0);
}

}// Fin Oyente

}// Fin Botón

Fig 4: Ventana del programa

He tenido que usar otra vez los layout y también los Panel. Lo siento porque todavía no los hemos tratado, sin embargo, es la única forma para introducir más GUI en la misma ventana. Por ejemplo, intentad quitar los Panel y, sucesivamente, añadid todo directamente a las ventanas, sin utilizar los Layout. Váis a ver lo que ocurre.
En la aplicación hay un botón que sirve para cerrar la ventana porque todavía no sabemos gestionar los sucesos de la ventana, como el close, que en este caso no funciona. Dentro de poco podremos gestionar incluso éstos.

En la aplicación no he gestionado los sucesos de las Checkbox porque no lo he necesitado. Hay situaciones en las que se tienen que gestionar, en las que, además del estado del botón cambia algo, por ejemplo, el estado de algún GUI. Lo vemos en este ejemplo.

import java.awt.*;
import java.awt.event.*;

public class Check2 extends Frame
{
// Constructot clase Botón


Button cierra=new Button("Sale de la aplicación");

Checkbox i1=new Checkbox("primeros 3");
Checkbox i2=new Checkbox("segundos 4");

Checkbox ii1=new Checkbox("uno");
Checkbox ii2=new Checkbox("dos");
Checkbox ii3=new Checkbox("tres");
Checkbox ii4=new Checkbox("cuatro");
Checkbox ii5=new Checkbox("cinco");
Checkbox ii6=new Checkbox("seis");
Checkbox ii7=new Checkbox("siete");



public Check2()
{
cierra.addActionListener(new Oyente());


Panel p1=new Panel();

Panel p2=new Panel();

p1.add(ii1);
p1.add(ii2);
p1.add(ii3);
p1.add(ii4);
p1.add(ii5);
p1.add(ii6);
p1.add(ii7);


ii1.addItemListener(new AItem1());
ii2.addItemListener(new AItem1());
ii3.addItemListener(new AItem1());
ii4.addItemListener(new AItem1());
ii5.addItemListener(new AItem1());
ii6.addItemListener(new AItem1());
ii7.addItemListener(new AItem1());


i1.addItemListener(new AItem2());
i2.addItemListener(new AItem2());

add(p1,BorderLayout.NORTH);

p2.add(i1);
p2.add(i2);



add(p2,BorderLayout.CENTER);

add(cierra,BorderLayout.SOUTH);

// métodos de Frame

pack();
show();

}

// main

public static void main (String [] arg)
{

new Check();

}


// Oyente de sucesos Action

public class Oyente implements ActionListener
{

public void actionPerformed (ActionEvent e)
{System.exit(0);}

}// Fin Oyente

// Oyente de sucesos Item
public class AItem1 implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{

i1.setState(ii1.getState()&&
ii2.getState()&&
ii3.getState());

i2.setState(ii4.getState()&&
ii5.getState()&&
ii6.getState()&&
ii7.getState());
}

}//Fin AItem1


public class AItem2 implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
ii1.setState(i1.getState());
ii2.setState(i1.getState());
ii3.setState(i1.getState());
ii4.setState(i2.getState());
ii5.setState(i2.getState());
ii6.setState(i2.getState());
ii7.setState(i2.getState());
}

}//Fin AItem2


}// Fin Botón



  Volver al inicio de la página