Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User defined Listener in Java

Tags:

java

In my web app, during some change over the object, i need to send a mail about the changes happened in the object. My question is how to write a listener for this. Please give me some article regarding this. Thanks

like image 715
Manoj Avatar asked Jul 02 '10 09:07

Manoj


People also ask

How do you define a listener in Java?

An event listener in Java is designed to process some kind of event — it "listens" for an event, such as a user's mouse click or a key press, and then it responds accordingly. An event listener must be connected to an event object that defines the event.

What is listener in AJP?

Java Prime Pack The Event listener represent the interfaces responsible to handle events. Java provides us various Event listener classes but we will discuss those which are more frequently used. Every method of an event listener method has a single argument as an object which is subclass of EventObject class.


2 Answers

A typical implementation could be like this: your object is observable. So every time, one of the (observed) values changes, an event is fired and all registered listeners are notified. One of those listeners now would be designed to take the notification and create and send an EMail (Java Mail API)

Let's take a sample bean which we make observable:

public class Bean implements Observable{

  // code to maintain listeners
  private List<Listener> listeners = new ArrayList<Listener>();
  public void add(Listener listener) {listeners.add(listener);}
  public void remove(Listener listener) {listeners.remove(listener);}

  // a sample field
  private int field;
  public int getField() {return field;}
  public int setField(int value) {
    field = value;
    fire("field");        
  }

  // notification code
  private void fire(String attribute) {
    for (Listener listener:listeners) {
      fieldChanged(this, attribute);
    }
  }
}

The Listener interface:

public interface Listener {
  public void fieldChanged(Object source, String attrbute);
}

The Observable interface:

public interface Observable {
  public void add(Listener listener);
  public void remove(Listener listener);
}

And the EMailer:

public class Sender implements Listener {

  public void register(Observable observable) {observable.add(this);}
  public void unregister(Observable observable) {observable.remove(this);}

  public void fieldChanged(Object source, String attribute) {
    sendEmail(source, attribute); // this has to be implemented
  }

}

EDIT Corrected an ugly mistake in the setter method - now the event is fired after the property has been set. Was the other way round, with the side effect, that if a listener read the changed property, he still saw the old, unchanged value...

like image 98
Andreas Dolk Avatar answered Sep 22 '22 14:09

Andreas Dolk


If you simply wish to know about the properties of an object being modified I would recommend using a PropertyChangeListener. That way you can use the PropertyChangeSupport utility class to manage your listener instances and the firing of events. You also avoid reinventing the wheel.

For more bespoke event firing I would recommend defining your own listener interface.

Example Class

public class MyBean {
  private final PropertyChangeSupport support;

  private int i;
  private boolean b;

  public MyBean() {
    this.support = new PropertyChangeSupport(this);
  }

  // Accessors and Mutators.  Mutating a property causes a PropertyChangeEvent
  // to be fired.
  public int getI() { return i; }

  public void setI(int i) {
    int oldI = this.i;
    this.i = i;
    support.firePropertyChange("i", oldI, this.i);
  }

  public boolean getB() { return b; }

  public void setB(boolean b) {
    boolean oldB = this.b;
    this.b = b;
    support.firePropertyChange("b", oldB, this.b);
  }

  // Wrapper methods that simply delegate listener management to
  // the underlying PropertyChangeSupport class.
  public void addPropertyChangeListener(PropertyChangeListener l) {
    support.addPropertyChangeListener(l);
  }

  public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
    // You would typically call this method rather than addPropertyChangeListener(PropertyChangeListener)
    // in order to register your listener with a specific property.
    // This then avoids the need for large if-then statements within your listener
    // implementation in order to check which property has changed.

    if (!"i".equals(propertyName) && !"b".equals(propertyName)) {
      throw new IllegalArgumentException("Invalid property name: " + propertyName);
    }

    support.addPropertyChangeListener(propertyName, l);
  }

  public void removePropertyChangeListener(PropertyChangeListener l) {
    support.removePropertyChangeListener(l);
  }

  public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
    support.removePropertyChangeListener(propertyName, l);
  }
}

Example Usage

// Create a new instance of our observable MyBean class.
MyBean bean = new MyBean();

// Create a PropertyChangeListener specifically for listening to property "b".
PropertyChangeListener listener = new PropertyChangeListener() {
  public void propertyChange(PropertyChangeEvent evt) {
    assert "b".equals(evt.getPropertyName());
    boolean oldB = (Boolean) evt.getOldValue();
    boolean newB = (Boolean) evt.getNewValue();

    System.err.println(String.format("Property b updated: %b -> %b, oldB, newB));
  }
}

// Register listener with specific property name.  It will only be called back
// if this property changes, *not* the "i" int property.
bean.addPropertyChangeListener("b", listener);
like image 41
Adamski Avatar answered Sep 19 '22 14:09

Adamski