La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

IGU en Java: Modelo de Eventos

Presentaciones similares


Presentación del tema: "IGU en Java: Modelo de Eventos"— Transcripción de la presentación:

1 IGU en Java: Modelo de Eventos
Ingeniería de la Programación Práctica 4

2 Contenido Introducción Elementos del modelo de eventos en Java
Jerarquía de eventos. Fuentes de eventos. Receptores de eventos e interfaces receptoras Registro de receptores. Clases adaptadoras. Estrategias de programación del receptor.

3 Objetivos Comprender el modelo de eventos de Java, basado en delegación. Seleccionar la mejor estrategia para programar los ‘listeners’ de eventos. Implementar eventos básicos para una IGU.

4 Introducción Todo sistema operativo que utiliza interfaces gráficas de usuario debe estar constantemente monitorizando el entorno para capturar y tratar los eventos que se producen. El sistema operativo informa de estos eventos a los programas que se están ejecutando y entonces cada programa decide qué hace para dar respuesta a esos eventos. Los eventos pueden estar producidos por el sistema o por el usuario. Los programas que gestionan las interacciones del usuario de esta forma se dice que están dirigidos por eventos.

5 Introducción Cada vez que el usuario realiza una determinada acción sobre una aplicación Java (pulsar sobre un botón, pulsar una tecla, pasar el ratón sobre una imagen) se produce un evento que el sistema operativo transmite al entorno de ejecución de Java. Java crea un objeto de una determinada clase de evento, el cual es transmitido a un determinado método para que lo gestione. El modelo de eventos de Java está basado en delegación (la responsabilidad de gestionar un evento que ocurre en un objeto – fuente/source- la tiene otro objeto-receptor/listener-). 1. Se registra como oyente Objeto fuente Objeto oyente 3. Cuando se produce un evento se comunica a todos los oyentes, mediante la invocación de un método del oyente (al que se le pasa como parámetro el evento) 2. Lo apunta en la lista de oyentes

6 Introducción Cada componente de la interfaz de usuario puede generar varios tipos de eventos. Java permite varios receptores para un mismo tipo de evento de un emisor. De igual forma varios emisores se pueden asociar a un único receptor. Objeto oyente 1 Objeto fuente Objeto oyente 2 Objeto fuente 1 Objeto oyente Objeto fuente 2

