event sources in java - java

Herbert Schildt describes the event source as an object that generates an event.
General form-
public void addTypeListener(TypeListener el)
My question is - where is this method declared and defined. in which class of which package. I have tried google but in vain.
Kindly help!

An event source can be any class you choose. If you're, like, creating a game, the Player class could be an event source. This is a small example for a Player class with player listeners.
public class Player {
public List<PlayerListener> listeners = new ArrayList<PlayerListener>();
// ...
public void addPlayerListener(PlayerListener listener) {
listeners.add(listener);
}
// ...
public void firePlayerEvent(PlayerEvent event) {
for(PlayerListener listener : listeners) {
listener.onPlayerEvent(event);
}
}
}
The addPlayerListener(PlayerListener) method adds an instance of PlayerListener to the list of listeners the Player object will notify if some player event was fired (see firePlayerEvent(PlayerEvent)).
In case you need some reference, I'm doing a homework for university that includes events. You can check it out at BitBucket.

Related

How or why do listener interfaces work? And do interfaces have any other use rather than being a listener?

Whenever we want to create a listener, we implement a listener interface. For example, lets implement SensorEventListener.
Now we have to override the methods of this listener interface.
public void onSensorChanged(SensorEvent event);
and
public void onAccuracyChanged(Sensor sensor, int accuracy);
What I don't understand is:
Why and how these methods work when I automatically use them?
Why does onAccuracyChanged method gets called when the accuracy changes?
After all, onAccuracyChanged is just an empty method that we override because our formula (or the interface we implement) requires us to do so. If it is something magical caused by the lower levels
When and why would someone actually use an interface in his/her
self-project regardless of android?
Here is a suitable answer. Allow me to give you an example about listeners.
Listeners:
Suppose there is a class that fetches data in the background, the Worker, and another class that is interested in that data, the InterestedClass.
public class Worker extends Thread{
interface DataFetchedListener{
void onDataFetched(String data);
}
private DataFetchedListener listener;
#Override
public void run(){
String data = fetchData();
// Data fetched inform your listener so he can take action
listener.onDataFetched(data);
}
public void setDataFetchedListener(DataFetchedListener listener){
this.listener = listener;
}
private String fetchData(){
// returns the fetched data after some operations
return "Data";
}
}
public class InterestedClass implements Worker.DatafetchedListener{
#Override
public void onDataFetched(String data){
doSomethingWith(data);
}
private doSomethingWith(String data){
// just print it in the console
System.out.println("Data fetched is -> " + data);
}
}
The Worker does not care which class will manipulate its data, as long as that class follows the contract of DataFetchedListener.
Equally this means that any class is able to do something with the data (InterestedClass just prints it in the console) but Worker does not need to know which class is that, just that it implements its interface.
The main could go like this...
public class Application{
public static void main(String[] args){
InterestedClass interested = new InterestedClass();
Worker worker = new Worker();
worker.setDataFetchedListener(intereseted);
worker.start(); // Starts Worker's thread
}
}
When the Worker will fetch the data then it will notify its listener (currently the interested object) and the listener will act accordingly (interested will print the data to the console).
In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information.(Wikipedia)
You may wish to respond to some events either system events or user events. But for that you need to know when the event you wish to capture occurs and also what must be done at that time.
And for that you open a confidential EAR to listen to events. But that will not be sufficient since you need to be notified too so that you can reply according to the event. You set callbacks that will notify when an event occur. Those empty body methods we create inside an interface.
A Listener is that interface that hears and notify back through callbacks.
So how can all that be used? And how all these do interact?
First create an interface with empty bodies methods that you intend to call when an event occurs:
public interface MyListener{
void actionOneHappens(Object o);
void actionTwo();
void actionThree();
}
Create a class that handles something, for example counts:
public class MyCounter{
//create a member of type MyListener if you intend to exchange infos
private MyListener myListener;
//let's create a setter for our listener
public void setMyListener(MyListener listener)
{
this.myListener=listener;
}
MyCounter(){
}
//this method will help us count
public void startCounting()
{
new CountDownTimer(10000,1000)
{
#Override
public void onTick(long millisUntilFinished) {
//I want to notify at third second after counter launched
if(millisUntilFinished/1000==3)
{
// I notify if true :
//as someone can forget to set the listener let's test if it's not //null
if(myListener!=null){
myListener.actionThree();
}
}
}
#Override
public void onFinish() {
}
}.start();
}
}
You can then create an object of type MyCounter and know when it's at three:
MyCounter myCounter=new MyCounter();
myCounter.setMyListener(new MyListener()
{
//then override methods here
#override
void actionOneHappens(Object o){
}
#override
void actionTwo()
{}
#override
void actionThree()
{
//Add you code here
Toast.makeText(getApplicationContext(),"I'm at 3",Toast.LENGTH_LONG).show()
}
});
//start your counter
myCounter.startCounting();
And it's done!! That's how we proceed.
Interfaces have no implementation and for using them we have two options:
A class that implement them
An anonymous class
And consider this code:
interface TestInterface {
void doSomething();
}
class TestClass{
private TestInterface ti;
public TestClass(TestInterface ti){
this.ti = ti;
}
public void testActionMethod(){
ti.doSomething();
//some other codes
}
}
class OurOwnLauncherApp{
public static void main(String[] args) {
TestClass tc = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Hi!");
}
});
tc.testActionMethod();
TestClass tc2 = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Bye!");
}
});
tc2.testActionMethod();
}
}
In here we have:
An Interface (Just like what you asked)
A function class the uses that interface
An application somewhere that we don't know (Maybe your phone app, maybe your friends phone app, etc)
What this code does, it gives an anonymous class (which implements TestInterface) to the testActionMethod and with calling doSomething method inside testActionMethod, we invert the calling back to our own method. that's why you will see this result:
Hi!
Bye!
This is exactly a simplified version of listener interfaces and how they work
There is no magic thing. Generally, the event-listener mechanism is as follow:
For some entities, there is the possibility to listen to some events on that entity (let name this entity as event generator). So some way should exist for other entities to listen to these changes (let name these entities as listeners). Now a listener registers itself as a listener of event generator. When an event occurs on the event generator, it calls the related method of registered listeners.
As a simple example assume a button. The button may generate an event for some actions such as click. Now if a listener wants to aware when the button is clicked, it should register itself as a listener of that button. On the other hand, the button should provide a unified way of registering the listeners. This unified way is the interface. Each entity which implements the interface could register itself as a listener for click on that button:
1- Listener implements the interface
2- Listener registers itself as a listener of button (Event Generator)
3- Event Generator calls the appropriate method of all registered listeners (this method is a method of the interface).
For your case, android provides a manager which you could register a listener on some sensors by it: android.hardware.SensorManager.registerListener(). All things occurs here (which is not magic!). When you register an entity (which implemented the related interface, SensorEventListener) as a sensor listener, changes in that sensor will cause to call methods of the listener).

