GWT JSNI - problem passing Strings
Asked Answered
E

2

5

I'm trying to provide some function hooks in my GWT project:

private TextBox hello = new TextBox();
private void helloMethod(String from) { hello.setText(from); }
private native void publish() /*-{
 $wnd.setText = $entry([email protected]::helloMethod(Ljava/lang/String;));
}-*/;

publish() being called in onModuleLoad(). But this doesn't work, providing no feedback as to why in the dev console. I've also tried:

private native void publish() /*-{
 $wnd.setText = function(from) {
  alert(from);
  [email protected]::helloMethod(Ljava/lang/String;)(from);
 }
}-*/;

which will toss a java.lang.ClassCastException in the FireBug console, though the alert fires just fine. Suggestions?

Edmonton answered 8/3, 2011 at 15:44 Comment(0)
C
7
private native void publish(EntryPoint p) /*-{
 $wnd.setText = function(from) {
  alert(from);
  [email protected]::helloMethod(Ljava/lang/String;)(from);
 }
}-*/;

Could you give this code a try?

Centro answered 8/3, 2011 at 17:0 Comment(2)
very nice - I think I prefer this over the var that = this syntax.Edmonton
I too prefer this. I also prefer to designate such methods as static to further signify that they don't rely on the "Java-style" this.Piecework
A
7

helloMethod is an instance method, and as such it requires the this reference to be set, when it is called. Your first example doesn't do this at call time. Your second example attempts to do this, but there's a little mistake, which one can make easily in JavaScript: The this reference in

$wnd.setText = function(from) {
  [email protected]::helloMethod(Ljava/lang/String;)(from);
};

points to the function itself. To avoid this, you'll have to do something like:

var that = this;
$wnd.setText = function(from) {
  [email protected]::helloMethod(Ljava/lang/String;)(from);
};

Or better:

var that = this;
$wnd.setText = $entry(function(from) {
  [email protected]::helloMethod(Ljava/lang/String;)(from)
});
Abert answered 8/3, 2011 at 16:50 Comment(5)
Chris, thanks - both your corrections work like a charm. You say the second one is better - can you clarify why?Edmonton
@Carl: Sure, the dev guide on JSNI says about $entry: "This implicitly-defined function ensures that the Java-derived method is executed with the uncaught exception handler installed and pumps a number of other utility services. The $entry function is reentrant-safe and should be used anywhere that GWT-derived JavaScript may be called into from a non-GWT context." BTW, the var that = this; line is a typical JavaScript idiom (see eg this article).Abert
weeell, I was hoping you'd actually explain what that quote from the dev guide meant (I'd already read it). I'm familiar with the var that = this; idiom, but going with @ykartal's solution makes it possible to make publish static - usually an early step towards being able to generify/extract/otherwise relocate methods.Edmonton
@Carl: I'm awful at mind reading over the internet. I'm a little bit hesitant now to explain the uncaught exception handler, if you understand... In any case, this would deserve a separate question.Abert
great post, do you have any idea why using $wnd.setText = $entry([email protected]::helloMethod(Ljava/lang/String;)); throws class cast exception (JavaScriptObject to com.example.my.Class)?Zita
C
7
private native void publish(EntryPoint p) /*-{
 $wnd.setText = function(from) {
  alert(from);
  [email protected]::helloMethod(Ljava/lang/String;)(from);
 }
}-*/;

Could you give this code a try?

Centro answered 8/3, 2011 at 17:0 Comment(2)
very nice - I think I prefer this over the var that = this syntax.Edmonton
I too prefer this. I also prefer to designate such methods as static to further signify that they don't rely on the "Java-style" this.Piecework

© 2022 - 2024 — McMap. All rights reserved.