7 Introducción textField1 manejador JTextField object listenerList
public void actionPerformed( java.awt.event.ActionEvent e) { // código de manejo del evento } listenerList Esta referencia la crea la sentencia: textField1.addActionListener( manejador);

8 Elementos del modelo de eventos de Java
Jerarquías de clases de Eventos Fuentes de Eventos (event sources) Receptores de Eventos (event listener) Interfaces listener. Registrar eventos. Adaptadores (adapter classes)

9 Jerarquías de eventos Cada vez que se produce un evento dicho evento se representa como una instancia de una clase descendiente de AWTEvent. ActionEvent (1) TextEvent (1) AWTEvent Object EventObject AdjustmentEvent (1) ComponentEvent ItemEvent (1) FocusEvent WindowEvent InputEvent ContainerEvent PaintEvent KeyEvent MouseEvent

10 Fuentes de eventos La fuente (source) de un evento es el objeto que lo detecta y lo comunica al objeto receptor (listener). Ejemplos de fuentes y eventos generados Fuente Evento generado Pulsación sobre un botón Pulsa <Return> sobre un campo de texto Pulsar sobre una opción de menú ActionEvent Cerrar la ventana principal de la aplicación WindowEvent Pulsar con el ratón sobre un componente MouseEvent Mover el ratón sobre un componente Un componente se hace visible ComponentEvent

11 Eventos generados por componentes AWT
Significado Button ActionEvent Pulsar el ratón sobre un botón Checkbox ItemEvent Seleccionar o deseleccionar un item CheckboxMenuItem Choice Component FocusEvent Obtener o perder el foco ComponentEvent Mover, cambiar tamaño, mostrar u ocultar un componente KeyEvent Pulsar o soltar un tecla MouseEvent Pulsar o soltar un botón del ratón, entrar o salir de un componente, mover o arrastrar el ratón (tenga en cuenta que el evento tiene 2 interfaces oyentes MouseListener y MouseMotionListener) Container ContainerEvent Añadir o eliminar un componente de un contenedor List Hacer doble click sobre un item de la lista Seleccionar o deseleccionar un item de la lista MenuItem Seleccionar un item de un menú Scrollbar AdjustmentEvent Cambiar el valor de la barra de desplazamiento TextComponent TextEvent Cambiar el contenido (texto). TextField Pulsar intro al editar un texto Window WindowEvent Acciones sobre una ventana: abrir, cerrar, iconizar (minimizar), restablecer, cerrar.

12 Eventos generados por componentes AWT (2)
Hay componentes de AWT que no poseen eventos propios (TextArea), pero todos los eventos de una superclase (en la jerarquía AWT) se aplican a la subclase. Con la consideración anterior un TextArea puede generar los siguientes eventos (todos heredados): Componente Evento TextArea ComponentEvent FocusEvent KeyEvent MouseEvent TextEvent

13 Receptores de eventos Cuando ocurre un evento un objeto fuente puede llamar a uno o varios objetos receptores. Los receptores (listeners) de eventos son objetos de una clase determinada que implementa un interface específico llamado interface listener. Existe una interface listener por cada tipo de evento.

14 Eventos generados por componentes Swing
Los eventos generados por los componentes Swing son de dos tipos: Una primera clase que engloba los oyentes que todos los componentes Swing pueden soportar: Component Listener: Oyentes para el cambio en el tamaño, posición o visibilidad de un componente. Focus Listener: Oyentes para manejar la perdida o ganancia de foco del teclado. Key Listener: Oyentes para detectar pulsaciones de teclado; los eventos de teclado son activados únicamente por el componente que tiene el foco del teclado. Mouse Listener: Oyentes para “clicks” del ratón, pulsar un botón del ratón, soltar un botón del ratón, entrar en el área de dibujo del componente, salir de la misma. Mouse-motion Listener: Cambiar la posición del cursor del ratón sobre un componente. Mouse-wheel Listener: Movimiento de la rueda del ratón sobre un componente. Hierarchy Listener: Oyentes para los cambios en la jerarquía de un componente. Hierarchy Bounds Listener: Oyentes para el cambio de posición y de tamaño. Una segunda clase que engloba oyentes específicos para cada tipo de componente.

15 Oyentes específicos

16 Oyentes específicos (2)

17 Interfaces receptoras
Evento Interfaz Listener Métodos de la Interfaz ActionEvent ActionListener actionPerformed AdjustmentEvent AdjustmentListener adjustmentValueChanged ComponentEvent ComponentListener componentHidden, componentMoved, componentResized, componentShown ContainerEvent ContainerListener componentAdded,componentRemoved FocusEvent FocusListener focusGained, focusLost ItemEvent ItemListener itemStateChanged KeyEvent KeyListener keyPressed,keyReleased,keyTyped MouseEvent MouseListener mousePressed,mouseReleased, mouseEntered, mouseExited. MouseMotionListener mouseDragged, mouseMove TextEvent TextListener textValueChanged WindowEvent WindowListener windowActivated, windowClosed, windowClosing,windowDeactivated, windowDeiconified, windowIconified, windowOpened.

18 Registro del receptor Cuando ya disponemos del objeto fuente y del objeto receptor es necesario asociarlos, es decir, hay que registrar el objeto receptor de eventos con el objeto fuente de los mismos: El objeto receptor debe implementar una determinada interface listener. Los métodos de la interfaz serán llamados cuando se produzca el evento. Con la instrucción remove<Evento>Listener(ObjetoReceptor) se puede eliminar el objeto oyente. ObjetoFuenteEventos.add<Event>Listener(ObjetoReceptorEventos) Se cambia por el evento que se quiera recibir

19 Adaptadores Los adaptadores (adapters class) simplifican la programación de las clases receptoras ya que no es necesario implementar todos los métodos de las interfaces listeners. Existe una clase adaptadora (xxxAdapter) por cada interface (xxxListener) que contenga más de un método: MouseAdapter, WindowAdapter, KeyAdapter, MouseMotionAdapter, FocusAdapter, ContainerAdapter y ComponentAdapter, etc. Las clases adaptadoras implementan (mediante código vacío) todos los métodos de la correspondiente interfaz. Las adaptadoras se extienden y se incluyen los métodos de la interfaz que sean de interés.

20 Programación del receptor: alternativas
Se pueden utilizar tres estrategias: Crear el receptor como clase interna, donde una clase interna es una clase definida dentro de otra, pudiendo acceder a todos los métodos y atributos de la clase que la contiene. Crear el receptor como una clase independiente. La propia ventana implemente el receptor.

21 1. Receptor: clase interna
Ejemplo: Cambiar el color de fondo de un formulario al pulsar un botón: gris-> blanco -> gris (proyecto visual editor ejemplo1) El emisor es un JButton y el evento generado es del tipo ActionEvent. El receptor debe implementar a la interface ActionListener que tiene únicamente el método: void actionPerformed( ActionEvent e) Dos soluciones: 1.a clase interna programada manualmente. (ejemplo 1) 1.b clase anónima interna, es lo que genera visual editor. (ejemplo 2)

22 1. Receptor: clase interna
public class VentanaPrincipal extends JFrame { private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JButton Boton = null; /* código añadido */ private boolean colorgris = true; /* código inicialización del componente */ private void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); this.setTitle("Ejemplo 1"); ProcesaBoton pb = new ProcesaBoton(); this.Boton.addActionListener(pb); } //* receptor clase local class ProcesaBoton implements ActionListener { public void actionPerformed(ActionEvent e) { if (colorgris) jContentPane.setBackground(Color.white); else jContentPane.setBackground(Color.lightGray); colorgris = !colorgris;

