En Java es posible manejar los eventos por medio de un patrón observador. Este tipo de gestor de eventos es muy útil, sobre todo cuando estamos construyendo un programa que debe reaccionar ante ciertos sucesos y no está enmarcado en una GUI (interfaz gráfica de usuario).
Por lo general, el patrón observer en Java se programa cuando tenemos la necesidad de que el cambio de un objeto sea conocido por los observadores y estos, a su vez, van a tener un comportamiento que vamos a determinar previamente.
Para construir o programar un gestor de eventos con el patrón observador necesitamos:
Es el objeto que está atento a los cambios que se producen en otro objeto. Puede haber uno o varios dependiendo de las necesidades que tenga el proyecto que estemos desarrollando.
Será el objeto que va a cambiar su estado y que va a notificar al observador u observadores.
Para usar estos elementos cuando estamos trabajando con un gestor de eventos es necesario que nos hayamos familiarizado previamente con las librerías java.util.Observable y java.util.Observer que contienen toda la información y componentes que ocuparemos en este tipo de proyectos.
Los gestores de eventos son esenciales cuando queremos establecer una relación donde uno o más elementos u objetos necesitan saber cuándo se produce un cambio de estado en otro objeto.
Estos elementos, que están alerta, escuchando o esperando que se produzca un cambio, tendrán cierta reacción, pero no tendrán la capacidad de establecer comunicación con el emisor u objeto que está siendo observado.
Tomando en cuenta el párrafo anterior, podemos decir que se trata de una comunicación unidireccional.
A continuación veremos un ejemplo comentado que ilustra de manera general cómo funciona un gestor de eventos en Java utilizando el patrón observador:
package gestor;
import java.util.ArrayList;
//una interface que tiene una función
interface Mensajero {
void hanSaludado();
}
//tenemos una clase emisor
class Emisor {
/*esta es una variable privada ArrayList que es de tipo “Mensajero”
contendrá una lista con todos los receptores*/
private ArrayList < Mensajero > receptores = new ArrayList < > ();
//encontramos un método que agrega receptores a la lista
public void meteReceptor(Mensajero receptor) {
receptores.add(receptor);
}
/*tenemos la función saluda que se va a ejecutar para cada uno de los
receptores de la lista*/
public void saluda() {
System.out.println("Hola");
for (Mensajero ml: receptores) {
ml.hanSaludado();
}
}
}
//ahora vemos la clase receptor que implementa al mensajero
class Receptor implements Mensajero {
@Override
public void hanSaludado() {
System.out.println("El emisor me ha saludado");
}
}
//creamos otra clase receptorB que implementa al mensajero
class ReceptorB implements Mensajero {
@Override
public void hanSaludado() {
System.out.println("Yo también he recibido el saludo");
}
}
public class Main {
public static void main(String[] args) {
//creamos un emisor
Emisor emisor = new Emisor();
//creamos un receptor de cada clase
Receptor receptor = new Receptor();
ReceptorB receptor2 = new ReceptorB();
//incluimos los receptores en la lista
emisor.meteReceptor(receptor);
emisor.meteReceptor(receptor2);
/*el emisor emite un comportamiento que será captado por los receptores*/
emisor.saluda();
}
}