On Sun, 29 Jan 2012 03:23:33 -0800 (PST)
Thomas Broyer <
t.broyer@gmail.com> wrote:
>
>
> On Friday, January 27, 2012 5:27:10 PM UTC+1, Sebastian Gurin wrote:
> >
> > Ok I found more or less how to do what I want, the following registers a
> > click handler in a native DOM object:
> >
> > public class DomEventTest1 {
> >
> > public static interface ClickHandler {
> > void notifyClick(Element source);
> > }
> >
> > /** call this directly from your Entry point class */
> > public static void test(RootPanel rootPanel) {
> >
> > //create a button using gwt DOM
> > ButtonElement button1 = Document.get().createPushButtonElement();
> > button1.setInnerHTML("clickme");
> > Document.get().getBody().appendChild(button1);
> >
> > addClickHandler(button1, new ClickHandler() {
> > @Override
> > public void notifyClick(Element source) {
> > System.out.println("CLICKED");
> > }
> > });
> > }
> > public static native void addClickHandler(Element e, ClickHandler
> > handler)/*-{
> > //dirty click handler registration, only for testing
> > e.onclick=function() {
> >
> > handler.@org.sgx.gwtraphaljstest.client.js.test.DomEventTest1.ClickHandler::notifyClick(Lcom/google/gwt/dom/client/Element;)(this);
> > }
> > }-*/;
> >
>
> You should wrap your function in $entry() so that a) exceptions are routed
> to the GWT.UncaughtExceptionHandler and b) Scheduler.scheduleEntry and
> Scheduler.scheduleFinally run appropriately. Also, note that you could pass
> the event to your Java code as a NativeEvent:
>
> e.onclick = $entry(function(e) {
> handler.@org.sgx.gwtraphaljstest.client.js.test.DomEventTest1.
> ClickHandler::notifyClick(Lcom/google/gwt/dom/client/NativeEvent;)(e);
> }
>
> (you might have to tweak the code for IE, which doesn't pass the event as
> an argument but uses window.event (or should it be $wnd.event?))
>
> }
> >
> >
> > Now two quiestion about jsni.
> >
> > The first question is: the statement
> >
> > handler.@org.sgx.gwtraphaljstest.client.js.test.DomEventTest1.ClickHandler::notifyClick(Lcom/google/gwt/dom/client/Element;)(this);
> > is a valid javascript statement? or is it some internal gwt compiler
> > language that is translated to javascript?
> >
>
> No, it's a special syntax for JSNI. It's not valid JavaScript.
>
>
> > What I would like is to be able of represent any javascript function using
> > java objects, like Runnable or other. The main problem for this is be able
> > to call a java instance method from javascript having the java class name,
> > method name and signature in strings. I would like something like:
> >
> > public static native void callJavaInstMethod(Object javaThisEl, String
> > className, String methodName, String methodSignature, Object[]params)/*-{
> > //and here do something like:
> >
> > javaThisEl.@${className}::${methodName}(${methodSignature})(${params})
> > }-*/;
> >
> > I tried to archieve something like this unssuccessfully with eval and
> > other hacks. A method like this, will allow me to represent any javascript
> > function using java objects. For example, instead of writing methods like
> > addClickHandler by hand, I could use an Artificial AbstractRunnable class
> > for represent javascript functions as java objects and do:
> >
> > button1.addClickHandler(new AbstractRunnable1<Element>(){
> > public void run(Element e) {
> > System.out.println("CLICKED");
> > }
> > });
> >
> > Any ideas on how to call a java instance method from native javascript
> > having all the necesary information in Strings ?
> >
>
> The GWT compiler will obfuscate all class names and method names, so it's
> not going to work. Only solution would be to create a map, something like:
>
>
> map['org.sgx.gwtraphaljstest.client.js.test.DomEventTest1.ClickHandler::notifyClick(Lcom/google/gwt/dom/client/Element;)']
> =
> someObject.@org.sgx.gwtraphaljstest.client.js.test.DomEventTest1.
> ClickHandler::notifyClick(Lcom/google/gwt/dom/client/Element;);
>
> (note that we don't call the method, we only reference it!)
> Then:
>
> var fn = map[className + '::' + methodName + '(' + methodSignature +
> ')'];
> fn.apply(javaThisEl, params);
>
> (but note that params would have to be a JS array if you want this to work
> in DevMode, as a Java array will be an opaque object in JS)
>
> Or of course you could do it using switch/case or if/else:
> switch (className + '::' + methodName) {
> case
> 'org.sgx.gwtraphaljstest.client.js.test.DomEventTest1.ClickHandler::notifyClick':
> javaThisEl.@org.sgx.gwtraphaljstest.client.js.test.DomEventTest1.
> ClickHandler::notifyClick(Lcom/google/gwt/dom/client/Element;)(params[0]);
> break;
> }
>
> However, I'd suggest you try to find another approach, as the compiler
> won't be able to prune unused code and produce an optimally optimized code.
>
> --
> You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
> To view this discussion on the web visit
https://groups.google.com/d/msg/google-web-toolkit/-/INg0raG3T48J.
> To post to this group, send email to
google-web-toolkit@googlegroups.com.
> To unsubscribe from this group, send email to
google-web-toolkit+unsubscribe@googlegroups.com.
> For more options, visit this group at
http://groups.google.com/group/google-web-toolkit?hl=en.
>