• Post Reply Bookmark Topic Watch Topic
  • New Topic

Event Listeners from other classes?  RSS feed

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am fairly new to Java and programming in general, and could not find satisfatory material on event handlers. I do get the general ideas, and have built a few succesfully. But I'm wondering, can you make class that only serves to handle events, and use and object of it on various different classes? I have made some experiments, and couldn't find out.

I have created a KeyTest class, that has the following method executed right at the start:



I have then, created another class, made an KeyTest k object, and removed the addKeyListener line from the init method. On the new class, I added it back, using k as a parameter. Could you explain, in a noob friendly way, why the program doesn't work the same way, and what should I know about Event Listeners? Once again, I did my research, but this doubt wasn't resolved. Thank you very much.

P.S.: I have just begun using this site, so please point out if I did anything wrong on the post. Thanks.
 
Marshal
Posts: 56608
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

I am not sure I understand the need for a single event listener class; each GUI will have different actions associated with events, so you would have to reprogram your class for each app.
 
Pedro Pelizzaro
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now that I come to think of it, I guess you're right. Dunno, feels more organized this way.
I know I probably should seek more applyable knowledge, but now I need to know, is there a way to do what I described?
Anyway, thanks a bunch for responding.
 
Campbell Ritchie
Marshal
Posts: 56608
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Of course you can do what you described, but why? And, “It's a pleasure.”
 
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pedro Pelizzaro wrote:But I'm wondering, can you make class that only serves to handle events, and use and object of it on various different classes? I have made some experiments, and couldn't find out.

I'm not absolutely sure what you're asking, but I hope it's something like: Can I create a generic event handler that will work for all sorts of classes?

And the answer to that is: Yes.

But there are qualifications. And the first is that you have to StopCoding and step back from the problem a bit.

In an event-driven system (and GUIs are just one type) you have three things:
1. An Event Producer - eg, a keyboard.
2. An Event Handler - ie, an object that is "listening out" for Events - eg, a JTextField that needs to know when a keyboard Event occurred, so it can react to it. Personally, I prefer the term 'Listener', because "Handler" is a bit vague.
3. The Event itself - ie, an object that contains information about what actually happened - eg, a keyboard Event, which will probably contain the "base" key that was pressed, the Unicode character that resulted, and maybe some other things like whether 'Ctrl', 'Shift' or 'Alt' were also pressed at the same time.

Now the examples I've given above are for Swing, but the same principles could be applied to an Inventory system that has to deal with Deliveries, Audits, Pick Lists etc.

So, we have three things, but we still don't know exactly how they're going to work. Is that a problem? No, because Java has wonderful things called interfaces, which allow us to describe WHAT something does without having the first clue about HOW they're going to do it.

Let's take them in reverse order. This bit is quite long, and assumes that you have at least some knowledge of generics, but I'll try to take you through it step-by-step:

1. An Event - since this is just an "information" object, the chances are that all it will need are a bunch of "getters" so that a Handler can get at the information. However, since we need to make sure that a Listener actually gets an Event, and not an Integer or a String, we should probably create an Event interface that all Event classes implement, viz:Unfortunately, everything else about an Event is likely to depend entirely on the class that implements it, so we can't really say anything more - and BTW, this is makes it a "Marker" interface.

2. A Handler (or Listener) - This is the object that will be "listening out" for Events. But any Event? From anywhere? Possibly, but it's likely to make the implementation very complicated. If a Listener can take any Event, then it's probably going to have to check its type to work out what it contains; and isn't that what Object-Orientation is meant to avoid? So, for now, let's say that a Hander can only handle ONE type of Event, viz:We also know that it will actually have to "handle" the Event it's listening for, so we should probably add a handling method:And for now, we can't say much more than that.

3. An Event producer - Again, the implementation is likely to be complex if a Producer needs to be able to produce any kind of Event, so lets make it type-specific:But we're not quite finished yet. When a Producer generates an Event, it needs to be able to inform a Handler that it did, so we add:

OK, so we now have three interfaces that can work with each other: An Event, a Handler than can handle a specific Event, and a Producer that can generate a specific Event and inform Handlers of the same type that it did. But is that all we need?

Question: How does a Producer know which Handlers to send its Event to?
Answer: Right now it doesn't.
Question: Can we solve that?
Answer: Sure. With a bit of thought.

And the way that most Event-driven systems do it is by something called a "callback" - and here we get back to the "From anywhere?" question:
We make it the Handler's responsibility to inform ALL the Producers it needs to that it wants to know about every Event they generate, and this process is called "registration", viz:And on the other side, we make it a Producer's responsibility to inform all "registered" Handlers, but in order to do that it needs to know who they are, so:
And there you have it: A basic generic Event-driven system for a specific Event. Just create some classes that implement those three interfaces and give it a whirl.
And note that we haven't said one thing about how these classes are going to work.

So the next question is: Why didn't Swing do it that way?
Answer: (almost certainly) because generics didn't exist when it was written. Java FX does have something similar.

Question: Does it solve all your problems?
Answer: No.

Why? Because GUI components are often Producers and/or Handlers of many types of Events at once, and Java doesn't allow multiple implementations of a typed interface. If it did, the above would probably work for pretty much anything you want to handle by Events.

However, these things are sent to try us, and it's probably not a bad start point.

Hope it helps.

Winston
 
Pedro Pelizzaro
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As for why, Campbell, no particular pratical reason, as you said, it would create a lot more work to do.

And whoa, that's a lot of detailed information, and it's all very clear, Winston. I'll try that soon.

Thanks a bunch for your answers, guys.
 
Saloon Keeper
Posts: 4038
94
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've found an event bus to be a very useful mechanism for distributing data around various components of an application, yet keeping disparate classes that need the same data separate from one another.

Rather than using Java's built-in classes, Google's Guava is useful for this (https://github.com/google/guava/wiki/EventBusExplained), and something very similar exists for Android.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!