Bukkit (spigot api) listener not responding?

I have been making a bukkit plugin, which shows up in the plugins list but when I do what I want the code to do nothing happens.
public class MyClass extends JavaPlugin implements Listener {
#EventHandler
public void onInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player.isSneaking()) {
player.sendMessage("Fire!");
Arrow arrow = player.launchProjectile(Arrow.class);
arrow.setShooter(player);
arrow.setGravity(false);
arrow.setSilent(true);
arrow.setBounce(false);
Block attach = arrow.getAttachedBlock();
Location attachlocation = attach.getLocation();
attachlocation.getWorld().createExplosion(attachlocation, 3);
arrow.setVelocity((player.getEyeLocation().getDirection().multiply(1000)));
}
}
}
I can't see you registering your listener. Bukkit needs to know what objects are listeners (you're not doing this) and it needs to know what methods to execute (with the #EventHandler annotation)
You can register the listener with PluginManager's registerEvents(Listener listener, Plugin plugin) method. A smart idea is to do this inside your onEnable method, to ensure your listener is registered as soon as your plugin starts.
public class MyClass extends JavaPlugin implements Listener {
#Override
public void onEnable() {
this.getServer().getPluginManager().registerEvents(this, this);
}
// rest of your code
}
Just a quick tip,
If you want to register a listener for a different class then the code in #onEnable() would be:
public void onEnable() {
this.getServer().getPluginManager().registerEvents(this, this); //You have to
register the main class as a listener too.
this.getServer().getPluginManager().registerEvents(new EventClass(), this);
}
Thanks!
The listener class code you are trying to call would be helpful to try and debug this scenario. You must make sure the following is true:
1) Class implements Listener
2) You register the class using:
Bukkit.getServer().getPluginManager().registerEvents(new [class] /* class of listener. this if it's your main class */, this/* your main class */);
3) You remembered #EventHandler before every event.
If you are learning bukkit programming it may be worth checking out this video: https://youtu.be/Rinjdx6c6r8 and this series:
https://www.youtube.com/watch?v=bVySbfryiMM&list=PLAF3anQEEkzREsHA8yZzVhc3_GHcPnqxR

