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

Ejemplo: editor de texto

Abstract Window Toolkit (AWT)

1ra. Parte:
Introducción

POO - EPS - UAM 4

La biblioteca AWT:
java.awt, java.awt.event Componentes predefinidas

 Componentes Label
 Componentes predefinidas
 Agregación de componentes TextField
 Las interfaces se dibujan a sí mismas: funciones de
dibujo Button
 Creación de nuevas componentes
 Interacción con el usuario: gestión de eventos TextArea
 Emisión de eventos
 Recepción y procesamiento de eventos Frame
 Layout de componentes

POO - EPS - UAM 2 POO - EPS - UAM 5

Anatomía de un programa basado


Disposición de las componentes
en GUI
 Componer interfaces con las clases predefinidas Ancho ocupa
 La clase Container, adición de subcomponentes toda la ventana
Alto fijo
 Control de la apariencia de las componentes manipulando su estado
 Definir la disposición de las partes de un contenedor Ancho fijo,
 Posiciones absolutas centrado
 Layout managers
 Gestionar los eventos: modelo emisor / receptor Llenar espacio
 Eventos de acción generados por las clases predefinidas disponible hasta
Ancho ocupa
 Gestión directa del input del usuario borde inferior toda la ventana
 Definir componentes personalizadas de la ventana
 La clase Canvas
 Utilización de las funciones de dibujo

POO - EPS - UAM 3 POO - EPS - UAM 6

1
Aspectos interactivos Ejemplo: código (III)

...
Editar texto public void actionPerformed (ActionEvent e) {
Cerrar String command = e.getActionCommand ();
del campo
ventana if (command.equals ("Quit")) dispose ();
else if (command.equals ("Load")) load ();
else if (command.equals ("Save")) save ();
}
Leer el fichero indicado public void windowClosing (WindowEvent e) { dispose (); }
en el campo de texto, public void windowActivated (WindowEvent e) {}
public void windowClosed (WindowEvent e) {}
asignar como string public void windowDeactivated (WindowEvent e) {}
del área de texto public void windowDeiconified (WindowEvent e) {}
public void windowIconified (WindowEvent e) {}
Escribir string del área de texto en el public void windowOpened (WindowEvent e) {}
...
fichero indicado en el campo de texto
Editar texto multilínea

POO - EPS - UAM 7 POO - EPS - UAM 10

Ejemplo: código (I) Ejemplo: código (IV)


import java.awt.*;
...
import java.awt.event.*;
void load () {
import java.io.*;
try {
RandomAccessFile input =
public class Editor extends Frame implements WindowListener,
new RandomAccessFile (fileName.getText (), "r");
ActionListener {
byte buffer[] = new byte [(int) input.length ()];
TextField fileName;
input.read (buffer);
TextArea fileBuffer;
input.close ();
Button load, save, quit;
fileBuffer.setText (new String (buffer));
} catch (IOException e) { System.out.println (e); }
Editor () {
}
setLayout (null);
void save () {
try {
Label label = new Label ("File Name: ");
FileWriter output =
label.setBounds (10, 30, 300, 20);
new FileWriter (fileName.getText ());
add (label);
output.write (fileBuffer.getText ());
output.close ();
fileName = new TextField ();
} catch (IOException e) { System.out.println (e); }
fileName.setBounds (10, 50, 290, 20);
}
add (fileName);
...
...

POO - EPS - UAM 8 POO - EPS - UAM 11

Ejemplo: código (II) Ejemplo: código (V)


load = new Button ("Load");
load.setBounds (40, 80, 60, 20);
add (load);

save = new Button ("Save"); ...


save.setBounds (120, 80, 60, 20); public static void main (String args[]) {
add (save); Editor edit = new Editor ();
quit = new Button ("Quit"); edit.setSize (320, 320);
quit.setBounds (200, 80, 60, 20); edit.setVisible (true);
add (quit);
}
fileBuffer = new TextArea (); } // Fin clase Editor
fileBuffer.setBounds (10, 110, 300, 200);
add (fileBuffer);

this.addWindowListener (this);
load.addActionListener (this);
save.addActionListener (this);
quit.addActionListener (this);
} // Fin del constructor

POO - EPS - UAM 9 POO - EPS - UAM 12

2
Jerarquía de componentes AWT:
Resumen el package java.awt
Jerarquía = Herencia
 Programar un IU para una aplicación en Java
involucra:
 Composición
 Layout
 Eventos
 Paint

POO - EPS - UAM 13 POO - EPS - UAM 16

Jerarquía de componentes AWT:


el package java.awt
Abstract Window Toolkit (AWT)
Jerarquía = Herencia

2da. Parte:
Componentes

POO - EPS - UAM 17

Componentes AWT predefinidas Uso componentes AWT: ejemplo

POO - EPS - UAM 15 POO - EPS - UAM 18

3
Clases en el ejemplo Código del ejemplo
Frame Converter /**
* Does the conversion from metric to U.S., or vice versa, and
* updates the appropriate ConversionPanel.
*/
Label
Choice void convert(ConversionPanel from) {
TextField ConversionPanel to;

if (from == metricPanel)
funcionalidad
ScrollBar to = usaPanel;
ConversionPanel else
to = metricPanel;

double multiplier = from.getMultiplier() / to.getMultiplier();


to.setValue(multiplier * from.getValue());
layout manager: GridBagLayout }

POO - EPS - UAM 19 POO - EPS - UAM 22

Código del ejemplo Código del ejemplo


