Blackboard
A generic blackboard system for listening to and firing events.
Sometimes, having a deep component hierarchy poses a problem, when you need to inform a component high up in the tree that something happened deep down below. You normally have one of two choices - either pass the listener all the way down the hierarchy, leading to more coupled code, or let each component in between be a listener/notifier, passing the event all the way back up.
With the Blackboard, you can register any listener to listen for any event, and when that event is fired, all the listeners for that event are triggered. This keeps your components clean and rid of unnecessary boilerplate code.
Versions 1.1.0 and 1.2.0 have a dependency to Google Collections.
Sample code
public class ExampleApplication { private static final Blackboard BLACKBOARD = new Blackboard(); public static void main(final String[] args) { BLACKBOARD.enableLogging(); /* * Informs Blackboard that all TestMessageEvents should be sent to all * objects that implement TestMessageListener. * * Keeping all registrations in one central place will make the code easier * to read, and mitigates application bugs regarding late registration. */ BLACKBOARD.register(TestMessageListener.class, TestMessageEvent.class); /* * Adds the two objects as listeners into Blackboard. Blackboard will now * inform these objects whenever an event is triggered that is registered to * their interface. * * The MessageConsumer implements TestMessageListener, which listens to * TestMessageEvents. When the event is fired, the MessageConsumer prints * out the message in the event. * * Note that order is not guaranteed by Blackboard. I.e. the order in which * the listeners are triggered is probably not the same in which the * listeners were added. */ BLACKBOARD.addListener(new MessageConsumer(1)); BLACKBOARD.addListener(new MessageConsumer(2)); /* * These strings will be passed to the two MessageConsumers just added to * blackboard, without any apparent direct connection. * * Each of these strings will appear twice in the console, since there are * two listeners interested in them. */ sendString("Hello listeners"); sendString("How are you doing?"); } private static void sendString(final String message) { BLACKBOARD.fire(new TestMessageEvent(message)); } } /** * A class that listens for {@link TestMessageEvent TestMessageEvents} and * echoes them out immediately. */ public class MessageConsumer implements TestMessageListener { private final int id; public MessageConsumer(final int id) { this.id = id; } /** * This method an example implementation of * {@link TestMessageListener#receiveTestMessage(TestMessageEvent)}, defined * by the listener interface. */ public void receiveTestMessage(final TestMessageEvent event) { final String message = event.getMessage(); System.out .println("[MSG] " + this + " got the message \"" + message + "\""); } @Override public String toString() { return getClass().getSimpleName() + id; } } /** * The event that is passed from {@link ExampleNotifier} to * {@link com.github.wolfie.blackboard.example.TestMessageEvent.TestMessageListener * TestMessageListener} . * <p/> * This class is simply a event wrapper for a string message. */ public class TestMessageEvent implements Event { /** * This interface represents a typical listener. * <p/> * The class name describes clearly what it is listening for and the method * name describes naturally what the listener is trying to do. */ public interface TestMessageListener extends Listener { @ListenerMethod public void receiveTestMessage(final TestMessageEvent event); } private final String message; /** * Creates a new {@link TestMessageEvent} with a given message that will be * passed from notifier to listener. * * @param message * The message to pass */ public TestMessageEvent(final String message) { this.message = message; } public String getMessage() { return message; } @Override public String toString() { return getClass().getSimpleName() + ": " + message; } }
Links
Compatibility
Was this helpful? Need more help?
Leave a comment or a question below. You can also join
the chat on Discord or
ask questions on StackOverflow.
Version
it is now allowed to register one listener to handle several events
- Released
- 2012-04-27
- Maturity
- STABLE
- License
- Apache License 2.0
Compatibility
- Framework
- Browser
- Browser Independent
Blackboard - Vaadin Add-on Directory
A generic blackboard system for listening to and firing events.Google Collections
Wiki Article / Manual
Source Code & Example Application
Blackboard version 1.1.1
A class now can implement many Listeners
Blackboard version 1.1.2
Changed weak values to soft values. Probably consumes more memory, but doesn't lose listeners instead.
Blackboard version 1.2.0
Logging added
Blackboard version 2.0.0
- API is incompatible with eariler releases
- Notifier is removed completely
- com.github.wolfie.blackboard.Event is now an interface
- Blackboard.register() now accepts only interface-Listeners
- The example application is cleaned up
- Dependency for Google Collections is removed
Blackboard version 2.0.1
Registering an abstract Event is disallowed.
Blackboard version 2.1.0
Added support for automatically register event/listener pairs
Blackboard version 2.1.1
Added some heuristics to determining a listener method, not strictly requiring an annotation.
Blackboard version 2.2.0
it is now allowed to register one listener to handle several events