Java observer pattern for a GUI - distinguish between different events without typeof

I have a simple Controller object that that implements Observer (i.e. it is the observer) which listens for events from a Mouse object that extends Observable (i.e. it is the observee).
So there can be multiple events in a Mouse object e.g. left click, scroll up, etc.
Now the Controller class implements the required method which is called every time any of the above events happen:
#Override
public void update(Observable o, Object arg)
{
// Handle mouse event
}
So it is the arg parameter that I am having trouble deciding how to approach (this case I am working on is simple enough such that the o parameter is not a concern). What is a good way to distinguish between different mouse events without using typeof?
I.e. what parameter should I feed in the notifyObservers(Object arg) method in the Mouse observee class?
Reading the comments it seems that you are using SWT -- SWT already implements event handlers via observer/observable callbacks.
What you are trying to do here is implement another layer of observer pattern on top of the already implemented observer pattern by SWT, which doesn't make much sense. But if you really wanted to do it for practice you might want to make several inner private classes to handle different events, e.g:
/**
* Controller.java
*/
import java.util.Observable;
import java.util.Observer;
public class Controller
{
/**
* The controller's inner classes are to be notified of mouse events.
*/
public Controller(Mouse mouse)
{
mouse.addObserver(new LeftClickObserver());
mouse.addObserver(new ScrollUpObserver());
}
private class LeftClickObserver implements Observer
{
#Override
public void update(Observable o, Object arg)
{
// TODO Handle left clicks
}
// Other left click logic here
// ...
}
private class ScrollUpObserver implements Observer
{
#Override
public void update(Observable o, Object arg)
{
// TODO Handle scroll up
}
// Other scroll up logic here
// ...
}
}
Then you can call the notifyObservers(Object arg) method in the appropriate event in the Mouse class to trigger a callback to the Controller.
However as mentioned, you should instead make use of the existing SWT libraries to handle events, then separate the implementation of the event handling in the controller, and away from the view (as you are trying to do already). Here's a simple example of how to do that (assuming you have a Controller initialized somewhere in the Mouse class, and the appropriate methods in the Controller class):
final Button button = new Button(shell, SWT.PUSH);
button.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
controller.handleWidgetSelectedEvent(event); // controller decides what to do...
}
public void widgetDefaultSelected(SelectionEvent event) {
controller.handleWidgetDefaultSelectedEvent(event); // controller decides what to do...
}
});
Note that there are some versions of the MVC pattern where the View does much of the handling of the events, and/or the model; so really, it depends on your project. Probably handling the event at the view straight away is the easiest strategy.

Event Handling For Java Game Engine

