Generically changing variables with listeners - java

I have a set of instances of a class named Marker that has a Marker#setDelay(double) method. This method is called based on mouse drags (you can drag around the markers). Every marker has a corresponding double variable in a config class.
I want to synchronize the config class with the marker instances. So whenever the Marker#setDelay(double) method is called, the corresponding variable in the config class should change too. How can I do that?
I tried using Runnables that I can apply to the markers, so the runnable would be called from within the Marker#setDelay(double) method, but this Runnable does not have access to the delay value. Is there some sort of method pointer workarround?
My last resort would be a interface and anonymous instances for every marker. But that seems kind of ugly...

The general off-the-shelf pattern here is straightforward: Introduce an interface like MarkerListener. Then you can create a (possibly anonymous) MarkerListener implementation that updates your config, and add it to the respective `Marker´.
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
interface MarkerListener
{
void delayChanged(double oldDelay, double newDelay);
}
class Marker
{
private double delay;
private final List<MarkerListener> markerListeners =
new CopyOnWriteArrayList<MarkerListener>();
void addMarkerListener(MarkerListener markerListener)
{
markerListeners.add(markerListener);
}
void removeMarkerListener(MarkerListener markerListener)
{
markerListeners.add(markerListener);
}
void setDelay(double newDelay)
{
if (newDelay != this.delay)
{
double oldDelay = this.delay;
this.delay = newDelay;
fireDelayChanged(oldDelay, newDelay);
}
}
private void fireDelayChanged(double oldDelay, double newDelay)
{
for (MarkerListener markerListener : markerListeners)
{
markerListener.delayChanged(oldDelay, newDelay);
}
}
}
Of course, this involves some code bloat. It is basically a minimalistic implementation of something that could also be achieved when using the DoubleProperty from JavaFX that Joop Eggen referred to in his answer. So you might want to consider using the DoubleProperty. (One could also solve this with PropertyChangeListeners, but these are probably not so appropriate here)
Since you referred to "function pointers": You could also use DoubleConsumer instances instead of introducing an own interface. But it's impossible to tell from the question whether this is the best solution here.

JavaFX has ...Property classes, which you can bind to receive change notifications. That is a much underestimated/overseen UI functionality.
So use a DoubleProperty. (A warning: the javadoc does not easily suffice for usage.)
See for a usage here.
Have a DoubleProperty
addListener new ChangeListener with as ObservableValue the DoubleProperty

I didn't fully understand the problem.
Here is my solution anyway
Create a Listener
public interface MarkerChangeListener{
void markerChanged(double value);
}
Implement the Config Class with listener
public class Config implements MarkerChangeListener{
private double delay;
#override
public void markerChanged(double value){
this.delay = value;
}
....
}
Add a method to your Marker class to add listener and fire the listener when the value updated
public class Marker{
private MarkerChangeListener listener;
public void addListener(MarkerChangerListener listener){
this.listener = listener;
}
public void setDelay(double delay){
this.delay = delay;
listener.markerChanged(delay)
}
}
Add the listener to the Marker class from where you create markers.
marker.addListener(config);

Related

How to find out whether Method has called for given instance. Like "Object obj" check whether obj called "equals" method or not

I want to find out whether method for some object is being called for that instance or not.
Is it possible in java ?
Like ...
class Button {
public void focus(){}
public void setName(){}
}
class MyTest {
public static void main(String[] args){
Button button = new Button();
button.focus();
// I want to find out on button instance whether focus() or setName() is called or not.
whetherMethodCalled(button);
// OR
whetherMethodCalled(button, 'focus');
whetherMethodCalled(button, 'setName');
}
}
EDIT : Forgot to add Button class is third party class which I cannot modify... Also I want to check in my code whether method has called for given object instance or not on basis of that I have to write some code.
In order to reduce extra work, perhaps profiling your application with JConsole or another tool is good enough to show if certain methods have run. Another option is using a code coverage tool like EMMA which detects dead code. There is a list of open-source profilers for Java at http://java-source.net/open-source/profilers and EMMA is at http://emma.sourceforge.net/.
With some extra work AspectJ could be use to intercept method calls without changing existing code. For example, the following would intercept calls to Button.focus()
#Aspect
public class InterceptButtonMethods {
#Before("execution(* Button.focus())")
public void beforeInvoke() {
System.out.println("Button.focus invoked");
incrementFocusCount();
}
}
If more extra work is ok, there is a way to wrap all calls to the Button's focus() and setName() methods so that they update separate counters in addition to their normal functions. This can be done by extending Button in YourButton class which is identical to Button except for a couple of int counters with getters, setters and increment methods; and countingFocus() and countingSetName() methods which update their counters and call focus() and setName() respectively, such as in outline:
Class YourButton extends Button {
int focusCount;
int setNameCount
int getFocusCount() {return this.focusCount;}
void setFocusCount(int counter) {this.focusCount = counter} // optional to reset counter
void incrementFocusCount() {this.focusCount = getFocusCount() + 1;)
...
void countingFocus() {
incrementFocusCount();
focus()
}
...
}
If it is required in many places and involves complex things, I recommend to use Mockito to test your code. Using that you can verify if the method was invoked (also how many times if invoked)
You can mock the button and verify in your MyTest how many times the method must be called. Using Mockito you can mock and stub your methods(Stubbing voids requires different approach from when(Object) because the compiler does not like void methods inside brackets) and then verify it using verify statement.
verify(mockButton, times(1)).focus();
verify(mockButton, times(1)).setName();
You can write a wrapper class over the 3rd party Button class through which all calls to Button class will be made.
This wrapper class can keep track of whether each method has been called or not
class ButtonCaller {
private Button button = null;
private boolean focusCalled;
private boolean setNameCalled;
public ButtonCaller() {
button = new Button();
focusCalled = false;
setNameCalled = false;
}
public void focus() {
button.focus();
focusCalled = true;
}
public void setName() {
button.setName();
setNameCalled = true;
}
public void whetherMethodCalled(ButtonMethod method) {
switch (method) {
case FOCUS:
return focusCalled;
case SET_NAME:
return setNameCalled;
}
throw new RuntimeException("Unknown ButtonMethod !!!");
}
public static Enum ButtonMethod {
FOCUS,
SET_NAME;
}
}

Testing Presenters in MVP GWT application

I have a simple application and want to make it testable. I m new in this area.
Here is a simple Presenter, taking in mind this code ,could you advice or give me some example how to test it.
public class SomePresenter extends Presenter<MainPanelPresenter.Display>
{
public interface Display extends WidgetDisplay
{
HasClickHandlers getAddButton();
HasClickHandlers getDeleteButton();
void setData(ArrayList<Person> data);
ArrayList<String> getSelectedRows();
Widget asWidget();
}
private final DispatchAsync dispatcher;
public static final Place PLACE = new Place("main");
#Inject
public SomePresenter(DispatchAsync dispatcher, EventBus eventBus, Display display)
{
super(display, eventBus);
this.dispatcher = dispatcher;
bind();
}
protected void onBind()
{
display.getAddButton().addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
eventBus.fireEvent(new AddButtonEvent());
}
});
display.getDeleteButton().addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
ArrayList<String> list = display.getSelectedRows();
deletePerson(list);
}
});
}
....
private void loadDbData()
{
..........
}
private void deletePerson(ArrayList<String> ids)
{
..........
}
}
Edit:
What does the Presenter is, load initial data from db, have 2 buttons add and delete.
When add is press then a new form is load and user is able to input data and save to the db,
delete button just delete person from db.
Thanks
The general idea of unit testing such a class would be, like for any other class :
create Mock version of the dependencies (Display, EventBus, etc...)
set expectations on what the depdencies should do when the Presenter works
exercice the Presenter and check the expectations
However there are a couple of issues with your version of the Presenter :
The loadDbData() method is not showed, but I assumed it means the Presenter also has access to some other component that does the fetching. Can this component be abtracted in a dependency, and mocked liked the rest ?
Then there is the testing of bind(). The only responsibility of your Presenter in this method is to set up callbacks on some buttons provided by the Display. What you want to test is both :
That the callbacks are set
That the set callbacks do the expected things
A few ideas to help with the later :
You can reduce the coupling between Presenter and Button. If possible, change the Display interface from :
Button getAddButton();
to
addAddButtonClickedHandler(ClickHandler);
This means your Presenter does not have to use a Display object that returns actual BUtton
You can reduce the callbacks content to calling a single method, that you can then test in isolation
protected void bind() {
display.addAddButtonClickHandler(new ClickHandler() {
public void onClick(ClickEvent) {
fireAdded();
}
});
}
// The fireAdded function can be tested independenty of the Display, potentially with
// a mock EventBus
protected void fireAdded() {
event.fireEvent(....)
}
If you really want to check that the callbacks are properly set, than you can use a 'Dummy' implementation of the Display class, that provides you a list of all the callbacks, and let you call them
private class DummyDisplay implements Display {
private List<ClickHandler> addButtonClickHandlers;
public void addAddButtonClickHandler(ClickHandler handler) {
addButtonClickHandlers.add(handler);
}
public void fireAddButtonClick() {
for (ClickHandler h in addButtonClickHandlers) {
h.onClick(new ClickEvent());
}
}
// ....
}
Then your test would :
create a presenter with such a dummy display
use bind to set the callbacks
use display.fireAddButtonClick() to simulate a user clicking
check that has the result of the click, the effects of fireAdded are seen
This type of class (that mostly glue other classes together) can tend to be hard to test ; at some point, it the other classes are thoroughly tested it can become slightly counter productive to concentrate on the gluers, rather than the glued.
Hoping this helps.

Java. Correct pattern for implementing listeners

Very typically I have a situation where a given object will need to have many listeners. For instance, I might have
class Elephant {
public void addListener( ElephantListener listener ) { ... }
}
but I'll have many such situations. That is, I'll also have a Tiger object that'll have TigerListeners. Now, TigerListeners and ElephantListeners are quite different:
interface TigerListener {
void listenForGrowl( Growl qrowl );
void listenForMeow( Meow meow );
}
while
interface ElephantListener {
void listenForStomp( String location, double intensity );
}
I find that I always have to keep re-implementing the broadcasting mechanism in each animal class, and the implementation is always the same. Is there a preferred pattern?
Instead of each Listener having specific methods for every event type you can send it, change the interface to accept a generic Event class. You can then subclass Event to specific subtypes if you need, or have it contain state such as double intensity.
TigerListener and ElephentListener then become
interface TigerListener {
void listen(Event event);
}
In fact, you can then further refactor this interface into a plain Listener:
interface Listener {
void listen(Event event);
}
Your Listener implementations can then contain the logic that they need for the specific events they care about
class TigerListener implements Listener {
#Overrides
void listen(Event event) {
if (event instanceof GrowlEvent) {
//handle growl...
}
else if (event instance of MeowEvent) {
//handle meow
}
//we don't care about any other types of Events
}
}
class ElephentListener {
#Overrides
void listen(Event event) {
if (event instanceof StompEvent) {
StompEvent stomp = (StompEvent) event;
if ("north".equals(stomp.getLocation()) && stomp.getDistance() > 10) {
...
}
}
}
}
The key relationship between the subscriber and the publisher is that the publisher can send events to the subscribers, it isn't necessarily that it can send it certain types of events - this type of refactoring pushes that logic from the interface down into the specific implementations.
This is a more general answer for people who come here just wanting to make a listener. I am summarizing Creating Custom Listeners from CodePath. Read that article if you need more explanation.
Here are the steps.
1. Define an Interface
This is in the child class that needs to communicate with some unknown parent.
public class MyClass {
// interface
public interface MyClassListener {
// add whatever methods you need here
public void onSomeEvent(String title);
}
}
2. Create a Listener Setter
Add a private listener member variable and a public setter method to the child class.
public class MyClass {
// add a private listener variable
private MyClassListener mListener = null;
// provide a way for another class to set the listener
public void setMyClassListener(MyClassListener listener) {
this.mListener = listener;
}
// interface from Step 1
public interface MyClassListener {
public void onSomeEvent(String title);
}
}
3. Trigger Listener Events
The child object can now call methods on the listener interface. Be sure to check for null because there might not be anyone listening. (That is, the parent class might not have called the setter method for our listener.)
public class MyClass {
public void someMethod() {
// ...
// use the listener in your code to fire some event
if (mListener != null)
mListener.onSomeEvent("hello");
}
// items from Steps 1 and 2
private MyClassListener mListener = null;
public void setMyClassListener(MyClassListener listener) {
this.mListener = listener;
}
public interface MyClassListener {
public void onSomeEvent(String myString);
}
}
4. Implement the Listener Callbacks in the Parent
The parent can now use the listener that we set up in the child class.
Example 1
public class MyParentClass {
private void someMethod() {
MyClass object = new MyClass();
object.setMyClassListener(new MyClass.MyClassListener() {
#Override
public void onSomeEvent(String myString) {
// handle event
}
});
}
}
Example 2
public class MyParentClass implements MyClass.MyClassListener {
public MyParentClass() {
MyClass object = new MyClass();
object.setMyClassListener(this);
}
#Override
public void onSomeEvent(String myString) {
// handle event
}
}
I think you're doing it correct, since your interfaces have semantic value and express what they are listening to (e.g. growls and meows instead of stomps). With a generic approach, you may be able to reuse the broadcasting code, but you may lose the readability.
For example, there is the java.beans.PropertyChangeSupport which is a utility for implementing Oberservers listening for value changes. It does the broadcasting, but you still need to implement the method in your domain class and delegate to the PropertyChangeSupport object. The callback methods are meaningless by themselves, and the events broadcasted are String-based:
public interface PropertyChangeListener extends java.util.EventListener {
void propertyChange(PropertyChangeEvent evt);
}
Another one is java.util.Observable which provides the broadcasting mechanism, but it's also not the best thing imho.
I like ElephantListener.onStomp()
A different options is the Whiteboard Pattern. This disconnects the publisher and subscriber from each other, and neither will contain any broadcasting code. They both simply use a messaging mechanism for pub/sub and neither has any direct connection to the other.
This is a common model for messaging in an OSGi platform.
I created a Signals library just for this purpose. To remove the boiler code involved in "re-implementing the broadcasting mechanism."
A Signal is an object created automatically from an interface. It has methods for adding listeners and dispatching/broadcasting events.
It looks like this:
interface Chat{
void onNewMessage(String s);
}
class Foo{
Signal<Chat> chatSignal = Signals.signal(Chat.class);
void bar(){
chatSignal.addListener( s-> Log.d("chat", s) ); // logs all the messaged to Logcat
}
}
class Foo2{
Signal<Chat> chatSignal = Signals.signal(Chat.class);
void bar2(){
chatSignal.dispatcher.onNewMessage("Hello from Foo2"); // dispatches "Hello from Foo2" message to all the listeners
}
}
In this example, Foo2 is the broadcaster of new messages over the Chat interface. Foo then listen to those and log it to logcat.
Note that there are no limitations on what interfaces you can use
You also have some sugar API for registering for only the first broadcast and unregistering from all the signals at once(Via the SignalsHelper)
Try the java kiss library and you will get this done faster and more correctly.
import static kiss.API.*;
class Elephant {
void onReceiveStomp(Stomp stomp) { ... }
}
class Tiger {
void onReceiveMeow(Meow meow) { ... }
void onReceiveGrowl(Growl growl) { ... }
}
class TigerMeowGenerator extends Generator<Meow> {
// to add listeners, you get:
// addListener(Object tiger); // anything with onReceiveMeow(Meow m);
// addListener(meow->actions()); // any lambda
// to send meow's to all listeners, use
// send(meow)
}
The generator is thread-safe and efficient (writing correct generators is the hardest part). It is an implementation of the ideas in
Java Dev. Journal - Skilled Listening in Java (local copy)

Monitor changes to a collection

Say you have the following java bean:
public class MyBean
{
private List<String> names = new ArrayList<String>();
public void addName(String name)
{
names.add(name);
fireNamesPropertyChange(name);
}
}
How would you normally implement a property change event for a collection? Do you try and use the index property which seems to be more for arrays than collections?
(NOTE: I updated this post after realizing a few mistakes of my own so this isn't the original but a more refined one instead)
For this purpose I'd do two new interfaces, ListListener and Listenable and then I would create a new class like ListenableArrayList which would wrap every List method with a call to one (or more) relevant methods defined in ListListener. In code it'd be something like this:
public class ListenableArrayList<T> extends ArrayList<T>
implements Listenable<T> {
private ArrayList<T> internalList;
private ListListener<T> listener;
/* .. */
public void add(T item) {
listener.beforeAdd(T item);
internalList.add(item);
listener.afterAdd(T item);
}
/* .. */
public void setListener(ListListener<T> listener) {
this.listener = listener;
}
}
public interface ListListener<T> {
/* .. */
void beforeAdd(T item);
void afterAdd(T item);
/* .. */
}
public interface Listenable<T> {
/* .. */
void setListener(ListListener<T> listener);
/* .. */
}
The reason I'd do it this way would be to allow for creating truly ad-hoc listeners on the fly instead of tying the ListenableArrayList to some specific implementation. For example with this the following would be possible:
Listenable<String> list = new ListenableArrayList<String>();
list.setListener(new ListListener<String>() {
#Override
public void beforeAdd(String item) {
System.out.println("About to add element "+item+"...");
}
#Override
public void afterAdd(String item) {
System.out.println("...element "+item+" has been added.");
}
});
A bit cluttered, maybe but on the other hand this would allow for easy extension to Collections, Sets and whatnot rather easily.
Take a look at Glazed Lists library, which has support for observable collections.
If I were to do it myself, I would likely create custom Listener interface with elementsAdded, elementsRemoved methods, or similar :-) (also depending on my needs)
You can use an Observable Collection: https://commons.apache.org/dormant/events/apidocs/org/apache/commons/events/observable/ObservableCollection.html
Normally I'd do the following:
public class MyBean {
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private List<String> names = new ArrayList<String>();
public void addName(String name) {
names.add(name);
pcs.firePropertyChange("names", null, Collections.unmodifiableList(names));
}
public void addPropertyChangeListener(PropertyChangeListener l) {
pcs.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
pcs.removePropertyChangeListener(l);
}
}
PropertyChangeSupport manages the listeners and fires the events on your behalf.
By passing null as the "old value" it forces the event to be fired. (It's likely that listeners won't really care about the old value anyway)
JDK 7+ solution:
import javafx.collections.*;
import java.util.*;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("s1");
list.add("s2");
ObservableList<String> observableList = FXCollections.observableList(list);
observableList.addListener(new ListChangeListener<String>() {
#Override
public void onChanged(Change<? extends String> change) {
while(change.next()){
System.out.println("added: " + change.getAddedSubList());
}
}
});
observableList.add("s3");
}
}
For a swing GUI event I'd normally just use an EventListenerList to do the work for me.
EDIT: on the rephrase of the questions: how do you treat collections, I'd usually use an event similar to the collections type, so for example a TreeModel event usually takes a TreePath argument, or for something in a map I'd indicate the key.
However for simple JavaBeans the most common is assume a list/array and just use the index.
Methinks you will need fireNamesPropertyAdd, fireNamesProperyDelete. A list level notification will IMHO not work, even if it was an array and an index was added as it can't handle deletes. If the element at some index can be changed, you will also need fireNamesProperyChange. It might be useful to have index as parameter in addition to the string value.
Are you perhaps looking for java.beans.PropertyChangeSupport?
In my opinion, you should avoid PropertyChangeEvent. IndexedPropertyChangeEvent is worse, and very infrequently used by Swing anyway. It's better to narrow the focus of your types, and fire a javax.swing.event.ChangeEvent or similar (even just call a Runnable).
For certain types (like lists!), Glazed Lists (or equivalent) mentioned in another post by Peter Štibraný seem like a good way to go.

Generic, annotation-driven event notification frameworks

While simple, interface-driven event notification frameworks in Java have been around since pre-Cambrian times (e.g. java.beans.PropertyChangeSupport), it is becoming increasingly popular for frameworks to use annotation-driven event notification instead.
For an example, see JBossCache 2.2. The listener class has its listener methods annotated, rather than conforming to a rigid interface. This is rather easier to program to, and easier to read, since you don't have to write empty implementations of listener callbacks that you're not interested in (and yes, I know about listener adapter superclasses).
Here's a sample from the JBossCache docs:
#CacheListener
public class MyListener {
#CacheStarted
#CacheStopped
public void cacheStartStopEvent(Event e) {
switch (e.getType()) {
case Event.Type.CACHE_STARTED:
System.out.println("Cache has started");
break;
case Event.Type.CACHE_STOPPED:
System.out.println("Cache has stopped");
break;
}
}
#NodeCreated
#NodeRemoved
#NodeVisited
#NodeModified
#NodeMoved
public void logNodeEvent(NodeEvent ne) {
log("An event on node " + ne.getFqn() + " has occured");
}
}
The problem with this, is that it's very much more of an involved process writing the framework to support this sort of thing, due to the annotation-reflection nature of it.
So, before I charge off down the road of writing a generic framework, I was hoping someone had done it already. Has anyone come across such a thing?
You can already do this today with EventBus.
Following example is from EventBus Getting Started guide. Statusbar that updates based on published events, and no need to register statusbar control/widget as listener of publisher(s). Without EventBus, statusbar will need to be added as listener to many classes. Statusbar can also be created and destroyed at any time.
public StatusBar extends JLabel {
public StatusBar() {
AnnotationProcessor.process(this);
}
#EventSubscriber(eventClass=StatusEvent.class)
public void updateStatus(StatusEvent statusEvent) {
this.setText(statusEvent.getStatusText();
}
}
A similar project is ELF (Event Listener Framework) but it seems to be less mature.
I'm currently researching about event notification frameworks on Publish-Subscribe Event Driven Programming | Kev's Spring vs Java EE Dev and the followup articles.
I've made http://neoevents.googlecode.com to handle this kind of annotation based event handler.
#actionPerformed
private void onClick() {
//do something
}
protected void initComponents() {
JButton button = new JButton("Click me!!!");
button.addActionListener(new ActionListener(this) );
}
It looks as simple as I was expecting it to be. Annotations are available for every single listener in J2SE.
Don't mistake complicated for clever. It seems to me that this would be:
A nightmare to debug
Difficult to follow (from a maintenance perspective, or someone attempting to change something 6 months down the line)
Full of if (event instanceof NodeCreatedEvent) like code. Why this is better than subclassing an adapter I have no idea!
The main problem I see here are the method parameters, which restrict which methods can actually be used for which events, and there's no compile-time help for that.
This is what makes interfaces attractive to me for observer pattern implementations like the Java event model. Tools like eclipse can autogen method stubs so you can't get the signatures wrong. In your example, it's very easy to use the wrong parameter type and never know it until an event occurs (which might be an error case several months down the line)
One thing you might try are my annotations & processor for implementing observers and null object implementations. Suppose you have
package a.b.c;
public interface SomeListener {
void fee();
void fie();
void fo();
void fum();
}
and wanted to create a listener instance. You could write
package x.y.z;
import a.b.c.SomeListener;
import com.javadude.annotation.Bean;
import com.javadude.annotation.NullObject;
#Bean(nullObjectImplementations = {#NullObject(type = SomeListener.class) })
public class Foo extends FooGen implements SomeListener {
#Override
public void fie() {
// whatever code you need here
}
}
To create a source for these events, you can write
package a.b.c;
import com.javadude.annotation.Bean;
import com.javadude.annotation.Observer;
#Bean(observers = {#Observer(type = SomeListener.class)})
public class Source extends SourceGen {
// SourceGen will have add/remove listener and fire methods
// for each method in SomeListener
}
See http://code.google.com/p/javadude/wiki/Annotations if you're interested. Might give you some other ideas as well.
Google Guava v11 has added an EventBus component that uses this style. They also explain why they decided to use annotations rather than interfaces.
I've been thinking about a generic annotation-driven event framework as well. I like the benefits provided by static typing, but the current interface-driven event model is painful to use (ugly code). Would it be possible to use a custom annotation processor to do some compile-time checking? That might help add some of the missing "safety" that we've all grown used to.
A lot of the error checking can also be done at the time that the listeners are "registered" with the event producers. Thus, the application would fail early (when the listeners are registered), possibly even at at startup-time.
Here's an example of what the generic framework I've been toying with might look like:
public class ExampleProducer {
private EventSupport<ActionEvent> eventSupport;
public ExampleProducer() {
eventSupport = new EventSupport<ActionEvent>(this);
}
#AddListenersFor(ActionEvent.class)
public void addActionListener(Object listener)
{
eventSupport.addListener(listener);
}
#RemoveListenersFor(ActionEvent.class)
public void removeActionListener(Object listener)
{
eventSupport.removeListener(listener);
}
public void buttonClicked() {
eventSupport.fire(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, "Click"));
}
}
The producer uses EventSupport, which uses reflection to invoke the events. As mentioned before, EventSupport could preform some initial checks when the events listeners are registered.
public class ExampleListener
{
private ExampleProducer submitButton;
public ExampleListener()
{
submitButton = new ExampleProducer();
EventSupport.autoRegisterEvents(this);
}
#HandlesEventFor("submitButton")
public void handleSubmitButtonClick(ActionEvent event)
{
//...some code to handle the event here
}
}
Here, EventSupport has a static method that uses reflection to auto-register the listener with the event producer. This eliminates the need to manually register with the event source. A custom annotation processor could be used to validate that the #HandlesEventFor annotation refers to an actual field of the ExampleListener. The annotation processor could do other checks as well, such as ensuring that the event handler method signature matches up with one of the registration methods on the ExampleProducer (basically, the same check that could be performed at registration-time).
What do you think? Is this worth putting some time into fully developing?
Here's a similar project called SJES.
public class SomeController {
private Calculator c1 = new Calculator();
private Calculator c2 = new Calculator();
public SomeController() {
c1.registerReceiver(this);
c2.registerReceiver(this);
c1.add(10, 10);
c2.add(20, 20);
}
#EventReceiver(handleFor="c1")
public void onResultC1(Calculator.Event e) {
System.out.println("Calculator 1 got: " + e.result);
}
#EventReceiver(handleFor="c2")
public void onResultC2(Calculator.Event e) {
System.out.println("Calculator 2 got: " + e.result);
}
#EventReceiver
public void onResultAll(Calculator.Event e) {
System.out.println("Calculator got: " + e.result);
}
}
public class Calculator {
private EventHelper eventHelper = new EventHelper(this);
public class Event {
long result;
public Event(long result) {
this.result = result;
}
}
public class AddEvent extends Event {
public AddEvent(long result) {
super(result);
}
}
public class SubEvent extends Event {
public SubEvent(long result) {
super(result);
}
}
public void unregisterReceiver(Object o) {
eventHelper.unregisterReceiver(o);
}
public void registerReceiver(Object o) {
eventHelper.registerReceiver(o);
}
public void add(long a, long b) {
eventHelper.fireEvent(new AddEvent(a + b));
}
public void sub(long a, long b) {
eventHelper.fireEvent(new SubEvent(a - b));
}
public void pass(long a) {
eventHelper.fireEvent(new Event(a));
}
}
I think this is very easy to use.
You can also check out MBassador It is annotation driven, very light-weight and uses weak references (thus easy to integrate in environments where objects lifecycle management is done by a framework like spring or guice or somethign).
It provides an object filtering mechanism (thus you could subscribe to NodeEvent and attach some filters to restrict message handling to a set of specific types only).
You can also define your own annotations to have customized declaration of your handlers.
And it's very fast and resource efficient. Check out this benchmark showing a performance graph for different scenarios using Guava or mbassador.

Categories