tags:

views:

183

answers:

1

Hi,

In javascript, I'm making an SVG shape and adding a click handler to it like this:

  var rect = document.createElementNS('http://www.w3.org/2000/svg','rect');
  rect.addEventListener('click', myClickHandler, false);

it works great. I'm trying to make an overlay Rect class in GWT. If possible, I'd like to simply do something like this:

public class SVGRect extends JavaScriptObject {

    public native void addClickHandler(ClickHandler handler) /*-{
        addEventListener('click', handler, false);
    }-*/;
}

this way I can pass a 'normal' GWT handler to this class, and use it from the outside as any other normal GWT UI element. I'm not sure how to hook up the ClickHandler object to the native javascript implementation of the object though?

Thanks

A: 

Because you need a ClickEvent to pass to ClickHandler.onClick and obtaining it from JavaScript poses a problem (AFAICT) - I'd go with a slightly different, more "generic" approach:

Create a simple Callback interface:

public interface Callback {
    void execute();
}

You can then pass it directly and call it like this:

public native void addClickHandler(Callback callback) /*-{
        addEventListener('click', function() {
           [email protected]::execute()();
        }, false);
}-*/;

Or create an intermediate step:

public void addClickHandler(Callback callback) {
    _addClickHandler(getCallback(callback));
}

private native void _addClickHandler(JavaScriptObject callback) /*-{
     addEventListener('click', callback, false);
}-*/;

// This can be moved to a better place
private native static JavaScriptObject getCallback(Callback callback) /*-{
    return function()
    {
        [email protected]::execute()();
    };
}-*/;

And, of course, you'd use it like this:

SVGRect svg = getMeSVGRect();
svg.addClickHandler(new Callback() {
    @Override
    public void execute() {
        // Do some stuff
    }
});

Personally, I prefer the second solution - while it's more code, I like to keep my native/JSNI methods private (unless it's an overlay object or something similar) and the code is more readable and less error-prone (no need to use the funky syntax to call Java functions from inside native/JSNI code).

Igor Klimer
Awesome, thanks!