Mostrando las entradas con la etiqueta listeners. Mostrar todas las entradas
Mostrando las entradas con la etiqueta listeners. Mostrar todas las entradas

4.4. Controlar Eventos con Oyentes

Vamos a poner en práctica lo que aprendimos del manejo de eventos en la Sección 3.5, "Eventos y Oyentes". Puede manejar los eventos de tres formas básicas, como se muestra a continuación.

El siguiente ejemplo sigue un modelo típico en el que tiene un componente Button y un oyente que se encarga de la interacción del usuario (clics) comunicado a la aplicación por eventos. Aquí definimos una clase que escucha los eventos clic.

public class ElBoton implements Button.ClickListener {
    Button elBoton;

    /** Crear el botón en el contenedor proporcionado. */
    public ElBoton(AbstractComponentContainer contenedor) {
        elBoton = new Button ("No presione este botón");
        elBoton.addListener(this);
        contenedor.addComponent(elBoton);
    }
    
    /** Controlar los eventos clic del boton para el boton. */
    public void buttonClick (Button.ClickEvent event) {
        elBoton.setCaption ("No presione este botón de nuevo");
    }
}

Como una aplicación suele recibir eventos de varios componentes de la misma clase, tales como múltiples botones, esta tiene que ser capaz de distinguir entre los componentes individuales. Hay varias técnicas para hacer esto, pero probablemente la más fácil es utilizar la propiedad del evento recibido, que se establece en el objeto enviando el evento. Esto requiere tener a mano una referencia para cada objeto que emite los eventos.

public class ElBoton implements Button.ClickListener {
    Button elBoton;
    Button segundoBoton;

    /** Crear dos botones en el contenedor proporcionado. */
    public ElBoton(AbstractComponentContainer contenedor) {
        elBoton = new Button ("No presione este botón");
        elBoton.addListener(this);
        contenedor.addComponent(elBoton);
        
        segundoBoton = new Button ("Yo soy un botón también");
        segundoBoton.addListener(this);
        contenedor.addComponent (segundoBoton);
    }
    
    /** Controlar los eventos clic del boton para los dos boton. */
    public void buttonClick (Button.ClickEvent event) {
        if (event.getButton() == elBoton)
            elBoton.setCaption("No presione este botón de nuevo");
        else if (event.getButton() == segundoBoton)
            segundoBoton.setCaption("Yo no soy un número");
    }
}

Otra solución para manejar eventos múltiples de la misma clase implica vincular un origen de eventos a un método oyente en lugar de la clase. Un evento puede ser vinculado a un método utilizando otra versión del método addListener(), el cual toma el método que maneja el evento como un parámetro. El método puede ser pasado ya sea por el nombre del método o como un objeto Method. En el siguiente ejemplo, utilizamos el nombre del método como una cadena (el cual no es comprobado en tiempo de compilación).

public class ElBoton2 implements Button.ClickListener {
    Button elBoton;
    Button segundoBoton;

    /** Crear dos botones en el contenedor proporcionado. */
    public ElBoton2(AbstractComponentContainer contenedor) {
        elBoton = new Button ("No presione este botón");
        elBoton.addListener(Button.ClickEvent.class, this,
                              "elButtonClick");
        contenedor.addComponent(elBoton);
        
        segundoBoton = new Button ("Yo soy un botón también");
        segundoBoton.addListener(Button.ClickEvent.class, this,
                                 "segundoButtonClick");
        contenedor.addComponent (segundoBoton);
    }
    
    public void elButtonClick (Button.ClickEvent event) {
        elBoton.setCaption ("No presione este botón de nuevo");
    }

    public void segundoButtonClick (Button.ClickEvent event) {
        segundoBoton.setCaption("Yo no soy un número");
    }
}

Agregar un método oyente con addListener() es realmente sólo un wrapper que crea un objeto oyente com.vaadin.event.ListenerMethod, que es un adaptador desde una clase oyente a un método. Este implementa la interfaz java.util.EventListener y por lo tanto puede trabajar para cualquier origen de eventos utilizando la interfaz. Tenga en cuenta que no todas las clases oyentes necesariamente heredan la interfaz EventListener.

La tercera forma, que utiliza definiciones de clases locales anónimas, es a menudo la más fácil ya que no necesita obstaculizar la administración de la clase con nuevas interfaces o métodos. En el siguiente ejemplo se define una clase anónima que hereda la interfaz Button.ClickListener e implementa el método buttonClick().

public class ElBoton3 {
    Button elBoton;
    Button segundoBoton;

    /** Crear dos botones en el contenedor proporcionado. */
    public ElBoton3(AbstractComponentContainer contenedor) {
        elBoton = new Button ("No presione este botón");

        /* Define un oyente en una clase anonima. */
        elBoton.addListener(new Button.ClickListener() {
            /* Controlar el clic. */
            public void buttonClick(ClickEvent event) {
                elBoton.setCaption (
                        "No presione este botón de nuevo");
            }
        });
        contenedor.addComponent(elBoton);
        
        segundoBoton = new Button ("Yo soy un botón también");
        segundoBoton.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                segundoBoton.setCaption ("Yo no soy un número!");            
            }
        });
        contenedor.addComponent (segundoBoton);
    }
}

