I'm trying to move most of my native JavaScript code out of JSNI methods and into scripts, and just leveraging the native JSNI methods to call those external methods.
Right now I'm having difficulties with one of my click handlers. When the user clicks a particular element, a JSNI method does some JQuery-based animation, and then calls a Java method in the callback. A simple example is this:
public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
$wnd.jQuery("#theElement").click(function() {
// some JQuery animation logic here...
$wnd.jQuery("#theElement").animate({ top: "500px" }, 500, function() {
[email protected]::doSomething()();
});
// some other code here...
});
}-*/;
This code works. It piles and works as expected. I want to move this into an external JavaScript. I tried the following. I put this in the external JavaScript:
function attachClickAction(customPanel) {
$("#theElement").click(function() {
// other stuff...
$("#theElement").animate({ top: "500px" }, 500, function() {
[email protected]::doSomething()();
});
// other stuff...
});
}
And modified the native function like this:
public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
$wnd.attachClickAction(customPanel);
}-*/;
But is incorrect. The JavaScript file won't even load because this is not correct JavaScript. (Chome's dev tools give me the error message "Uncaught SyntaxError: Unexpected identifier".)
Is there a way to call a Java method from an external JavaScript file, not from a JSNI method?
I'm in GWT 2.4, if it matters.
I'm trying to move most of my native JavaScript code out of JSNI methods and into scripts, and just leveraging the native JSNI methods to call those external methods.
Right now I'm having difficulties with one of my click handlers. When the user clicks a particular element, a JSNI method does some JQuery-based animation, and then calls a Java method in the callback. A simple example is this:
public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
$wnd.jQuery("#theElement").click(function() {
// some JQuery animation logic here...
$wnd.jQuery("#theElement").animate({ top: "500px" }, 500, function() {
[email protected]::doSomething()();
});
// some other code here...
});
}-*/;
This code works. It piles and works as expected. I want to move this into an external JavaScript. I tried the following. I put this in the external JavaScript:
function attachClickAction(customPanel) {
$("#theElement").click(function() {
// other stuff...
$("#theElement").animate({ top: "500px" }, 500, function() {
[email protected]::doSomething()();
});
// other stuff...
});
}
And modified the native function like this:
public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
$wnd.attachClickAction(customPanel);
}-*/;
But is incorrect. The JavaScript file won't even load because this is not correct JavaScript. (Chome's dev tools give me the error message "Uncaught SyntaxError: Unexpected identifier".)
Is there a way to call a Java method from an external JavaScript file, not from a JSNI method?
I'm in GWT 2.4, if it matters.
Share Improve this question asked Aug 24, 2012 at 21:26 Roddy of the Frozen PeasRoddy of the Frozen Peas 15.2k10 gold badges59 silver badges106 bronze badges3 Answers
Reset to default 5The answer is no, you cannot call Java methods explicitly from the external JavaScript function.
However, you can be clever and take advantage of the fact that JavaScript allows you to pass functions themselves as parameters.
I modified my JavaScript function like so:
function attachClickAction(callbackFunction) {
$("#theElement").click(function() {
// other stuff...
$("#theElement").animate({ top: "500px" }, 500, callbackFunction);
// other stuff...
});
}
And in my Java code I explicitly passed the Java method as a callback function parameter:
public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
$wnd.attachClickAction(function() {
[email protected]::doSomething()();
});
}-*/;
This way, when the JSNI method piles, it correctly calls the doSomething()
Java method, and that method call is correctly passed in its entirety to the external JavaScript function.
Although you cannot make calls to Java classe's methods directly from JavaScript with vanilla GWT, gwt-exporter does a lot of the plumbing required for calling the methods of 'Java' objects from native JavaScript.
You can do things like:
Java:
@ExportPackage("")
@Export("MYOBJ");
class MyClass implements Exportable {
public void doSomething();
}
JavaScript:
MYOBJ.doSomething();
gwt-exporter works well with GWT 2.4,
Yes, you can export your Java (GWT) methods as JavaScript functions, and you can put your Java objects into JavaScript variables. Here's a simple example:
@Override
public void onModuleLoad() {
exportJavaMethodsToJs();
final SomeCustomPanel firstCustomPanel = new SomeCustomPanel("first");
exportJavaObjectToJs("firstCustomPanel", firstCustomPanel);
final SomeCustomPanel anotherCustomPanel = new SomeCustomPanel("another");
exportJavaObjectToJs("anotherCustomPanel", anotherCustomPanel);
}
native void exportJavaMethodsToJs() /*-{
$wnd.doSomething = function(panel) {
[email protected]::doSomething()();
}
// Export any methods you need in JavaScript here...
}-*/;
native void exportJavaObjectToJs(final String key, final Object object) /*-{
$wnd[key] = object;
}-*/;
Then, in JavaScript (after onModuleLoad() has been called!), you can use it easily like
doSomething(firstCustomPanel);
doSomething(anotherCustomPanel);
Your example would now look like this:
jQuery("#theElement").click(function() {
// some JQuery animation logic here...
$wnd.jQuery("#theElement").animate({ top: "500px" }, 500, function() {
doSomething(firstCustomPanel);
});
// some other code here...
});