Ejemplo: editor de texto Abstract Window Toolkit (AWT) 1ra. Parte: Introducción
POO - EPS - UAM
La biblioteca AWT: java.awt, java.awt.event
Label
Componentes predefinidas Agregación de componentes Las interfaces se dibujan a sí mismas: funciones de dibujo Creación de nuevas componentes
TextField Button
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
Anatomía de un programa basado en GUI
La clase Container, adición de subcomponentes Control de la apariencia de las componentes manipulando su estado
Posiciones absolutas
Layout managers
Ancho ocupa toda la ventana
Alto fijo
Ancho fijo, centrado
Gestionar los eventos: modelo emisor / receptor
Llenar espacio disponible hasta borde inferior de la ventana
Eventos de acción generados por las clases predefinidas Gestión directa del input del usuario
Definir componentes personalizadas
5
Disposición de las componentes
Definir la disposición de las partes de un contenedor
POO - EPS - UAM
Componer interfaces con las clases predefinidas
Componentes predefinidas
Componentes
4
Ancho ocupa toda la ventana
La clase Canvas Utilización de las funciones de dibujo POO - EPS - UAM
3
POO - EPS - UAM
6
1
Aspectos interactivos Editar texto del campo
Ejemplo: código (III) Cerrar ventana
Leer el fichero indicado en el campo de texto, asignar como string del área de texto Escribir del área de texto en el string fichero indicado en el campo de texto
... 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 public public public public public public ...
void void void void void void void
windowClosing (WindowEvent e) { dispose (); } windowActivated (WindowEvent e) {} windowClosed (WindowEvent e) {} windowDeactivated (WindowEvent e) {} windowDeiconified (WindowEvent e) {} windowIconified (WindowEvent e) {} windowOpened (WindowEvent e) {}
Editar texto multilínea POO - EPS - UAM
7
Ejemplo: código (I)
10
Ejemplo: código (IV)
import java.awt.*; import java.awt.event.*; import java.io.*;
... 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); } } ...
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); ...
POO - EPS - UAM
POO - EPS - UAM
8
Ejemplo: código (II)
POO - EPS - UAM
11
Ejemplo: código (V)
load = new Button ("Load"); load.setBounds (40, 80, 60, 20); add (load);
... public static void main (String args[]) { Editor edit = new Editor (); edit.setSize (320, 320); edit.setVisible (true); } } // Fin clase Editor
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 load.addActionListener save.addActionListener quit.addActionListener } // Fin del constructor
(this); (this); (this); (this);
POO - EPS - UAM
9
POO - EPS - UAM
12
2
Jerarquía de componentes AWT: el package java.awt
Resumen
Programar un IU para una aplicación en Java involucra:
Jerarquía = Herencia
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
Componentes AWT predefinidas
POO - EPS - UAM
17
Uso componentes AWT: ejemplo
15
POO - EPS - UAM
18
3
Clases en el ejemplo Frame
Código del ejemplo
Converter
/** * Does the conversion from metric to U.S., or vice versa, and * updates the appropriate ConversionPanel. */
Label void convert(ConversionPanel from) { ConversionPanel to;
Choice
TextField
if (from == metricPanel) to = usaPanel; else to = metricPanel;
ScrollBar ConversionPanel
double multiplier = from.getMultiplier() / to.getMultiplier(); to.setValue(multiplier * from.getValue());
: GridBagLayout layout manager
}
POO - EPS - UAM
19
POO - EPS - UAM
Código del ejemplo import java.awt.*; import java.awt.event.*; import java.util.*; import jav a.applet.Applet; public class Converter extends Frame { ConversionPanel metricPanel, usaPanel; Unit[] metricDistances = new Unit[3]; Unit[] usaDistances = new Unit[4];
funcionalidad
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); }
Creación de la ventana
Dibujo
/** * 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); }
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)); ....
POO - EPS - UAM
22
20
POO - EPS - UAM
Código del ejemplo
23
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); } }); Main //Create a Converter instance. Converter converter = new Converter(); converter.init();
// 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. Inicialización 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 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);
//Add both ConversionPanels to the Converter. add(metricPanel); add(usaPanel);
}
}
} POO - EPS - UAM
21
POO - EPS - UAM
24
4
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;
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);
Panel interno
POO - EPS - UAM
25
POO - EPS - UAM
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.
controller = myController; //Save arguments in instance variables. units = myUnits;
//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);
+ componentes
}
26
Código del ejemplo
POO - EPS - UAM
29
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); }
//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);
Dibujo
/** * 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); }
+ componentes
POO - EPS - UAM
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);
Composición
POO - EPS - UAM
28
Código del ejemplo
ConversionPanel(Converter myController, String myTitle, Un it[] myUnits) { //Initialize this ConversionPanel to use a GridBagLayout. GridBagConstraints c = new GridBagConstraints(); GridBagLayout gridbag = new GridBagLayout (); setLayout(gridbag);
//Set up default layout constraints. c.fill = GridBagConstraints.HORIZONTAL;
+ componentes
27
POO - EPS - UAM
30
5
Jerarquía de componentes: la clase java.awt.Container
Código del ejemplo /** Respond to the text field */ public void actionPerformed(ActionEvent e) { setSliderValue((double)Double.valueOf( textField.getText()).doubleValue()); controller.convert(this); }
Jerarquía = Composición
Respuesta a eventos
/** Respond to the choice */ public void itemStateChanged(ItemEvent e) { controller.convert(this); }
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
/** Respond to the slider. */ public void adjustmentValueChanged(AdjustmentEvent e) { textField.setText(String.valueOf(e.getValue())); controller.convert(this); } POO - EPS - UAM
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
31
POO - EPS - UAM
Código del ejemplo
34
Jerarquía de componentes (II) Jerarquía = Composición
/** Set the values in the slider and text field. */ void setValue(double f) { setSliderValue(f); textField.setText(String.valueOf((float)f)); }
Las componentes se pueden añadir:
/** 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);
Agregar: add(Component) Retirar: remove(Component)
Modificación componentes
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()
} } POO - EPS - UAM
32
Cómo se usan las componentes AWT
Jerarquía de componentes:
35
Jerarquía de componentes: ejemplo
Jerarquía = Composición
Las componentes son estructuradas en una jerarquía de componentes, con instancias de (subclases de) Container definiendo dicha estructura.
Dibujo de las componentes:
POO - EPS - UAM
public class Converter extends Frame { ... public void init() { ... add(metricPanel); add(usaPanel); ...
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) 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)
Cuándo
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
Quién solicita
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 En los tres primeros casos, el sistema AWT. En el último caso, el mismo programa
37
POO - EPS - UAM
Dibujo de componentes
Refresco de las componentes
El dibujo comienza por el componente más alto en la jerarquía que necesita ser dibujado
Por ejemplo, un Frame.
El proceso de dibujo en sí sólo puede llevarse a cabo cuando lo diga el sistema AWT
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 POO - EPS - UAM
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
38
POO - EPS - UAM
AWT decide dibujar un componente
Caja del borde
Se dibuja uno de los dos ConversionPanel
update(Graphics) y repaint()
Se dibuja el frame Se dibuja el Converter
Caja del borde
Los componentes de este panel (Label, TextField, Scrollbar y Choice) son dibujados POO - EPS - UAM
41
Refresco de las componentes:
Dibujo de componentes: ejemplo
40
Lo solicita el programa
39
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)
invoca a repaint() Petición al sistema AWT para llamar a update lo antes posible El programa no debe llamar a paint directamente
POO - EPS - UAM
42
7
Refresco de las componentes: el objeto Graphics
Es el argumento de los métodos update y paint
Gestión de eventos
Normalmente nos llega a nuestro código desde AWT
Se produce input del usuario: MouseEvent,KeyEvent Un widget se acciona: ActionEvent, TextEvent,
Provee métodos para:
Los eventos son objetos de distintas subclases de AWTEvent Se generan eventos cuando:
Dibujar y rellenar rectángulos, arcos, líneas, óvalos, polígonos, textos e imágenes. Obtener o cambiar el color, tipo de f uente o área de actuales. clipping Cambiar el modo de dibujo.
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
POO - EPS - UAM
43
POO - EPS - UAM
Refresco de las componentes: ejemplo
46
Estructura de programa
La forma más simple de dibujar una componente es especializar el método paint Ejemplo:
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 {
/** Draws a box around this panel. */ public void paint(Graphics g) { Dimension d = getSize(); g.drawRect(0,0, d.width - 1, d.height - 1); }
2.
Código que registra una instancia del manejador como receptor de eventos de uno o más e misores:
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
44
POO - EPS - UAM
Gestión de eventos: modelo de eventos de AWT 1.1
class ConversionPanel extends Panel implements ActionListener, AdjustmentListener, ItemListener {
Eventos generados por emisores (sources) de eventos. Objetos (listeners) se registran para ser notificados de eventos:
Ejemplo visto
Modelo basado en delegación
47
textField.addActionListener(this);
De cierto tipo Desde un emisor en particular
public void actionPerformed(ActionEvent e) { 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:
Repaso de clases básicas
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) POO - EPS - UAM
Clases auxiliares en java.awt
java.awt.Component
Dibujarse en la pantalla: paint(),
update(),
Procesamiento de eventos: delegación Control de la apariencia visual:
Color: setForeground(Color),
getForeground(), setBackground(Color), getBackground()
Posiciones y tamaños:
repaint()
Font: setFont(Font), getFont() Cursor: setCursor(Cursor), getCursor()
Polygon: npoints, xpoints, ypoints, addPoint(Point) 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
53
Clases auxiliares en java.awt (II)
(II)
Tamaño y posición:
Font:
setSize(int,int)
getSize() Dimension
getLocation() Point
getName(), getStyle(), getSize()
Constantes de estilo: Font.BOLD,
getLocationOnScreen() Point setBounds(int,int,int,int)
getBounds() Rectangle
Mostrar detalles en System.out: POO - EPS - UAM
new Font ("Helvetica", Font.BOLD + Font.ITALIC, 18) Font.ITALIC,
Font.PLAIN
Cursor:
new Cursor(Cursor.HAND_CURSOR) Cursor.CROSSHAIR_CURSOR
etc.
(El layout manager puede alterar estos valores)
Rectangle: x, y, width, height, contains(Point)
50
java.awt.Component
Dimension: width, height Point: x, y
Color:
POO - EPS - UAM
52
list()
51
POO - EPS - UAM
54
9
Modelo de eventos: ejemplo Abstract Window Toolkit (AWT) public class Beeper implements ActionListener { ... //where initialization occurs: button = new Button("Click Me"); button.addActionListener(this); ... public void actionPerformed(ActionEvent e){ ...//Implements the answer... } }
3ra. Parte: Gestión de Eventos
POO - EPS - UAM
Utilización de adapters y clases internas
Modelo de eventos
Modelo basado en delegación. A cada tipo de evento xxxEvent corresponde:
Un tipo de receptor (excepción: xxxListener MouseEvent tiene dos) Una lista de clases de componentes que pu eden producir el evento Un método addxxxListener para registrar receptores de esos eventos
La mayoría de las interfaces de eventos contienen más de un evento.
Este método está definido en las clases que generan el evento listeners del tipo de eventos Una componente sólo puede registrar que genera la componente POO - EPS - UAM
58
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
56
POO - EPS - UAM
Modelo de eventos: ejemplo
59
Ejemplo de código de listener public class MyClass implements MouseListener {
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)
... 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) { }
Una componente sólo puede registrar listeners del tipo de eventos que genera la componente
public void mouseClicked(MouseEvent e) { ...//Event handler implementation goes here... } }
POO - EPS - UAM
57
POO - EPS - UAM
60
10
Utilización de adapters
class MyListener extends MouseAdapter {
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
Adaptadores: código public void mouseEntered (MouseEvent e) { ... // Respuesta de la ventana al evento } }
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.
class Ventana extends Frame { Ventana () { Button boton = new Button ();
Crear una subclase del adaptador definiendo sólo los métodos que interesen
boton.addMouseListener (new MyListener ()); ... } }
POO - EPS - UAM
61
POO - EPS - UAM
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 interfaz MouseListener . class MouseAdapter implements public void mouseClicked public void mousePressed public void mouseReleased public void mouseEntered public void mouseExited }
MouseListener { (MouseEvent e) (MouseEvent e) (MouseEvent e) (MouseEvent e) (MouseEvent e)
{} {} {} {} {}
62
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
Adaptadores: problemas (I)
A menudo los métodos listener necesitan acceder a variables de la clase de componente
public class MyClass extends MouseAdapter { ... someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) { ...//Event handler implementation goes here... } }
POO - EPS - UAM
64
65
Adaptador como clase interna
Una subclase de Component no puede heredar de otra clase ⇒ Utilizar un objeto adaptador auxiliar para hacer de listener
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); ... } } }
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 () {
4ta. Parte: Gestión de Eventos: Implementación de los listeners
Button boton = new Button (); boton.addMouseListener ( new MouseAdapter () { public void mouseEntered (MouseEvent e) { ... System.out.println (nombre); ... } } ); } }
POO - EPS - UAM
67
Adaptadores autosuficientes = reutilizables
¿Qué deben hacer los métodos de los receptores?
class Mover extends MouseAdapter implements MouseMotionListener { private Point initialPoint; public Mover (Component c) { listenTo (c); } public void listenTo (Component c) { c.addMouseListener (this); new Mover (obj); 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) {} }
POO - EPS - UAM
Modificar características de la interfaz
Ejecutar programas de la aplicación
68
Normalmente se refleja algún resultado en la interfaz
POO - EPS - UAM
Ver apéndice A
71
¿Procesar eventos o ignorarlos?
Clases de Eventos Métodos de los listeners
Eventos de bajo nivel recogidos en widgets y elaborados en forma de eventos de alto nivel
69
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
POO - EPS - UAM
Cambiar colores, fonts, etiquetas, etc. Mover objetos, cambiar su tamaño Ocultar, mostrar, añadir, eliminar componentes Abrir un cuadro de diálogo etc.
TextEvent, ItemEvent, ComponentEvent, ContainerEvent, AdjustmentEvent, etc. POO - EPS - UAM
72
12
Ejemplo de ActionListener
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
73
POO - EPS - UAM
Implementación de un
Ejemplo de ActionListener
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?
sobre un botón Click sobre un item de lista Doble Click Elegir un menu item en un campo de texto Enter
Como resultado, se envía el mensaje actionPerformed a todos los listeners que se han registrado para ese componente POO - EPS - UAM
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"); } }
74
POO - EPS - UAM
Interfaz ActionListener
76
77
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)
5ta. Parte: Layout de componentes dentro de un contenedor
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 POO - EPS - UAM
Layout de componentes
Clases de Layout Manager
¿Qué es layout?
Disposición global de un conjunto de componentes Layout Manager
Cada Container tiene un controlador por omisión.
Panel FlowLayout
Windows BorderLayout
Si no sirve, se puede cambiar fácilmente
POO - EPS - UAM
80
83
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
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
Es posible incluso crear manejadores propios
Reglas generales de uso
Objeto que controla el tamaño y posición de los componentes de un contenedor. Implementan la interfaz LayoutManager ¿Por qué layout managers?
setLayoutManager(LayoutManager) de Container.
POO - EPS - UAM
Layout Manager
82
81
POO - EPS - UAM
84
14
LayoutManager Cómo elegir
Escenario:
Ver apéndice C
Se necesita mostrar una componente en tanto espacio como sea posible.
Clases de layout managers
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 c omponentes sean igual de grandes, se puede usar un GridLayout. POO - EPS - UAM
85
POO - EPS - UAM
Interfaz KeyListener
Cómo elegir LayoutManager (II)
Escenario:
void keyTyped(KeyEvent)
Se necesita mostrar unas pocas componentes en una f ila 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:
Llamado por AWT después que el u suario introduce un carácter Unicode en la componente de interés.
void keyPressed(KeyEvent)
Llamado por AWT después que el u suario presiona una tecla en el teclado.
void keyReleased(KeyEvent)
Es necesario mostrar unos pocos componentes del mismo tamaño en filas y/o columnas.
Llamado por AWT después que el u suario suelta una tecla en el teclado.
El GridLayout es perfecto para esto. POO - EPS - UAM
86
POO - EPS - UAM
int getKeyChar()
Los siguientes métodos de Container provocan invocaciones al layout manager:
void setKeyChar(char)
Obtiene o cambia el carácter Unicode asociado con el evento.
int getKeyCode()
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
89
Clase KeyEvent
Algunas guías de uso
88
87
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.
POO - EPS - UAM
90
15
(III)
BorderLayout
Abstract Window Toolkit (AWT)
Apéndice C Clases de layout managers
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)
POO - EPS - UAM
BorderLayout
POO - EPS - UAM
BorderLayout
FlowLayout
92
FlowLayout
95
(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.
Importante: en este caso, siempre se debe utilizar una
versión de add con dos argumentos:
POO - EPS - UAM
(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")); } }
94
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"); 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
FlowLayout
setColumns(int)
(IV)
public FlowLayout()
public FlowLayout(int alignment)
(V)
GridLayout
FlowLayout.LEFT FlowLayout.CENTER
FlowLayout.RIGHT
Horizontal y Vertical gap:
distancia entre
101
(III)
Constructores:
public GridLayout(int rows, int columns)
componentes (omisión: 5) POO - EPS - UAM
(II)
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")); } }
Alineamiento:
100
POO - EPS - UAM
public FlowLayout(int alignment, int horizontalGap, int verticalGap)
→
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.
98
Tres constructores:
tantas filas como hagan falta Ejemplo:
GridLayout
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")); } }
GridLayout(0,n)
POO - EPS - UAM
FlowLayout
GridLayout(2,3)
97
POO - EPS - UAM
setRows(int),
public GridLayout(int rows, int columns, int horizontalGap, int verticalGap) 99
POO - EPS - UAM
102
17
CardLayout
CardLayout
Eligiendo componente:
public void first(Container parent)
public void next(Container parent)
public void previous(Container parent)
public void last(Container parent)
POO - EPS - UAM
CardLayout
public void show(Container parent, String name)
El primer argumento siempre es el contenedor para quien el manager está trabajando.
103
POO - EPS - UAM
(II)
106
GridBagLayout
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:
(IV)
mantienen igualdad
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
CardLayout
104
(III)
GridBagLayout
//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
POO - EPS - UAM
105
(II)
El más flexible (y complejo) de los layout managers. Coloca a las componentes en una grilla de filas y columnas
107
Ciertos componentes pueden abarcar varias filas o columnas. No todas las filas (columnas) deben q ue 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. POO - EPS - UAM
108
18
GridBagLayout
Restricciones de GridBagLayout
(III)
(II)
gridwidth, gridheight
mantienen igualdad y ocupan todo el ancho
toma todo el espacio adicional
POO - EPS - UAM
GridBagLayout
109
POO - EPS - UAM
(III)
fill
Se crea instancia de GridBagConstraint, Se le da valor a sus variables de instancia, Se asocia la restricción con el componente
Usado cuando el área disponible para una componente es mayor que la requerida:
GridBagConstraints.NONE (valor por omisión),
GridBagConstraints.HORIZONTAL: la 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
crece para ocupar horizontalmente toda el área, pero n o cambia su alto. GridBagConstraints.VERTICAL: la componente crece para ocupar verticalmente toda el área, pero no cambia su ancho. GridBagConstraints.BOTH: hace que la componente llene por completo el área dis ponible.
ipadx, ipady
gridbag.setConstraints(theComponent, c); add(theComponent);
POO - EPS - UAM
112
Restricciones de GridBagLayout
(IV)
Las posiciones y tamaños se especifican mediante restricciones (constraints ) para cada componente.
Especifica el número de columnas (filas) que ocupa la componente. No son pixels. El valor es 1. default Usar GridBagConstraints.REMAINDERpara 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).
110
Especifica el margen interno (por omisión es 0). El ancho (alto) de la componente es, por lo menos el ancho (alto) 113 POO - EPS - UAM i
*
i
l
i
*
i
l
Restricciones de GridBagLayout
Restricciones de GridBagLayout
(IV)
Insets
Se puede usar la misma instancia de GridBagLayout para distintas componentes.
Anchor
gridx, gridy
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.
Especifica la celda que contiene el extremo izquierdo (superior) del componente. La primera celda tiene gridx (gridy) = 0. GridBagConstraints.RELATIVE (el valor Usar por omisión) para especificar que el componente se coloque justo a la derecha (o abajo) del componente anterior. POO - EPS - UAM
111
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 POO - EPS - UAM
114
19
Restricciones de GridBagLayout (V)
GridBagLayout : Ejemplo
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 d istribuye 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
Cada componente tan grande como sea posible 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);
115
Restricciones de GridBagLayout (VI)
(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).
POO - EPS - UAM
GridBagLayout : Ejemplo
weightx, weighty
Si no estuviera
GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setLayout(gridbag); c.fill = GridBagConstraints.BOTH; c.weightx = 1.0;
Para los componentes multicolumnas (multifilas) el peso es dividido de alguna manera entre las co lumnas (filas) que abarca
El espacio extra tiende a irse hacia abajo a la derecha. POO - EPS - UAM
118
makebutton("Button1", gridbag, c); makebutton("Button2", gridbag, c); makebutton("Button3", gridbag, c);
116
GridBagLayout : Ejemplo
POO - EPS - UAM
119
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;
GridBagConstraints c = new GridBagConstraints();
ocupa dos filas
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
GridBagLayout : Ejemplo
124
GridBagLayout : Ejemplo
c.gridwidth = GridBagConstraints.REMAINDER; //end of row
c.gridwidth = 1; //reset to the default
makebutton("Button4", gridbag, c);
c.gridheight = 2;
es el único con valor > 0
c.weightx = 0.0; //reset to the default
c.weighty = 1.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);
POO - EPS - UAM
makebutton("Button10", gridbag, c);
122
POO - EPS - UAM
GridBagLayout : Ejemplo
125
GridBagLayout : Ejemplo protected void makebutton(String name, GridBagLayout gridbag, GridBagConstraints c) {
c.gridwidth = 1; //reset to the default 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 d efault makebutton("Button9", gridbag, c); makebutton("Button10", gridbag, c);
POO - EPS - UAM
123
POO - EPS - UAM
126
21
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.
Estado y propiedades
Constructores: Button(),
Button(String)
El string se utiliza como etiqueta del botón
Cambiar / acceder a la etiqueta: GetLabel(), SetLabel(String)
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
java.awt.Button
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)
127
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.
POO - EPS - UAM
130
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.reshape(50 + insets.left, 5 + insets.top, 50, 20); b2.reshape(70 + insets.left, 35 + insets.top, 50, 20);
b1.addActionListener (this); b3.addActionListener (this);
b3.reshape(130 + insets.left, 15 + insets.top, 50, 30); laidOut = true;
} ...
}
POO - EPS - UAM
128
POO - EPS - UAM
Abstract Window Toolkit (AWT) Apéndice D Widgets AWT Clases predefinidas de componentes estándar
}
131
... 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); } }
POO - EPS - UAM
132
22
class CheckboxDemo extends Frame { CheckboxDemo () { setLayout (new GridLayout (1, 2));
Widgets de selección Checkbox
List
Choice
ItemEvent lleva número de item
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);
Menu
Emiten ActionEvents
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);
Doble click Selección múltiple
Ahorro de espacio
}
Emiten ItemEvents POO - EPS - UAM
} 133
POO - EPS - UAM
136
POO - EPS - UAM
137
java.awt.Checkbox
Descripción
Botón seleccionable con dos estados: seleccionado / deseleccionado Agrupable en grupos de botones d e selección excluyente (radio buttons)
Estado y propiedades
Checkbox(), Checkbox(String), Checkbox(String,boolean) getLabel(), setLabel(String)
getState(), setState(boolean)
POO - EPS - UAM
134
java.awt.Checkbox (cont.)
java.awt.Choice
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:
(label del checkbox) getItemSelectable()→Object (la componente checkbox) getItem()→String
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
135
Lista de selección desplegable Uno de los elementos de la lista está seleccionado
Estado y propiedades
Botones excluyentes: grupos de Checkbox'es
Descripción
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
POO - EPS - UAM
138
23
java.awt.List
Descripción
... Panel p = new Panel (); p.setLayout (new GridLayout (2, 1, 10, 10)); p.add (spanish); p.add (italian);
Lista de selección con barras de scroll El modo de selección puede ser simple o múltiple
Estado y propiedades
output = new TextArea (10, 40); output.setEditable (false);
List(), List(int), List(int,boolean) add(String), add(String,int), remove(String), remove(int), getItem(int), getItems(), getItemCount(), getRows()
add (output); add (p); } // Fin del constructor ...
select(int), select(String), isIndexSelected(int), getSelectedItem() → String, getSelectedIndex() → int, getSelectedObjects() → Object[] isMultipleMode(), setMultipleMode(boolean) POO - EPS - UAM
139
POO - EPS - UAM
... 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"); }
java.awt.List (cont.)
Operación
142
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
}
POO - EPS - UAM
140
POO - EPS - UAM
143
POO - EPS - UAM
144
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
24
java.awt.Menu
Operación
Descripción
(cont.)
java.awt.Menu
MenuItem emite sólo ActionEvent como un botón, con
Conjunto de items de distintas modalidades:
MenuItem: tipo botón
CheckboxMenuItem: tipo checkbox
Menu: submenú
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
checkbox, con el label del item seleccionado / deseleccionado como label del evento Source del evento: el propio CheckboxMenuItem
MenuItem
Menu
un
CheckBoxMenuItem
POO - EPS - UAM
145
POO - EPS - UAM
148
Widgets de texto
java.awt.Menu Construcción
TextComponent
Menu(), Menu(String), MenuItem(), MenuItem(String), CheckboxMenuItem(), CheckboxMenuItem(String)
Añadir items:
Label
add(String|MenuItem|CheckboxMenuItem|Menu),
TextField
TextArea
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
java.awt.Menu
146
(cont.)
getLabel(), setLabel(String)de Menu
Descripción
/
Texto estático
MenuItem
Estado y propiedades
Activar / desactivar item: isEnabled(), setEnabled(boolean)de Menu / MenuItem
Selección de CheckboxMenuItem: getState(), setState(boolean)
Label(), Label(String), Label(String,LEFT|RIGHT|CENTER)
getText(), setText(String)
getAlignment(), setAlignment(LEFT|RIGHT|CENTER)
Operación
POO - EPS - UAM
149
java.awt.Label
Estado y propiedades
POO - EPS - UAM
147
No tiene POO - EPS - UAM
150
25
java.awt.TextComponent
Descripción
Superclase de TextField y TextArea Texto editable, seleccionable
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);
Estado y propiedades
getText(), setText(String)
isEditable(), setEditable(boolean)
getCaretPosition(), setCaretPosition(int)
add (textField); add (textArea);
getSelectedText(), select(int,int), selectAll(), getSelectionStart(), getSelectionEnd(), setSelectionStart(int), setSelectionEnd(int) } POO - EPS - UAM
textField.addActionListener (this); } public void actionPerformed (ActionEvent evt) { String text = textField.getText (); textArea.append (text + "\n"); textField.selectAll (); }
151
POO - EPS - UAM
154
POO - EPS - UAM
155
java.awt.TextField
Descripción
Estado y propiedades (además de las de TextComponent)
Texto editable de una sola línea 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
KeyEvent's si interesa obtener el Puede interesar procesar carácter
Cuando se pulsa 'Enter' emite un ActionEvent con el texto del widget como action command string POO - EPS - UAM
152
java.awt.Dialog
java.awt.TextArea
Descripción
Estado y propiedades (además de las de TextComponent)
Texto editable multilínea con scrolling
SCROLLBARS_VERTICAL_ONLY...
getColumns(), setColumns(int), getRows(), setRows(int) append(String), insert(String,int), replaceRange(String,int,int)
Dialog (Frame [,String] [,boolean])
Modal / no modal: isModal(),
Emite un TextEvent cuando se cambia un carácter del texto No emite ActionEvent's POO - EPS - UAM
153
Se destruye cuando se destruye la ventana principal Desaparece cuando se minimiza la ventana principal
Estado y propiedades
Operación
TextArea.SCROLLBARS_NONE,
Depende de otra ventana:
TextArea(), TextArea(String), TextArea(String,int,int)
Scrollbars: TextArea(String,int,int,int),
Descripción
setModal(boolean)
isResizeable(), setResizeable(boolean) de Window
FileDialog extends Dialog
getDirectory(), setDirectory(String)
getFile(), setFile(String) POO - EPS - UAM
156
26
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);
java.awt.Dialog
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; 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); ...
POO - EPS - UAM
158
... 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
irn fie D
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 (); la FontMetrics metrics = g.getFontMetrics (); us g.drawRect (0, 0, dim.width-1, dim.height-1); iv g.drawString (label, ot ce (dim.width - metrics.stringWidth (label)) / 2, ps (dim.height - metrics.getHeight ()) / 2 a + metrics.getMaxAscent ()); } ... POO - EPS - UAM 161
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); } ...
159
POO - EPS - UAM
162
27
)k ca bd ee (fl au si v at se up se R
ior au su le d nó ic ca a
... public void mouseClicked (MouseEvent e) { selected = !selected; if (selected) { setBackground (Color.black); setForeground (Color.white); } else { setBackground (Color.white); setForeground (Color.black); } } public public public public ...
void void void void
mousePressed (MouseEvent e) {} mouseReleased (MouseEvent e) {} mouseEntered (MouseEvent e) {} mouseExited (MouseEvent e) {}
POO - EPS - UAM
te gd i w le d od tas el e ra lo rt no c ar ap za fr ten I }
4. Exit
2. Enter
5. Enter
3. Click
6. Drag
163
... 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); // } POO - EPS - UAM
1. Inicio
164
POO - EPS - UAM
166
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 (
Generación de eventos en respuesta a la interacción
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); }
}
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); }
a kc ab de ef sá M
oi ra us ul ed se no ic ca }
public void mouseEntered (MouseEvent e) { pointedAt = true; repaint (); } public void mouseExited (MouseEvent e) { pointedAt = false; repaint (); }
POO - EPS - UAM
165
28