Example: Custom Event Observer Pattern

Hi just was looking around for a way to use custom events and found a great java observer pattern example at https://programming.guide/java/create-a-custom-event.html

Firing an event in the one class to activate something in the second class. I have extended this example a bit further to use a custom data object for passing variables with the events which you can filter on relevance for your intended actions in other classes.

Perhaps this example is relevant to anyone that wants to create their own events, thought i should share this bit.

Best,
Arne.

/********************************************************
OBSERVER EVENT

Introduction:
Implementing the Observer pattern as custom event system.
This EventData class provides the prototype and a custom data object.
The data object is used to pass custom variables with the events.

How to use:
1. In the class you want to dispatch an event include on top:
private List<EventListener> listeners = new ArrayList<EventListener>();
EventData evt;

2. In its constructor load the object:
public Initiator() {
  evt = new EventData();
}

3. Add a listener function:
public void addListener(EventListener toAdd) {
    listeners.add(toAdd);
}

4. Set the optional variables and dispatch the event:
evt.state = State.YES;
evt.integer = 10;
for (EventListener hl : listeners) {
    hl.onEvent(evt);
}

5. Register the objects that are interested in receiving the event in the main setup:
initiator.addListener(responder);

6. Fire the event from the main setup or anywere inside the dispatching class itself:
initiator.action();

7. In the listener class pick up the event and do something with it:
public void onEvent(EventData data) {
  switch(data.state) {
    case YES:
      System.out.println("Yes");
      break;
  }
}

Reference:
https://programming.guide/java/create-a-custom-event.html
********************************************************/

// IMPORT
import java.util.*;

// LISTENER
interface EventListener {  
  void onEvent(EventData data);
}

// STATE
enum State {
  YES,
  NO
}

// EVENT DATA
class EventData {
  public State state;
  public int integer;
  public float floater;
  public String string;
  
  public EventData() {};
  
  public void setState(State state) { this.state = state; };
  public void setInteger(int i) { this.integer = i; };
  public void setFloater(float f) { this.floater = f; };
  public void setString(String s) { this.string = s; };
}

// CLASS
class Initiator {
    private List<EventListener> listeners = new ArrayList<EventListener>();
    EventData evt;
    
    public Initiator() {
      evt = new EventData();
    }
    public void addListener(EventListener toAdd) {
        listeners.add(toAdd);
    }

    public void action() {
        System.out.println("Yes or no?");
        
        //dispatch event
        evt.state = State.YES;
        for (EventListener l : listeners) {
            l.onEvent(evt);
        }
    }
}

// CLASS
class Responder implements EventListener { 
    @Override
    public void onEvent(EventData data) {
        //System.out.println(data.state);
        
        switch(data.state) {
          case YES:
            System.out.println("Yes");
            break;
          case NO:
            System.out.println("No");
            break;
          default:
            System.out.println("Maybe");
        }
    }
}

// OBJECTS
Initiator initiator;
Responder responder;

void setup() {
  size(200,200);
  initiator = new Initiator();
  responder = new Responder();
  initiator.addListener(responder);
  initiator.action();
}

void draw() {
  background(0);
}

void mousePressed() {
  initiator.action();
}
7 Likes

This is interesting! Thank you for developing and sharing it.

One request ā€“ could the imports be more explicit than java.util.*? This is especially helpful for learners because it makes clear what parts of the code are not part of the Processing API.

You might also be interested in approaches using built-in java.util.Observer or using PropertyChangeListener ā€“ Iā€™d be curious about your thoughts on the advantages of the different approaches.