test area

93
1 Interfaces Gráficas de Usuario Introducción Programación basada en eventos POO - EPS - UAM 2 Desarrollo de interfaces de usuario Generalización del Importancia creciente uso del ordenador de la facilidad de uso La interfaz de usuario no añade funcionalidad a una aplicación Sin embargo es un aspecto decisivo en el éxito de un producto Desarrollo muy costoso Normalmente, 50% del esfuerzo se dedica al desarrollo de la interfaz Herramientas que ayudan al desarrollo de interfaces

Transcript of test area

Page 1: test area

1

Interfaces Gráficas de Usuario

Introducción Programación basada en eventos

POO - EPS - UAM 2

Desarrollo de interfaces de usuario

  Generalización del ⇒ Importancia creciente uso del ordenador de la facilidad de uso

  La interfaz de usuario no añade funcionalidad a una

aplicación   Sin embargo es un aspecto decisivo en el éxito de un producto

  Desarrollo muy costoso   Normalmente, 50% del esfuerzo se dedica al desarrollo de la interfaz

  Herramientas que ayudan al desarrollo de interfaces

Page 2: test area

2

POO - EPS - UAM 3

Herramientas: software para el desarrollo de interfaces (I)

  Basadas en una categorización, modelización de formas de

interfaz

  Facilitan el desarrollo

  Proporcionan parte del código

  Ayudan a organizar/estructurar el código escrito por el programador

  Limitan (condicionan) las características de las interfaces

que se pueden desarrollar

  Alternativa: pintar en la pantalla, seguir movimiento e input

del ratón

POO - EPS - UAM 4

Herramientas: software para el desarrollo de interfaces (II)

  Sistemas de ventanas / toolkits: Microsoft Windows, X-Window + Motif, Mac/OS, OS/2 PM, etc.

  Interfaz al sistema operativo

  Librería para el desarrollo de interfaces gráficas

  Bajo nivel, máxima expresividad, dificultad de uso

  Librerías de objetos: Java AWT, Swing, Microsoft MFC, Borland OWL, etc.   Código más fácil de producir y mantener

  Normalmente acompañadas de un constructor gráfico de interfaces

  Constructores gráficos de interfaces: MS-Visual Studio, Netbeans, etc.   Programación visual

  Gran facilidad de uso, utilidad limitada

  Otras herramientas avanzadas: campo de investigación

Page 3: test area

3

POO - EPS - UAM 5

Nivel de las herramientas

Facilidad de desarrollo

Rango de interfaces generadas

POO - EPS - UAM 6

¿Qué tienen que ver las interfaces con POO?

 El usuario ve objetos en la pantalla  El usuario puede manipular los objetos  Los objetos tienen comportamiento propio: distintas

formas de responder a una acción del usuario:   Por ejemplo: pulsar el ratón sobre un objeto gráfico

Page 4: test area

4

POO - EPS - UAM 7

¿Qué tienen que ver las interfaces con POO?

 No existe una función "pulsar ratón" que sepa lo que debe hacer según el elemento sobre el que actúa

 Cada elemento gráfico contiene la funcionalidad correspondiente a la acción de pulsar el ratón (la responsabilidad reside en el objeto)

 Programación basada en eventos (mensajes)

POO - EPS - UAM 8

Un nuevo modelo de programación

Programación basada en eventos

Main

f (x)

f(arg)

g()

g()

control, flujo ejecución

Main

f(arg)

g()

ejecuta

pregunta / respuesta

termina

no hay orden estrictro

Page 5: test area

5

POO - EPS - UAM 9

Programación basada en eventos (I)

  El modo de operación de una interfaz de usuario no se ajusta

a un control de flujo estrictamente secuencial

  El usuario tiene un alto grado de libertad en todo momento:

normalmente dispone de un amplio conjunto de acciones

posibles

  Es muy difícil representar todos los caminos posibles con un

modelo de programación tradicional

POO - EPS - UAM 10

Programación basada en eventos (II)

  Modelo utilizado en las interfaces de usuario actuales basadas en ventanas

  La iniciativa no la lleva el programa sino el usuario   El programa se divide en subprogramas asociados a ventanas o

componentes gráficas   Las componentes están a la espera de las acciones del usuario   Las acciones del usuario generan eventos que se acumulan en una cola   El sistema de eventos extrae eventos de la cola y los envía a los

programas   Los programas procesan los eventos recibidos respondiendo según el

tipo de evento   Cada tipo de componente se caracteriza por una forma propia de

respuesta a los eventos

Page 6: test area

6

POO - EPS - UAM 11

evento 1

evento 2

...

event n

...

Despachador

Programación basada en eventos (III)

eventos (acciones) de usuario

Interfaz

Cola de eventos

Componentes de la interfaz

mensajes

POO - EPS - UAM 12

La base: el sistema de ventanas   Funciones de dibujo de primitivas gráficas: formas geométricas, texto, etc.

  Generación de mensajes (eventos)

  La ventana recibe eventos sin diferenciar

  Respuesta de ventanas a eventos:

  Repintar

  Cambiar apariencia y repintar

  Ejecutar una función (acción)

Usuario Acción del usuario Sistema

de ventanas (p.e. Windows)

Mensaje

Ventana

Page 7: test area

7

POO - EPS - UAM 13

Ventanas

  Área rectangular de la pantalla en la que tiene lugar una

interacción (intercambio de input y output) con el usuario

  Recibe input del usuario (ratón y teclado), muestra output

por intermedio del sistema de ventanas, mediante envío de

mensajes

  Ventana marco: ventana principal asociada a una aplicación

  Ventanas hijas: subáreas que procesan sus propios eventos

POO - EPS - UAM 14

Ejemplo de programa con Java AWT

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

public class Ventana extends Frame implements WindowListener { public static void main (String args[]) { Ventana v = new Ventana (); v.setSize (300, 200); v.addWindowListener (v); v.setVisible (true); } public void paint (Graphics g) { g.drawString("Hola a todos!", 100, 100); } public void windowClosing (WindowEvent e) { dispose (); } public void windowClosed (WindowEvent e) {} public void windowActivated (WindowEvent e) {} public void windowDeactivated (WindowEvent e) {} public void windowIconified (WindowEvent e) {} public void windowDeiconified (WindowEvent e) {} public void windowOpened (WindowEvent e) {} }

Page 8: test area

8

POO - EPS - UAM 15

Resultado...

POO - EPS - UAM 16

Java Abstract Window Toolkit (AWT)

  Las componentes son objetos   A cada tipo de evento corresponde un

método de la componente   La respuesta a eventos se define

implementando métodos

Acción del usuario

Sistema de ventanas

Mensaje

Componentes AWT

Sistema AWT

Invocación a método

Usuario

Page 9: test area

9

POO - EPS - UAM 17

Interfaces orientadas a objetos

 Objetos gráficos con:   Estado: variables de la clase

  Propiedades visuales: color, posición, tamaño   Valores visualizados: string, bitmap, etc.   Valores internos

  Presencia en la pantalla: método paint ()   Mantiene un dibujo en la pantalla   Depende del estado: controlar la apariencia a través del estado

  Comportamiento: respuesta a eventos   Cambios de estado o apariencia   Ejecución de funciones (acción)   Emisión de eventos

POO - EPS - UAM 18

Objetos gráficos

Objetos del programa

Presentación en la pantalla

Page 10: test area

10

Abstract Window Toolkit (AWT)

1ra. Parte: Introducción

POO - EPS - UAM 20

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

 Componentes   Componentes predefinidas   Agregación de componentes   Las interfaces se dibujan a sí mismas: funciones de

dibujo   Creación de nuevas componentes

  Interacción con el usuario: gestión de eventos   Emisión de eventos   Recepción y procesamiento de eventos

 Layout de componentes

Page 11: test area

11

POO - EPS - UAM 21

Anatomía de un programa basado en GUI

  Componer interfaces con las clases predefinidas   La clase Container, adición de subcomponentes   Control de la apariencia de las componentes manipulando su estado

  Definir la disposición de las partes de un contenedor   Posiciones absolutas   Layout managers

  Gestionar los eventos: modelo emisor / receptor   Eventos de acción generados por las clases predefinidas   Gestión directa del input del usuario

  Definir componentes personalizadas   La clase Canvas   Utilización de las funciones de dibujo

