I am trying to send an object through the gwt event bus and i don't know why it doesn't work.
Usually, i have a component A which creates a popup. A registers to the popup, and the popup fires the event.
Now, the listener (OtherComponent) isn't related to the popup. When the popup fires the event, the other compoment doesn't catch it.
Here's my code :
Handler:
public interface MyEventHandler extends EventHandler {
public void onChanged(MyEvent event);
}
Event :
public class MyEvent extends GwtEvent<MyEventHandler> {
private static final GwtEvent.Type<MyEventHandler> TYPE = new GwtEvent.Type<MyHandler>();
private MyBean my;
public MaterielEvent(My bean) {
my = bean;
}
#Override
public com.google.gwt.event.shared.GwtEvent.Type<MyEventHandler> getAssociatedType() {
return TYPE;
}
public static Type<MyEventHandler> getType() {
return TYPE;
}
#Override
protected void dispatch(MyEventHandler handler) {
handler.onChanged(this);
}
public MyBean getBean() {
return my;
}
}
Component :
public class OtherPanel extends Composite implements HasMyEventHandlers {
interface OtherPanelUiBinder extends UiBinder<Widget, OtherPanel> {}
private static OtherPanelUiBinder uiBinder = GWT.create(OtherPanelUiBinder.class);
public OtherPanel() {
this.addMyEventHandler(new MyEventHandler() {
#Override
public void onChanged(MyEvent event) {
NotificationManager.success("event recieved");
}
});
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public HandlerRegistration addMyEventHandler(MyEventHandler handler) {
return addHandler(handler, MyEvent.getType());
}
}
Call (inside another component) :
fireEvent(new MyEvent(myBean));
The notification "event received" is never called.
I surely missed something. Thanks for your help
You're creating a new instance of an EventBus and defining the eventHandler on that new instance.
I can't see how you're calling the fireEvent method (or from what instance of the eventBus you are calling it), but you need to have a single eventBus instance defined in your code which you pass around.
So you instantiate an eventBus, then define any handlers you want it to have, and then have any components which will interact with eventBus accept a "MyEventHandler" as a parameter to the constructor. Then you can pass your pre-defined instance of an event bus into that component, allowing that component to later interact with the singular eventBus that your application has.
As #Jeff Allen wrote. Each widget has its private EventBus instance (it is not static).
if your events are not instance specific you can use EventBus directly not via Widgets wrapper methods. Your Event and Handler classes are perfectly ready for this.
See javadoc at http://google-web-toolkit.googlecode.com/svn/javadoc/2.4/com/google/gwt/event/shared/EventBus.html (as you noticed Widgets event methods are simply wrappers over evtnbus methods.
Related
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).
I would like to call different code (callbacks) from within a background thread loop and use that background thread to perform the work. It would be similar to delegates in C#.
public class test {
private boolean keepRunning;
private boolean messageReady;
private MyClass myClass;
void LongBackgroundWork(){
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while (keepRunning) {
if (messageReady){
myClass.callback(); // call different methods here
// to be decided at runtime and run on this worker thread
}
}
}
});
thread.start();
}
}
I want to use the background thread not the UI thread. I want to set a callback from within myClass to choose what code is called. It's easy in C# how to do it Java.
I don't have much experience in Java and don't understand what mechanism to use. Should I be using a handler? Can a handler run code on a background thread?
I'd wager you want to have a pattern where an event or some occurence happens and you need to initiate a code block somewhere.
A pattern that could help you is perhaps an Observer Wiki and firing off to the event. You can also check out this SO question here if you'd like: Delegate vs Callback in Java
In your case, I think you'd want to have someone handle the responsibility of what you have to do when a message is ready. So what you're looking for is someone to perform the action, once the event is read (message ready).
Take for example Class Foo is your container of listeners, or also called an Observer that will be notified of any events. You can have a list of callbacks here to some object that is responsible for your logic to do what you need to do next.
Then you would have an Observable object or a class that would implement some logic when notified. You could then have various class objects perform the necessary logic by implementing the callback function required.
Example:
// Observer
public class Foo {
// List of objects that implement Callbacks interface
private List<Callbacks> mList;
public Foo() {
// Initialize here
}
public void addListener(Callbacks cb) {
mList.add(cb);
}
public void notifyListeners() {
for ( Callback cb : mList) {
cb.onCallback();
}
}
// Public interface to be implemented by users
public interface Callback {
void onCallback();
}
}
Then just have a class implement this object and you can pass it along if you'd like.
// Bar implements Foo.Callback interface
public class Bar implements Foo.Callback {
public class Bar() {}
#Override
public void onCallback() {
// Perform logic here
}
}
Finally in your code, you'd just create the Foo object, add a listener, and notify them when it's time to fire your event.
if i understood you properly,you cant do this on UI thread, basically when android see Thread like this it will expect that it's a long operation however you can call it by AsyncTask or Handler
you can make something like this
private class MyAsyncTask extends AsyncTask<Void,Void,Void>{
protected Void doInBackground() {
MyClass myClass=new MyClass();
myClass.LongBackgroundWork();
}
return totalSize;
}
}
this is how yo can call your thread otherwise you have to use Handler instead
Handler handler=new Handler();
handler.post(new Runnable(){
MyClass myClass=new MyClass();
myClass.LongBackgroundWork();
})
I'm using Guava Eventbus in Vaadin+Spring project and started to have a problem with posting an event from background thread.
Eventbus is instantiated in wrapper class. Objects communicate with the eventbus using static method defined in main UI class to obtain the eventbus object. It is the same way as proposed in Vaadin Dashboard example (DashboardEventBus).
public class MainUI extends UI implements ViewDisplay
{
private EventBusWrapper eventbus_ = new EventBusWrapper();
public static EventBusWrapper GetEventBusWrapper()
{
return ((MainUI) getCurrent()).eventbus_;
}
}
Problem appears in presenter/services classes where I create new thread class and start the thread.
Inside Runnable implemenation of run method I create another object which makes some job.
public class SearchResultsPresenter extends AbstractPresenter<SearchResultView>
{
public SearchResultsPresenter()
{
EventBusWrapper.register(this);
}
#Subscribe
public void UserSearchRequested(Event.UserSearchRequestEvent e)
{
new UpdateContentComponentThread(e.GetSearchElem()).start();
}
#Subscribe
public void UserSearchAppendFoundElement(Event.UserSearchElementFound e)
{
if(e.GetElement().IsValid())
view_.AddElement(e.GetElement());
}
public class UpdateContentComponentThread extends Thread
{
private final Search searcher_;
UpdateContentComponentThread(SearchElement search)
{
searcher_ = new DefaultSearch(search);
}
#Override
public void run()
{
searcher_.Search();
}
}
}
It performs some validation/checking and creates other helper classes.
public class DefaultSearch implements Search
{
private final Scraper scraper_;
...
#Override
public void Search()
{
if(!scraper_.IsConfigured())
return;
...
scraper_.FindElements();
}
}
Then inside scraper's FindElements body I try to post an event using static post method defined in EventBusWrapper.
public class HttpElementScraper extends WebScraper
{
...
#Override
public Collection<Element> FindElements()
{
...
Element elem = ...
Event.UserSearchElementFound e = new Event.UserSearchElementFound(elem);
EventBusWrapper.post(e);
return foundelements;
}
}
At this moment the NullPointerException is thrown and I cannot solve and help myself with the problem.
Exception in thread "Thread-10" java.lang.NullPointerException
at com.project.MainUI.GetEventBusWrapper(MainUI.java:109)
at com.project.events.EventBusWrapper.register(EventBusWrapper.java:24)
at com.project.service.search.scraper.HttpElementScraper.FindElements(HttpElementScraper.java:92)
at com.project.service.search.DefaultSearch.Search(DefaultSearch.java:38)
at com.project.view.search.SearchResultsPresenter$UpdateContentComponentThread.run(SearchResultsPresenter.java:71)
// I ommited not important lines of code and annotations. Most of the components and services connected with them are UIscoped.
Vaadin assumes that access to Vaadin component (and related) instances is synchronized properly. When using the traditional single-threaded request-response cycle to access components it's synchronized automatically.
When using external threads, you need to synchronize code accessing your Vaadin components by using UI.access(). For example:
getUI().access(() -> label.setValue("Hello"));
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?
public class MyActivity extends AbstractActivity implements ContextChangedEvent.Handler
{
public MyActivity()
{
ClientFactory.INSTANCE.getEventBus().addHandler(ContextChangedEvent.TYPE, this);
}
#override
public void onContextChanged()
{
//do stuff
}
}
//The getEventBus Implementation:
public EventBus getEventBus()
{
if (eventBus == null)
eventBus = new ResettableEventBus(new SimpleEventBus());
return eventBus;
}
When I add a breakpoint in the onContextChange() method, I get the following behavior:
on the first Place, i break only once for each event fired
after a place changed, I break twice
after another place change, 3 times....
Since I'm using a new instance of MyActivity for each place, my guess is that I break in several instances of MyActivity. The ResettableEventBus should unregister all handler on each place change.
I am missing something?
With ResettableEventBus you still have to call removeHandlers (plural) to detach everything. ResettableEventBus only keeps track of your handlers and adds a function to remove all handlers that was attached to this instance.
If you are using ActivityManager and passing in your eventbus, ActivityManager will wrap your EventBus in ResettableEventBus and pass it to you in start.
ActivityManager(myActivityMap, ClientFactory.INSTANCE.getEventBus());
...
public class MyActivity extends AbstractActivity implements ContextChangedEvent.Handler
{
public MyActivity()
{
}
#override
public void onContextChanged()
{
// do Stuff
}
#override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
eventBus.addHandler(ContextChangedEvent.TYPE, this);
}
}
If you use the eventBus passed to you in "start", ActivityManager will automatically clean the handlers you attach to it automatically for you.
Also I would suggest constructing a SimpleEventBus in your factory instead of ResettableEventBus. There is a bug in the current version of ResettableEventBus that causes issue if you nest it (Memory Leak).
http://code.google.com/p/google-web-toolkit/issues/detail?id=5700
This is more of a FYI. Also don't remove any handlers manually from the passed in eventbus. This is caused by the same bug as above.