I'm trying my first javascript toolkit porting to java in gwt. I think JavaScript Overlay Types is exactly what I need. Everithing seems to be well supported with the exception of javascript functions...
Explanation. The objective behind Overlay Types as I understand is to easily and safely "present" a javascript object in java language. But javascript objects often require the pass of a function as function parameter, for example, subscribing to an event with a javascript function handler:
jQuery(el).click(function(){......});
My question is, can I represent a javascript function in java? for example with a java.lang.Runnable?
My intention is:
public class MyWrapp extends JavaScriptObject {
public void click(Runnable listener) {
and here handle somehow the function listener::run
as a java object functionObject and pass it via jsni like:
this.click(functionObject);
}
}
and then in my java code use the wrapper:
MyWrap wrapper = ...;
wrapper.click(new Runnable(){
Window.alert("clicked!");
});
Note:
In java2script (a java to javascript compiler similar to GWT), it was not so hard to do this because method functions are implemented inside context objects natively. i.e. In Runnable r, r.run is a javascript function natively, s onatively I can simply perform r.run(), taking care of pointing javascript context object to 'r'.
In GWT this is different, calling r.run() natively must be done with something like:
r.@org.my.Runnable::run()();
I'm still investigating possible sollutions to this problem. Also, I found that the new GWT DOM API (http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/dom/client/package-tree.html), that I think it is based on Overlay Types doesn't seem to have support for event registration or any task implying javascript function manipulation/presentation in java.
Well, any idea is most welcome. Regards
--
Sebastian Gurin <sgu...@softpoint.org>
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);
}
}-*/;
}
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?
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 ?
Regards, and thanks in advance.
> --
> You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
> To post to this group, send email to google-we...@googlegroups.com.
> To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
>
--
Sebastian Gurin <sgu...@softpoint.org>
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);
}
}-*/;
}
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?
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 ?
project page
http://code.google.com/p/raphael4gwt/
demo with java sources available:
http://cancerbero.vacau.com/gwt/raphael4gwtGallery/
This library was written by me in few days and from scratch.
Initially I wanted to create a layer for "doing javascript in java", so I can write javascript in java without jsni (but paying a little overhead price), like something like this:
JavaScriptObject o1 = getNativeObject();
JsUtils.put(o1, "property1", "value1");
JsUtils.put(o1, "onclick", JsUtils.FUNC(new Runnable1(){
public JavaScriptObject run1(NativeEvent e) {
...
}
});
JsUtil.put performs obj[1]=b, jsUtil.FUNC converts a Runnable in a javascript function, etc
But this seems to be impossiblein gwt. More, looking at generated sources, I see gwt compiler do a beautifull job optimizing jsni based code. Also I'm feeling very confortably programing overlay types in eclipse with gwt eclipse plugin. So I discarded my initial idea of "doing javascript in java", and I'm working with "normal" overlay types.
Thanks again, I will notify the group when my gwt4raphael library supports 100% of the raphaeljs api (neverthelessm,it is very usable right now)
Regards, and thank you again.
> --
> 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.
* raphaelgwt is based in raphaeljs 1.0 and mine in raphael2.0.
* raphaelgwt has limited support for doing native stuff it is base on gwt widgets for solving some problems. Specially there are no native event support (events are managed at gwt widget level). My library, raphael4gwt is not based on gwt widgets at all and support 100% of raphaeljs api with overlay types for zero overhead. You can put a raphael canvas object inside a widget, but contrary to raphaelgwt, the java api is only for the raphael canvas and shapes, not widgets.
last section of the wiki explains my motivations a little more: http://code.google.com/p/raphael4gwt/wiki/MainDocumentation
Nevertheless, I'm thinking on contributing some things to raphaelgwt, specially native support for event handling.
I will anounce raphael4gwt in this group once I get a more polished version.
Regards.
--
Sebastian Gurin <sgu...@softpoint.org>