Question

We have coded a browser plugin. It fires custom events like 'mycustomevent'. I need to incorporate (i.e. assign listeners for) these custom events into GWT. Here is my plugin class in GWT.

class PluginObject extends Composite implements HasMyCustomEventHandler{
    private Element plugin;
    private HTML html;
    private HandlerManager handlerManager;

    public PluginObject(){
        handlerManager = new HandlerManager(this);
        html = new HTML("<object id='plugin0' type='application/x-ourplugin' width='300' height='300'>"
                       +"<param name='onload' value='pluginLoaded' />"
                       +"</object>");
        initWidget(html);
        plugin = html.getElement().getFirstChildElement();
    }
}

Here is how I am adding it in my View (I am using gwtp). It is being added and is functioning correctly in the page and I can call its js functions from gwt with JSNI.

@Inject
public MyPageView(){

    ...
    plugin = new PluginObject();
    panel.add(plugin);
}

I need to be able to assign handlers for the events fired from the plugin. I'd like to be able to do the following in my presenter but thus far I have been un able to get it wired up.

@Override
protected void onBind(){
    super.onBind();
    registerHandler(getView().getPluginObject().addMyCustomEventHandler(
        new MyCustomEventHandler() {
            @Override
            public void onMyCustomEvent(MyCustomEvent event) {
                // call some other presenter stuff here...
            }
        }));
}

The above mentions a few additional classes. I have a MyCustomEvent class defined, a MyCustomEventHandler interface that extends EventHandler defined, and a HasMyCustomEventHandler interface that extends HasHandlers defined but after wiring them all up I get nothing. I've omitted them for brevity, I'd be glad to add anything that might help.

I can add event listeners in bare js.

obj.addEventListener("mycustomevent", function(){ foo(); }, false);

and catch the event (foo() gets called) every time so I'm confident the events are being fired.

I've tried adding the following to my PluginObject class, but this is just me guessing from things I've found searching. It has not worked.

public HandlerRegistration addMyCustomEventHandler(MyCustomEventhandler handler){
    return handlerManager.addHandler(MyCustomEvent.TYPE, handler);
}

What is the proper approach here?

Was it helpful?

Solution

Here is what I ended up doing in the PluginObject. I'd love to hear ways to improve it. I got hung up a while on subscribeToBrowserEvents() and the reference to 'this'. Initially I was calling the addEvent method and referring to

this.@....

Which was referencing the wrong place at runtime. More about the issue here in this bit of the JSNI docs. Enjoy.

class PluginObject extends Composite implements HasMyCustomEventHandler{

public PluginObject(){
    handlerManager = new HandlerManager(this);

    html = new HTML("<object id='plugin0' type='application/x-myplugin' width='300' height='300'>"
                         +"<param name='onload' value='pluginLoaded' />"
                         +"</object>");
    initWidget(html);
    plugin = html.getElement().getFirstChildElement();      
}

public void bindBrowserEvents(){
    subscribeToBrowserEvents(plugin);
}

public void eventHandlerMethod(String message){
    MyCustomEvent event = new MyCustomEvent(message);       
    fireEvent(event);
}
@Override
public void fireEvent(GwtEvent<?> event){
    handlerManager.fireEvent(event);
}

public native void subscribeToBrowserEvents(Element eventObject) /*-{

    var pluginReference = this;

    // bind the listener
    function addEvent(obj, name, func)
    {
        if (window.addEventListener) {
            obj.addEventListener(name, func, false); 
        } else {
            obj.attachEvent("on"+name, func);
        }
    }

    addEvent(eventObject.br,'mycustomevent', 
        function(message){
            pluginReference.@com.Name.SomeTest2.client.core.PluginObject::eventHandlerMethod(Ljava/lang/String;)(message);
        });
}-*/;

@Override
protected void onAttach(){
    super.onAttach();
    // bind in the onAttach, it was not working earlier. I assume the plugin needs to exist before the bindings will work  
    bindBrowserEvents();
}

@Override
public HandlerRegistration addMyCustomEventHandler(MyCustomEventHandler handler)
{ 
    return handlerManager.addHandler(MyCustomEvent.TYPE, handler);
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top