0

I have been trying to wrap my head around callbacks and have been struggling to grasp the concept. The following code is an example that I found here

starting from first to last I understand the flow to be such:

  • CallMe is instantiated, thus calling the constructor of said class
  • The variable en is set, subsequently instantiating the EventNotifier class and calling it's constructor which is passed a reference to the object CallMe
  • The variable ie is set to the object CallMe which was passed into the constructor
  • The variable somethinghappened is set to false (I would assume some conditional statement would be used to determine whether or not to set the value otherwise)
  • Ummm... done?

I do not understand this code. How does doWork get called? How does this signify an event? Why would one not simply call interestingevent from the constructor of callme .... For that matter why not just call dowork in place of whatever would change the value of somethinghappened?

Try as I might I cannot seem to grasp the idea. I understand that callbacks are used primarily to signify an event has occurred such as a mouse or button click but how does it make the connection between the event occurring and the methods being called? Should there not be a loop that checks for changes, and thus triggers the event?

Can someone please provide a (not over-simplified) explanation of callbacks in java and help clarify how something like this could be useful?

public interface InterestingEvent
{
    public void interestingEvent ();
}

public class EventNotifier
{
    private InterestingEvent ie;
    private boolean somethingHappened; 
    public EventNotifier (InterestingEvent event)
    {
        ie = event; 
        somethingHappened = false;
    } 

    public void doWork ()
    {
        if (somethingHappened)
        {
            ie.interestingEvent ();
        }
    } 
}

public class CallMe implements InterestingEvent
{
    private EventNotifier en; 
    public CallMe ()
    {
        en = new EventNotifier (this);
    } 

    public void interestingEvent ()
    {
        // Wow!  Something really interesting must have occurred!
        // Do something...
    } 
}

EDIT: please see the comments in the approved answer... ---this--- link was very helpful for me =)

Community
  • 1
  • 1

2 Answers2

2

There is no main method or static blocks. Nothing is actually run from the code you posted; hence, doWork() is never called. I read the article and looked at the code, and it appears to be incomplete, or perhaps some code is left out because the author felt that it didn't need to be explained.

Here's the gist:

We have an interface InterestingEvent, a class EventNotifier, and another class CallMe, which implements InterestingEvent.

EventNotifier takes an InterestingEvent in its constructor, and sets somethingHappened to false.

The constructor for CallMe initializes its EventNotifier instance member by passing the EventNotifier constructor a reference to the CallMe object, itself.

The following is not in the code, but if we detect that some particular action takes place, we set somethingHappened = true. So after that, if doWork() is called for an EventNotifier, interestingEvent() will be called on that EventNotifier's InterestingEvent ie. We can do this, since CallMe implements InterestingEvent.

NB: This article was from 1996 and much has changed since then. You mentioned how to detect mouse click events, but this is different. The point of the article, I assume, was to show how you can use objects in conjunction with interfaces and booleans to see if something occurred.

To actually detect a mouse click, take a look at this tutorial. Here's another tutorial on Writing Event Listeners. Finally, since you asked about threading in a comment, here's a great book: Java Concurrency in Practice.

Steve P.
  • 14,489
  • 8
  • 42
  • 72
  • so how would we detect the event? Would we use a thread with a loop to detect the signal that something has occurred? Furthermore, why do this if you could just call the `interestingevent` method instead of setting the boolean value? – Konner Rasmussen Jul 20 '13 at 05:23
  • I don't think this is a good tutorial or explanation for anything except illustrating some of the functionality of an interface... I posted another link. Swing and AWT provide [Listener classes](http://docs.oracle.com/javase/tutorial/uiswing/events/api.html) for you-- you don't want to recreate the wheel. You can take a look at the source code for a particular class to see how it actually works, but yes, the listener is going to be in a different thread waiting for some specific signal. – Steve P. Jul 20 '13 at 05:29
  • so is there no other point in callbacks but to detect external input? from what i gather, the greatest use is to pass information between objects running on separate threads, am i correct in this? – Konner Rasmussen Jul 20 '13 at 05:40
  • also -- [here](http://stackoverflow.com/questions/17494474/java-passing-an-instance-of-this-during-instantiation/17494655?noredirect=1#17494655) -- is a question i posted a while back, would that be an example of a callback? – Konner Rasmussen Jul 20 '13 at 05:40
  • If you're asking if communication between threads is useful, then yes, it is... This tutorial is highly misleading/not-informative and is ancient--don't pay anymore attention to it. A callback is: *a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time*. Here's a link to [Callback functions in Java](http://stackoverflow.com/questions/443708/callback-functions-in-java). PS: added some links. – Steve P. Jul 20 '13 at 05:42
  • thank you so much, that was exactly what i wanted to know, i shall check and link to that post in the original question. – Konner Rasmussen Jul 20 '13 at 05:53
  • Agree with Steve. The article was written in 1996. – Jops Jul 20 '13 at 05:55
2

The way that I typically use callbacks is with PropertyChangeListeners/PropertyChangeSupport classes. There is probably of lot of different explanations about those classes that you might find helpful.

Anyway, to the point of your question.

First, you need to understand that the two classes you have are normally running on different threads. What the callback does is allow you to get an asynchronous notification that something has happened on the other thread. This allows the notified thread to do its part when it regains control. For example, you have a serial line that is receiving data. The InterestingEvent would be something like 10 characters have arrived on this line. Now, instead of having just one EventNotifier, you'd have one for each serial line coming in. The CallMe instance would be running doing something, periodically checking to see if interestingEvent had been called. interestingEvent would set some sort of flag so that CallMe would know that it had new data to process. When CallMe sees that, it takes care of whatever the interestingEvent was and then goes back to its normal activity.

The whole point of the interface is to have a well-defined way to access an instance of CallMe. If you develop this more, you are probably going to want to manage the other instances that are accessing your instance of CallMe. That's where reading up on the PropertyChange stuff that I mentioned earlier would be really helpful.

wjr
  • 324
  • 1
  • 3
  • 14
  • so could i take it that -[this](http://stackoverflow.com/questions/17494474/java-passing-an-instance-of-this-during-instantiation/17494655?noredirect=1#17494655)- question i asked a while back makes use of callbacks? – Konner Rasmussen Jul 20 '13 at 05:31
  • no. that code won't compile as is. and I have no idea what you are trying to do. the whole point of a callback is to provide communication between two threads. in a standard java gui swing app, keyboard and mouse events, mouse clicks, key pressing, etc., are on a different thread than the main application thread. callbacks are how you communicate between the two. – wjr Jul 20 '13 at 05:50
  • i know that code doesn't compile, the idea of that was that by passing "this" into an object, you have access to all the members of "this" in said object. i simply wanted to know what callbacks are and how they are used so that i can understand if i should be using them or if i could change the flow of my code for the better with their use. your information has been very useful and will provide me with alot of reading (oh joy) thank you =) – Konner Rasmussen Jul 20 '13 at 06:01