I’ve been trying to make an event system for several days now but I can’t find a way to do the following.
I can’t find a way to make the event interactable from a method, I mean this:
api.addEventListener (event -> { CODE );
The operation is simple, I would like that when the event is fired to the listeners in that method, I could add my code.
I am relatively new to Java and still struggle with this kind of thing.
I currently have these 5 classes:
This interface corresponds to the Listener, the one that will receive the event.
public interface UserCreateMessageListener extends GloballyAttachableListener { void fire (); }
Implementation of the above.
public class UserCreateMessageListenerImpl implements UserCreateMessageListener { @Override public void fire () { //CODE } }
This interface will contain the methods to add listeners and receive the event by adding code (which I intend to look for in the example above)
public interface GloballyAttachableListener { default void addUserCreateMessageEvent (UserCreateMessageListener listener) { // I add the listeners to my listener initializer } }
This class fires events to declared listeners.
public class Initializer extends ListenerAdapter { private static List <UserCreateMessageListener> listeners = new ArrayList <UserCreateMessageListener> (); public static void addListener (UserCreateMessageListener toAdd) { listeners.add (toAdd); } } @Override public void onMessageReceived (MessageReceivedEvent event) { for (UserCreateMessageListener e: listeners) { e.fire (); } }
This class is the class from which I intend to get information and events.
public interface Api extends GloballyAttachableListener { default String getPrefix () { return ConfigAccessor.getPrefix (); } default long getId () { return ConfigAccessor.getId (); } }
Advertisement
Answer
I recommend that use template classes for object-specific handling.
ListenerAdapter:
public class ListenerAdapter<T> { private final List<EventListener<T>> listeners = new ArrayList<>(); public void addEventListener(EventListener<T> listener) { listeners.add(listener); } public void removeEventListener(EventListener<T> listener) { listeners.remove(listener); } public void fire(T item) { listeners.forEach(listener -> listener.consume(item)); } }
EventListener:
public interface EventListener<T> { void consume(T item); }
Simple test:
public class User { private String name; public User(String name) { this.name = name; } public String getName() { return name; } } public class Main { public static void main(String[] args) { ListenerAdapter<User> listenerAdapter = new ListenerAdapter<>(); listenerAdapter.addEventListener(item -> System.out.println(item.getName())); listenerAdapter.fire(new User("john")); } }