3rd party JS library with functions on a JSON object

9 views
Skip to first unread message

markmccall

unread,
Jun 14, 2010, 2:28:19 PM6/14/10
to Google Web Toolkit
I am integrating a 3rd party JavaScript library into my GWT 2.0
application and I have succeeded in invoking the libary using basic
JSNI but I want to take the integration even further so that callers
of the library never have to code any JSNI, if possible. The 3rd
party library has a class Foo with a JSON structure as a constructore
parameter. The structure contains simple properties as well as
predefined functions where users of this library can place custom own
behavior. Foo will call those functions to invoke the custom behavior
at time of is own choosing. In the example below I have shown 2
functions called 'onBeforeCompute' and 'onAfterCompute' which would be
invoked during Foo's loadData prcoess. The normal JSNI implementation
would look something like this:

public native JavaScriptObject setUp() /*-{
var config = {
prop1: 'val1',
prop2: 'val2',
onBeforeCompute: function(someparam) {
// do something custom here
},
onAfterCompute: function(someparam1, someparam2) {
// do something custom here
}
};
var foo = $wnd.Foo(config);
foo.loadData(...)
}-*/


I would like to wrap all of this code up so that my applications that
use the 3rd party library never have to code any JSNI, if possible. I
am envisioning something like this:

public class MyWidget extends Composite
{
public MyWidget()
{
Config config = new Config();
config.setProp1("val1");
config.setProp2("val2");
config.setOnBeforeHandler(new MyOnBeforeComputeHandler());
config.setOnAfterHandler(new MyOnAfterComputeHandler());
Foo foo1 = new Foo(config);
SimplePanel panel = new SimplePanel(foo1);
initWidget(panel);
foo1.loadData(...);
}
}

public class MyOnBeforeComputeHandler implements
OnBeforeComputeHandler // interface definition excluded for brevity
{
public void onBeforeCompute(JavaScriptObject someparam)
{
// do something custom here
}
}

public class MyOnAfterComputeHandler implements
OnAfterComputeHandler // interface definition excluded for brevity
{
public void onAfterComputeHandler(JavaScriptObject someparam1,
JavaScriptObject someparam2)
{
// do something custom here
}
}

Setting the simple properties on the Config class is easy - I can
simply use the JSONObject, but I do not know how to deal with the
onBeforeCompute and onAfterCompute functions that are part of the
Config object

public class Config
{
private JSONObject jsonPeer = new JSONObject();
public void setProp1(String value){ jsonPeer.put ("prop1", value)};
public void setProp2(String value){ jsonPeer.put ("prop2", value)};
public asJson() {return jsonPeer.getJavaScriptObject());
public void setPreLoadHandler(PreLoadHandler handler) { ??? }
public void setPostLoadHandler(PostLoadHandler handler) { ??? }
}

Am I on the right track? Is there a better way?

Thomas Broyer

unread,
Jun 14, 2010, 4:51:59 PM6/14/10
to Google Web Toolkit


On 14 juin, 20:28, markmccall <markwmcc...@gmail.com> wrote:
> I am integrating a 3rd party JavaScript library into my GWT 2.0
> application and I have succeeded in invoking the libary using basic
> JSNI but I want to take the integration even further so that callers
> of the library never have to code any JSNI, if possible.  The 3rd
> party library has a class Foo with a JSON structure as a constructore
> parameter.

JSON is a data format, what you're talking about is a JavaScript
object, which you probably generally write directly as an object
literal (the thing within braces, with comma-separated name:value
pairs)
Why not use a JavaScriptObject "overlay type"?

>         public void setProp1(String value){ jsonPeer.put ("prop1", value)};
>         public void setProp2(String value){ jsonPeer.put ("prop2", value)};
>         public asJson() {return jsonPeer.getJavaScriptObject());
>         public void setPreLoadHandler(PreLoadHandler handler) { ??? }
>         public void setPostLoadHandler(PostLoadHandler handler) { ??? }
>
> }
>
> Am I on the right track?  Is there a better way?

Re-written as an overlay type:

public final class Config extends JavaScriptObject {
public static Config newInstance() /*-{ }-*/;

protected Config() { }

public native void setProp1(String value) /*-{ this.prop1 = value; }-
*/;
public native void setProp2(String value) /*-{ this.prop2 = value;}-
*/;
public native void setPreLoadHandler(PreLoadHandler handler) /*-{
var that = this;
this.onBeforeCompute = $entry(function(someparam) {
handler.@my.app.client.PreLoadHandler::onBeforeCompute(Lcom/
google/gwt/core/client/JavaScriptObject;)(someparam);
});
}-*/;
public native void setPostLoadHandler(PostLoadHandler handler) /*-{
var that = this;
this.onBeforeCompute = $entry(function(someparam) {
handler.@my.app.client.PostLoadHandler::onAfterCompute(Lcom/
google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/
JavaScriptObject;)(someparam1, someparam2);
});
}-*/;
}

markmccall

unread,
Jun 14, 2010, 7:19:07 PM6/14/10
to Google Web Toolkit
Thanks for the clarification on the JSON vs JavaScript object. I
thought about using an overlay type earlier, but came away from the
documentation with the impression that overlays were intended to be
used for already existing objects "in the wild", but the technique you
demonstrate below seems to make sense and I will try it tomorrow.
>       handl...@my.app.client.PreLoadHandler::onBeforeCompute(Lcom/
> google/gwt/core/client/JavaScriptObject;)(someparam);
>     });
>   }-*/;
>   public native void setPostLoadHandler(PostLoadHandler handler) /*-{
>     var that = this;
>     this.onBeforeCompute = $entry(function(someparam) {
>       handl...@my.app.client.PostLoadHandler::onAfterCompute(Lcom/
Reply all
Reply to author
Forward
0 new messages