What is and how to implement a Listener in Java?

11

Although you have already asked the Differences between listeners and adapters in the swing and also Listeners are an implementation of Observer? , I would like a more detailed explanation.

What are listeners in java? How to implement one?

    
asked by anonymous 10.09.2017 / 22:01

2 answers

9

The Observer Pattern goes far beyond Java and Swing

As you've seen, "Listener" and "Observer" are different names for the same pattern , and , it can be used for several things beyond use in Swing, and can be implemented in several other languages. Within Java, for example, the JavaFX bindings system uses (internally) the Observer pattern by binding between Properties , which allows a Property to be changed (updated) when another is; and this system can be used even in softwares without Graphical Interface (you can use Properties and bindings even without a GUI).

Why Use the Observer Pattern

It is common to use this pattern when you want a given code to be executed (the observer's code) when something happens (the event) in something (this "something" is the observed thing, button on the screen).

It is also common to use this standard to automatically update data (which is the case of JavaFX Properties and Bindings); in this case, you can have an implementation that ensures even data consistency from these automatic updates.

  • For example, you can have a dataDeNascimento attribute and a idade attribute within a Pessoa Object, and, when the value in dataDeNascimento is changed, the value in idade is automatically updated , in order to ensure% will always correctly match the date of birth. So if you call idade and then call setDataDeNascimento(...) you will get the age already updated (but be careful about competition issues, not read data that is not yet up to date or, in the case of long data structures being updated, reading the structure while it is still "half-updated").

Example Observer Pattern Usage

The code below is a simple implementation to exemplify the Observer Pattern:

public class Observado {
    private Object atributoQualquer;
    private final List<Observador> observadores = new ArrayList<Observador>();

    private void notificarObservadores() {
        for (Observador observador : observadores) {
            observador.notificar(this);
        }
    }
    public void adicionarObservador(Observador obs) { //também chamado de addListener(...)
        observadores.add(obs); //"obs" passará a ser notificado sobre mudanças em this
    }
    public void removerObservador(Observador obs) { //também chamado de removeListener(...)
        observadores.remove(obs); //"obs" deixará de ser notificado sobre mudanças em this
    }
    public void setAtributoQualquer(Object novoValor) {
        atributoQualquer = novoValor;
        notificarObservadores(); //avisamos os Observadores que houve uma alteração em this
    }
}

public interface Observador { //também chamado de "Listener"
    public void notificar(Observado obs); //também chamado de "notify()"
}

public class ObservadorA implements Observador {
    public void notificar(Observado obs) { //Chamado quando ocorrer uma alteração em "obs"
        //Atualiza dados, executa código que deve ser executado quando "obs" for alterado, etc.
        //Aqui dentro pode-se chamar GETTERS de "obs" para obter os novos dados em "obs", como chamar "obs.getAtributoQualquer()"
    }
}

Having the code above, it is still necessary to register getIdade() as an observer of ObservadorA so that it can be notified when Observado is changed, we can do it like this:

Observado observado = new Observado();
observado.adicionarObservador(new ObservadorA());

Done, that way the Observado of notificar(...) method will be called when ObservadorA() is changed (changed when calling observado ).

Considerations for this Example:

  • I made a method setAtributoQualquer(...) , this method signature causes the Observer to "pull" ( pull ) the data of notificar(Observado obs) to know what was changed and what new values in obs , this is done by calling the GETTERS of obs .

  • The method could be, for example, obs or notificar(Object novoValor) or even notificar(Observado obs, Object novoValor) , any of these would be pushing the data to the viewer, so that it does not have to call the GETTERS of notificar(Observado obs, Object novoValor, Object valorAnterior) . Note: obs signature is similar to notificar(Observado obs, Object novoValor, Object valorAnterior) method signature of JavaFX% class:
    changed(...)

  • It is common for Observers to add "Observers" for different types of events / changes, so you will find methods like ChangeListener , void changed(ObservableValue<? extends T> observable, T oldValue, T newValue) , etc. (for example, addXXXXListener() , addYYYYListener() , addFocusListener(...) , etc.). This allows you to create codes to "hear" (or "observe") different things, without having to listen / observe everything that happens in the Observed object.

  • It is also very common to create Anonymous Classes and, more recently, Lambda Expressions , instead of creating Observer Classes, this reduces the amount of code, and is used directly in addActionListener(...) methods. Examples:

    • addMouseListener(...)

    • addXXXXListener(...)

JavaFX has an Observer system that is very interesting, and goes far beyond what I presented here, I highly recommend Study it .

    
11.09.2017 / 06:21
0

If we translate the word Listener into Portuguese we will have the word "Listener". Listener in the Portuguese language is defined as "He who hears".

And now in the programming?

We can define it as a listener too, because it stays as if it were aware of all user actions .

It waits, as if it were filtered all the data generated by the user (mouse movement, click the mouse, key pressed ...), then take the defined attitude.

If we were to assign synonyms to the Listener function we would assign the following words:

  • Listener

  • Receiver

  • Viewer

  • Helper

  • Observer

Perhaps because of the extension of the subject I recommend to read carefully the following matter which covers well this.

link

Example of a Listener interface:

public interface EventListener {
    void fireEvent (Event e);
}

A video that might also be of help for the creation would be this: link

Listener has some peculiarities that make it difficult to explain by writing.

    
11.09.2017 / 03:03