El patrón Observer en Swing
El patron observer en Swing es un poco más intrincado de lo que estudiamos en la teoría la primera vez, sobre todo por la gran cantidad de eventos y clases que hay, pero con un diagrama UML para una clase concreta, creo que podremos abstraer esta lógica.
Pongamos por ejemplo el caso de un JComboBox.
El JComboBox es un componente de Swing que nos permite seleccionar una opción de una lista desplegable, lo que nos da una pista: debe ser algo que se deba observar y este notificará cuando un evento como la selección de un ítem tenga lugar. Tendrá presumiblemente el rol de Observable.
Si echamos un vistazo a su implementación, nos encontraremos con que se compone entre otros, de un objeto de tipo EventListenerList. Si investigamos un poco, vemos que es un objeto muy sencillo , y la base del patrón Observer en Swing. No en vano JComponent (su clase padre) tiene este mismo campo, siendo según la documentación «The base class for both standard and custom components that use the Swing architecture».
Pongamos lo que sabemos por ahora en un diagrama UML: Un Componente de tipo JComboBox tiene un campo donde se almacenan diferentes objetos que extienden de la clase EventListener.
Ya tenemos al elemento Observable más o menos definido. Ahora falta definir el Observador, que puede ser cualquier cosa, siempre y cuando le podamos enviar mensajes.
Si recordamos, el observador debe implementar un método para recibir notificaciones. Ese método es el que se llama desde el elemento observado para desencadenar un algoritmo del que ya no es responsable.
¿Recuerdas de qué tipo son los oyentes en la lista de tipo EventListenerList del objeto Observable? Todos heredaban de una de tres interfaces: ActionListener, ItemListener y PopupMenuListener. Pues por definición, si queremos meter un oyente en esa lista para que sea notificado, debe implementar una de estas tres interfaces e implementar los métodos correspondientes.
El cómo llama al evento es algo que dejo para las personas que tengan paciencia para comprender a fondo como funciona Swing. Se ven implicadas otras clases y supondría desviarse del tema demasiado. Pero el cuándo, es fácil de adivinar: cuando se llaman a los métodos que comienzan por fire, por ejemplo fireActionEvent().
Así que si queremos que nuestra clase observadora sea notificada de un evento de un JComboBox solo tendremos que seguir estos dos pasos:
- Implementar la interfaz del evento que queramos escuchar y añadirle una funcionalidad.
- Añadir como oyente a nuestra clase observable de tipo JComboBox.
Y por último…
No hace falta decir que este modelo está muy simplificado, para facilitar la comparación con el modelo teórico. Muchas más interfaces heredan de EventListener y el JComboBox implementa varias interfaces para escuchar (es a la vez observadora y observada).
Os animo a bucear por el código fuente del JDK alguna vez en clases no muy enrevesadas. Es un gran ejercicio tanto para conocer el lenguaje como para coger fluidez en la lectura de código.