Utilizar adaptadores y clases internas para manejar eventos del AWT

Esta sección te cuenta cómo utilizar los adaptadores y las clases internas (inner) para reducir el atestamiento de tu código. Si no te importa esto, puedes saltar libremente a la siguiente sección.

La mayoría de los interfaces oyentes del AWT, al contrario que ActionListener, contienen más de un método. Por ejemplo, el interface MouseListener contiene cinco métodos: mousePressed, mouseReleased, mouseEntered, mouseExited, y mouseClicked. Incluso si sólo te importan los clicks del ratón, si tu clase implementa directamente MouseListener, debes implementar estos cinco métotos. Los métodos que no te interesen pueden tener cuerpos vacíos. Aquí tienes un ejemplo:

//Un ejemplo de atestamiento pero con código válido.
MyClass implements MouseListener {
    ...
	someObject.addMouseListener(this);
    ...
    /* Definición de método vacío. */
    public void mousePressed(MouseEvent e) {
    }

    /* Definición de método vacío. */
    public void mouseReleased(MouseEvent e) {
    }

    /* Definición de método vacío. */
    public void mouseEntered(MouseEvent e) {
    }

    /* Definición de método vacío. */
    public void mouseExited(MouseEvent e) {
    }

    public void mouseClicked(MouseEvent e) {
	...//La implementación del manejador del eventos va aquí...
    }
}
Desafortunadamente, el resultado de la colección de cuerpos de métodos vacíos puede hacer el código difícil de leer y de mantener. Para ayudarte a evitar el atestamiento de tu código con cuerpos de métodos vacíos, el AWT proporciona una clase adaptadora para cada interface oyente con más de un método. (Manejar eventos estándard del AWT lista todos los oyentes y sus adaptadores.) Por ejemplo, la clase MouseAdapter implementa el interface MouseListener. Una clase adaptador implementa versiones vacías para todos sus métodos del interface.

Para utilizar un adaptador, crea una subclase de él, en lugar de implementar directamente un interface oyente. Por ejemplo, extendiendo MouseAdapter, tu clase puede heredar definiciones vacías para los cinco métodos contenidos por MouseListener.

/*
 * Un ejemplo de extensión de una clase adaptador en vez de 
 * implementar directamente un interface oyente.
 */
MyClass extends MouseAdapter {
    ... 
	someObject.addMouseListener(this);
    ... 
    public void mouseClicked(MouseEvent e) {
	...//La implementación del manejador de eventos va aquí...
    }
}
¿Qué pasa si no quieres que tu clase manejadora de eventos descienda de una clase adaptador? Por ejemplo, supón que has escrito un applet, y quieres que tu subclase de Applet contenga algo de código para menajar eventos del ratón. Como el lenguaje Java no permite la herencia múltiple, tu clase no puede descender de Applet y MouseAdapter a la vez. La solución es definer una clase inner -- una clase dentro de tu subclase de Applet -- que extienda la clase MouseAdapter,
//Un ejemplo de implementación de las clases internas.
MyClass extends Applet {
    ...
	someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
	    ...//La implementación del manejador de eventos va aquí...
        }
    }
}
Las clases internas funcionan bién incluso si tu manejador de eventos necesita acceder a variables privadas de la clase superior. Siempre que no declares una clase interna como static, ésta puede referirse a ejemplares de variables y métodos como si su código estuviera en la clase superior.

A lo largo de esta lección verás el uso de las clases internas. Para más información sobre las clases inner puedes ver la Especificación de las Clases Inner en la site de JavaSoft.


Ozito