También existen otras técnicas para la separación entre las diferentes fuentes. Ellas incluyen el uso de las propiedades de los objetos, nombres o títulos para separarlos entre ellos. Utilizar títulos o cualquier otro texto visible es generalmente desalentador, ya que puede crear problemas para la internacionalización. Utilizar otras cadenas simbólicas también puede ser peligroso, porque la sintaxis de estas cadenas se verifican sólo en tiempo de ejecución.

Los eventos son generalmente emitidos por el framework, pero también las aplicaciones pueden necesitar emitirlos en algunas situaciones, como cuando se requiere actualizar alguna parte de la interface de usuario. Los eventos pueden emitirse utilizando el método fireEvent(Component.Event) de AbstractComponent. El evento entonces es retransmitido a todos los oyentes del evento en particular de la clase para el objeto. Algunos componentes tienen un tipo de evento por defecto, por ejemplo, un Button tiene una clase Button.ClickEvent anidada y una correspondiente interfaz Button.ClickListener. Estos eventos pueden ser desencadenados con fireComponentEvent().



Anterior
4.3. Ventanas Secundarias
Siguiente
4.5. Referenciar Recursos

3.5. Eventos y Oyentes

Vaadin ofrece un modelo de programación orientada a eventos para el manejo de la interacción del usuario. Cuando un usuario hace algo, como hacer clic en un botón o seleccionar un elemento, la aplicación necesita tener conocimiento de esto. Muchos frameworks basados en interfaz de usuario Java siguen el modelo Evento-Oyente (conocido tambien como el modelo de diseño Observador) para comunicar la entrada de datos por el usuario a la lógica de la aplicación. Vaadin también lo hace. El modelo de diseño implica dos clases de elementos: un objeto que genera ("dispara" o "emite") eventos y un número de oyentes que escuchan los eventos. Cuando ocurre un evento, el objeto envía una notificación de ello a todos los oyentes. En un caso típico, sólo hay un oyente.

Los eventos pueden servir para muchos propósitos. En Vaadin, el propósito habitual de los eventos es manejar la interacción del usuario en una interfaz de usuario. La administración de sesiones puede requerir eventos especiales, tales como el tiempo-muerto, cuyo caso el evento es en realidad la falta de interacción del usuario. El tiempo-muerto es un caso especial de eventos programados o previstos, donde un evento ocurre en una fecha y hora específica o cuando se ha cumplido una hora. Las bases de datos y otros tipos de comunicación asincrónica también pueden causar eventos.

Para recibir eventos de un tipo en particular, una aplicación debe registrar un objeto oyente con el origen del evento. Los oyentes son registrados en los componentes con el addListener(). El método tiene una versión genérica definida en el nivel de AbstractComponent, la clase base de todos los componentes.

La mayoría de los componentes que tienen eventos relacionados definen su propia clase de evento y sus respectivas clases oyentes. Por ejemplo, Button tiene eventos Button.ClickEvent, el cual puede ser escuchado a travéz de la interfaz Button.ClickListener.

A continuación, manejamos los clics de button con un oyente implementado como una clase anónima:

final Button button = new Button("Presionalo!");

button.addListener(new Button.ClickListener() {
    public void buttonClick(ClickEvent event) {
        button.setCaption("Lo presionaste!");
    }
});

La Figura 3.3, "Diagrama de Clases de un Oyente de Clic de Button" ilustra un ejemplo donde una clase específica de la aplicación hereda la interfaz Button.ClickListener capaz de escuchar eventos clic de button. La aplicación debe crear instancias de la clase oyente y registrarla con addListener(). Cuando ocurre un evento, el evento de un objeto es instanciado, en este caso un ClickEvent. El evento del objeto conoce el componente de interfaz de usuario relacionado, en este caso Button.

Figura 3.3. Diagrama de Clases de un Oyente de Clic de Button

En los viejos tiempos de programación en C, las retrollamadas a funciones llenaron en gran parte la misma necesidad como los oyentes lo hacen ahora. En lenguajes orientados a objetos, sólo tenemos clases y métodos, no funciones, por lo que la aplicación tiene que proporcionar una clase interface en lugar de un puntero a una retrollamada de función al framework. Sin embargo, Vaadin también admite la definición de un método como un oyente, utilizando el wrapper MethodListener.

Tenga en cuenta que muchas interfaces oyentes heredan de la superinterface java.util.EventListener, pero generalmente no es necesario heredarlo.

La Sección 4.4, "Controlar Eventos con Oyentes" explica en detalle como manejar eventos en la práctica.



Anterior
3.4. Motor del Lado del Cliente
Siguiente
Capítulo 4. Escribir una Aplicación Web