I'm writing a little game-engine in Java and want to know how to optimize my event-handling.
For event-handling I have a class EventManager, here you can register a EventHandler (EventHandler is simply a flag-interface). The EventManager scans through all the methods of the EventHandler and when there is a method with the #EventCallback annotation and it has has exactly one Paramter with a type that extends Event, it adds this method to an Map : Map<Class<? extends Event>, Set<Callback>> (a Callback simply saves the Method and its Object so the Method can be invoked later).
What i like about this kind of event-handling is, that you can name your handler-methods however you want and you can handle different events in the same class without having to implement many interfaces.
A event-handling class would look like this:
class ExampleHandler implements EventHandler {
ExampleHandler(Game game) {
game.getEventManager().registerHandler(this);
}
#EventCallback
public void exampleKeyCallback(KeyPressEvent evt) {
//I only care about key-pressing, not key-releasing in this class
System.out.println(evt.getKey() + " was pressed");
}
#EventCallback
public void i_can_name_this_method_however_i_want(PlayerDeathEvent evt) {
System.out.println(evt.getPlayer().getName() + " died");
}
}
For example when my player dies it will send the PlayerDeathEvent to the EventManager:
//Inside the player-class
public void update() {
if (health <= 0) {
getGame().getEventHandler().fireEvent(new PlayerDeathEvent(this));
}
}
and the EventHandler will invoke all the callbacks for this Event:
//Inside the eventmanager-class
private Map<Class<? extends Event>, Set<Callback>> eventCallbackMap = new HashMap<>();
public void registerEventHandler(EventHandler evt) {
// find all the #EventCallback-Methods and find the Class-Type of their Paramater,
// then add the Method to the Set of Methods for this Class of Events.
// for example: exampleKeyCallback(KeyPressEvent)
// it will be added to the Set for KeyPressEvent.class
}
public void fireEvent(Event evt) {
Set<Callback> callbacks = eventCallbackMap.get(evt.getClass());
for (Callback callback : callbacks) {
callback.invoke(evt);
}
}
Which invokes i_can_name_this_method_however_i_want with the PlayerDeathEvent and prints "*Player-Name* died" on the console.
I want to know if this is a good way to handle events and if it will be fast enough for handling the Events in the Game or if i have to change it. And if I have to change it, how can i make it better?

Is it possible to create my own event listener list in Java containing multiple listener types?