import java.awt.*;
/** Draws a box around this panel. */
import java.awt.event.*;
public void paint(Graphics g) {
import java.util.*; Dimension d = getSize();
import java.applet.Applet;
Creación Dibujo
g.drawRect(0,0, d.width - 1, d.height - 1);
de la }
public class Converter extends Frame { ventana
ConversionPanel metricPanel, usaPanel;
/**
Unit[] metricDistances = new Unit[3];
* Puts a little breathing space between
Unit[] usaDistances = new Unit[4];
* the panel and its contents, which lets us draw a box
* in the paint() method.
public void init() {
*/
// Use a GridLayout with 2 rows, as many columns as necessary,
public Insets getInsets() {
// and 5 pixels of padding around all edges of each cell.
return new Insets(5,5,5,5);
setLayout(new GridLayout(2,0,5,5));
}
....

POO - EPS - UAM 20 POO - EPS - UAM 23

Código del ejemplo Código del ejemplo


// Create Unit objects for metric distances, and then public static void main(String[] args) {
// instantiate a ConversionPanel with these Units. //Create a new window.
metricDistances[0] = new Unit("Centimeters", 0.01); Frame f = new Frame("Converter Applet/Application");
metricDistances[1] = new Unit("Meters", 1.0); f.addWindowListener(new WindowAdapter() {
metricDistances[2] = new Unit("Kilometers", 1000.0);
public void windowClosing(WindowEvent e) {
metricPanel = new ConversionPanel(this, "Metric System", metricDistances);
System.exit(0);
//Create Unit objects for U.S. distances, and then }
//instantiate a ConversionPanel with these Units. });
Inicialización //Create a Converter instance.
Main
usaDistances[0] = new Unit("Inches", 0.0254);
usaDistances[1] = new Unit("Feet", 0.305); Converter converter = new Converter();
usaDistances[2] = new Unit("Yards", 0.914); converter.init();
usaDistances[3] = new Unit("Miles", 1613.0);
usaPanel = new ConversionPanel(this, "U.S. System", usaDistances);
//Add the Converter to the window and display the window.
//Add both ConversionPanels to the Converter.
f.add("Center", converter);
add(metricPanel); f.pack(); //Resizes the window to its natural size.
add(usaPanel); f.setVisible(true);
} }
}
POO - EPS - UAM 21 POO - EPS - UAM 24

4
Código del ejemplo Código del ejemplo

class ConversionPanel extends Panel //Add the pop-up list (Choice). + componentes
implements ActionListener,
AdjustmentListener, unitChooser = new Choice();
ItemListener { for (int i = 0; i < units.length; i++) { //Populate it.
TextField textField; unitChooser.add(units[i].description);
Choice unitChooser; }
Scrollbar slider; c.weightx = 0.0; //The default value.
int max = 10000; c.gridwidth = GridBagConstraints.REMAINDER; //End a row.
int block = 100; Panel interno gridbag.setConstraints(unitChooser, c);
Converter controller; add(unitChooser);
Unit[] units; unitChooser.addItemListener(this);

POO - EPS - UAM 25 POO - EPS - UAM 28

Código del ejemplo Código del ejemplo


ConversionPanel(Converter myController, String myTitle, Unit[] myUnits) {
//Initialize this ConversionPanel to use a GridBagLayout.
// Add the slider. It's horizontal, and it has the maximum
GridBagConstraints c = new GridBagConstraints();
// value specified by the instance variable max. Its initial
GridBagLayout gridbag = new GridBagLayout();
// and minimum values are the default (0). A click increments
setLayout(gridbag);
// the value by block units.
controller = myController; //Save arguments in instance variables.
slider = new Scrollbar(Scrollbar.HORIZONTAL);
units = myUnits;
slider.setMaximum(max + 10);
slider.setBlockIncrement(block);
//Set up default layout constraints. Composición c.gridwidth = 1; //The default value.
c.fill = GridBagConstraints.HORIZONTAL;
gridbag.setConstraints(slider, c);
add(slider);
//Add the label. It displays this panel's title, centered.
slider.addAdjustmentListener(this);
Label label = new Label(myTitle, Label.CENTER);
} + componentes
c.gridwidth = GridBagConstraints.REMAINDER; //It ends a row.
gridbag.setConstraints(label, c);
add(label);
POO - EPS - UAM 26 POO - EPS - UAM 29

Código del ejemplo Código del ejemplo


/** Draws a box around this panel. */
public void paint(Graphics g) {
//Add the text field. It initially displays "0" and needs Dimension d = getSize();
//to be at least 10 columns wide. g.drawRect(0,0, d.width - 1, d.height - 1); Dibujo
}
textField = new TextField("0", 10);
c.weightx = 1.0; //Use maximum horizontal space... /**
c.gridwidth = 1; //The default value. * Puts a little breathing space between the panel
gridbag.setConstraints(textField, c); * and its contents, which lets us draw a box in the paint() method.
add(textField); */
textField.addActionListener(this); public Insets getInsets() {
return new Insets(5,5,5,8);
+ componentes }

POO - EPS - UAM 27 POO - EPS - UAM 30

5
Jerarquía de componentes:
Código del ejemplo la clase java.awt.Container
/** Respond to the text field */ Jerarquía = Composición
public void actionPerformed(ActionEvent e) {  Las interfaces se construyen agregando componentes a
setSliderValue((double)Double.valueOf(
textField.getText()).doubleValue());
modo de piezas
Respuesta
controller.convert(this);  La jerarquía de componentes debe empezar con una ventana
a eventos
} (frame) o un applet
/** Respond to the choice */  Una componente sólo puede añadirse a un Container
public void itemStateChanged(ItemEvent e) {  Agregar: add(Component)
controller.convert(this);  Retirar: remove(Component)
}
 Las ventanas no pueden añadirse a otra componente
/** Respond to the slider. */  La colocación de las componentes en un contenedor se
public void adjustmentValueChanged(AdjustmentEvent e) { puede definir:
textField.setText(String.valueOf(e.getValue()));
 Mediante layout managers de distintos tipos
controller.convert(this);
}  A mano, con posiciones absolutas
POO - EPS - UAM 31 POO - EPS - UAM 34

Código del ejemplo Jerarquía de componentes (II)


/** Set the values in the slider and text field. */ Jerarquía = Composición
void setValue(double f) {
setSliderValue(f);  Las componentes se pueden añadir:
textField.setText(String.valueOf((float)f));
}  En el constructor del contenedor
 En main
/** Set the slider value. */
void setSliderValue(double f) {  En cualquier función
int sliderValue = (int)f;  Atravesar el árbol de componentes:
Modificación  Acceso a componentes: getComponent(int),
if (sliderValue > max)
sliderValue = max; componentes getComponentAt(int,int), getComponentCount(),
if (sliderValue < 0) getComponents()
sliderValue = 0;
slider.setValue(sliderValue);  Acceso al contenedor desde una componente:
} getParent()
}
POO - EPS - UAM 32 POO - EPS - UAM 35

Cómo se usan las componentes


Jerarquía de componentes: ejemplo
AWT
 Jerarquía de componentes: Jerarquía = Composición public class Converter extends Frame {
...
 Las componentes son estructuradas en una jerarquía de public void init() {
componentes, con instancias de (subclases de) Container ...
definiendo dicha estructura. add(metricPanel); add(usaPanel);
...
 Dibujo de las componentes:
 Los componentes son dibujados desde el tope de la
jerarquía (la Ventana) hacia abajo, hasta arribar a las
hojas (componentes no contenedores)
 Manejo de eventos:
 Los eventos son enviados a los objetos que se registran
como “event listeners”  Modelo de delegación

POO - EPS - UAM 33 POO - EPS - UAM 36

6
Apariencia de las componentes: Refresco de las componentes
paint(Graphics) de Component
Refresco = (re)dibujar
 La apariencia en pantalla de cada subclase de Component
está definida por el código de paint(Graphics)  Cuándo
 El código de paint consiste en llamadas a funciones de  Al desplegar una ventana o cambiarle el tamaño
dibujo sobre el objeto de tipo Graphics  Al hacer visible un componente
 Es poco factible cambiar el dibujo de las componentes  Al cambiar desde el programa propiedades visuales de un
predefinidas componente
(En cambio, es fácil cambiar su respuesta a eventos)
 Normalmente no se redefine paint de las clases predefinidas  Al ser necesario cambiar la apariencia de uno
 Para modificar su apariencia, modificar su estado (el sistema refleja componente para reflejar cambios en la aplicación
los cambios en la pantalla automáticamente)
 En componentes personalizadas desde cero sí se define paint
 Quién solicita
 Es importante que paint no sea costoso de ejecutar  En los tres primeros casos, el sistema AWT.
 Utilizar hilos si es necesario para no bloquear el repintado  En el último caso, el mismo programa
POO - EPS - UAM 37 POO - EPS - UAM 40

Dibujo de componentes Refresco de las componentes

 El dibujo comienza por el componente más alto en  El proceso de dibujo en sí sólo puede llevarse
la jerarquía que necesita ser dibujado a cabo cuando lo diga el sistema AWT
 Por ejemplo, un Frame.  Estos procesos se deben ejecutar sin
 Se baja por la jerarquía, dibujando cada interrupción.
componente intermedio, hasta las hojas.  AWT hace que todos los dibujos ocurran en el
 El sistema de dibujo de AWT organiza este mismo hilo.
procedimiento  El dibujo no puede insumir mucho tiempo
 No se pueden hacer suposiciones sobre el orden  Si es necesario, crear un hilo separado para
relativo de dibujo de las componentes ejecutar alguna operación larga

POO - EPS - UAM 38 POO - EPS - UAM 41

Dibujo de componentes: ejemplo Refresco de las componentes:


update(Graphics) y repaint()
 Se dibuja el frame  AWT decide dibujar un componente
 Se dibuja el Converter   invoca a update(Graphics)
 Caja del borde  Esta invocación se hace desde el hilo de procesamiento
de eventos
 Se dibuja uno de los  update(Graphics) borra el área a refrescar e invoca a
dos ConversionPanel paint(Graphics)
 Caja del borde
 Lo solicita el programa
 Los componentes de   invoca a repaint()
este panel (Label,  Petición al sistema AWT para llamar a update lo antes
TextField, Scrollbar y posible
Choice) son dibujados  El programa no debe llamar a paint directamente

POO - EPS - UAM 39 POO - EPS - UAM 42

7
Refresco de las componentes: el
Gestión de eventos
objeto Graphics
 Los eventos son objetos de distintas subclases de AWTEvent
 Es el argumento de los métodos update y paint
 Se generan eventos cuando:
 Normalmente nos llega a nuestro código desde AWT
 Se produce input del usuario: MouseEvent,KeyEvent
 Provee métodos para:  Un widget se acciona: ActionEvent, TextEvent,
 Dibujar y rellenar rectángulos, arcos, líneas, óvalos, AdjustmentEvent
polígonos, textos e imágenes.  Una ventana es manipulada: WindowEvent
 Otras causas: ContainerEvent, ComponentEvent,
 Obtener o cambiar el color, tipo de fuente o área de PaintEvent, etc.
clipping actuales.
 Los manejadores de eventos (listeners) pueden ser instancias de
 Cambiar el modo de dibujo. cualquier clase.
 Sólo es necesario que la clase implemente la interfaz listener
correspondiente

POO - EPS - UAM 43 POO - EPS - UAM 46

Refresco de las componentes:


Estructura de programa
ejemplo
 En cada programa con un manejador de eventos:
 La forma más simple de dibujar una
componente es especializar el método paint 1. En el encabezamiento de la clase, declaración de implementar la
interfaz (o extender una clase que la implemente):
 Ejemplo: public class MyClass implements ActionListener {

/** Draws a box around this panel. */


2. Código que registra una instancia del manejador como receptor de
public void paint(Graphics g) {
eventos de uno o más emisores:
Dimension d = getSize();
someComponent.addActionListener(instanceOfMyClass);
g.drawRect(0,0, d.width - 1, d.height - 1);
}
3. La implementación de los métodos declarados en la interfaz:
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...}

POO - EPS - UAM 44 POO - EPS - UAM 47

Gestión de eventos: modelo de


Ejemplo visto
eventos de AWT 1.1
class ConversionPanel extends Panel
 Modelo basado en delegación implements ActionListener,

 Eventos generados por emisores (sources) de


AdjustmentListener, 
ItemListener {
eventos.
 Objetos (listeners) se registran para ser textField.addActionListener(this); 
notificados de eventos:
 De cierto tipo public void actionPerformed(ActionEvent e) {
 Desde un emisor en particular setSliderValue((double)Double.valueOf(
textField.getText()).doubleValue());
 Se pueden tratar y generar eventos 
controller.convert(this);
}

POO - EPS - UAM 45 POO - EPS - UAM 48

8
java.awt.Graphics
Abstract Window Toolkit (AWT)  Argumento de paint() y update()
 Dibujo de primitivas gráficas:
 drawLine(int,int, int,int),
drawRect(int,int,int,int),
Repaso de clases básicas drawArc(int,int,int,int,int,int),
fillRect(int,int,int,int)
 drawString(String,int,int)
 drawImage(Image,int,int[,int,int],ImageObserver)
 Estado:
 Componente sobre la que dibujar: getGraphics() de Component
 Origen de coordenadas: translate(int,int)
 Área de clip: getClip(), setClip(int,int,int,int)
 Color: setColor(Color), getColor()
 Font: setFont(Font), getFont()
 Modo XOR: setXORMode(Color)
POO - EPS - UAM 52

java.awt.Component Clases auxiliares en java.awt


 Posiciones y tamaños:
 Dibujarse en la pantalla: paint(), update(),
 Dimension: width, height
repaint()
 Point: x, y
 Procesamiento de eventos: delegación  Rectangle: x, y, width, height,
 Control de la apariencia visual: contains(Point)
 Color: setForeground(Color),  Polygon: npoints, xpoints, ypoints,
getForeground(), setBackground(Color), addPoint(Point)
getBackground()  Color:
 Font: setFont(Font), getFont()  new Color(0.8f, 0.3f, 1.0f) en RGB
 Cursor: setCursor(Cursor), getCursor()  Constantes de tipo Color: Color.white,Color.blue,
etc.
 Funciones para conversión RGB ↔ HSB
POO - EPS - UAM 50 POO - EPS - UAM 53

Clases auxiliares en java.awt


java.awt.Component (II)
(II)
 Tamaño y posición:  Font:
 setSize(int,int)  new Font ("Helvetica", Font.BOLD +
 getSize()  Dimension Font.ITALIC, 18)
 getLocation()  Point  getName(), getStyle(), getSize()
 getLocationOnScreen()  Point  Constantes de estilo: Font.BOLD, Font.ITALIC,
 setBounds(int,int,int,int) Font.PLAIN
 getBounds()  Rectangle  Cursor:
 new Cursor(Cursor.HAND_CURSOR)
(El layout manager puede alterar estos valores)
 Cursor.CROSSHAIR_CURSOR
 Mostrar detalles en System.out: list()
 etc.

POO - EPS - UAM 51 POO - EPS - UAM 54

9
Modelo de eventos: ejemplo
Abstract Window Toolkit (AWT)
public class Beeper implements ActionListener {
...
3ra. Parte: //where initialization occurs:
button = new Button("Click Me");
Gestión de Eventos button.addActionListener(this);
...
public void actionPerformed(ActionEvent e){
...//Implements the answer...
}
}

POO - EPS - UAM 58

Utilización de adapters y clases


Modelo de eventos
internas
 Modelo basado en delegación.  La mayoría de las interfaces de eventos
 A cada tipo de evento xxxEvent corresponde: contienen más de un evento.
 Un tipo de receptor xxxListener (excepción:
MouseEvent tiene dos)  Por ejemplo, MouseListener define cinco
 Una lista de clases de componentes que pueden producir métodos.
el evento  Aunque sólo nos interese un evento, si nuestra
 Un método addxxxListener para registrar receptores de clase implementa directamente la interfaz, igual
esos eventos
 Este método está definido en las clases que generan el evento debemos dar código (probablemente un cuerpo
 Una componente sólo puede registrar listeners del tipo de eventos vacío) para los otros cuatro métodos
que genera la componente

POO - EPS - UAM 56 POO - EPS - UAM 59

Modelo de eventos: ejemplo Ejemplo de código de listener


public class MyClass implements MouseListener {
Clase de evento: ActionEvent ...
someObject.addMouseListener(this);
Objetos que lo emiten: Button, TextField, List,
...
MenuItem
/* Empty method definition. */
Tipo de interfaz listener: ActionListener public void mousePressed(MouseEvent e) { }
/* Empty method definition. */
Métodos a implementar en clase listener: actionPerformed (ActionEvent)
public void mouseReleased(MouseEvent e) { }
Método para registrar listener: addActionListener /* Empty method definition. */
(ActionListener) public void mouseEntered(MouseEvent e) { }
/* Empty method definition. */
public void mouseExited(MouseEvent e) { }
Una componente sólo puede registrar listeners public void mouseClicked(MouseEvent e) {
del tipo de eventos que genera la componente ...//Event handler implementation goes here...
}
}
POO - EPS - UAM 57 POO - EPS - UAM 60

10
Utilización de adapters Adaptadores: código
class MyListener extends MouseAdapter {
 Este tipo de código resulta más difícil de leer y
public void mouseEntered (MouseEvent e) {
mantener.
... // Respuesta de la ventana al evento
 Para evitar la implementación vacía de métodos, }
AWT provee clases adapters }
 implementan listeners con métodos vacíos; class Ventana extends Frame {
 proporciona los adaptadores en java.awt.event; Ventana () {
 para cada interfaz de listener con más de un método. Button boton = new Button ();
 Crear una subclase del adaptador definiendo sólo boton.addMouseListener (new MyListener ());
los métodos que interesen ...
}
}
POO - EPS - UAM 61 POO - EPS - UAM 64

Utilización de adapters: ejemplo Adaptadores: problemas (II)


 Por ejemplo, si se extiende la clase MouseAdapter se hereda
definiciones (vacías) de los cinco métodos definidos por la  A menudo los métodos listener necesitan
interfaz MouseListener. acceder a variables de la clase de
class MouseAdapter implements MouseListener {
public void mouseClicked (MouseEvent e) {} componente
public void mousePressed (MouseEvent e) {}
public void mouseReleased
public void mouseEntered
(MouseEvent e) {}
(MouseEvent e) {}
 Incluir en el adaptador una variable que apunte a
public void mouseExited (MouseEvent e) {} la componente
}

public class MyClass extends MouseAdapter {


 O bien definir el adaptador como clase interna
...
someObject.addMouseListener(this);
de la clase de componente
...
public void mouseClicked(MouseEvent e) {
...//Event handler implementation goes here...
}
}
POO - EPS - UAM 62 POO - EPS - UAM 65

Adaptadores: problemas (I) Adaptador como clase interna


class Ventana extends Frame {
 Una subclase de Component no puede
private String nombre;
heredar de otra clase
Ventana () {
Button boton = new Button ();
⇒ Utilizar un objeto adaptador auxiliar para boton.addMouseListener (new MyListener ());
hacer de listener ...
}
class MyListener extends MouseAdapter {
public void mouseEntered (MouseEvent e) {
...
System.out.println (nombre);
...
}
}
}

POO - EPS - UAM 63 POO - EPS - UAM 66

11
Adaptador como clase anónima
Abstract Window Toolkit (AWT)
class Ventana extends Frame {
private String nombre;
Ventana () {
Button boton = new Button ();
boton.addMouseListener (
4ta. Parte:
new MouseAdapter () { Gestión de Eventos:
public void mouseEntered (MouseEvent e) {
... Implementación de los listeners
System.out.println (nombre);
...
}
}
);
}
}

POO - EPS - UAM 67

Adaptadores autosuficientes = ¿Qué deben hacer los métodos


reutilizables de los receptores?
class Mover extends MouseAdapter
implements MouseMotionListener {
private Point initialPoint;  Modificar características de la interfaz
public Mover (Component c) { listenTo (c); }
public void listenTo (Component c) {  Cambiar colores, fonts, etiquetas, etc.
c.addMouseListener (this); new Mover (obj);  Mover objetos, cambiar su tamaño
c.addMouseMotionListener (this);
}  Ocultar, mostrar, añadir, eliminar componentes
public void mousePressed (MouseEvent e) {
initialPoint = e.getPoint ();  Abrir un cuadro de diálogo
}
public void mouseDragged (MouseEvent e) {  etc.
Component c = (Component) e.getSource ();
Point p = c.getLocation ();  Ejecutar programas de la aplicación
c.setLocation (p.x + e.getX () - initialPoint.x,
p.y + e.getY () - initialPoint.y);
 Normalmente se refleja algún resultado en la interfaz
}
public void mouseMoved (MouseEvent e) {}
}
POO - EPS - UAM 68 POO - EPS - UAM 71

Ver apéndice A ¿Procesar eventos o ignorarlos?

 Clases de Eventos  Eventos de bajo nivel recogidos en widgets y elaborados en


forma de eventos de alto nivel
 Métodos de los listeners  Botones: MouseEvent → ActionEvent
 Widgets de texto: MouseEvent, KeyEvent → TextEvent,
ActionEvent
 Widgets de selección: MouseEvent → ItemEvent, ActionEvent
 etc.
 Eventos de cambio de estado de componentes: procesar los
eventos inmediatamente vs. acceder al estado cuando se
necesite
 TextEvent, ItemEvent, ComponentEvent, ContainerEvent,
AdjustmentEvent, etc.

POO - EPS - UAM 69 POO - EPS - UAM 72

12
Contenido de las clases de eventos Ejemplo de ActionListener

Las distintas clases de eventos incluyen:


 Constantes (variables estáticas)
 ID de los distintos eventos de una clase
Ejemplo: MouseEvent.MOUSE_MOVED,
KeyEvent.KEY_RELEASED
 Constantes para ciertas propiedades de los eventos
(valores devueltos por métodos)
Ejemplo: ItemEvent.SELECTED, ItemEvent.DESELECTED
 Métodos
 Devuelven información adicional sobre el evento
Ejemplo: getX(), getY() de MouseEvent, getKeyChar() de
KeyEvent, getID() de AWTEvent

POO - EPS - UAM 73 POO - EPS - UAM 76

Implementación de un Ejemplo de ActionListener


ActionListener
 Probablemente son los más fáciles y comunes de public class MultiListener ... implements ActionListener {
implementar. ...
//where initialization occurs:
 Se implementa un ActionListener para responder a las button1.addActionListener(this);
indicaciones del usuario de que alguna acción dependiente button2.addActionListener(this);
button2.addActionListener(new Eavesdropper(bottomTextArea));
de la implementación debe ocurrir. }
 Cuándo ocurre? public void actionPerformed(ActionEvent e) {
topTextArea.append(e.getActionCommand() + "\n");
 Click sobre un botón }
 Doble Click sobre un item de lista }
 Elegir un menu item
class Eavesdropper implements ActionListener {
 Enter en un campo de texto ...
 Como resultado, se envía el mensaje actionPerformed public void actionPerformed(ActionEvent e) {
myTextArea.append(e.getActionCommand() + "\n");
a todos los listeners que se han registrado para ese }
componente }

POO - EPS - UAM 74 POO - EPS - UAM 77

Interfaz ActionListener Ver apéndice B

 Define un solo método  Implementación de interfaces de listeners


void actionPerformed(ActionEvent)
 Llamado por AWT justo después que el usuario
informe a la componente “oída” que algo debe ocurrir.
 Por lo tanto, no tiene clase Adapter

POO - EPS - UAM 75 POO - EPS - UAM 78

13
Clases de Layout Managers
Abstract Window Toolkit (AWT)
 Existen distintas clases de manager para
5ta. Parte: distintos tipos de layout
Layout de componentes dentro de un  Predefinidos por AWT
contenedor  Simples: FlowLayout y GridLayout
 Específicos: BorderLayout, CardLayout
 Ultra flexible:GridBagLayout
 Cada uno tiene sus propias “reglas” de uso

POO - EPS - UAM 82

Layout de componentes Clases de Layout Manager

 ¿Qué es layout?  Cada Container tiene un controlador por


 Disposición global de un conjunto de omisión.
componentes  Panel  FlowLayout
 Windows  BorderLayout
Layout
Manager  Si no sirve, se puede cambiar fácilmente
 setLayoutManager(LayoutManager) de Container.
 Es posible incluso crear manejadores propios

POO - EPS - UAM 80 POO - EPS - UAM 83

Layout Manager Reglas generales de uso

 Objeto que controla el tamaño y posición de los  A menos que el programador lo cambie, cada
componentes de un contenedor. contenedor tiene su propia instancia de
 Implementan la interfaz LayoutManager LayoutManager asociada.
 ¿Por qué layout managers?  Es consultado cada vez que que el
 La posición de una componente depende de las componentes contenedor tiene que cambiar su apariencia.
que la rodean y del espacio disponible para el grupo
 La mayoría de los LayoutManagers no
 Un layout manager por encima de las componentes requiere que se llame explícitamente a sus
individuales impone un orden
métodos
 Las componentes negocian su colocación y tamaño con el
layout manager.
POO - EPS - UAM 81 POO - EPS - UAM 84

14
Cómo elegir LayoutManager Ver apéndice C
 Escenario:
 Se necesita mostrar una componente en tanto espacio  Clases de layout managers
como sea posible.
 Considere BorderLayout o GridBagLayout
 Con BorderLayout, se debe poner la componente
ávida de espacio en el centro.
 Con GridBagLayout es necesario que la propiedad
fill de las restricciones sea
fill=GridBagConstraints.BOTH.
 Si no importa que las otras componentes sean igual de
grandes, se puede usar un GridLayout.

POO - EPS - UAM 85 POO - EPS - UAM 88

Cómo elegir LayoutManager (II) Interfaz KeyListener

 Escenario:  void keyTyped(KeyEvent)


 Se necesita mostrar unas pocas componentes en una fila a  Llamado por AWT después que el usuario introduce un
tamaño natural. carácter Unicode en la componente de interés.
 Considere utilizar un Panel para contener los  void keyPressed(KeyEvent)
componentes y el manager por omisión para el  Llamado por AWT después que el usuario presiona una
Panel, el FlowLayout manager. tecla en el teclado.
 void keyReleased(KeyEvent)
 Escenario:
 Llamado por AWT después que el usuario suelta una
 Es necesario mostrar unos pocos componentes del mismo tecla en el teclado.
tamaño en filas y/o columnas.
 El GridLayout es perfecto para esto.
POO - EPS - UAM 86 POO - EPS - UAM 89

Algunas guías de uso Clase KeyEvent


 int getKeyChar()
 Los siguientes métodos de Container  void setKeyChar(char)
Obtiene o cambia el carácter Unicode asociado con el evento.
provocan invocaciones al layout manager: 

 int getKeyCode()
 add(), remove(), removeAll(): en  void setKeyCode(int)
cualquier momento.  Obtiene o cambia el código de tecla asociado al evento.
 layout(): usualmente como resultado de una  La clase KeyEvent define varias constantes de códigos para las
teclas comunes. Por ejemplo:
solicitud paint, y no directamente.  VK_A especifica la tecla con rótulo A
 VK_ESCAPE especifica la tecla ESCAPE.
 preferredSize(), minimumSize(): el
 void setModifiers(int)
retorno es sólo una sugerencia, el programa tiene  Cambia el estado de las teclas modificadoras para el evento.
que mantener estos valores.
POO - EPS - UAM 87 POO - EPS - UAM 90

15
BorderLayout (III)
Abstract Window Toolkit (AWT)
 La parte central es la que más varía con la ventana.
 Las otras partes sólo varían para mantener ocupado
Apéndice C todo el espacio disponible.
Clases de layout managers  Manager por omisión de las ventanas.
 Por omisión, no tiene ninguna distancia al borde
 Se puede especificar con este constructor:

public BorderLayout(int horizontalGap,


int verticalGap)

POO - EPS - UAM 94

BorderLayout FlowLayout

POO - EPS - UAM 92 POO - EPS - UAM 95

BorderLayout (II) FlowLayout (II)


class Ventana extends Frame {
Ventana () {
setLayout (new BorderLayout ());  Este manager pone las componentes en una
setTitle ("Border Layout");
add("North", new Button("North"));
fila, cada una a su preferredSize().
add("South", new Button("South"));
add("East", new Button("East"));  Si el espacio horizontal es muy pequeño,
add("West", new Button("West"));
add("Center", new Button("Center"));
agrega nuevas filas.
}
}
 En cada fila los componentes puedan estar
Importante: en este caso, siempre se debe utilizar una centrados (omisión), alineados a izquierda o
versión de add con dos argumentos: a derecha.
Sector
Componente

POO - EPS - UAM 93 POO - EPS - UAM 96

16
FlowLayout (III) GridLayout

class Ventana extends Frame {


Ventana () {
setLayout (new FlowLayout ());
setTitle ("Flow Layout");  setRows(int),
add (new Button ("Button 1")); setColumns(int)
add (new Button ("Button 2"));
add (new Button ("Button 3"));  GridLayout(0,n) →
add (new Button ("Button 4")); tantas filas como hagan falta
add (new Button ("Button 5"));
}  Ejemplo:
} GridLayout(2,3)

POO - EPS - UAM 97 POO - EPS - UAM 100

FlowLayout (IV) GridLayout (II)

 Este manager pone las componentes en una grilla


de celdas.
class Ventana extends Frame {
 Cada componente toma todo el espacio disponible
Ventana () { en su celda, las cuales tienes todas el mismo
FlowLayout f = new FlowLayout ();
f.setAlignment(FlowLayout.RIGHT); tamaño.
setLayout (f); setTitle ("Flow Layout");
add (new Button ("Button 1"));  Cuando se redimensiona una ventana con
add (new Button ("Button 2"));
add (new Button ("Button 3"));
GridLayout, se cambia el tamaño de las celdas
add (new Button ("Button 4"));
add (new Button ("Button 5"));
de forma que sean lo más grandes posibles dado el
add (new Button ("Button 6")); espacio disponible.
}
}

POO - EPS - UAM 98 POO - EPS - UAM 101

FlowLayout (V) GridLayout (III)


class Ventana extends Frame {
 Tres constructores: Ventana () {
 public FlowLayout() setLayout (new GridLayout (2,3));
 public FlowLayout(int alignment) setTitle ("Grid Layout");
add (new Button ("Button 1"));
 public FlowLayout(int alignment, int horizontalGap,
add (new Button ("Button 2"));
int verticalGap)
add (new Button ("Button 3"));
 Alineamiento: add (new Button ("Button 4"));
add (new Button ("Button 5"));
 FlowLayout.LEFT }
 FlowLayout.CENTER }
 FlowLayout.RIGHT  Constructores:
 Horizontal y Vertical gap: distancia entre public GridLayout(int rows, int columns)
componentes (omisión: 5) public GridLayout(int rows, int columns,
int horizontalGap, int verticalGap)

POO - EPS - UAM 99 POO - EPS - UAM 102

17
CardLayout CardLayout (IV)

 Eligiendo componente:
 public void first(Container parent)
 public void next(Container parent)
 public void previous(Container parent)
 public void last(Container parent)
 public void show(Container parent,
String name)
 El primer argumento siempre es el contenedor para
quien el manager está trabajando.

POO - EPS - UAM 103 POO - EPS - UAM 106

CardLayout (II) GridBagLayout

 Un CardLayout permite manipular dos o más


componentes (usualmente Paneles) para que
compartan el mismo espacio de la pantalla. mantienen igualdad

 Conceptualmente, una pila de cartas donde sólo se


ve la que está en la cima.
 Se puede elegir qué carta estará en la cima:
 Solicitando la primera o última carta (orden en que se
agregaron al contenedor).
 Recorriendo la pila hacia delante o hacia atrás.
 Especificando una carta por nombre

POO - EPS - UAM 104 POO - EPS - UAM 107

CardLayout (III) GridBagLayout (II)


//Where instance variables are declared:
Panel cards;
 El más flexible (y complejo) de los layout
final static String BUTTONPANEL = "Panel with Buttons"; final managers.
static String TEXTPANEL = "Panel with TextField";
...  Coloca a las componentes en una grilla de filas y
//Where the container is initialized:
cards = new Panel();
columnas
cards.setLayout(new CardLayout());  Ciertos componentes pueden abarcar varias filas o
...
//Create a Panel named p1. Put buttons in it.
columnas.
//Create a Panel named p2. Put a text field in it.  No todas las filas (columnas) deben que tener el mismo
...
cards.add(BUTTONPANEL, p1);
alto (ancho).
cards.add(TEXTPANEL, p2);
...
 Coloca las componentes en celdas y luego utiliza
((CardLayout)cards.getLayout()).show(cards, BUTTONPANEL); los preferredSize de las componentes para
// o bien
((CardLayout)cards.getLayout()).show(cards, TEXTPANEL);
determinar el tamaño de las celdas.

POO - EPS - UAM 105 POO - EPS - UAM 108

18
GridBagLayout (III) Restricciones de GridBagLayout
(II)

mantienen igualdad y ocupan todo el ancho  gridwidth, gridheight


 Especifica el número de columnas (filas) que ocupa la
componente. No son pixels. El valor default es 1.
 Usar GridBagConstraints.REMAINDER para
especificar que la componente sea la última de la fila
toma todo (columna).
el espacio
 Usar GridBagConstraints.RELATIVE para
adicional
especificar que la componente sea la anteúltima en la fila
(columna).

POO - EPS - UAM 109 POO - EPS - UAM 112

GridBagLayout (IV) Restricciones de GridBagLayout


(III)
 fill
 Las posiciones y tamaños se especifican mediante restricciones
(constraints) para cada componente.  Usado cuando el área disponible para una componente es
 Se crea instancia de GridBagConstraint, mayor que la requerida:
 Se le da valor a sus variables de instancia,  GridBagConstraints.NONE (valor por omisión),
 Se asocia la restricción con el componente  GridBagConstraints.HORIZONTAL: la componente
crece para ocupar horizontalmente toda el área, pero no
GridBagLayout gridbag = new GridBagLayout(); cambia su alto.
GridBagConstraints c = new GridBagConstraints();  GridBagConstraints.VERTICAL: la componente crece
setLayout(gridbag); para ocupar verticalmente toda el área, pero no cambia su
// Para cada componente a ser agregado:
ancho.
//... Se crea el componente ...  GridBagConstraints.BOTH: hace que la componente
//... Se da valor a las variables de c llene por completo el área disponible.
gridbag.setConstraints(theComponent, c);  ipadx, ipady
add(theComponent);
 Especifica el margen interno (por omisión es 0). El ancho
(alto) de la componente es, por lo menos el ancho (alto)
POO - EPS - UAM 110 POO - EPS - UAM 113
mínimo más ipadx*2 pixels (ipady*2 pixels).

Restricciones de GridBagLayout Restricciones de GridBagLayout


(IV)
 Insets
 Especifica el margen externo de la componente – el mínimo espacio
 Se puede usar la misma instancia de entre la componente y los márgenes del área disponible. El valor es
GridBagLayout para distintas componentes. especificado en un objeto Insets. Por omisión el valor es 0.
 gridx, gridy  Anchor
 Usado cuando la componente es menor que el área disponible, para
 Especifica la celda que contiene el extremo izquierdo determinar dónde (dentro del área) ubicarlo:
(superior) del componente.  GridBagConstraints.CENTER (default)
 La primera celda tiene gridx (gridy) = 0.  GridBagConstraints.NORTH
 GridBagConstraints.NORTHEAST
 Usar GridBagConstraints.RELATIVE (el valor
 GridBagConstraints.EAST
por omisión) para especificar que el componente se  GridBagConstraints.SOUTHEAST
coloque justo a la derecha (o abajo) del componente  GridBagConstraints.SOUTH
anterior.  GridBagConstraints.SOUTHWEST
 GridBagConstraints.WEST
 GridBagConstraints.NORTHWEST
POO - EPS - UAM 111 POO - EPS - UAM 114

19
Restricciones de GridBagLayout GridBagLayout: Ejemplo
(V)
 weightx, weighty
 Especificar los pesos es un arte que puede tener un Cada componente tan
impacto significativo en la apariencia final. grande como sea posible
 Son usados para determinar cómo se distribuye el GridBagLayout gridbag = new GridBagLayout();
espacio entre las columnas (filas); esto es importante
GridBagConstraints c = new GridBagConstraints();
para el comportamiento de redimensionamiento.
setLayout(gridbag);
 A menos que se especifique un valor distinto de cero, c.fill = GridBagConstraints.BOTH;
todas las componentes se agrupan juntas en el centro del
c.weightx = 1.0;
contenedor. Esto es porque cuando el peso es 0.0
(default), el GridBagLayout pone cualquier espacio makebutton("Button1", gridbag, c);
extra en los márgenes externos del contenedor. makebutton("Button2", gridbag, c);
 (continúa) makebutton("Button3", gridbag, c);

POO - EPS - UAM 115 POO - EPS - UAM 118

Restricciones de GridBagLayout GridBagLayout: Ejemplo


(VI)
 weightx, weighty (cont.) Si no estuviera
 Generalmente los pesos son especificados con 0.0 y 1.0
como valores extremos, usando números intermedios
cuando es necesario. GridBagLayout gridbag = new GridBagLayout();
 Números mayores indican que la fila (columna) del GridBagConstraints c = new GridBagConstraints();
componente debe tener más espacio. setLayout(gridbag);
 Para cada columna (fila), el peso es relacionado con el c.fill = GridBagConstraints.BOTH;
mayor weightx (weighty) especificado para un c.weightx = 1.0;
componente en esa columna (fila). makebutton("Button1", gridbag, c);
 Para los componentes multicolumnas (multifilas) el peso es makebutton("Button2", gridbag, c);
dividido de alguna manera entre las columnas (filas) que abarca
makebutton("Button3", gridbag, c);
 El espacio extra tiende a irse hacia abajo a la derecha.

POO - EPS - UAM 116 POO - EPS - UAM 119

GridBagLayout: Ejemplo GridBagLayout: Ejemplo

Todas las columnas iguales


y mayores que 0
GridBagLayout gridbag = new GridBagLayout(); GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints(); GridBagConstraints c = new GridBagConstraints();
setLayout(gridbag); setLayout(gridbag);
c.fill = GridBagConstraints.BOTH; c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0; c.weightx = 1.0;
makebutton("Button1", gridbag, c); makebutton("Button1", gridbag, c);
makebutton("Button2", gridbag, c); makebutton("Button2", gridbag, c);
makebutton("Button3", gridbag, c); makebutton("Button3", gridbag, c);

POO - EPS - UAM 117 POO - EPS - UAM 120

20
GridBagLayout: Ejemplo GridBagLayout: Ejemplo

Si no estuviera (es
decir, weightx = 0)
c.gridwidth = 1; //reset to the default
GridBagLayout gridbag = new GridBagLayout(); c.gridheight = 2; ocupa dos filas
GridBagConstraints c = new GridBagConstraints(); c.weighty = 1.0;
setLayout(gridbag);
makebutton("Button8", gridbag, c);
c.fill = GridBagConstraints.BOTH;
c.weighty = 0.0; //reset to the default
c.weightx = 1.0;
makebutton("Button1", gridbag, c); c.gridwidth = GridBagConstraints.REMAINDER; //end of row

makebutton("Button2", gridbag, c); c.gridheight = 1; //reset to the default


makebutton("Button3", gridbag, c); makebutton("Button9", gridbag, c);
makebutton("Button10", gridbag, c);
POO - EPS - UAM 121 POO - EPS - UAM 124

GridBagLayout: Ejemplo GridBagLayout: Ejemplo

c.gridwidth = GridBagConstraints.REMAINDER; //end of row c.gridwidth = 1; //reset to the default


makebutton("Button4", gridbag, c);
c.gridheight = 2;

c.weightx = 0.0; //reset to the default c.weighty = 1.0; es el único con valor > 0
makebutton("Button5", gridbag, c); //another row makebutton("Button8", gridbag, c);
c.weighty = 0.0; //reset to the default
c.gridwidth = GridBagConstraints.RELATIVE; //next to last
c.gridwidth = GridBagConstraints.REMAINDER; //end of row
makebutton("Button6", gridbag, c);
c.gridheight = 1; //reset to the default
c.gridwidth = GridBagConstraints.REMAINDER; //end of row makebutton("Button9", gridbag, c);
makebutton("Button7", gridbag, c); makebutton("Button10", gridbag, c);
POO - EPS - UAM 122 POO - EPS - UAM 125

GridBagLayout: Ejemplo GridBagLayout: Ejemplo

protected void makebutton(String name,


GridBagLayout gridbag,
c.gridwidth = 1; //reset to the default GridBagConstraints c) {
c.gridheight = 2;
c.weighty = 1.0; Button button = new Button(name);
makebutton("Button8", gridbag, c); gridbag.setConstraints(button, c);
c.weighty = 0.0; //reset to the default
add(button);
c.gridwidth = GridBagConstraints.REMAINDER; //end of row
}
c.gridheight = 1; //reset to the default
makebutton("Button9", gridbag, c);
makebutton("Button10", gridbag, c);
POO - EPS - UAM 123 POO - EPS - UAM 126

21
Trabajando sin Layout Manager java.awt.Button
 Estado y propiedades
 Se debe utilizar un layout manager siempre que sea posible.  Constructores: Button(), Button(String)

 Con ellos es más fácil redimensionar los contenedores y El string se utiliza como etiqueta del botón
 Cambiar / acceder a la etiqueta: GetLabel(),
ajustar la apariencia de componentes dependientes de la SetLabel(String)
plataforma. También es fácil reutilizarlos.  Botón activo / inactivo: setEnabled(boolean)
 Operación
 Si el contenedor no será reutilizado, no puede ser  Emite un ActionEvent al ser pulsado
redimensionado, y controla por completo los factores que  Identificación para el evento de acción:
setActionCommand(String)
normalmente dependen de la plataforma (fuentes y aspecto  Asocia un string al botón (por omisión, el mismo que la etiqueta)
 El string formará parte de la información incluida en los
de los componentes), entonces puede tener sentido un layout ActionEvent's emitidos por el botón (ver getActionCommand()
absoluto. de ActionEvent)

POO - EPS - UAM 127 POO - EPS - UAM 130

class ButtonDemo extends Frame implements ActionListener {


Trabajando sin Layout Manager Button b1, b2, b3;
ButtonDemo () {
setLayout (new FlowLayout ());
b1 = new Button ();
public void paint(Graphics g) {
b1.setLabel ("Disable middle button");
if (!laidOut) { b1.setActionCommand ("Disable");
Insets insets = insets(); b2 = new Button ("Middle button");
/* We're guaranteed that insets() will return a valid b3 = new Button ("Enable middle button");
* Insets if called from paint() -- it isn't valid when b3.setEnabled (false);
* called from the constructor. b3.setActionCommand ("Enable");
*/
add (b1);
add (b2);
b1.reshape(50 + insets.left, 5 + insets.top, 50, 20); add (b3);
b2.reshape(70 + insets.left, 35 + insets.top, 50, 20);
b3.reshape(130 + insets.left, 15 + insets.top, 50, 30); b1.addActionListener (this);
laidOut = true; b3.addActionListener (this);
}
}
...
POO - EPS - UAM 128 POO - EPS - UAM 131

...
public void actionPerformed (ActionEvent e) {
String command = e.getActionCommand();
if (command.equals ("Disable")) {
Abstract Window Toolkit (AWT) b1.setEnabled (false);
b2.setEnabled (false);
b3.setEnabled (true);
}
else {
Apéndice D b1.setEnabled (true);
b2.setEnabled (true);
Widgets AWT b3.setEnabled (false);
}
Clases predefinidas de componentes }
}

estándar

POO - EPS - UAM 132

22
class CheckboxDemo extends Frame {
Widgets de selección CheckboxDemo () {
setLayout (new GridLayout (1, 2));
Panel p1 = new Panel ();
Checkbox List Choice Menu Checkbox cb = new Checkbox ();
cb.setLabel ("Checkbox 1");
cb.setState (true);
p1.add (cb);
p1.add (new Checkbox ("Checkbox 2"));
ItemEvent lleva p1.add (new Checkbox ("Checkbox 3"));
número de item Emiten add (p1);
ActionEvents
Panel p2 = new Panel ();
Doble click CheckboxGroup group = new CheckboxGroup ();
p2.add (new Checkbox ("Checkbox 4", group, false));
Selección múltiple Ahorro de espacio p2.add (new Checkbox ("Checkbox 5", group, false));
p2.add (new Checkbox ("Checkbox 6", group, false));
add (p2);
}
Emiten ItemEvents }
POO - EPS - UAM 133 POO - EPS - UAM 136

java.awt.Checkbox

 Descripción
 Botón seleccionable con dos estados: seleccionado /
deseleccionado
 Agrupable en grupos de botones de selección excluyente
(radio buttons)
 Estado y propiedades
 Checkbox(), Checkbox(String),
Checkbox(String,boolean)
 getLabel(), setLabel(String)
 getState(), setState(boolean)

POO - EPS - UAM 134 POO - EPS - UAM 137

java.awt.Checkbox (cont.) java.awt.Choice

 Operación
 Emite un ItemEvent al cambiar de estado  Descripción
El item asociado el evento es el label del checkbox
 Lista de selección desplegable
 Identificación del item desde el evento:  Uno de los elementos de la lista está seleccionado
 getItem()→String (label del checkbox)  Estado y propiedades
 getItemSelectable()→Object (la componente checkbox)  add(String), getItem(int), getItemCount()
 Botones excluyentes: grupos de Checkbox'es  select(int), select(String),
 Crear objeto de la clase CheckboxGroup isIndexSelected(int), getSelectedItem() →
 Utilizar el constructor
String, getSelectedIndex() → int
Checkbox(String,boolean,CheckboxGroup)  Operación
 Los checkbox creados con el mismo grupo como argumento forman
un grupo
 Emite un ItemEvent al cambiar la selección
 Sólo un checkbox de un grupo puede estar seleccionado El item asociado el evento es el string del item seleccionado

POO - EPS - UAM 135 POO - EPS - UAM 138

23
java.awt.List
...
Panel p = new Panel ();
 Descripción p.setLayout (new GridLayout (2, 1, 10, 10));
 Lista de selección con barras de scroll p.add (spanish);
 El modo de selección puede ser simple o múltiple p.add (italian);
 Estado y propiedades output = new TextArea (10, 40);
 List(), List(int), List(int,boolean) output.setEditable (false);
 add(String), add(String,int), remove(String),
remove(int), getItem(int), getItems(), add (output);
getItemCount(), getRows() add (p);
 select(int), select(String), } // Fin del constructor
isIndexSelected(int), getSelectedItem() → ...
String, getSelectedIndex() → int,
getSelectedObjects() → Object[]
 isMultipleMode(), setMultipleMode(boolean)

POO - EPS - UAM 139 POO - EPS - UAM 142

...
java.awt.List (cont.) public void actionPerformed (ActionEvent e) {
List list = (List) (e.getSource ());
String language = (list == spanish)? "Spanish" : "Italian";
output.append ("Action event on " + list.getSelectedItem ()
+ " in " + language + ".\n");
 Operación }
public void itemStateChanged (ItemEvent e) {
 Seleccionar / deseleccionar item: emite List list = (List) (e.getItemSelectable ());
ItemEvent String language = (list == spanish)? "Spanish" : "Italian";
int index = ((Integer) (e.getItem ())) .intValue ();
El item asociado al evento es el número de if (e.getStateChange () == ItemEvent.SELECTED) {
output.append ("Select event on item " + index
posición del item seleccionado + " (" + list.getItem (index) + ")"
+ " in " + language + ".\n");
 Doble click: emite ActionEvent con el texto del }
item seleccionado como action command string else output.append ("Deselect event on item " + index
+ " (" + list.getItem (index) + ")"
+ " in " + language + ".\n");
}
}

POO - EPS - UAM 140 POO - EPS - UAM 143

class ListDemo extends Frame


implements ActionListener, ItemListener {
TextArea output;
List spanish, italian;
ListDemo () {
setLayout (new FlowLayout ());
spanish = new List (3, true);
spanish.add ("uno");
spanish.add ("dos");
spanish.add ("tres");
spanish.add ("cuatro");
spanish.addActionListener (this);
spanish.addItemListener (this);
italian = new List ();
italian.add ("uno");
italian.add ("due");
italian.add ("tre");
italian.add ("quattro");
italian.addActionListener (this);
italian.addItemListener (this);
... POO - EPS - UAM 141 POO - EPS - UAM 144

24
java.awt.Menu java.awt.Menu (cont.)

Operación
Descripción
 MenuItem emite sólo ActionEvent como un botón, con
 Conjunto de items de distintas modalidades:
el label del item pulsado como action command string
 MenuItem: tipo botón
Source del evento: el item o el Menu contenedor del item
 CheckboxMenuItem: tipo checkbox
 CheckboxMenuItem emite sólo ItemEvent como un
 Menu: submenú checkbox, con el label del item seleccionado /
MenuItem
deseleccionado como label del evento
Source del evento: el propio CheckboxMenuItem
Menu CheckBoxMenuItem

POO - EPS - UAM 145 POO - EPS - UAM 148

java.awt.Menu Widgets de texto


Construcción
 Menu(), Menu(String), MenuItem(), MenuItem(String), TextComponent
CheckboxMenuItem(), CheckboxMenuItem(String)
 Añadir items: Label TextField TextArea
add(String|MenuItem|CheckboxMenuItem|Menu),
insert(String|MenuItem|...,int), getItem(int),
addSeparator()
 Se requiere una barra de menús para añadir menús a una ventana:
 setMenuBar(MenuBar) de Frame
 add(Menu), getMenu(int), getMenuCount() de MenuBar

POO - EPS - UAM 146 POO - EPS - UAM 149

java.awt.Menu (cont.) java.awt.Label

Estado y propiedades Descripción


 getLabel(), setLabel(String)de Menu /  Texto estático

MenuItem Estado y propiedades


 Label(), Label(String),
 Activar / desactivar item: isEnabled(),
Label(String,LEFT|RIGHT|CENTER)
setEnabled(boolean)de Menu / MenuItem  getText(), setText(String)
 Selección de CheckboxMenuItem:  getAlignment(), setAlignment(LEFT|RIGHT|CENTER)

getState(), setState(boolean) Operación


 No tiene
POO - EPS - UAM 147 POO - EPS - UAM 150

25
class TextDemo extends Frame implements ActionListener {
java.awt.TextComponent TextField textField;
TextArea textArea;
TextDemo () {
setLayout (new FlowLayout ());
 Descripción textField = new TextField (20);
 Superclase de TextField y TextArea textArea = new TextArea (5, 20);
 Texto editable, seleccionable textArea.setEditable (false);

 Estado y propiedades add (textField);


 getText(), setText(String) add (textArea);
 isEditable(), setEditable(boolean) textField.addActionListener (this);
 getCaretPosition(), setCaretPosition(int) }
 getSelectedText(), select(int,int), public void actionPerformed (ActionEvent evt) {
selectAll(), getSelectionStart(), String text = textField.getText ();
getSelectionEnd(), setSelectionStart(int), textArea.append (text + "\n");
setSelectionEnd(int) textField.selectAll ();
}
}

POO - EPS - UAM 151 POO - EPS - UAM 154

java.awt.TextField
 Descripción
 Texto editable de una sola línea
 Estado y propiedades (además de las de TextComponent)
 TextField(), TextField(String),
TextField(String,int)
 getColumns(), setColumns(int)
 getEchoChar(), setEchoChar(char), echoCharIsSet()
 Operación
 Emite un TextEvent cuando se cambia un carácter del texto
Puede interesar procesar KeyEvent's si interesa obtener el
carácter
 Cuando se pulsa 'Enter' emite un ActionEvent con el texto del
widget como action command string

POO - EPS - UAM 152 POO - EPS - UAM 155

java.awt.TextArea java.awt.Dialog

 Descripción  Descripción
 Texto editable multilínea con scrolling  Depende de otra ventana:
 Estado y propiedades (además de las de TextComponent)  Se destruye cuando se destruye la ventana principal
 TextArea(), TextArea(String),  Desaparece cuando se minimiza la ventana principal
TextArea(String,int,int)  Estado y propiedades
 Scrollbars: TextArea(String,int,int,int),  Dialog (Frame [,String] [,boolean])
TextArea.SCROLLBARS_NONE,
SCROLLBARS_VERTICAL_ONLY...
 Modal / no modal: isModal(), setModal(boolean)
 getColumns(), setColumns(int), getRows(), setRows(int)
 isResizeable(), setResizeable(boolean)
 append(String), insert(String,int), replaceRange(String,int,int)
de Window
 Operación  FileDialog extends Dialog
 Emite un TextEvent cuando se cambia un carácter del texto  getDirectory(), setDirectory(String)
 No emite ActionEvent's  getFile(), setFile(String)

POO - EPS - UAM 153 POO - EPS - UAM 156

26
class DialogWindow extends Frame implements ActionListener {
private SimpleDialog dialog;
private TextArea textArea;
java.awt.Dialog
public DialogWindow () {
textArea = new TextArea (5, 40);
textArea.setEditable (false);
add ("Center", textArea);
Button button = new Button ("Click to bring up dialog");
button.addActionListener (this);
Panel panel = new Panel ();
panel.add (button);
add ("South", panel);
}
public void actionPerformed (ActionEvent event) {
if (dialog == null)
dialog = new SimpleDialog (this, "A Simple Dialog");
dialog.setVisible (true);
}
public void addLine (String text) {
textArea.append(text + "\n");
}
}

POO - EPS - UAM 157 POO - EPS - UAM 160

Widgets personalizados
class SimpleDialog extends Dialog implements ActionListener {
TextField field;
DialogWindow parent; class Boton extends Canvas implements MouseListener {
Button setButton; private boolean selected = false;
SimpleDialog (Frame w, String title) { protected String label;
super (w, title, false); public Boton (String str) {
parent = (DialogWindow) w; label = str;
Panel p1 = new Panel (); addMouseListener (this);
p1.setLayout (new GridLayout (2, 1)); new Mover (this);
Label label = new Label ("Enter text here:"); }
p1.add (label); public void paint (Graphics g) {
field = new TextField (40); Dimension dim = getSize ();
aspecto visual

field.addActionListener (this); FontMetrics metrics = g.getFontMetrics ();


p1.add (field); g.drawRect (0, 0, dim.width-1, dim.height-1);
Definir

add ("Center", p1); g.drawString (label,


... (dim.width - metrics.stringWidth (label)) / 2,
(dim.height - metrics.getHeight ()) / 2
+ metrics.getMaxAscent ());
}
POO - EPS - UAM 158 ... POO - EPS - UAM 161

...
Panel p2 = new Panel(); Métodos para negociar
p2.setLayout (new FlowLayout (FlowLayout.RIGHT)); tamaño con layout managers
Button b = new Button ("Cancel");
b.addActionListener (this); ...
setButton = new Button ("Set"); public Dimension getPreferredSize () {
setButton.addActionListener (this); FontMetrics metrics = getGraphics () .getFontMetrics ();
p2.add (b); return new Dimension (metrics.stringWidth (label) + 20,
p2.add (setButton); metrics.getHeight () + 10);
}
add ("South", p2);
pack ();
public Dimension getMinimumSize () {
} Dimension dim = getPreferredSize ();
return new Dimension (dim.width / 2, dim.height / 2);
public void actionPerformed (ActionEvent event) { }
Object source = event.getSource();
if ((source == setButton) || (source == field)) public Dimension getMaximumSize () {
parent.addLine (field.getText()); Dimension dim = getPreferredSize ();
field.selectAll (); return new Dimension (dim.width * 2, dim.height * 2);
setVisible (false); }
...
}
}
POO - EPS - UAM 159 POO - EPS - UAM 162

27
...
public void mouseClicked (MouseEvent e) {
1. Inicio 4. Exit
selected = !selected;
Respuesta visual (feedback)
if (selected) {
a acción del usuario
setBackground (Color.black);
setForeground (Color.white);
}
else {
setBackground (Color.white);
2. Enter 5. Enter
setForeground (Color.black);
}
}

public void mousePressed (MouseEvent e) {}


public void mouseReleased (MouseEvent e) {}
public void mouseEntered (MouseEvent e) {}
public void mouseExited (MouseEvent e) {} 3. Click 6. Drag
...

POO - EPS - UAM 163 POO - EPS - UAM 166

...
public String getLabel () { return label; } class BotonAccion extends Boton {
public void setLabel (String str) { private ActionListener multicaster = null;
label = str; public BotonAccion (String str) { super (str); }
Interfaz para controlar el estado del widget

repaint (); public void mouseClicked (MouseEvent e) {


} super.mouseClicked (e);
public boolean getState () { return selected; } processEvent ( Generación de eventos en
public void setState (boolean state) { respuesta a la interacción
new ActionEvent (
selected = state; this, ActionEvent.ACTION_PERFORMED, label));
if (selected) { }
setBackground (Color.black); public void addActionListener (ActionListener listener) {
setForeground (Color.white); multicaster =
} AWTEventMulticaster.add (multicaster, listener);
else { }
setBackground (Color.white); public void processEvent (AWTEvent e) {
setForeground (Color.black); if (e.getID () == ActionEvent.ACTION_PERFORMED
}
} && multicaster != null)
// public void mouseClicked (MouseEvent e) { multicaster.actionPerformed ((ActionEvent) e);
// setState (!selected); super.processEvent (e);
}
// } }
}
POO - EPS - UAM 164 POO - EPS - UAM 167

class Boton2 extends Boton {


boolean pointedAt = false;
public Boton2 (String str) { super (str); }

public void paint (Graphics g) {


super.paint (g);
Dimension dim = getSize ();
if (pointedAt)
g.drawRect (4, 4, dim.width-9, dim.height-9);
}

public void mouseEntered (MouseEvent e) {


acciones del usuario

pointedAt = true;
Más feedback a

repaint ();
}
public void mouseExited (MouseEvent e) {
pointedAt = false;
repaint ();
}
}

POO - EPS - UAM 165

28

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