Definición: Un widget es un elemento gráfico con el que el usuario puede interactuar. Un widget ocupa una porción rectangular en una ventana. Ejemplos de widgets son: botones, áreas de texto, etiquetas, etc. El kit AWT implementa los widgets más usuales. Sin embargo, las aplicaciones avanzadas requieren de widgets más sofisticados. En estos casos, Java ofrece Swing que por razones de tiempo y de complejidad, no podemos ver en este curso.
Para usar los widget de la AWT es necesario importar las clases del paquete java.awt:
import java.awt.*;
En la ventana (clase Frame) se puede apreciar en el centro un canvas (clase Canvas). Este widget representa una tela de pintar y se usa cuando ninguno de los widgets ofrecidos por la AWT cumple los requerimientos de la aplicación. A la izquierda se muestra un área de texto (TextArea), a la derecha una lista de ítemes (List) y arriba una etiqueta (Label). Abajo se observa un panel que se usa para agrupar widgets y procesarlos como si se tratase de uno solo. El panel consiste en un campo de texto (TextField), un botón (Button) y un botón de encendido y apagado (Checkbox).
Para construir una interfaz gráfica, el programador debe armar una jerarquía de widgets cuya raíz es la ventana de la aplicación. Por ejemplo, la ventana de más arriba posee la siguiente jerarquía:
Observe que:
En la raíz se encuentra la clase Component. Esto significa que todos los widgets son subclases de Component.
Frame frame= new Frame("Titulo de la ventana");
Botón: | Button boton= new Button("nombre del boton"); |
---|---|
Etiqueta: | Label etiq= new Label("nombre", Label.CENTER); |
Area de texto: | TextArea area= new TextArea(5, 20); |
Campo de texto: | TextField texto= new TextField(15); |
Botón on/off: | Checkbox check= new Checkbox("nombre"); |
El panel de widgets:
List lista = new List(3);
for (int i = 1; i <= 10; i++) {
lista.addItem("List item " + i);
}
Panel panel= new Panel();
El layout manager elige la mejor posición y tamaño de cada widget
de acuerdo al espacio disponible.
frame.setLayout(new BorderLayout());
panel.setLayout(new FlowLayout());
Un ejemplo de layout managers son BorderLayout que organiza un contenedor en 5 zonas:
Otro ejemplo es FlowLayout que coloca los widgets de izquierda a derecha y de arriba hacia abajo:
panel.add(texto);
panel.add(boton);
panel.add(check);
frame.add("North", etiq);
frame.add("West", area);
frame.add("East", lista);
frame.add("South", panel);
Estas instrucciones deben ser las últimas que se ejecuten a partir del
método run. Todo el resto del proceso se realiza atrapando
los eventos que produce el usuario al interactuar con los widgets.
frame.pack();
frame.show();
Un bean es un objeto inspeccionable por el RAD. El RAD provee de una paleta de beans, entre los que se cuentan los widgets vistos anteriormente.
Ejemplos de RAD son JBuilder de Borland (disponible en los PCs de la Facultad), Cafe de Symantec, VisualAge for Java de IBM, Netbeans de Sun y muchos otros.
Cumpliento algunos requisitos, el nuevo widget se puede agregar
a la paleta de beans de cualquier RAD.
Canvas canvas= new MiCanvas();
frame.add("Center", canvas);
La subclase MiCanvas debe definir los métodos paint, getMinimumSize y getPreferredSize:
(Ver el programa completo en Gui.java.)
class MiCanvas extends Canvas {
public void paint(Graphics g) {
int w = getSize().width;
int h = getSize().height;
g.drawLine(10,10, 100,100);
}
public Dimension getMinimumSize() {
return new Dimension(150,130);
}
public Dimension getPreferredSize() {
return getMinimumSize();
}
}
El sistema gráfico invoca el método paint de un canvas cuando se necesita redibujarlo parcial o completamente. Esto ocurre cuando el usuario saca una ventana que cubría una parte del canvas.
El layout manager invoca los métodos getMinimumSize y getPreferredSize para obtener hints acerca del mejor tamaño del widget. Se invoca al mostrar en pantalla la ventana que contiene el canvas o cuando el usuario redimensiona la ventana.
La mayoría de los widgets (como botones, etiquetas, texto, etc.) ya tienen redefinidos estos métodos en forma conveniente.
Ejercicio:
Escribir una interfaz gráfica que despliegue una ventana con los siguientes widgets: una etiqueta que diga ``Archivo:'', un campo de texto en donde el usuario pueda ingresar el nombre de un archivo y por último un botón etiquetado con la leyenda ``mostrar''. Solución:
(Ver el programa completo en Type.java.)
import tools.*;
import java.awt.*;
class Type extends Program {
// Componentes o widgets
Frame vent; // La ventana
Label etiq; // una etiqueta que dice "Archivo: "
TextField campo; // El campo de texto
Button boton; // El boton
void run() {
// Crear vantana
vent= new Frame("Type");
// Establecer una politica de organizacion (layout) de la ventana
vent.setLayout(new FlowLayout());
// Crear los widgets
etiq= new Label("Archivo: ");
campo= new TextField(15);
boton= new Button("mostrar");
// Colocarlos en la ventana
vent.add(etiq);
vent.add(campo);
vent.add(boton);
// Mostrar la ventana
vent.pack();
vent.show();
}
}
Observación: Este programa todavía no es capaz de reaccionar cuando el usuario presiona el botón mostrar:
En este curso sólo nos preocuparemos de los eventos de acción. Estos eventos se gatillan cuando el usuario realiza la interacción fundamental por la que fue concebido un widget. Por ejemplo cuando el usuario:
Los widgets provistos por la AWT saben capturar y responder la mayoría de de los eventos, con excepción de los eventos de acción porque estos tienen relación con la lógica de la aplicación (a veces se habla del negocio de la aplicación refiriéndose a la funcionalidades que ella entrega).
class MiOyente extends Program implements ActionListener {
public void actionPerformed(ActionEvent e) {
... // Aquí se coloca el grupo de instruciones I
}
}
El método addActionListener registra el objeto creado para ser utilizado
más tarde cuando se presione el botón. Cuando se gatilla este evento,
el botón invoca el método actionPerformed de los objetos suscritos.
b.addActionListener(new MiOyente());
import java.awt.*; // los widgets
import java.awt.event.*; // los eventos
import ...; // otras bibliotecas
class Gui extends Program {
// la ventana
Frame ventana= new Frame("título de la ventana");
// todos los widgets
TextArea area= new TextArea(5, 20);
...
void run() {
ventana.setLayout(new BorderLayout()); // asigna el layout
panel.setLayout(new FlowLayout());
// armamos el panel
panel.add(texto);
...
// armamos la ventana
ventana.add("North", etiq);
...
// Inscripcion para los eventos
lista.addActionListener(new SeleccionLista());
...
ventana.pack();
ventana.show();
}
// clases para los eventos de acción
...
}
(Ver el programa completo en GuiEv.java.)
Ejercicio: Escribir un programa que despliegue una interfaz como la de Type.java pero que además incluya un area de texto en donde mostrar el contenido de un archivo. El programa debe capturar el evento de acción asociado al botón ``mostrar'' mostrando en el area de texto el archivo que aparezca indicado en el campo de texto.
Solución:
(Ver el programa completo en ShowFile.java.)
import tools.*;
import java.awt.*;
import java.awt.event.*;
class ShowFile extends Program {
// Componentes o widgets
Frame vent; // La ventana
Panel panel; // Un panel para colocar la etiqueta, el campo y el boton
Label etiq; // una etiqueta que dice "Archivo: "
TextField campo; // Un campo de texto para el ingreso del nombre del archivo
Button boton; // Un boton para indicar cuando se debe mostrar el archivo
Button salir; // Un boton para terminar la aplicacion
TextArea texto; // Un area de texto en donde se mostrara el archivo
void run() {
// Crear la ventana
vent= new Frame("Type");
// Establecer una politica de organizacion (layout) de la ventana
vent.setLayout(new BorderLayout());
// Crear los widgets
panel= new Panel();
panel.setLayout(new FlowLayout());
etiq= new Label("Archivo: ");
campo= new TextField(15);
boton= new Button("mostrar");
salir= new Button("salir");
texto= new TextArea(5, 15);
// Colocarlos en el panel y la ventana
panel.add(etiq);
panel.add(campo);
panel.add(boton);
panel.add(salir);
vent.add("Center", texto);
vent.add("South", panel);
// Agregar oyentes
ActionListener oyente= new MuestraArchivo(this);
boton.addActionListener(oyente);
campo.addActionListener(oyente);
salir.addActionListener(new Salir());
// Mostrar la ventana
vent.pack();
vent.show();
}
}
class MuestraArchivo extends Program
implements ActionListener {
ShowFile show;
MuestraArchivo(ShowFile show) {
this.show= show;
}
public void actionPerformed(ActionEvent e) {
String nomArch= show.campo.getText();
show.campo.setText("");
TextReader lect= new TextReader(nomArch);
StringBuffer buff= new StringBuffer();
while(true) {
String lin= lect.readLine();
if (lect.eofReached())
break;
buff.append(lin);
buff.append("\n");
}
show.texto.setText(buff.toString());
}
}
class Salir extends Program
implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}