I'm implementing a client-server system where the client is in a continuous blocking read loop listening for messages from the server. When a message is received I'd like to raise an "event" based on the type of the message, which other GUI classes may add listeners to. I'm more familiar with C# events so I am still getting used to the Java way of doing things.
There will be many message types so I will need an interface for each, call it MessageTypeAListener, MessageTypeBListener, etc., each of which will contain one handle method, which my GUI classes will implement. However, there will be be many types and instead of maintaining a list of listeners per type and having several "fire" methods I wanted to have one big listener list and a typed fire method. Then the fire method could say "only fire listeners whose type is what I specify."
So for example (pseudocode):
ListenerList.Add(MessageTypeAListener);
ListenerList.Add(MessageTypeBListener);
<T> fire(message) {
ListenerList.Where(type is T).handle(message)
}
...
fire<MessageTypeAListener>(message);
However, type erasure seems to be making this difficult. I could try casting and catching exceptions but that seems wrong. Is there a clean way of implementing this or is it just wiser to keep a separate list of listeners for every type, even though there will be tons of types?
I implemented something like this, cause I have a visceral dislike of Java's EventListenerList. First, you implement a generic Listener. I defined the listener based upon the Event it was receiving, with basically one method
interface GenericListener<T extends Event> {
public void handle(T t);
}
This saves you having to define ListenerA, ListernerB etc... Though you could do it your way with ListenerA, ListenerB, etc, all extending some base like MyListener. Both ways have plusses and minuses.
I then used a CopyOnWriteArraySet to hold all these listeners. A set is something to consider cause all too often listeners get added twice by sloppy coders. YMMV. But, effectively you have a Collection<GenericListener<T extends Event>> or a Collection<MyListener>
Now, as you've discovered, with type erasure, the Collection can only hold one type of listener. That is often a problem. Solution: Use a Map.
Since I'm basing everything upon the event, I used
Map<Class<T extends Event>, Collection<GenericListener<T extends Event>>>
based upon the class of the event, get the list of listeners who want to get that event.
Your alternative is to base it upon the class of the listener
Map<Class<T extends MyListener>, Collection<MyListener>>
There's probably some typos above...
Old-fashioned pattern approach, using Visitor pattern:
class EventA {
void accept(Visitor visitor) {
System.out.println("EventA");
}
}
class EventB {
void accept(Visitor visitor) {
System.out.println("EventB");
}
}
interface Visitor {
void visit(EventA e);
void visit(EventB e);
}
class VisitorImpl implements Visitor {
public void visit(EventA e) {
e.accept(this);
}
public void visit(EventB e) {
e.accept(this);
}
}
public class Main {
public static void main(String[] args) {
Visitor visitor = new VisitorImpl();
visitor.visit(new EventA());
}
}
More modern approach is just to have Map between classes of events, which should not derive each other, and respective handlers of these events. This way you avoid disadvantages of Visitor pattern (which is, you'll need to change all your visitor classes, at least, base of them, every time you add new Event).
And another way is to use Composite pattern:
interface Listener {
void handleEventA();
void handleEventB();
}
class ListenerOne implements Listener {
public void handleEventA() {
System.out.println("eventA");
}
public void handleEventB() {
// do nothing
}
}
class CompositeListener implements Listener {
private final CopyOnWriteArrayList<Listener> listeners = new CopyOnWriteArrayList<Listener>();
void addListener(Listener l) {
if (this != l)
listeners.add(l);
}
public void handleEventA() {
for (Listener l : listeners)
l.handleEventA();
}
public void handleEventB() {
for (Listener l : listeners)
l.handleEventB();
}
}
After going through iterations of just about everyone's suggestions here, I ended up going a very slightly modified route of the standard Listener interfaces and listener lists. I started with Swing's EventListenerList, only to be disappointed with the amount of add/remove methods for dozens of message types. I realized this could not be condensed while still maintaining a single EventListenerList, so I started thinking about a separate list for each type. This makes it similar to .NET events where each event holds its own list of delegates to fire when raised. I wanted to avoid tons of add/remove methods, so I made a quick Event class that just looks like this:
public class Event<T extends EventListener> {
private List<T> listeners = new ArrayList<T>();
public void addListener(T listener) {
listeners.add(listener);
}
public void removeListener(T listener) {
listeners.remove(listener);
}
public List<T> getListeners() {
return listeners;
}
}
Then I keep several instances of this class around, each typed according to a listener, so Event<MessageTypeAListener>, etc. My classes can then call the add method to add themselves to that particular event. I would've like to be able to call a generic Raise method on the Event instance to then fire all the handlers, but I did not want them to all have to have the same "handle" method, so this was not possible. Instead, when I'm ready to fire the listeners, I just do
for (MessageTypeAListener listener : messageTypeAEvent.getListeners())
listener.onMessageTypeA(value);
I'm sure this is not a new idea and has probably been done before and in better/more robust ways, but it's working great for me and I'm happy with it. Best of all, it's simple.
Thanks for all the help.
If you only have simple events, i.e. events without data or where all events have the same data types, enum could be a way forward:
public enum Event {
A,
B,
C
}
public interface EventListener {
void handle(Event event);
}
public class EventListenerImpl implements EventListener {
#Override
public void handle(Event event) {
switch(event) {
case A:
// ...
break;
}
}
}
public class EventRegistry {
private final Map<Event, Set<EventListener>> listenerMap;
public EventRegistry() {
listenerMap = new HashMap<Event, Set<EventListener>>();
for (Event event : Event.values()) {
listenerMap.put(event, new HashSet<EventListener>());
}
}
public void registerEventListener(EventListener listener, Event event) {
Set<EventListener> listeners = listenerMap.get(event);
listeners.add(listener);
}
public void fire(Event event) {
Set<EventListener> listeners = listenerMap.get(event);
for (EventListener listener : listeners) {
listener.handle(event);
}
}
}
Comments:
The switch statement in the EventListnerImpl may be omitted if it is only registered to a single event, or if it should always act in the same way regardless of which Event it receives.
The EventRegister has stored the EventListener(s) in a map, meaning that each listener will only get the kind of Event(s) that it has subscribed to. Additionally, the EventRegister uses Sets, meaning that an EventListener will only receive the event at most once (to prevent that the listener will receive two events if someone accidentally registers the listener twice).

Categories