4,4. Manejando sucessos con escuchadores

4,4. Manejando sucessos con escuchadores

Pongamos en practica lo que hemos aprendido sobre el manejo de sucessos en el Capitulo 3.5 “Sucessos y escuchadores”. Puedes elegir 3 caminos basicos para manejar Sucessos, como mostramos a continuación.

El siguiente ejemplo es un caso tipico donde tenemos una pieza botón y un escuchador que maneja “la interaccion del usuario” (clicks) comunicandoselo a la aplicación como un sucesso. Aqui creamos una clase para escuchar los sucessos clicados.

public class TheButton implements Button.ClickListener {
    Button thebutton;

    /** Creates button into given container. */
    public TheButton(AbstractComponentContainer container) {
        thebutton = new Button ("Do not push this button");
        thebutton.addListener(this);
        container.addComponent(thebutton);
    }
    
    /** Handle button click events from the button. */
    public void buttonClick (Button.ClickEvent event) {
        thebutton.setCaption ("Do not push this button again");
    }
}
collectivo classe ElBotón herramienta Botón.ClickEscuchador {
    Botón elboton;

    /** Crear botón dandole un container. */
    collectivo ElBoton(IconoPiezaContainer container) {
        elBotón = nuevo Botón ("No pulses este boton");
        elBoton.sumaEscuchador(esto);
        contenedor.sumaPieza(elboton);
    }
    
    /** Manejar los sucessos click del boton desde el boton. */
    collectivo vacio botonClick(Boton.ClickSucesso sucesso) {
        elboton.colocaTitulo("No pulses este botón otra vez!");
    }
}

Como una App suele recibir sucessos a menudo para muchas piezas de la misma classe, como son los botones multiples, tiene que poder distinguir entre piezas individuales. Hay muchas tecnicas para hacerlo, pero la mas facil es usando la propiedad del sucesso recivido, esta propiedad es puesta con el objeto que manda el evento. Esto significa estar atento a escribir una propiedad a todos los objetos que emiten sucessos.


public class TheButtons implements Button.ClickListener {
    Button thebutton;
    Button secondbutton;

    /** Creates two buttons in given container. */
    public TheButtons(AbstractComponentContainer container) {
        thebutton = new Button ("Do not push this button");
        thebutton.addListener(this);
        container.addComponent(thebutton);
        
        secondbutton = new Button ("I am a button too");
        secondbutton.addListener(this);
        container.addComponent (secondbutton);
    }
    
    /** Handle button click events from the two buttons. */
    public void buttonClick (Button.ClickEvent event) {
        if (event.getButton() == thebutton)
            thebutton.setCaption("Do not push this button again");
        else if (event.getButton() == secondbutton)
            secondbutton.setCaption("I am not a number");
    }
}

collectivo classe LosBotones herramientas Boton.ClickEscuchador {
    Boton elboton;
    Boton segundoboton;

    /** Crea 2 botones en el container. */
    collectivo ElBoton(IconoPiezaContainer container) {
        elboton = nuevo Boton("No pulses el boton otra vez");
        elboton.sumaEscuchador(esto);
        contenedor.sumaPieza(elboton);
        
        segundoboton = nuevo Boton("yo soy un boton tambien");
        segundoboton.sumaEscuchador(esto);
        container.sumaPieza(segundoboton);
    }
    
    /** Manejar sucessos clic de los botones desde los 2 botones */
    collectivo vacio botonClick(Boton.ClickSucesso sucesso) {
        si (suceso.recibeBoton() == elboton)
            elboton.colocaTitulo("No vuelvas a pulsar el boton otra vez");
        sino si (sucesso.recibeBoton() == segundoboton)
            segundoboton.colocaTitulo("No soy un numero");
    }
}

Otra solucion para manejar multiples sucessos con la misma classe consiste en fusionar un codigo de sucesso en el escuchador en vez de a la classe. Un sucesso puede ser fusionado a un escuchador usando otro codigo distinto al “addListener() - sumaEscuchador”. El codigo puede pasar con el nombre del codigo, o creando un codigo objeto. En el ejemplo a continuacion, usamos un “String - Cadena” (que no es controlada en el tiempo del agrupador).


public class TheButtons2 {
    Button thebutton;
    Button secondbutton;

    /** Creates two buttons in given container. */
    public TheButtons2(AbstractComponentContainer container) {
        thebutton = new Button ("Do not push this button");
        thebutton.addListener(Button.ClickEvent.class, this,
                              "theButtonClick");
        container.addComponent(thebutton);
        
        secondbutton = new Button ("I am a button too");
        secondbutton.addListener(Button.ClickEvent.class, this,
                                 "secondButtonClick");
        container.addComponent (secondbutton);
    }
    
    public void theButtonClick (Button.ClickEvent event) {
        thebutton.setCaption ("Do not push this button again");
    }

