20

I am .Net developer. i want to know that is there any event handling mechanism in Java for Events Handling like C#.

what i want to do is i want to raise/fire an event form my class upon some condition. and consumer of this class should register that event and write event handling method.

this can be done easily in C#. i have to implement this thing in Java.

after googling out i found some links but all those are talking about GUI events in AWT and swing.

can any one help me out.

Mohsan
  • 2,483
  • 6
  • 47
  • 62
  • 1
    See http://stackoverflow.com/questions/1093367/good-tutorial-for-java-events and http://stackoverflow.com/questions/436050/events-in-java – kgiannakakis Oct 07 '09 at 09:22

4 Answers4

30

Although most of the examples will be to do with GUI events, the principles are basically the same. You basically want an interface or abstract class to represent a handler for the event, e.g.

public interface EventHandler
{
    // Change signature as appropriate of course
    void handleEvent(Object sender, EventArgs e);
}

then the publisher of the event would have:

public void addEventHandler(EventHandler handler)
public void removeEventHandler(EventHandler handler)

It would either keep a list of event handlers itself, or possibly have them encapsulated in a reusable type. Then when the event occurs, you just call handleEvent in each handler in turn.

You can think of delegate types in C# as being very similar to single-method interfaces in Java, and events are really just an add/remove pair of methods.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    As now Java 8 is out, with the help of `Consumers` and FunctionalInterfaces can there be a better design of this? – Sisir Jun 11 '19 at 17:41
  • @Sisir: I don't think there's very much demand for mimicking C# here, to be honest. – Jon Skeet Jun 11 '19 at 17:48
  • Actually I am working with android and here there are lot of places where a C# like event can be used e.g. to return values from an AsyncTask to UI, call a click listener from list item etc – Sisir Jun 11 '19 at 18:11
  • @Sisir: In that case you have a very specific use case, so I suggest you take the ideas of this answer, and apply them to that concrete situation. Although I'd really suggest just going with the idiom that other Android code uses to be honest. – Jon Skeet Jun 11 '19 at 18:12
  • With the current way of interface implementation it is too much verbose for such small tasks and with the help of Java 8 features like FuncationalInterfaces I am able to create delegate kind of designs but not the actual event design. I want the event owner should only be able to raise it not anyone from outside – Sisir Jun 11 '19 at 18:13
  • @Sisir: It's already a single-method interface - so you should be able to use it with a lambda expression. Add the `@FunctionalInterface` annotation if you want to, although I don't believe you have to. – Jon Skeet Jun 11 '19 at 18:16
  • Agree, but with this it serves more as a delegate rather than an event. This interface holder can be accessed from outside the publisher class as well and hence can be called from outside, defying the IOC principle that events give. – Sisir Jun 11 '19 at 18:21
  • 2
    @Sisir: The interface was always meant to serve as the delegate. The methods on the event publisher (`addEventHandler` and `removeEventHandler`) are the event part. They could use a `List` internally, for example. But really at this point it would be best if you could ask a new question, showing how far you've progressed and the concrete problem you still face. – Jon Skeet Jun 11 '19 at 19:46
  • I opened a new question [here](https://stackoverflow.com/questions/56567562/implementing-a-proper-c-sharp-event-not-delegate-in-java). Please see the code snippets and suggest any design change if there can be. – Sisir Jun 12 '19 at 17:44
16

I love C# Events,

They are simple to use and convenient. i missed them in java so wrote a small utility class that mimics the very basics of C# Event.

  • using java 8 (for lambdas)
  • no += operator, instead call .addListener((x) -> ...)
  • to trigger an event, call .broadcast(<EventArgs insance>)

Online Demo - https://repl.it/DvEo/2


Event.java

import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;

public class Event {
    private Set<Consumer<EventArgs>> listeners = new HashSet();

    public void addListener(Consumer<EventArgs> listener) {
        listeners.add(listener);
    }

    public void broadcast(EventArgs args) {
        listeners.forEach(x -> x.accept(args));
    }
}
  • You may want com.google.common.collect.Sets.newConcurrentHashSet() for thread safety

EventArgs.java

public class EventArgs {
}
Community
  • 1
  • 1
Jossef Harush Kadouri
  • 32,361
  • 10
  • 130
  • 129
  • 1
    Except that, `broadcast()` can be called from anywhere unlike the C# events which can only be raised from the publishing class. This implementation is more of a delegate model implementation rather than event model implementation. – Sisir Jun 11 '19 at 17:44
9

Java has support through various event handling implementations - the simple Observer/Observable in java.util, PropertyChangeEvents in java.beans, and GUI events which inherit from AWTEvent.

An Observable object has a list of observers which implement the Observer interface, and mechanisms for adding and removing observers. If o.notifyObservers(x) is called on the observable, update(o,x) will be called on each observer. This mechanism is somewhat old fashioned and rarely used in new code - it dates from Java 1.0 before EventObject was added in Java 1.1 and better event handling added for AWT and beans.

Beans and GUI events propagate an object which extends java.util.EventObject to listeners which implement a sub-interface of EventListener. Usually if you're using an existing API you will only care about the events and listeners for that API, but if you're defining an API the events and listeners should follow that convention.

It's also the convention in Java APIs to call the handlers for events "listeners" rather than handlers, and all listener interface names end with Listener. The names of the methods don't start with 'on' but should be past tense -mouseMoved or handshakeCompleted rather than onMouseMove or handleMouseMove.

The PropertyChangeSupport class provides an implementation of the mechanism for adding and removing listeners from a bean, and is also used for properties of Swing widgets.

If you write your own listener handling, it's conventional to allow listeners to remove themselves by calling source.removeXXXListener(this) from within their event handling method. Just iterating over a simple collection of listeners and calling their handling methods would give a ConcurrentModificationException with in these cases - you need to copy the collection of listeners or use a concurrently modifiable collection.

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
1

Check out this tutorial. It goes through some of the Swing event handling stuff that you have come across in your searches, but the concepts are pretty general. In simple terms, event handlers maintain a collection of listeners (implementing an interface) and iterate over them when they fire an event, calling the method in the interface.

akf
  • 38,619
  • 8
  • 86
  • 96