POO - EPS - UAM 22

Ejemplo: editor de texto

Page 12: test area

12

POO - EPS - UAM 23

Componentes predefinidas

Frame

TextField

Button

TextArea

Label

POO - EPS - UAM 24

Disposición de las componentes

Alto fijo

Llenar espacio disponible hasta

borde inferior de la ventana

Ancho ocupa toda la ventana

Ancho fijo, centrado

Ancho ocupa toda la ventana

Page 13: test area

13

POO - EPS - UAM 25

Aspectos interactivos

Editar texto del campo

Cerrar ventana

Editar texto multilínea

Leer el fichero indicado en el campo de texto,

asignar como string del área de texto

Escribir string del área de texto en el fichero indicado en el campo de texto

POO - EPS - UAM 26

Ejemplo: código (I) import java.awt.*; import java.awt.event.*; import java.io.*;

public class Editor extends Frame implements WindowListener, ActionListener { TextField fileName; TextArea fileBuffer; Button load, save, quit;

Editor () { setLayout (null);

Label label = new Label ("File Name: "); label.setBounds (10, 30, 300, 20); add (label);

fileName = new TextField (); fileName.setBounds (10, 50, 290, 20); add (fileName); ...

Page 14: test area

14

POO - EPS - UAM 27

Ejemplo: código (II) load = new Button ("Load"); load.setBounds (40, 80, 60, 20); add (load);

save = new Button ("Save"); save.setBounds (120, 80, 60, 20); add (save);

quit = new Button ("Quit"); quit.setBounds (200, 80, 60, 20); add (quit);

fileBuffer = new TextArea (); 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 28

Ejemplo: código (III)

... public void actionPerformed (ActionEvent e) { String command = e.getActionCommand (); if (command.equals ("Quit")) dispose (); else if (command.equals ("Load")) load (); else if (command.equals ("Save")) save (); }

public void windowClosing (WindowEvent e) { dispose (); } public void windowActivated (WindowEvent e) {} public void windowClosed (WindowEvent e) {} public void windowDeactivated (WindowEvent e) {} public void windowDeiconified (WindowEvent e) {} public void windowIconified (WindowEvent e) {} public void windowOpened (WindowEvent e) {} ...

Page 15: test area

15

POO - EPS - UAM 29

Ejemplo: código (IV)

... void load () { try { RandomAccessFile input = new RandomAccessFile (fileName.getText (), "r"); byte buffer[] = new byte [(int) input.length ()]; input.read (buffer); input.close (); fileBuffer.setText (new String (buffer)); } catch (IOException e) { System.out.println (e); } } void save () { try { FileWriter output = new FileWriter (fileName.getText ()); output.write (fileBuffer.getText ()); output.close (); } catch (IOException e) { System.out.println (e); } } ...

POO - EPS - UAM 30

Ejemplo: código (V)

... public static void main (String args[]) { Editor edit = new Editor (); edit.setSize (320, 320); edit.setVisible (true); } } // Fin clase Editor

Page 16: test area

16

POO - EPS - UAM 31

Resumen

