$wnd and $doc Calling native JavaScript with JSNI
$wnd 是什么?
GWT provides the $wnd
and $doc
variables to refer to the window and document objects
GWT使用通过Java Native method使用它,声明一个native方法,将含有JavaScript的方法体注释。编译器将注释块内的内容逐字输出,使之与编译产生的JavaScript整合到一起。
Java调用JavaScript方法:
JSNI方法定义需要使用native关键字,并且需要在参数列表之后,结尾的分号之前定义。JSNI方法的开始使用 /*-{ , 结尾使用}-*/,例如:
public static native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
这是gwt Window 类中的源码--一个标准的jsni 方法, 我们可以看到,方法实现就是一行简单的javascript 代码. (这里没有用 alert 或者 window.alert 的原因是: gwt 代码运行在一个iframe中,如果直接用alert或者window.alert,引用的是iframe文档,而不是host page 文档). 经过这个方法包装,以后在gwt程序中使用 " Window.alert" 实际上就是调用了javascript 的 alert 方法,当然你也可以不用这个封装, 直接实用 $wnd.alert .
当上述方法在Java中调用的时候,实际上将调用Window的alert()方法,将传入的内容打印出来。在Hosted Mode下,断点可以调协在上述方法中,可以查看传入的参数。
参考如下:
http://www.javaeye.com/topic/365678
http://www.webreference.com/programming/java/toolkits/
The GWT makes ingenious use of Java's native methods with something called the JavaScript Native Interface. You declare native methods with commented-out bodies that contain JavaScript. When those native methods are compiled, the GWT incorporates the commented JavaScript. Here's an example of such a native method:
Calling native JavaScript with JSNI
http://www.ibm.com/developerworks/java/library/j-ajax4/
Visual-effects libraries are becoming increasingly popular in Web application development, whether their effects are used to provide subtle user-interaction cues or just to add polish. I'd like to add some eye-candy to the Weather Reporter application. GWT doesn't provide this type of functionality, but its JavaScript Native Interface (JSNI) offers a solution. JSNI lets you make JavaScript calls directly from GWT client Java code. This means that I can exploit effects from the Scriptaculous library (see Resources) or from the Yahoo! User Interface library, for example.
JSNI uses a cunning combination of the Java language's native
keyword and JavaScript embedded in a special comment block. It's probably best explained by example, so Listing 10 shows a method that invokes a given Scriptaculous effect on an Element
:
Listing 10. Invoking Scriptaculous effects with JSNI
private native void applyEffect(Element element, String effectName) /*-{
// Trigger named Scriptaculous effect
$wnd.Effect[effectName](element);
}-*/;
This is perfectly valid Java code because the compiler sees only private native void applyEffect(Element element, String effectName);
. GWT parses the contents of the comment block and outputs the JavaScript verbatim. GWT provides the $wnd
and $doc
variables to refer to the window and document objects. In this case, I'm simply accessing the top-level Scriptaculous Effect
object and using JavaScript's square-bracket object-accessor syntax to invoke the named function specified by the caller. The Element
type is a "magic" type provided by GWT that represents a Widget
's underlying HTML DOM element in both Java and JavaScript code. String
s are one of the few other types that can be passed transparently between Java code and JavaScript via JSNI.
Now I have a weather report that fades in nicely when the data is returned from the server. The final touch is to re-enable the ZIP code TextBox
when the effect has finished. Scriptaculous uses an asynchronous callback mechanism to notify listeners about the life cycle of effects. This is where things get a little more complex because I need to have JavaScript call back into my GWT client Java code. In JavaScript, you can invoke any function with an arbitrary number of arguments, so Java-style method overloading doesn't exist. This means that JSNI needs to use an unwieldy syntax to refer to Java methods to disambiguate possible overloads. The GWT documentation states this syntax as:
[instance-expr.]@class-name::method-name(param-signature)(arguments) |
The instance-expr.
part is optional because static methods are invoked without the need for an object reference.