23 1. Receptor código generado por eclipse
Eclipse genera una clase anónima interna, vea ejemplo 2. private JButton getBoton() { if (Boton == null) { Boton = new JButton(); Boton.setText("Cambiar color"); Boton.addActionListener( new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { // TODO Auto-generated Event stub actionPerformed() if (colorgris) jContentPane.setBackground(Color.white); else jContentPane.setBackground(Color.lightGray); colorgris = ! colorgris; } }); return Boton; Clase anónima interna

24 2. Receptor: clase separada
Al ser clases separadas no se puede acceder a las características de la clase que contiene al emisor, si éstas se quieren modificar se pasa una referencia a la ventana de la aplicación, en la llamada al constructor del receptor (ejemplo 3). public class Ejemplo3 extends JFrame { // el receptor se registra igual en el caso 1. private void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); this.setTitle("Ejemplo 3"); // registrar el receptor... ProcesaBoton pb = new ProcesaBoton(this); this.Boton.addActionListener(pb); } public void CambiarColor() { } } class ProcesaBoton implements ActionListener { private Ejemplo3 Marco; public ProcesaBoton(Ejemplo3 MarcoPrincipal) { Marco = MarcoPrincipal;} public void actionPerformed(ActionEvent e) { Marco.CambiarColor();}

25 2. Receptor: clase separada pero generada automáticamente
Algunas herramientas como JBuilder o JDeveloper generan el siguiente código. public class Ejemplo4_Marco extends JFrame { JPanel contentPane; JButton Boton = new JButton(); public Ejemplo4_Marco() {… } private void jbInit() throws Exception { contentPane = (JPanel) getContentPane(); contentPane.setLayout(boxLayout21); setSize(new Dimension(400, 300)); setTitle("Ejemplo 4"); Boton.setText("Cambiar Color"); Boton.addActionListener( new Ejemplo4_Marco_Boton_actionAdapter(this)); contentPane.add(Boton, null); } public void Boton_actionPerformed(ActionEvent e) {

26 2. Receptor: clase separada pero generada automáticamente
La solución es similar a la del ejemplo 3 class Ejemplo4_Marco_Boton_actionAdapter implements ActionListener { private Ejemplo4_Marco adaptee; public Ejemplo4_Marco_Boton_actionAdapter(Ejemplo4_Marco adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.Boton_actionPerformed(e);

27 3. Receptores: la ventana implementa el receptor
public class Ejemplo5 extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JButton Boton = null; private boolean colorgris = true; … // en azul código añadido a mano. private JButton getBoton() { if (Boton == null) { Boton = new JButton(); Boton.setText("Pulsa"); Boton.setBounds(new Rectangle(16, 46, 66, 26)); Boton.addActionListener(this);} return Boton; } public void actionPerformed(ActionEvent e) { if (colorgris) jContentPane.setBackground(Color.white); else jContentPane.setBackground(Color.lightGray); colorgris = ! colorgris; }

28 Ejemplo clases adaptadoras
Ejemplo: validar la longitud de un campo de texto (JTextField) cuando pierde el foco (FocusEvent)*. El receptor tiene que ser un objeto que implemente a la interface FocusListener que tiene los métodos: public void focusLost( FocusEvent e) public void focusGained( FocusEvent e) Utilizaremos el adaptador FocusAdapter, ya que únicamente queremos implementar el método focusLost. El receptor será una clase separada. *Lo habitual es programar un manejador para los botones class ManejaFocoDNI extends java.awt.event.FocusAdapter { private Ejemplo6 adaptador; public ManejaFocoDNI(Ejemplo6 adaptador1) { this.adaptador = adaptador1; } public void FocusLost(FocusEvent e) { // código para manejar la pérdida de foco. System.out.println("Perdida de foco"); }

29 Otro ejemplo: cerrar una ventana
this.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { if (jtfText.getText().compareTo("")==0) ; else { int resp; resp=javax.swing.JOptionPane.showConfirmDialog (null, “¿Estas seguro?", "Aviso", javax.swing.JOptionPane.OK_CANCEL_OPTION); if (resp==JOptionPane.OK_OPTION) System.exit(0); } });

30 Referencias Tutorial sobre Swing, accesible en:
Tutorial sobre Java, con eventos. Creating a GUI with JFC/Swing, accesible en:

31 Ejercicio Consiste en implementar la funcionalidad de la Gestión de Máquinas de la práctica 3, haciendo uso de la clase ModeloTablaMaquina. Para ello debemos implementar los manejadores de eventos de los diferentes botones y opciones de menú, haciendo que ejecuten los métodos del objeto ModeloTablaMaquina asociado en la Práctica 3 a la tabla de la Ventana Principal.

32 Ejercicio Punto 1: Enlace entre ventanas. Botones Añadir y Detalle.
VentanaDetalle v=new VentanaDetalle(tabla.getModel()); v.setVisible(true); Debe pasarle como parámetro el modelo de la tabla Debe pasarle como parámetro la máquina seleccionada Maquina m= modelo.recuperaMaquinaPorPosicion (tabla.getSelectedRow()); VentanaDetalle v=new VentanaDetalle(m); v.setVisible(true);

33 Ejercicio Punto 2: Constructor y Botones Ventana Detalle.
Constructor: Sobrecargado. Recibe un ModeloTablaMaquina o una Maquina. En el caso de recibir una Maquina visualiza sus datos en la caja de texto y deshabilita el botón Guardar. Botón Guardar. Habilitado sólo cuando el constructor recibe un ModeloTablaMaquina (i.e. se accede con el botón Añadir de la Ventana Principal). Crea una Máquina a partir de los campos de texto y la guarda mediante el método addMaquina del la clase ModeloTablaMaquina. Si todo es correcto cierra la Ventana Detalle. Botón Volver: Cierra la Ventana Detalle

34 Ejercicio Punto 3: Menús de la Ventana Principal. Menu Archivo
Guardar: serializa el listado de máquina mediante el método guardaMaquinas de la clase ModeloTablaMaquina. Utilice el cuadro de diálogo implementado en la clase JFileChooser para permitir al usuario escoger el fichero que almacena los objetos la primera vez que se guarda. En veces sucesivas usar el fichero seleccionado sin consultar al usuario. Guardar como: serializa el listado de máquinas mediante el método guardaMaquinas de la clase ModeloTablaMaquina. Utilice el cuadro de diálogo implementado en la clase JFileChooser para permitir escoger siempre el fichero que almacena los objetos. Cargar de disco: carga el listado de máquina desde disco mediante el método cargaMaquinas de la clase ModeloTablaMaquina. Utilice el cuadro de diálogo implementado en la clase JFileChooser para seleccionar siempre el fichero desde donde cargar. Salir: Cierra la aplicación Menú Aspecto: Cambia los colores de la fuente y el fondo de la aplicación. Utilice la paleta de colores implementada en la clase JColorChooser.

35 Ejercicio Punto 4: Barra de Herramientas y Botón Borrar de la Ventana Principal. Barra de Herramientas: sus botones guardan y cargan en disco como los items “Guardar como” y “Cargar de disco” del menú archivo. Botón Borrar: Elimina la Maquina seleccionada usando el método borraMaquinaPorPosicion de la clase ModeloTablaMaquina.

36 Ejercicio Adicionalmente:
Utilice la barra de estado para informar al usuario de las acciones realizadas. Antes de borrar una Máquina pregunte al usuario si está seguro. Gestione las siguientes excepciones. En cada una de ellas debe informarse al usuario con un mensaje de error en una caja de diálogo (puede utilizar la clase JOptionPane) Si se intenta añadir una Máquina con alguno de sus campos en blanco, se avisará al usuario con un mensaje. Si ya existe una Máquina con ese número, se avisará al usuario con un mensaje. Igual que en la Práctica 2. Cuando se cierra la aplicación (desde el aspa del marco o desde la opción de menú Salir) se deberá detectar si ha habido cambios en la lista de Máquinas desde el último guardado, informando al usuario si desea almacenar en disco dichos cambios. Si es la primera vez que se almacena la lista se pedirá al usuario el nombre del fichero (como en la opción de menú Guardar como…)


Descargar ppt "IGU en Java: Modelo de Eventos"

Presentaciones similares


Anuncios Google