 Programar un IU para una aplicación en Java involucra:   Composición   Layout   Eventos   Paint

Abstract Window Toolkit (AWT)

2da. Parte: Componentes

Page 17: test area

17

POO - EPS - UAM 33

Componentes AWT predefinidas

POO - EPS - UAM 34

Jerarquía de componentes AWT: el package java.awt

Jerarquía = Herencia

Page 18: test area

18

POO - EPS - UAM 35

Jerarquía de componentes AWT: el package java.awt

Jerarquía = Herencia

POO - EPS - UAM 36

Uso componentes AWT: ejemplo

Page 19: test area

19

POO - EPS - UAM 37

Clases en el ejemplo

Label

TextField

ScrollBar

Converter Frame

Choice

ConversionPanel

layout manager: GridBagLayout

POO - EPS - UAM 38

Código del ejemplo

import java.awt.*; import java.awt.event.*; import java.util.*; import java.applet.Applet;

public class Converter extends Frame { ConversionPanel metricPanel, usaPanel; Unit[] metricDistances = new Unit[3]; Unit[] usaDistances = new Unit[4];

public void init() { // Use a GridLayout with 2 rows, as many columns as necessary, // and 5 pixels of padding around all edges of each cell. setLayout(new GridLayout(2,0,5,5)); ....

Creación de la

ventana

Page 20: test area

20

POO - EPS - UAM 39

Código del ejemplo // Create Unit objects for metric distances, and then // instantiate a ConversionPanel with these Units. metricDistances[0] = new Unit("Centimeters", 0.01); metricDistances[1] = new Unit("Meters", 1.0); metricDistances[2] = new Unit("Kilometers", 1000.0); metricPanel = new ConversionPanel(this, "Metric System", metricDistances);

//Create Unit objects for U.S. distances, and then //instantiate a ConversionPanel with these Units. usaDistances[0] = new Unit("Inches", 0.0254); usaDistances[1] = new Unit("Feet", 0.305); usaDistances[2] = new Unit("Yards", 0.914); usaDistances[3] = new Unit("Miles", 1613.0); usaPanel = new ConversionPanel(this, "U.S. System", usaDistances);

//Add both ConversionPanels to the Converter. add(metricPanel); add(usaPanel); }

Inicialización

POO - EPS - UAM 40

Código del ejemplo

/** * Does the conversion from metric to U.S., or vice versa, and * updates the appropriate ConversionPanel. */

void convert(ConversionPanel from) { ConversionPanel to;

if (from == metricPanel) to = usaPanel; else to = metricPanel;

double multiplier = from.getMultiplier() / to.getMultiplier(); to.setValue(multiplier * from.getValue()); }

funcionalidad

Page 21: test area

21

POO - EPS - UAM 41

Código del ejemplo

/** Draws a box around this panel. */ public void paint(Graphics g) { Dimension d = getSize(); g.drawRect(0,0, d.width - 1, d.height - 1); }

/** * Puts a little breathing space between * the panel and its contents, which lets us draw a box * in the paint() method. */ public Insets getInsets() { return new Insets(5,5,5,5); }

Dibujo

POO - EPS - UAM 42

Código del ejemplo public static void main(String[] args) { //Create a new window. Frame f = new Frame("Converter Applet/Application"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); //Create a Converter instance. Converter converter = new Converter(); converter.init();

//Add the Converter to the window and display the window. f.add("Center", converter); f.pack(); //Resizes the window to its natural size. f.setVisible(true); } }

Main

Page 22: test area

22

POO - EPS - UAM 43

Código del ejemplo

class ConversionPanel extends Panel implements ActionListener, AdjustmentListener, ItemListener { TextField textField; Choice unitChooser; Scrollbar slider; int max = 10000; int block = 100; Converter controller; Unit[] units;

Panel interno

POO - EPS - UAM 44

Código del ejemplo ConversionPanel(Converter myController, String myTitle, Unit[] myUnits) { //Initialize this ConversionPanel to use a GridBagLayout. GridBagConstraints c = new GridBagConstraints(); GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag);

controller = myController; //Save arguments in instance variables. units = myUnits;

//Set up default layout constraints. c.fill = GridBagConstraints.HORIZONTAL;

//Add the label. It displays this panel's title, centered. Label label = new Label(myTitle, Label.CENTER); c.gridwidth = GridBagConstraints.REMAINDER; //It ends a row. gridbag.setConstraints(label, c); add(label);

Composición

Page 23: test area

23

POO - EPS - UAM 45

Código del ejemplo

//Add the text field. It initially displays "0" and needs //to be at least 10 columns wide.

textField = new TextField("0", 10); c.weightx = 1.0; //Use maximum horizontal space... c.gridwidth = 1; //The default value. gridbag.setConstraints(textField, c); add(textField); textField.addActionListener(this);

+ componentes

POO - EPS - UAM 46

Código del ejemplo

//Add the pop-up list (Choice).

unitChooser = new Choice(); for (int i = 0; i < units.length; i++) { //Populate it. unitChooser.add(units[i].description); } c.weightx = 0.0; //The default value. c.gridwidth = GridBagConstraints.REMAINDER; //End a row. gridbag.setConstraints(unitChooser, c); add(unitChooser); unitChooser.addItemListener(this);

+ componentes

Page 24: test area

24

POO - EPS - UAM 47

Código del ejemplo

// Add the slider. It's horizontal, and it has the maximum // value specified by the instance variable max. Its initial // and minimum values are the default (0). A click increments // the value by block units.

slider = new Scrollbar(Scrollbar.HORIZONTAL); slider.setMaximum(max + 10); slider.setBlockIncrement(block); c.gridwidth = 1; //The default value. gridbag.setConstraints(slider, c); add(slider); slider.addAdjustmentListener(this); } + componentes

POO - EPS - UAM 48

Código del ejemplo

/** Draws a box around this panel. */ public void paint(Graphics g) { Dimension d = getSize(); g.drawRect(0,0, d.width - 1, d.height - 1); }

/** * Puts a little breathing space between the panel * and its contents, which lets us draw a box in the paint() method. */ public Insets getInsets() { return new Insets(5,5,5,8); }

Dibujo

Page 25: test area

25

POO - EPS - UAM 49

Código del ejemplo

/** Respond to the text field */ public void actionPerformed(ActionEvent e) { setSliderValue((double)Double.valueOf( textField.getText()).doubleValue()); controller.convert(this); }

/** Respond to the choice */ public void itemStateChanged(ItemEvent e) { controller.convert(this); }

/** Respond to the slider. */ public void adjustmentValueChanged(AdjustmentEvent e) { textField.setText(String.valueOf(e.getValue())); controller.convert(this); }

Respuesta a eventos

POO - EPS - UAM 50

Código del ejemplo

/** Set the values in the slider and text field. */ void setValue(double f) { setSliderValue(f); textField.setText(String.valueOf((float)f)); }

/** Set the slider value. */ void setSliderValue(double f) { int sliderValue = (int)f;

if (sliderValue > max) sliderValue = max; if (sliderValue < 0) sliderValue = 0; slider.setValue(sliderValue); } }

Modificación componentes

Page 26: test area

26

POO - EPS - UAM 51

Cómo se usan las componentes AWT

 Jerarquía de componentes:   Las componentes son estructuradas en una jerarquía de

componentes, con instancias de (subclases de) Container definiendo dicha estructura.

 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

Jerarquía = Composición

POO - EPS - UAM 52

Jerarquía de componentes: la clase java.awt.Container

  Las interfaces se construyen agregando componentes a modo de piezas

  La jerarquía de componentes debe empezar con una ventana (frame) o un applet

  Una componente sólo puede añadirse a un Container   Agregar: add(Component)   Retirar: remove(Component)

  Las ventanas no pueden añadirse a otra componente   La colocación de las componentes en un contenedor se

puede definir:   Mediante layout managers de distintos tipos   A mano, con posiciones absolutas

Jerarquía = Composición

Page 27: test area

27

POO - EPS - UAM 53

Jerarquía de componentes (II)

 Las componentes se pueden añadir:   En el constructor del contenedor   En main   En cualquier función

 Atravesar el árbol de componentes:   Acceso a componentes: getComponent(int),

getComponentAt(int,int), getComponentCount(), getComponents()

  Acceso al contenedor desde una componente: getParent()

Jerarquía = Composición

POO - EPS - UAM 54

Jerarquía de componentes: ejemplo

public class Converter extends Frame { . . . public void init() { . . . add(metricPanel); add(usaPanel); . . .

Page 28: test area

28

POO - EPS - UAM 55

Apariencia de las componentes: paint(Graphics) de Component

  La apariencia en pantalla de cada subclase de Component está definida por el código de paint(Graphics)

  El código de paint consiste en llamadas a funciones de dibujo sobre el objeto de tipo Graphics

  Es poco factible cambiar el dibujo de las componentes predefinidas (En cambio, es fácil cambiar su respuesta a eventos)   Normalmente no se redefine paint de las clases predefinidas   Para modificar su apariencia, modificar su estado (el sistema refleja

los cambios en la pantalla automáticamente)   En componentes personalizadas desde cero sí se define paint

  Es importante que paint no sea costoso de ejecutar   Utilizar hilos si es necesario para no bloquear el repintado

POO - EPS - UAM 56

Dibujo de componentes

 El dibujo comienza por el componente más alto en la jerarquía que necesita ser dibujado   Por ejemplo, un Frame.

 Se baja por la jerarquía, dibujando cada componente intermedio, hasta las hojas.

 El sistema de dibujo de AWT organiza este procedimiento

 No se pueden hacer suposiciones sobre el orden relativo de dibujo de las componentes

Page 29: test area

29

POO - EPS - UAM 57

Dibujo de componentes: ejemplo

 Se dibuja el frame  Se dibuja el Converter

  Caja del borde  Se dibuja uno de los

dos ConversionPanel   Caja del borde

 Los componentes de este panel (Label, TextField, Scrollbar y Choice) son dibujados

POO - EPS - UAM 58

Refresco de las componentes

 Cuándo   Al desplegar una ventana o cambiarle el tamaño   Al hacer visible un componente   Al cambiar desde el programa propiedades visuales de un

componente   Al ser necesario cambiar la apariencia de uno

componente para reflejar cambios en la aplicación  Quién solicita

  En los tres primeros casos, el sistema AWT.   En el último caso, el mismo programa

Refresco = (re)dibujar

Page 30: test area

30

POO - EPS - UAM 59

Refresco de las componentes

 El proceso de dibujo en sí sólo puede llevarse a cabo cuando lo diga el sistema AWT   Estos procesos se deben ejecutar sin

interrupción.   AWT hace que todos los dibujos ocurran en el

mismo hilo.  El dibujo no puede insumir mucho tiempo

  Si es necesario, crear un hilo separado para ejecutar alguna operación larga

POO - EPS - UAM 60

Refresco de las componentes: update(Graphics) y repaint()

 AWT decide dibujar un componente   invoca a update(Graphics)   Esta invocación se hace desde el hilo de procesamiento

de eventos   update(Graphics) borra el área a refrescar e invoca a

paint(Graphics)  Lo solicita el programa

  invoca a repaint()   Petición al sistema AWT para llamar a update lo antes

posible   El programa no debe llamar a paint directamente

Page 31: test area

31

POO - EPS - UAM 61

Refresco de las componentes: el objeto Graphics

 Es el argumento de los métodos update y paint   Normalmente nos llega a nuestro código desde AWT

 Provee métodos para:   Dibujar y rellenar rectángulos, arcos, líneas, óvalos,

polígonos, textos e imágenes.   Obtener o cambiar el color, tipo de fuente o área de

clipping actuales.   Cambiar el modo de dibujo.

POO - EPS - UAM 62

Refresco de las componentes: ejemplo

 La forma más simple de dibujar una componente es especializar el método paint

 Ejemplo: /** Draws a box around this panel. */ public void paint(Graphics g) { Dimension d = getSize(); g.drawRect(0,0, d.width - 1, d.height - 1); }

Page 32: test area

32

POO - EPS - UAM 63

Gestión de eventos: modelo de eventos de AWT 1.1

 Modelo basado en delegación   Eventos generados por emisores (sources) de

eventos.   Objetos (listeners) se registran para ser

notificados de eventos:  De cierto tipo  Desde un emisor en particular

 Se pueden tratar y generar eventos

POO - EPS - UAM 64

Gestión de eventos

  Los eventos son objetos de distintas subclases de AWTEvent   Se generan eventos cuando:

  Se produce input del usuario: MouseEvent,KeyEvent   Un widget se acciona: ActionEvent, TextEvent, AdjustmentEvent

  Una ventana es manipulada: WindowEvent   Otras causas: ContainerEvent, ComponentEvent, PaintEvent, etc.

  Los manejadores de eventos (listeners) pueden ser instancias de cualquier clase.   Sólo es necesario que la clase implemente la interfaz listener

correspondiente

Page 33: test area

33

POO - EPS - UAM 65

Estructura de programa

  En cada programa con un manejador de eventos:

1.  En el encabezamiento de la clase, declaración de implementar la interfaz (o extender una clase que la implemente):

public class MyClass implements ActionListener {

2.  Código que registra una instancia del manejador como receptor de eventos de uno o más emisores:

someComponent.addActionListener(instanceOfMyClass);

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 66

Ejemplo visto

class ConversionPanel extends Panel implements

ActionListener, AdjustmentListener, ItemListener {

textField.addActionListener(this);

public void actionPerformed(ActionEvent e) {

setSliderValue((double)Double.valueOf( textField.getText()).doubleValue());

controller.convert(this);

}

Page 34: test area

34

Abstract Window Toolkit (AWT)

Repaso de clases básicas

POO - EPS - UAM 68

java.awt.Component

 Dibujarse en la pantalla: paint(), update(), repaint()

 Procesamiento de eventos: delegación  Control de la apariencia visual:

  Color: setForeground(Color), getForeground(), setBackground(Color), getBackground()

  Font: setFont(Font), getFont()   Cursor: setCursor(Cursor), getCursor()

Page 35: test area

35

POO - EPS - UAM 69

java.awt.Component (II)

 Tamaño y posición:   setSize(int,int)

  getSize() Dimension

  getLocation() Point

  getLocationOnScreen() Point

  setBounds(int,int,int,int)

  getBounds() Rectangle

(El layout manager puede alterar estos valores)  Mostrar detalles en System.out: list()

POO - EPS - UAM 70

java.awt.Graphics

  Argumento de paint() y update()   Dibujo de primitivas gráficas:

  drawLine(int,int, int,int), drawRect(int,int,int,int), 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)

Page 36: test area

36

POO - EPS - UAM 71

Clases auxiliares en java.awt

 Posiciones y tamaños:   Dimension: width, height

  Point: x, y

  Rectangle: x, y, width, height, contains(Point)

  Polygon: npoints, xpoints, ypoints, addPoint(Point)

 Color:   new Color(0.8f, 0.3f, 1.0f) en RGB   Constantes de tipo Color: Color.white,Color.blue,

etc.   Funciones para conversión RGB ↔ HSB

POO - EPS - UAM 72

Clases auxiliares en java.awt (II)

 Font:   new Font ("Helvetica", Font.BOLD + Font.ITALIC, 18)

  getName(), getStyle(), getSize()

  Constantes de estilo: Font.BOLD, Font.ITALIC, Font.PLAIN

 Cursor:   new Cursor(Cursor.HAND_CURSOR)

  Cursor.CROSSHAIR_CURSOR

  etc.

Page 37: test area

37

Abstract Window Toolkit (AWT)

3ra. Parte: Gestión de Eventos

POO - EPS - UAM 74

Modelo de eventos

 Modelo basado en delegación.  A cada tipo de evento xxxEvent corresponde:

  Un tipo de receptor xxxListener (excepción: MouseEvent tiene dos)

  Una lista de clases de componentes que pueden producir el evento

  Un método addxxxListener para registrar receptores de esos eventos   Este método está definido en las clases que generan el evento   Una componente sólo puede registrar listeners del tipo de eventos

que genera la componente

Page 38: test area

38

POO - EPS - UAM 75

Clase de evento: ActionEvent

Objetos que lo emiten: Button, TextField, List, MenuItem

Tipo de interfaz listener: ActionListener

Métodos a implementar en clase listener: actionPerformed (ActionEvent)

Método para registrar listener: addActionListener (ActionListener)

Modelo de eventos: ejemplo

Una componente sólo puede registrar listeners del tipo de eventos que genera la componente

POO - EPS - UAM 76

Modelo de eventos: ejemplo

public class Beeper implements ActionListener { ... //where initialization occurs: button = new Button("Click Me"); button.addActionListener(this); ... public void actionPerformed(ActionEvent e){ ...//Implements the answer... } }

Page 39: test area

39

POO - EPS - UAM 77

Utilización de adapters y clases internas

 La mayoría de las interfaces de eventos contienen más de un evento.   Por ejemplo, MouseListener define cinco

métodos.   Aunque sólo nos interese un evento, si nuestra

clase implementa directamente la interfaz, igual debemos dar código (probablemente un cuerpo vacío) para los otros cuatro métodos

POO - EPS - UAM 78

Ejemplo de código de listener public class MyClass implements MouseListener { ...

someObject.addMouseListener(this);

...

/* Empty method definition. */

public void mousePressed(MouseEvent e) { }

/* Empty method definition. */

public void mouseReleased(MouseEvent e) { }

/* Empty method definition. */

public void mouseEntered(MouseEvent e) { }

/* Empty method definition. */

public void mouseExited(MouseEvent e) { }

public void mouseClicked(MouseEvent e) {

...//Event handler implementation goes here... }

}

Page 40: test area

40

POO - EPS - UAM 79

Utilización de adapters

 Este tipo de código resulta más difícil de leer y mantener.

 Para evitar la implementación vacía de métodos, AWT provee clases adapters   implementan listeners con métodos vacíos;   proporciona los adaptadores en java.awt.event;   para cada interfaz de listener con más de un método.

 Crear una subclase del adaptador definiendo sólo los métodos que interesen

POO - EPS - UAM 80

Utilización de adapters: ejemplo

  Por ejemplo, si se extiende la clase MouseAdapter se hereda definiciones (vacías) de los cinco métodos definidos por la interfaz MouseListener. class MouseAdapter implements MouseListener { public void mouseClicked (MouseEvent e) {} public void mousePressed (MouseEvent e) {} public void mouseReleased (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseExited (MouseEvent e) {} }

public class MyClass extends MouseAdapter { ... someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) { ...//Event handler implementation goes here... } }

Page 41: test area

41

POO - EPS - UAM 81

Adaptadores: problemas (I)

 Una subclase de Component no puede heredar de otra clase

⇒ Utilizar un objeto adaptador auxiliar para hacer de listener

POO - EPS - UAM 82

Adaptadores: código

class MyListener extends MouseAdapter {

public void mouseEntered (MouseEvent e) {

... // Respuesta de la ventana al evento

} }

class Ventana extends Frame {

Ventana () {

Button boton = new Button ();

boton.addMouseListener (new MyListener ());

...

} }

Page 42: test area

42

POO - EPS - UAM 83

Adaptadores: problemas (II)

 A menudo los métodos listener necesitan acceder a variables de la clase de componente   Incluir en el adaptador una variable que apunte a

la componente   O bien definir el adaptador como clase interna

de la clase de componente

POO - EPS - UAM 84

class Ventana extends Frame {

private String nombre;

Ventana () { Button boton = new Button (); boton.addMouseListener (new MyListener ()); ... }

class MyListener extends MouseAdapter { public void mouseEntered (MouseEvent e) { ... System.out.println (nombre); ... } } }

Adaptador como clase interna

Page 43: test area

43

POO - EPS - UAM 85

class Ventana extends Frame {

private String nombre; Ventana () { Button boton = new Button ();

boton.addMouseListener (

new MouseAdapter () { public void mouseEntered (MouseEvent e) { ...

System.out.println (nombre);

... } } ); } }

Adaptador como clase anónima

POO - EPS - UAM 86

class Mover extends MouseAdapter implements MouseMotionListener { private Point initialPoint; public Mover (Component c) { listenTo (c); } public void listenTo (Component c) { c.addMouseListener (this); c.addMouseMotionListener (this); } public void mousePressed (MouseEvent e) { initialPoint = e.getPoint (); } public void mouseDragged (MouseEvent e) { Component c = (Component) e.getSource (); Point p = c.getLocation (); c.setLocation (p.x + e.getX () - initialPoint.x, p.y + e.getY () - initialPoint.y); } public void mouseMoved (MouseEvent e) {} }

Adaptadores autosuficientes = reutilizables

new Mover (obj);

Page 44: test area

44

POO - EPS - UAM 87

Ver apéndice A

 Clases de Eventos  Métodos de los listeners

Abstract Window Toolkit (AWT)

4ta. Parte: Gestión de Eventos:

Implementación de los listeners

Page 45: test area

45

POO - EPS - UAM 89

¿Qué deben hacer los métodos de los receptores?

 Modificar características de la interfaz   Cambiar colores, fonts, etiquetas, etc.   Mover objetos, cambiar su tamaño   Ocultar, mostrar, añadir, eliminar componentes   Abrir un cuadro de diálogo   etc.

 Ejecutar programas de la aplicación   Normalmente se refleja algún resultado en la interfaz

POO - EPS - UAM 90

¿Procesar eventos o ignorarlos?

  Eventos de bajo nivel recogidos en widgets y elaborados en forma de eventos de alto nivel   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.

Page 46: test area

46

POO - EPS - UAM 91

Contenido de las clases de eventos

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 92

Implementación de un ActionListener

  Probablemente son los más fáciles y comunes de implementar.

  Se implementa un ActionListener para responder a las indicaciones del usuario de que alguna acción dependiente de la implementación debe ocurrir.

  Cuándo ocurre?   Click sobre un botón   Doble Click sobre un item de lista   Elegir un menu item   Enter en un campo de texto

  Como resultado, se envía el mensaje actionPerformed a todos los listeners que se han registrado para ese componente

Page 47: test area

47

POO - EPS - UAM 93

Interfaz ActionListener

 Define un solo método 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 94

Ejemplo de ActionListener

Page 48: test area

48

POO - EPS - UAM 95

Ejemplo de ActionListener

public class MultiListener ... implements ActionListener { ... //where initialization occurs: button1.addActionListener(this); button2.addActionListener(this); button2.addActionListener(new Eavesdropper(bottomTextArea)); } public void actionPerformed(ActionEvent e) { topTextArea.append(e.getActionCommand() + "\n"); } }

class Eavesdropper implements ActionListener { ... public void actionPerformed(ActionEvent e) { myTextArea.append(e.getActionCommand() + "\n"); } }

POO - EPS - UAM 96

Ver apéndice B

 Implementación de interfaces de listeners

Page 49: test area

49

Abstract Window Toolkit (AWT)

5ta. Parte: Layout de componentes dentro de un

contenedor

POO - EPS - UAM 98

Layout de componentes

 ¿Qué es layout?   Disposición global de un conjunto de

componentes

Layout Manager

Page 50: test area

50

POO - EPS - UAM 99

Layout Manager

 Objeto que controla el tamaño y posición de los componentes de un contenedor.

  Implementan la interfaz LayoutManager  ¿Por qué layout managers?

  La posición de una componente depende de las componentes que la rodean y del espacio disponible para el grupo

  Un layout manager por encima de las componentes individuales impone un orden

  Las componentes negocian su colocación y tamaño con el layout manager.

POO - EPS - UAM 100

Clases de Layout Managers

 Existen distintas clases de manager para distintos tipos de layout   Predefinidos por AWT

 Simples: FlowLayout y GridLayout  Específicos: BorderLayout, CardLayout  Ultra flexible:GridBagLayout

  Cada uno tiene sus propias “reglas” de uso

Page 51: test area

51

POO - EPS - UAM 101

Clases de Layout Manager

 Cada Container tiene un controlador por omisión.   Panel FlowLayout   Windows BorderLayout

 Si no sirve, se puede cambiar fácilmente   setLayoutManager(LayoutManager) de Container.

 Es posible incluso crear manejadores propios

POO - EPS - UAM 102

Reglas generales de uso

 A menos que el programador lo cambie, cada contenedor tiene su propia instancia de LayoutManager asociada.

 Es consultado cada vez que que el contenedor tiene que cambiar su apariencia.

 La mayoría de los LayoutManagers no requiere que se llame explícitamente a sus métodos

Page 52: test area

52

POO - EPS - UAM 103

Cómo elegir LayoutManager

 Escenario:   Se necesita mostrar una componente en tanto espacio

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 104

Cómo elegir LayoutManager (II)

 Escenario:   Se necesita mostrar unas pocas componentes en una fila a

tamaño natural.

 Considere utilizar un Panel para contener los componentes y el manager por omisión para el Panel, el FlowLayout manager.

 Escenario:   Es necesario mostrar unos pocos componentes del mismo

tamaño en filas y/o columnas.

 El GridLayout es perfecto para esto.

Page 53: test area

53

POO - EPS - UAM 105

Algunas guías de uso

 Los siguientes métodos de Container provocan invocaciones al layout manager:   add(), remove(), removeAll(): en

cualquier momento.   layout(): usualmente como resultado de una

solicitud paint, y no directamente.   preferredSize(), minimumSize(): el

retorno es sólo una sugerencia, el programa tiene que mantener estos valores.

POO - EPS - UAM 106

Ver apéndice C

 Clases de layout managers

Page 54: test area

54

POO - EPS - UAM 107

Interfaz KeyListener

  void keyTyped(KeyEvent)   Llamado por AWT después que el usuario introduce un

carácter Unicode en la componente de interés.  void keyPressed(KeyEvent)

  Llamado por AWT después que el usuario presiona una tecla en el teclado.

 void keyReleased(KeyEvent)   Llamado por AWT después que el usuario suelta una

tecla en el teclado.

POO - EPS - UAM 108

Clase KeyEvent   int getKeyChar()   void setKeyChar(char)

  Obtiene o cambia el carácter Unicode asociado con el evento.   int getKeyCode()   void setKeyCode(int)

  Obtiene o cambia el código de tecla asociado al evento.   La clase KeyEvent define varias constantes de códigos para las

teclas comunes. Por ejemplo:   VK_A especifica la tecla con rótulo A   VK_ESCAPE especifica la tecla ESCAPE.

  void setModifiers(int)   Cambia el estado de las teclas modificadoras para el evento.

Page 55: test area

55

Abstract Window Toolkit (AWT)

Apéndice C Clases de layout managers

POO - EPS - UAM 110

BorderLayout

Page 56: test area

56

POO - EPS - UAM 111

BorderLayout (II) class Ventana extends Frame { Ventana () { setLayout (new BorderLayout ()); setTitle ("Border Layout"); add("North", new Button("North")); add("South", new Button("South")); add("East", new Button("East")); add("West", new Button("West")); add("Center", new Button("Center")); } }

 Importante: en este caso, siempre se debe utilizar una versión de add con dos argumentos:

 Sector  Componente

POO - EPS - UAM 112

BorderLayout (III)

 La parte central es la que más varía con la ventana.  Las otras partes sólo varían para mantener ocupado

todo el espacio disponible.  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)

Page 57: test area

57

POO - EPS - UAM 113

FlowLayout

POO - EPS - UAM 114

FlowLayout (II)

 Este manager pone las componentes en una fila, cada una a su preferredSize().

 Si el espacio horizontal es muy pequeño, agrega nuevas filas.

 En cada fila los componentes puedan estar centrados (omisión), alineados a izquierda o a derecha.

Page 58: test area

58

POO - EPS - UAM 115

FlowLayout (III)

class Ventana extends Frame { Ventana () { setLayout (new FlowLayout ()); setTitle ("Flow Layout"); add (new Button ("Button 1")); add (new Button ("Button 2")); add (new Button ("Button 3")); add (new Button ("Button 4")); add (new Button ("Button 5")); } }

POO - EPS - UAM 116

FlowLayout (IV)

class Ventana extends Frame { Ventana () { FlowLayout f = new FlowLayout (); f.setAlignment(FlowLayout.RIGHT); setLayout (f); setTitle ("Flow Layout"); add (new Button ("Button 1")); add (new Button ("Button 2")); add (new Button ("Button 3")); add (new Button ("Button 4")); add (new Button ("Button 5")); add (new Button ("Button 6")); } }

Page 59: test area

59

POO - EPS - UAM 117

FlowLayout (V)

 Tres constructores:   public FlowLayout()

  public FlowLayout(int alignment)

  public FlowLayout(int alignment, int horizontalGap, int verticalGap)

 Alineamiento:   FlowLayout.LEFT

  FlowLayout.CENTER

  FlowLayout.RIGHT

  Horizontal y Vertical gap: distancia entre componentes (omisión: 5)

POO - EPS - UAM 118

GridLayout

  setRows(int), setColumns(int)

  GridLayout(0,n) → tantas filas como hagan falta

  Ejemplo: GridLayout(2,3)

Page 60: test area

60

POO - EPS - UAM 119

GridLayout (II)

 Este manager pone las componentes en una grilla de celdas.

 Cada componente toma todo el espacio disponible en su celda, las cuales tienes todas el mismo tamaño.

 Cuando se redimensiona una ventana con GridLayout, se cambia el tamaño de las celdas de forma que sean lo más grandes posibles dado el espacio disponible.

POO - EPS - UAM 120

GridLayout (III)

  Constructores:

public GridLayout(int rows, int columns)

public GridLayout(int rows, int columns, int horizontalGap, int verticalGap)

class Ventana extends Frame { Ventana () { setLayout (new GridLayout (2,3)); setTitle ("Grid Layout"); add (new Button ("Button 1")); add (new Button ("Button 2")); add (new Button ("Button 3")); add (new Button ("Button 4")); add (new Button ("Button 5")); } }

Page 61: test area

61

POO - EPS - UAM 121

CardLayout

POO - EPS - UAM 122

CardLayout (II)

 Un CardLayout permite manipular dos o más componentes (usualmente Paneles) para que compartan el mismo espacio de la pantalla.

 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

Page 62: test area

62

POO - EPS - UAM 123

CardLayout (III) //Where instance variables are declared: Panel cards; final static String BUTTONPANEL = "Panel with Buttons"; final static String TEXTPANEL = "Panel with TextField"; ... //Where the container is initialized: cards = new Panel(); cards.setLayout(new CardLayout()); ... //Create a Panel named p1. Put buttons in it. //Create a Panel named p2. Put a text field in it. ... cards.add(BUTTONPANEL, p1); cards.add(TEXTPANEL, p2); ... ((CardLayout)cards.getLayout()).show(cards, BUTTONPANEL); // o bien ((CardLayout)cards.getLayout()).show(cards, TEXTPANEL);

POO - EPS - UAM 124

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.

Page 63: test area

63

POO - EPS - UAM 125

GridBagLayout

mantienen igualdad

POO - EPS - UAM 126

GridBagLayout (II)

 El más flexible (y complejo) de los layout managers.

 Coloca a las componentes en una grilla de filas y columnas   Ciertos componentes pueden abarcar varias filas o

columnas.   No todas las filas (columnas) deben que tener el mismo

alto (ancho).  Coloca las componentes en celdas y luego utiliza

los preferredSize de las componentes para determinar el tamaño de las celdas.

Page 64: test area

64

POO - EPS - UAM 127

GridBagLayout (III)

mantienen igualdad y ocupan todo el ancho

toma todo el espacio adicional

POO - EPS - UAM 128

GridBagLayout (IV)

  Las posiciones y tamaños se especifican mediante restricciones (constraints) para cada componente.   Se crea instancia de GridBagConstraint,   Se le da valor a sus variables de instancia,   Se asocia la restricción con el componente

GridBagLayout gridbag = new GridBagLayout();

GridBagConstraints c = new GridBagConstraints();

setLayout(gridbag);

// Para cada componente a ser agregado: //... Se crea el componente ... //... Se da valor a las variables de c gridbag.setConstraints(theComponent, c);

add(theComponent);

Page 65: test area

65

POO - EPS - UAM 129

Restricciones de GridBagLayout

 Se puede usar la misma instancia de GridBagLayout para distintas componentes.

 gridx, gridy   Especifica la celda que contiene el extremo izquierdo

(superior) del componente.   La primera celda tiene gridx (gridy) = 0.   Usar GridBagConstraints.RELATIVE (el valor

por omisión) para especificar que el componente se coloque justo a la derecha (o abajo) del componente anterior.

POO - EPS - UAM 130

Restricciones de GridBagLayout (II)

 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 (columna).

  Usar GridBagConstraints.RELATIVE para especificar que la componente sea la anteúltima en la fila (columna).

Page 66: test area

66

POO - EPS - UAM 131

Restricciones de GridBagLayout (III)

 fill   Usado cuando el área disponible para una componente es

mayor que la requerida:   GridBagConstraints.NONE (valor por omisión),   GridBagConstraints.HORIZONTAL:lacomponentecreceparaocuparhorizontalmentetodaelárea,peronocambiasualto.

  GridBagConstraints.VERTICAL:lacomponentecreceparaocuparverticalmentetodaelárea,peronocambiasuancho.

  GridBagConstraints.BOTH:hacequelacomponentelleneporcompletoeláreadisponible.

 ipadx, ipady   Especifica el margen interno (por omisión es 0). El ancho

(alto) de la componente es, por lo menos el ancho (alto) mínimo más ipadx*2 pixels (ipady*2 pixels).

POO - EPS - UAM 132

Restricciones de GridBagLayout (IV)

  Insets   Especifica el margen externo de la componente – el mínimo espacio

entre la componente y los márgenes del área disponible. El valor es especificado en un objeto Insets. Por omisión el valor es 0.

  Anchor   Usado cuando la componente es menor que el área disponible, para

determinar dónde (dentro del área) ubicarlo:   GridBagConstraints.CENTER (default)   GridBagConstraints.NORTH

  GridBagConstraints.NORTHEAST

  GridBagConstraints.EAST

  GridBagConstraints.SOUTHEAST

  GridBagConstraints.SOUTH

  GridBagConstraints.SOUTHWEST

  GridBagConstraints.WEST

  GridBagConstraints.NORTHWEST

Page 67: test area

67

POO - EPS - UAM 133

Restricciones de GridBagLayout (V)

 weightx, weighty   Especificar los pesos es un arte que puede tener un

impacto significativo en la apariencia final.   Son usados para determinar cómo se distribuye el

espacio entre las columnas (filas); esto es importante para el comportamiento de redimensionamiento.

  A menos que se especifique un valor distinto de cero, todas las componentes se agrupan juntas en el centro del contenedor. Esto es porque cuando el peso es 0.0 (default), el GridBagLayout pone cualquier espacio extra en los márgenes externos del contenedor.

  (continúa)

POO - EPS - UAM 134

Restricciones de GridBagLayout (VI)

 weightx, weighty(cont.)  Generalmente los pesos son especificados con 0.0 y 1.0

como valores extremos, usando números intermedios cuando es necesario.

  Números mayores indican que la fila (columna) del componente debe tener más espacio.

  Para cada columna (fila), el peso es relacionado con el mayor weightx (weighty) especificado para un componente en esa columna (fila).   Para los componentes multicolumnas (multifilas) el peso es

dividido de alguna manera entre las columnas (filas) que abarca   El espacio extra tiende a irse hacia abajo a la derecha.

Page 68: test area

68

POO - EPS - UAM 135

GridBagLayout: Ejemplo

GridBagLayout gridbag = new GridBagLayout();

GridBagConstraints c = new GridBagConstraints();

setLayout(gridbag);

c.fill = GridBagConstraints.BOTH;

c.weightx = 1.0;

makebutton("Button1", gridbag, c);

makebutton("Button2", gridbag, c);

makebutton("Button3", gridbag, c);

POO - EPS - UAM 136

GridBagLayout: Ejemplo

GridBagLayout gridbag = new GridBagLayout();

GridBagConstraints c = new GridBagConstraints();

setLayout(gridbag);

c.fill = GridBagConstraints.BOTH;

c.weightx = 1.0;

makebutton("Button1", gridbag, c);

makebutton("Button2", gridbag, c);

makebutton("Button3", gridbag, c);

Cada componente tan grande como sea posible

Page 69: test area

69

POO - EPS - UAM 137

GridBagLayout: Ejemplo

GridBagLayout gridbag = new GridBagLayout();

GridBagConstraints c = new GridBagConstraints();

setLayout(gridbag);

c.fill = GridBagConstraints.BOTH;

c.weightx = 1.0;

makebutton("Button1", gridbag, c);

makebutton("Button2", gridbag, c);

makebutton("Button3", gridbag, c);

Si no estuviera

POO - EPS - UAM 138

GridBagLayout: Ejemplo

GridBagLayout gridbag = new GridBagLayout();

GridBagConstraints c = new GridBagConstraints();

setLayout(gridbag);

c.fill = GridBagConstraints.BOTH;

c.weightx = 1.0;

makebutton("Button1", gridbag, c);

makebutton("Button2", gridbag, c);

makebutton("Button3", gridbag, c);

Todas las columnas iguales y mayores que 0

Page 70: test area

70

POO - EPS - UAM 139

GridBagLayout: Ejemplo

GridBagLayout gridbag = new GridBagLayout();

GridBagConstraints c = new GridBagConstraints();

setLayout(gridbag);

c.fill = GridBagConstraints.BOTH;

c.weightx = 1.0;

makebutton("Button1", gridbag, c);

makebutton("Button2", gridbag, c);

makebutton("Button3", gridbag, c);

Si no estuviera (es decir, weightx = 0)

POO - EPS - UAM 140

GridBagLayout: Ejemplo

c.gridwidth = GridBagConstraints.REMAINDER; //end of row

makebutton("Button4", gridbag, c);

c.weightx = 0.0; //reset to the default

makebutton("Button5", gridbag, c); //another row

c.gridwidth = GridBagConstraints.RELATIVE; //next to last

makebutton("Button6", gridbag, c);

c.gridwidth = GridBagConstraints.REMAINDER; //end of row

makebutton("Button7", gridbag, c);

Page 71: test area

71

POO - EPS - UAM 141

GridBagLayout: Ejemplo

c.gridwidth = 1; //reset to the default

c.gridheight = 2;

c.weighty = 1.0;

makebutton("Button8", gridbag, c);

c.weighty = 0.0; //reset to the default

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 142

GridBagLayout: Ejemplo

c.gridwidth = 1; //reset to the default

c.gridheight = 2;

c.weighty = 1.0;

makebutton("Button8", gridbag, c);

c.weighty = 0.0; //reset to the default

c.gridwidth = GridBagConstraints.REMAINDER; //end of row

c.gridheight = 1; //reset to the default

makebutton("Button9", gridbag, c);

makebutton("Button10", gridbag, c);

ocupa dos filas

Page 72: test area

72

POO - EPS - UAM 143

GridBagLayout: Ejemplo

c.gridwidth = 1; //reset to the default

c.gridheight = 2;

c.weighty = 1.0;

makebutton("Button8", gridbag, c);

c.weighty = 0.0; //reset to the default

c.gridwidth = GridBagConstraints.REMAINDER; //end of row

c.gridheight = 1; //reset to the default

makebutton("Button9", gridbag, c);

makebutton("Button10", gridbag, c);

es el único con valor > 0

POO - EPS - UAM 144

GridBagLayout: Ejemplo

protected void makebutton(String name, GridBagLayout gridbag, GridBagConstraints c) {

Button button = new Button(name);

gridbag.setConstraints(button, c);

add(button);

}

Page 73: test area

73

POO - EPS - UAM 145

Trabajando sin Layout Manager

  Se debe utilizar un layout manager siempre que sea posible.

  Con ellos es más fácil redimensionar los contenedores y ajustar la apariencia de componentes dependientes de la plataforma. También es fácil reutilizarlos.

  Si el contenedor no será reutilizado, no puede ser redimensionado, y controla por completo los factores que normalmente dependen de la plataforma (fuentes y aspecto de los componentes), entonces puede tener sentido un layout absoluto.

POO - EPS - UAM 146

Trabajando sin Layout Manager

public void paint(Graphics g) {

if (!laidOut) {

Insets insets = insets();

/* We're guaranteed that insets() will return a valid

* Insets if called from paint() -- it isn't valid when

* called from the constructor.

*/

b1.reshape(50 + insets.left, 5 + insets.top, 50, 20);

b2.reshape(70 + insets.left, 35 + insets.top, 50, 20);

b3.reshape(130 + insets.left, 15 + insets.top, 50, 30);

laidOut = true;

}

Page 74: test area

74

Abstract Window Toolkit (AWT)

Apéndice D Widgets AWT

Clases predefinidas de componentes estándar

POO - EPS - UAM 148

java.awt.Button   Estado y propiedades

  Constructores: Button(), Button(String) El string se utiliza como etiqueta del botón

  Cambiar / acceder a la etiqueta: GetLabel(), SetLabel(String)

  Botón activo / inactivo: setEnabled(boolean)   Operación

  Emite un ActionEvent al ser pulsado   Identificación para el evento de acción: setActionCommand(String)   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 ActionEvent's emitidos por el botón (ver getActionCommand() de ActionEvent)

Page 75: test area

75

POO - EPS - UAM 149

class ButtonDemo extends Frame implements ActionListener { Button b1, b2, b3; ButtonDemo () { setLayout (new FlowLayout ()); b1 = new Button (); b1.setLabel ("Disable middle button"); b1.setActionCommand ("Disable"); b2 = new Button ("Middle button"); b3 = new Button ("Enable middle button"); b3.setEnabled (false); b3.setActionCommand ("Enable");

add (b1); add (b2); add (b3);

b1.addActionListener (this); b3.addActionListener (this); } ...

POO - EPS - UAM 150

... public void actionPerformed (ActionEvent e) { String command = e.getActionCommand(); if (command.equals ("Disable")) { b1.setEnabled (false); b2.setEnabled (false); b3.setEnabled (true); } else { b1.setEnabled (true); b2.setEnabled (true); b3.setEnabled (false); } } }

Page 76: test area

76

POO - EPS - UAM 151

Widgets de selección Checkbox List Choice Menu

Selección múltiple

Doble click

Ahorro de espacio

ItemEvent lleva número de item

Emiten ItemEvents

Emiten ActionEvents

POO - EPS - UAM 152

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)

Page 77: test area

77

POO - EPS - UAM 153

java.awt.Checkbox (cont.)   Operación

  Emite un ItemEvent al cambiar de estado

El item asociado el evento es el label del checkbox   Identificación del item desde el evento:

  getItem()→String (label del checkbox)   getItemSelectable()→Object (la componente checkbox)

  Botones excluyentes: grupos de Checkbox'es   Crear objeto de la clase CheckboxGroup   Utilizar el constructor Checkbox(String,boolean,CheckboxGroup)

  Los checkbox creados con el mismo grupo como argumento forman un grupo

  Sólo un checkbox de un grupo puede estar seleccionado

POO - EPS - UAM 154

class CheckboxDemo extends Frame { CheckboxDemo () { setLayout (new GridLayout (1, 2));

Panel p1 = new Panel (); Checkbox cb = new Checkbox (); cb.setLabel ("Checkbox 1"); cb.setState (true); p1.add (cb); p1.add (new Checkbox ("Checkbox 2")); p1.add (new Checkbox ("Checkbox 3")); add (p1);

Panel p2 = new Panel (); CheckboxGroup group = new CheckboxGroup (); p2.add (new Checkbox ("Checkbox 4", group, false)); p2.add (new Checkbox ("Checkbox 5", group, false)); p2.add (new Checkbox ("Checkbox 6", group, false)); add (p2); } }

Page 78: test area

78

POO - EPS - UAM 155

POO - EPS - UAM 156

java.awt.Choice

 Descripción   Lista de selección desplegable   Uno de los elementos de la lista está seleccionado

 Estado y propiedades   add(String), getItem(int), getItemCount()

  select(int), select(String), isIndexSelected(int), getSelectedItem() → String, getSelectedIndex() → int

 Operación   Emite un ItemEvent al cambiar la selección

El item asociado el evento es el string del item seleccionado

Page 79: test area

79

POO - EPS - UAM 157

java.awt.List

 Descripción   Lista de selección con barras de scroll   El modo de selección puede ser simple o múltiple

 Estado y propiedades   List(), List(int), List(int,boolean)

  add(String), add(String,int), remove(String), remove(int), getItem(int), getItems(), getItemCount(), getRows()

  select(int), select(String), isIndexSelected(int), getSelectedItem() → String, getSelectedIndex() → int, getSelectedObjects() → Object[]

  isMultipleMode(), setMultipleMode(boolean)

POO - EPS - UAM 158

java.awt.List (cont.)

 Operación   Seleccionar / deseleccionar item: emite ItemEvent

El item asociado al evento es el número de posición del item seleccionado   Doble click: emite ActionEvent con el texto del

item seleccionado como action command string

Page 80: test area

80

POO - EPS - UAM 159

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 160

... Panel p = new Panel (); p.setLayout (new GridLayout (2, 1, 10, 10)); p.add (spanish); p.add (italian);

output = new TextArea (10, 40); output.setEditable (false);

add (output); add (p); } // Fin del constructor ...

Page 81: test area

81

POO - EPS - UAM 161

... 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"); } public void itemStateChanged (ItemEvent e) { List list = (List) (e.getItemSelectable ()); String language = (list == spanish)? "Spanish" : "Italian"; int index = ((Integer) (e.getItem ())) .intValue (); if (e.getStateChange () == ItemEvent.SELECTED) { output.append ("Select event on item " + index + " (" + list.getItem (index) + ")" + " in " + language + ".\n"); } else output.append ("Deselect event on item " + index + " (" + list.getItem (index) + ")" + " in " + language + ".\n"); } }

POO - EPS - UAM 162

Page 82: test area

82

POO - EPS - UAM 163

java.awt.Menu

Descripción  Conjunto de items de distintas modalidades:

  MenuItem: tipo botón

  CheckboxMenuItem: tipo checkbox

  Menu: submenú MenuItem

Menu CheckBoxMenuItem

POO - EPS - UAM 164

java.awt.Menu

Construcción   Menu(), Menu(String), MenuItem(), MenuItem(String),

CheckboxMenuItem(), CheckboxMenuItem(String)

  Añadir items: 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

Page 83: test area

83

POO - EPS - UAM 165

java.awt.Menu (cont.)

Estado y propiedades  getLabel(), setLabel(String)de Menu / MenuItem

 Activar / desactivar item: isEnabled(), setEnabled(boolean)de Menu / MenuItem

 Selección de CheckboxMenuItem: getState(), setState(boolean)

POO - EPS - UAM 166

java.awt.Menu (cont.)

Operación   MenuItem emite sólo ActionEvent como un botón, con

el label del item pulsado como action command string

Source del evento: el item o el Menu contenedor del item

  CheckboxMenuItem emite sólo ItemEvent como un checkbox, con el label del item seleccionado / deseleccionado como label del evento

Source del evento: el propio CheckboxMenuItem

Page 84: test area

84

POO - EPS - UAM 167

Widgets de texto

Label TextArea TextField

TextComponent

POO - EPS - UAM 168

java.awt.Label

Descripción   Texto estático

Estado y propiedades   Label(), Label(String), Label(String,LEFT|RIGHT|

CENTER)

  getText(), setText(String)

  getAlignment(), setAlignment(LEFT|RIGHT|CENTER)

Operación   No tiene

Page 85: test area

85

POO - EPS - UAM 169

java.awt.TextComponent

 Descripción   Superclase de TextField y TextArea   Texto editable, seleccionable

 Estado y propiedades   getText(), setText(String)

  isEditable(), setEditable(boolean)

  getCaretPosition(), setCaretPosition(int)

  getSelectedText(), select(int,int), selectAll(), getSelectionStart(), getSelectionEnd(), setSelectionStart(int), setSelectionEnd(int)

POO - EPS - UAM 170

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

Page 86: test area

86

POO - EPS - UAM 171

java.awt.TextArea

  Descripción   Texto editable multilínea con scrolling

  Estado y propiedades (además de las de TextComponent)   TextArea(), TextArea(String), TextArea(String,int,int)

  Scrollbars: TextArea(String,int,int,int), TextArea.SCROLLBARS_NONE, SCROLLBARS_VERTICAL_ONLY...   getColumns(), setColumns(int), getRows(), setRows(int)   append(String), insert(String,int), replaceRange(String,int,int)

  Operación   Emite un TextEvent cuando se cambia un carácter del texto   No emite ActionEvent's

POO - EPS - UAM 172

class TextDemo extends Frame implements ActionListener { TextField textField; TextArea textArea; TextDemo () { setLayout (new FlowLayout ()); textField = new TextField (20); textArea = new TextArea (5, 20); textArea.setEditable (false);

add (textField); add (textArea);

textField.addActionListener (this); } public void actionPerformed (ActionEvent evt) { String text = textField.getText (); textArea.append (text + "\n"); textField.selectAll (); } }

Page 87: test area

87

POO - EPS - UAM 173

POO - EPS - UAM 174

java.awt.Dialog

 Descripción   Depende de otra ventana:

  Se destruye cuando se destruye la ventana principal   Desaparece cuando se minimiza la ventana principal

 Estado y propiedades   Dialog (Frame [,String] [,boolean])   Modal / no modal: isModal(), setModal(boolean)   isResizeable(), setResizeable(boolean)

de Window   FileDialog extends Dialog

  getDirectory(), setDirectory(String)

  getFile(), setFile(String)

Page 88: test area

88

POO - EPS - UAM 175

class DialogWindow extends Frame implements ActionListener { private SimpleDialog dialog; private TextArea textArea; 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 176

class SimpleDialog extends Dialog implements ActionListener { TextField field; DialogWindow parent; Button setButton; SimpleDialog (Frame w, String title) { super (w, title, false); parent = (DialogWindow) w; Panel p1 = new Panel (); p1.setLayout (new GridLayout (2, 1)); Label label = new Label ("Enter text here:"); p1.add (label); field = new TextField (40); field.addActionListener (this); p1.add (field); add ("Center", p1); ...

Page 89: test area

89

POO - EPS - UAM 177

... Panel p2 = new Panel(); p2.setLayout (new FlowLayout (FlowLayout.RIGHT)); Button b = new Button ("Cancel"); b.addActionListener (this); setButton = new Button ("Set"); setButton.addActionListener (this); p2.add (b); p2.add (setButton); add ("South", p2); pack (); }

public void actionPerformed (ActionEvent event) { Object source = event.getSource(); if ((source == setButton) || (source == field)) parent.addLine (field.getText()); field.selectAll (); setVisible (false); } }

POO - EPS - UAM 178

java.awt.Dialog

Page 90: test area

90

POO - EPS - UAM 179

Widgets personalizados class Boton extends Canvas implements MouseListener { private boolean selected = false; protected String label; public Boton (String str) { label = str; addMouseListener (this); new Mover (this); } public void paint (Graphics g) { Dimension dim = getSize (); FontMetrics metrics = g.getFontMetrics (); g.drawRect (0, 0, dim.width-1, dim.height-1); g.drawString (label, (dim.width - metrics.stringWidth (label)) / 2, (dim.height - metrics.getHeight ()) / 2 + metrics.getMaxAscent ()); } ...

Def

inir

as

pect

o vi

sual

POO - EPS - UAM 180

Métodos para negociar tamaño con layout managers

... public Dimension getPreferredSize () { FontMetrics metrics = getGraphics () .getFontMetrics (); return new Dimension (metrics.stringWidth (label) + 20, metrics.getHeight () + 10); }

public Dimension getMinimumSize () { Dimension dim = getPreferredSize (); return new Dimension (dim.width / 2, dim.height / 2); }

public Dimension getMaximumSize () { Dimension dim = getPreferredSize (); return new Dimension (dim.width * 2, dim.height * 2); } ...

Page 91: test area

91

POO - EPS - UAM 181

... public void mouseClicked (MouseEvent e) { selected = !selected; if (selected) { setBackground (Color.black); setForeground (Color.white); } else { setBackground (Color.white); setForeground (Color.black); } }

public void mousePressed (MouseEvent e) {} public void mouseReleased (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseExited (MouseEvent e) {} ...

Resp

uest

a vi

sual

(fee

dbac

k)

a ac

ción

del

usu

ario

POO - EPS - UAM 182

... public String getLabel () { return label; } public void setLabel (String str) { label = str; repaint (); } public boolean getState () { return selected; } public void setState (boolean state) { selected = state; if (selected) { setBackground (Color.black); setForeground (Color.white); } else { setBackground (Color.white); setForeground (Color.black); } } // public void mouseClicked (MouseEvent e) { // setState (!selected); // } }

Inte

rfaz

par

a co

ntro

lar e

l est

ado

del w

idge

t

Page 92: test area

92

POO - EPS - UAM 183

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) { pointedAt = true; repaint (); } public void mouseExited (MouseEvent e) { pointedAt = false; repaint (); } }

Más

feed

back

a

acci

ones

del

usu

ario

POO - EPS - UAM 184

3. Click

2. Enter

4. Exit

5. Enter

6. Drag

1. Inicio

Page 93: test area

93

POO - EPS - UAM 185

class BotonAccion extends Boton {

private ActionListener multicaster = null; public BotonAccion (String str) { super (str); } public void mouseClicked (MouseEvent e) { super.mouseClicked (e);

processEvent ( new ActionEvent ( this, ActionEvent.ACTION_PERFORMED, label)); }

public void addActionListener (ActionListener listener) { multicaster = AWTEventMulticaster.add (multicaster, listener); }

public void processEvent (AWTEvent e) { if (e.getID () == ActionEvent.ACTION_PERFORMED && multicaster != null) multicaster.actionPerformed ((ActionEvent) e); super.processEvent (e); } }

Generación de eventos en respuesta a la interacción