13/04/2007 GESTIÓN DE EVENTOS GUI EN JAVA 13/04/2007 DAI Conceptos básicos z Evento: Objeto que describe qué sucede z Generador de evento (event source). Ej: pulsación de botónÎ genera ActionEvent: – getActionCommand(): comando asociado a la acción – getModifiers(): modificadores capturados durante la acción Gestor de evento (event handler): Método que recibe un objeto Evento Modelo de eventos Java 2: Modelo de delegación z z 13/04/2007 DAI 1 13/04/2007 Modelo de delegación de eventos z Origen JDK1.1 z Los eventos se envían al componente que los origina z Cada componente debe tener registradas las clases listeners que contienen los gestores de eventosÎ Separación objeto-gestor de eventos z Los eventos se envían a los listeners z Cada evento tiene un interfaz de escucha – Métodos a definir para recibir y tratar el evento 13/04/2007 DAI Gestión de Eventos 13/04/2007 DAI 2 13/04/2007 13/04/2007 DAI Consideraciones de diseño z z Ejecución rápida al ejecutarse en el mismo thread Î ejecutar en otro thread si la acción va a requerir tiempo Î aspectos de concurrencia en Swing ¿Uso de clases diferentes para ¿ p tipos p diferentes de listeners? – z Simplicidad de mantenimiento vs rendimiento Listeners en clases públicas o privadas 13/04/2007 DAI 3 13/04/2007 Objetos de Evento (EventObject) z Cada método de listener tiene como argumento un objeto que hereda de java.util.EventObject(ActionEvent, ItemEvent,…) z Object getSource() : obtenemos el objeto que disparó el evento 13/04/2007 DAI AWTEvent z Clase raíz para los objetos de evento AWT 13/04/2007 DAI 4 13/04/2007 Tipos de eventos z Bajo nivel – Eventos de ventana, de ratón, de teclado..generalmente entradas de usuario z Semánticos – A veces activados por entradas de usuario – Eventos disparados por la inserción de datos, selección de item en lista o combo, etc – Son los que más deben preocuparnos para tener un código robusto y portable 13/04/2007 DAI Adaptadores de eventos (Adapter) z Algunos interfaces contienen más de 1 método Î Tenemos que implementarlos todos, aun cuando no queramos hacer nada con ellos Î cuerpo vacío z Ejemplo:MouseListener – mousePressed, mouseReleased, mouseEntered, mouseExited, mouseClicked. 13/04/2007 DAI 5 13/04/2007 Clases internas z z Cómo usar una clase adaptadora sin tener que heredar Î Puede ser necesario al no existir herencia múltiple en Java Solución 1: Clase adaptadora interna public class MyClass extends Applet { ... someObject.addMouseListener(new MyAdapter()); ... class MyAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) {.. } } } 13/04/2007 DAI Clases internas anónimas z Es la solución 2 public class MyClass extends Applet { ... someObject.addMouseListener(new MouseAdapter() { public bli void id mouseClicked(MouseEvent Cli k d(M E e)) { …... } }); ... } } 13/04/2007 DAI 6 13/04/2007 Peligros de clases internas y anónimas z Internas: – – z El tiempo de carga de la aplicación y el uso de memoria es directamente proporcional al número de clases usadas. Si no se declara como clase static, tiene acceso a variables i bl d de iinstancia t i final fi l privadas i d d de lla clase l contenedora Anónimas: El mecanismo de persistencia no las considera 13/04/2007 DAI El manejador de eventos z A partir de JDK1.4 se introduce la clase EventHandler para soportar event listeners muy simples z Utilidad: – Crear event listener persistente sin tener que incluirlos en una clase propia – Rendimiento, R di i t ya que no ““añade” ñ d ” otra t clase l z Dificultad de construcción: errores no se detectan en tiempo de compilación 13/04/2007 DAI 7 13/04/2007 Ejemplo de manejador de eventos import java.beans.EventHandler; public class ColorChooserDemo extends JPanel { ... tcc.getSelectionModel().addChangeListener( (ChangeListener) EventHandler.create( ChangeListener.class, banner, "foreground", "source.selectedColor")); ) ... ... } 13/04/2007 DAI Listeners soportados por componentes z Component listener: Cambios en tamaño, posición o visibilidad z Focus listener: Escucha si el componente está en disposición de recibir entrada de teclado z Key listener: Escucha pulsaciones de teclas; únicamente si el componente es el foco actual z Mouse listener: Clics de ratón y entrada/salida del área del componente z Mouse-motion listener: Cambios en la posición del ratón en la superficie del componente z Mouse-wheel listener (a partir de 1.4): Movimiento de la rueda del ratón por el componente 13/04/2007 DAI 8 13/04/2007 Interfaz ActionListener z z z Sirve para detectar ActionEvent Ejemplos:Pulsar botón, pulsar return en JTextArea ¿Cómo detectamos el evento? z z Public void actionPerformed(ActionEvent e) ¿Cómo situamos un objeto a la escucha de este evento? – Public addActionListener(ActionListener) 13/04/2007 DAI ActionEvent z Evento semántico que hereda de Java.awt.AWTEvent, indica que ha ocurrido una acción en un componente 13/04/2007 DAI 9 13/04/2007 Ejemplo ActionListener 13/04/2007 DAI Interfaz ItemListener z z Escuchar eventos ItemEvent producidos por JCheckbox, JList, JCheckBoxMenuItem Método a implementar: – z Public void itemStateChanged(ItemEvent e) Añadir objeto a escucha: – Public addItemListener(ItemListener) 13/04/2007 DAI 10 13/04/2007 ItemEvent z Evento semántico que indica que se ha seleccionado un objeto, hereda de AWTEvent 13/04/2007 DAI Ejemplo ItemListener public class ComponentEventDemo extends JPanel implements ComponentListener, ItemListener { .. JCheckBox checkbox = new JCheckBox("Label visible", true); checkbox.addItemListener(this); .. public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { label.setVisible(true); label.revalidate(); label.repaint(); } else { label.setVisible(false); } } 13/04/2007 DAI 11 13/04/2007 ComponentListener z Generado por JDialog y Jframe para ComponentEvent 13/04/2007 DAI ComponentEvent z Evento de bajo nivel que indica cambio en tamaño, posición, visibilidad en componente 13/04/2007 DAI 12 13/04/2007 Ejemplo ComponentListener public class ComponentEventDemo ... implements ComponentListener{ …… public void componentHidden(ComponentEvent e) { displayMessage("componentHidden event from " + e.getComponent().getClass().getName()); } public void componentMoved(ComponentEvent e) { Component c = e.getComponent(); displayMessage("componentMoved event from " + c.getClass().getName() + "; new location: " + c.getLocation().x + ", " + c.getLocation().y); } public void componentResized(ComponentEvent e) { Component c = e.getComponent(); displayMessage("componentResized event from " + c.getClass().getName() + "; new size: " + c.getSize().width + ", " + c.getSize().height); } public void componentShown(ComponentEvent e) { displayMessage("componentShown event from " + e.getComponent().getClass().getName()); } ….} 13/04/2007 DAI Window Listener z z z Para manejar WindowEvent, producidos por JDialog y JFrame Public void addWindowListener(WindowListener e) Métodos a implementar 13/04/2007 DAI 13 13/04/2007 WindowEvent z Evento de bajo nivel que indica cambio en estado de ventana, que hereda de ComponentEvent 13/04/2007 DAI Ejemplo WindowListener public WindowEventDemo() { ... frame.addWindowListener(this); frame.addWindowFocusListener(this); frame.addWindowStateListener(this); } public void windowClosing(WindowEvent e) { displayMessage(“windowClosing."); ActionListener task = new ActionListener() { boolean alreadyDisposed = false; public void actionPerformed(ActionEvent e) { if (!alreadyDisposed) { alreadyDisposed = true; frame.dispose(); } else { //make sure the program exits System.exit(0); } } }; Timer timer = new Timer(500, task); timer.setInitialDelay(2000); timer.start(); 13/04/2007 DAI } 14 13/04/2007 Interfaz MouseListener z MouseEvent generado por Canvas, JDialog, JFrame, JPanel y JWindow 13/04/2007 DAI MouseEvent z z z Indica la ocurrencia de una acción de ratón Hereda de InputEvent(ComponentEvent) Evento de bajo nivel generado por – Acciones de ratón (MouseEvent) z z – Acciones sobre botones Posicionamiento del ratón sobre componentes Acciones de movimiento de ratón (MouseMotionEvent) z Desplazar/arrastrar el ratón 13/04/2007 DAI 15 13/04/2007 MouseEvent 13/04/2007 DAI Ejemplo MouseListener public class MouseEventDemo ... implements MouseListener { blankArea.addMouseListener(this); addMouseListener(this); ... public void mousePressed(MouseEvent e) { saySomething("Mouse pressed; # of clicks: " + e.getClickCount(), e); } public void mouseReleased(MouseEvent e) { saySomething("Mouse released; # of clicks: " + e.getClickCount(), e); } public void mouseEntered(MouseEvent e) { saySomething("Mouse entered", e); } public void mouseExited(MouseEvent e) { saySomething("Mouse exited", e); } public void mouseClicked(MouseEvent e) { saySomething("Mouse clicked (# of clicks: " + e.getClickCount() + ")", e); } void saySomething(String eventDescription, MouseEvent e) { textArea.append(eventDescription + " detected on " + e.getComponent().getClass().getName() + "." + newline); } } 13/04/2007 DAI 16 13/04/2007 MouseMotionListener z Canvas, JDialog, JFrame, JPanel, JWindow 13/04/2007 DAI MouseWheelEvent z Hereda de MouseEvent, indicando rotación en la rueda del ratón 13/04/2007 DAI 17 13/04/2007 MouseWheelListener public class MouseWheelEventDemo ... implements MouseWheelListener ... { public MouseWheelEventDemo() { textArea.addMouseWheelListener(this); ... } public void mouseWheelMoved(MouseWheelEvent e) { String message; int notches = e.getWheelRotation(); if (notches < 0) { message = "Mouse wheel moved UP " + -notches + " notch(es)" + newline; } else { message = "Mouse wheel moved DOWN " + notches + " notch(es)" + newline; } if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { message += " Scroll type: WHEEL_UNIT_SCROLL" + newline; message += " Scroll amount: " + e.getScrollAmount() + " unit increments per notch" + newline; message += " Units to scroll: " + e.getUnitsToScroll() + " unit increments" + newline; message += " Vertical unit increment: " + scrollPane.getVerticalScrollBar().getUnitIncrement(1) + " pixels" + newline; } else { message += " Scroll type: WHEEL_BLOCK_SCROLL" + newline; message += " Vertical block increment: " + scrollPane.getVerticalScrollBar().getBlockIncrement(1) + " pixels" + newline; } saySomething(message, e); } ... } 13/04/2007 DAI FocusListener z Se produce FocusEvent cuando un componente recibe el foco, es decir, es el componente “activo” 13/04/2007 DAI 18 13/04/2007 FocusEvent z Evento de bajo nivel que indica que un componente recibe el foco de la aplicación 13/04/2007 DAI Ejemplo FocusListener public class FocusEventDemo ... implements FocusListener public void focusGained(FocusEvent e) { displayMessage("Focus gained", e); } public void focusLost(FocusEvent e) { displayMessage("Focus lost", e); } 13/04/2007 DAI 19 13/04/2007 KeyListener z z Permite tratar los eventos gestionados por pulsación de tecla(s)ÎKeyEvent ¿Qué podemos detectar? – Pulsación (key-typed) – Presionar (key-pressed) y soltar una tecla (key-released) Î única forma de detectar la pulsación de teclas que no generan carácter Unicode (p (p.ej. ej Fx Fx, ctrl ctrl,etc) etc) 13/04/2007 DAI KeyEvent z Evento de bajo nivel generado por componente al pulsar, presionar o soltar una tecla. Hereda de InputEvent 13/04/2007 DAI 20 13/04/2007 KeyEvent (II) 13/04/2007 DAI Ejemplo KeyListener public class KeyEventDemo ... implements KeyListener ... { public void keyTyped(KeyEvent e) { displayInfo(e, "KEY TYPED: "); } public void keyPressed(KeyEvent e) { displayInfo(e, "KEY PRESSED: "); } public void keyReleased(KeyEvent e) { int id = e.getID(); if (id == KeyEvent.KEY_TYPED) { char c = e.getKeyChar(); keyString = "key character = '" + c + "'"; } else { int keyCode = e.getKeyCode(); keyString = "key code = " + keyCode + " (" + KeyEvent.getKeyText(keyCode) + ")"; }} ... 13/04/2007 DAI 21 13/04/2007 Resumen de Listeners 13/04/2007 DAI Resumen de Interfaces de Eventos(II) 13/04/2007 DAI 22 13/04/2007 Resumen de Interfaces de Eventos(III) 13/04/2007 DAI Resumen de Interfaces de Eventos(IV) 13/04/2007 DAI 23 13/04/2007 Manejo de múltiples Listeners z Múltiples listeners pueden estar a la escucha de un mismo evento z Cada listener recibiría el evento y el objeto que lo produce y actuaría en consecuencia 13/04/2007 DAI Ejemplo de múltiples listeners public class MultiListener ... implements ActionListener { ... ……… button1.addActionListener(this); button2.addActionListener(this); button2.addActionListener(new Eavesdropper(bottomTextArea)); } public void actionPerformed(ActionEvent e) { topTextArea.append(e.getActionCommand() + newline); }} class Eavesdropper implements ActionListener { ... public void actionPerformed(ActionEvent e) { myTextArea.append(e.getActionCommand() + newline); }} 13/04/2007 DAI 24