    public void secondButtonClick (Button.ClickEvent event) {
        secondbutton.setCaption ("I am not a number!");
    }
}

collectivo classe LosBottones2 {
    Boton elboton;
    Boton segundoboton;

    /** Crea 2 botones en el container dado. */
    collectivo LosBotones2(IconoPiezaContainer container) {
        elboton = nuevo Boton ("No pulses este boton");
        elboton.sumaEscuchador(Boton.ClickSucesso.classe, esto,
                              "elBotonClick");
        container.sumaPieza(elboton);
        
        segundoboton = nuevo Boton ("Soy un boton tambien");
        segundoboton.sumaEscuchador(Boton.ClickSucesso.classe, esto, 
                                 "segundoBotonClick");
        contenedor.sumaPieza(segundoboton);
    }
    
    collectivo vacio elBotonClick(Boton.ClickSucesso sucesso) {
        elboton.colocaTitulo("No pulses este boton otra vez");
    }

    collectivo vacio segundoBotonClick(Boton.ClickSucesso sucesso) {
        segundoboton.colocaTitulo("No soy un numero");
    }
}

El codigo anyadir un escuchador utilizando “addListener - sumaEscuchador” es solo un agrupador que crea un objeto escuchador “com.vaadin.event.ListenerMethod”, el cual es un adaptador de la classe escuchador hacia un codigo. Usa como herramienta interaccionadora “java.util.EventListener” por eso puede usarse con cualquier codigo de sucesso usando este interaccionador. Ten encuenta que no todas las classes de escuchadores heredan el interaccionador “EventListener - SucessoEscuchador”.

El tercer camino, que usa nombres anonimos para las classes locales, es quiza el mas facil porque no requiere tener que manejar la classe con nuevos interaccionadores o codigos. En el siguiente ejemplo usa una classe anonima que hereda la interaccion “Button.ClickListener - Boton.ClickEscuchador” i usa de herramienta el codigo “buttonClick() - botonClick()”.


public class TheButtons3 {
    Button thebutton;
    Button secondbutton;

    /** Creates two buttons in given container. */
    public TheButtons3(AbstractComponentContainer container) {
        thebutton = new Button ("Do not push this button");

        /* Define a listener in an anonymous class. */
        thebutton.addListener(new Button.ClickListener() {
            /* Handle the click. */
            public void buttonClick(ClickEvent event) {
                thebutton.setCaption (
                        "Do not push this button again");
            }
        });
        container.addComponent(thebutton);
        
        secondbutton = new Button ("I am a button too");
        secondbutton.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                secondbutton.setCaption ("I am not a number!");            
            }
        });
        container.addComponent (secondbutton);
    }
}

collectivo classe LosBotones3 {
    Boton elboton;
    Boton segundoboton;

    /** Crea 2 botones en el contenedor dado. */
    collectivo LosBotones3(IconoPiezaContainer container) {
        elboton = nuevo Boton("No pulses este boton");

        /* Nombrar un escuchador en una classe anonima. */
        elboton.sumaEscuchador(nuevo Boton.ClickEscuchador() {
            /* Maneja el click. */
            collectivo vacio botonClick(ClickSucesso sucesso) {
                elboton.colocaTitulo (
                        "No pulses este boton otra vez");
            }
        });
        container.sumaPieza(elboton);
        
        segundoboton = nuevo Boton ("soy un boton tambien");
        segundoboton.sumaEscuchador(nuevo Boton.ClickEscuchador() {
            collectivo vacio botonClick(ClickSucesso sucesso) {
                segundoboton.colocaTitulo ("No soy un numero");            
            }
        });
        container.sumaPieza (segundoboton);
    }
}

Existen otras técnicas para separar entre diferentes codigos. Usando rasgos de los objetos, nombres, o titulos separados entre si. Usando titulos o cualquier otra forma de texto visible suele descartarse, porque puede crear problemas de comprension a la App. Usando otras cadenas simbolicas tambien puede ser peligroso, porque la sintaxis de esas cadenas se controla solo “runtime”???

Los sucessos son emitidos desde el cuadro del cliente (navegador), pero las App a veces tambien tienen que emitir sucesso en algunos casos, como cuando se tiene que actualizar algunas partes “de las interacciones del usuario”. Los sucessos pueden ser emitidos usando codigo de PiezaIcono “fireEvent(Component.Event) - fuegoSuesso(Pieza.Sucesso)”. El sucesso es transmitido a todos los escuchadores de la misma classe de sucesso para el objeto. Algunas Piezas tienen un sucesso de tipo Standard, por ejemplo, el Boton tiene una classe incorporada “Button.ClickEvent - Boton.ClickSucesso” i su correspondiente interaacionador “Button.ClickListener - Boton.ClickEscuchador”. Esos sucessos pueden ser provocado con el "fireComponentEvent() - fuegoPiezaSucesso().