PDA

View Full Version : GXT Custom Events, How To



chalu
8 Feb 2010, 10:41 PM
Coming from EXT JS background, you could make custom components that have their own events - e.g beforenavigate, afternavigate, finish are events in my Wizard extension, this way client code can communicate with the wizard by listening for its events. I have been trying to do the same with my custom components in GXT but have not found a way.

Ok I have a component called ConsoleNav that extends TreePanel, also another component called WorkSpace that extends TabPanel, I want to tell WorkSpace that an item in the tree was clicked so that it can do somthing (open the appropriate tab), but I don't want to pass these objects through constructors

I don't want to do this


tree.addListener(Events.onClick, new Listener<TreePanelEvent>(){
public void handleEvent*TreePanelEvent evt){
// meaning I have a reference to the tabPanel here, maybe from the constructor or set method
tabPanel.add(new TabItem("title"));
}
});


Here is what I'd like


tree.addListener*Events.onClick, new Listener<TreePanelEvent>(){
public void handleEvent*TreePanelEvent evt){
// here I'd just fire the right custom event which the workspace will listen for
// and act accordingly.
}
});

Any hints

takayser
11 Feb 2010, 2:19 AM
create something like an eventbus (with BaseObservable e.g.) that every component can listen to the events he is interessted in. Then your ConsoleNav can fire events to the eventbus and your WorkSpace get them. So ConsoleNav and WorkSpace does not have to know each other.

chalu
13 Feb 2010, 11:43 AM
Thanks takayser, I made an EventBus class that extends BaseObservable, coupled with another class that acts like GTS's Events class - I am very happy with the results thus far.

I will make a tutorial soon on the GXT learning site about this, there really is some worry in some GXT quarters that GXT does not comply with the Google IO 2009 recommended best practice of using a Bus, it actually does :)

marcora
2 Mar 2010, 1:02 PM
I would be pleased if you could share your event bus implementation.

need4speed
2 Mar 2010, 6:41 PM
You may refer to document "GoogleWebToolkitArchitecture BestPracticesForArchitectingYourGWTApp" by Ray Ryan, who suggest using HandlerManager for eventBus.

marcora
3 Mar 2010, 2:56 AM
I am interested in the more GXT specific implementation that uses BaseObservable. I am a total noob when it comes to Java (I am coming from ExtJS where it was very easy to implement an event bus)... the actual Java code used to implement the event bus would actually be of great help.

Thanx!

marcora
3 Mar 2010, 6:45 AM
Here is the way I came up with (it seems to work, but more testing is needed):

First, create an EventBus singleton that extends BaseObservable:



import com.extjs.gxt.ui.client.event.BaseObservable;

public class EventBus extends BaseObservable {
// singleton pattern
private static EventBus instance;

private EventBus() {
}

public static synchronized EventBus get() {
if (instance == null)
instance = new EventBus();
return instance;
}
}



Second, define a class containing the app events:



import com.extjs.gxt.ui.client.event.EventType;

public class AppEvents {
// define an error event
public static final EventType Error = new EventType();
}



Third, use the message bus to broadcast app events...:



// fire an error event using the event bus
EventBus.get().fireEvent(AppEvents.Error, new BaseEvent(AppEvents.Error));



...as well as respond to app events:



// respond to the error event by listening to the event bus
EventBus.get().addListener(AppEvents.Error, new Listener<BaseEvent>() {
public void handleEvent(BaseEvent e) {
// do something in response to the error event
MessageBox.alert("Error", "An error occurred", null);
}
});



Any feedback would be welcomed. Hope this helps other GXT newbies like me.

Cheers,

Edoardo "Dado" Marcora

chalu
3 Mar 2010, 6:47 AM
I don't know if I have done it exactly well, but here is the code for my event system


...
inside my tree class
navTree.addListener(Events.OnClick, new Listener<TreePanelEvent>(){
public void handleEvent(TreePanelEvent evt) {
EventBus.getInstance().fireEvent(ChronicleEvents.NavClick, evt);
}
});

.. from inside my tabpanel class
EventBus.getInstance().addListener(ChronicleEvents.NavClick, new Listener<TreePanelEvent>(){
public void handleEvent(TreePanelEvent tpe) {
handleNavClick(tpe);
}
});