JSNI 学习例子

JSNI 学习例子

native JavaScriptObject init(JavaScriptObject myColumns,JavaScriptObject myData)/*-{  
try{
$wnd.mygrid = new $wnd.AW.UI.Grid;
$wnd.mygrid.setSize(75 0, 35 0);

// provide cells and headers text
$wnd.mygrid.setCellText(myData);
$wnd.mygrid.setHeaderText(myColumns);

// set number of rows/columns
$wnd.mygrid.setRowCount(myData.length);
$wnd.mygrid.setColumnCount(myColumns.length);
...
$doc.getElementById('mygrid').innerHTML = $wnd.mygrid;

return $wnd.mygrid;
}
catch(e){
$wnd.alert(e.description);
}

return null;

}-*/;

native JavaScriptObject init(JavaScriptObject myColumns,JavaScriptObject myData)/*-{
try{
$wnd.mygrid = new $wnd.AW.UI.Grid;
$wnd.mygrid.setSize(75 0, 35 0);

// provide cells and headers text
$wnd.mygrid.setCellText(myData);
$wnd.mygrid.setHeaderText(myColumns);

// set number of rows/columns
$wnd.mygrid.setRowCount(myData.length);
$wnd.mygrid.setColumnCount(myColumns.length);
...
$doc.getElementById('mygrid').innerHTML = $wnd.mygrid;

return $wnd.mygrid;
}
catch(e){
$wnd.alert(e.description);
}

return null;

}-*/;



JSNI 可以视为内联汇编代码的 Web 对等物,可以用来:


* 直接在 JavaScript 内实现 Java 代码。

* 为现有的 JavaScript 包装上类型安全的 Java 方法签名。

* 从 JavaScript 调用 Java 代码,反之亦然。

* 跨 Java/JavaScript 界线抛出异常。

* 从 JavaScript 读写 Java 字段。

* 使用宿主模式调试 Java 源代码(通过 Java 调试器)和
JavaScript(通过脚本调试器)。


GWT 开发文档提示说必须慎重使用 JSNI
,因为不能保证浏览器的可移植性,而且编译代码的优化是有限制的。至于商业控件,您可以依赖供应商的承诺来支持多个浏览器类型和部署平台。

当从 JSNI 访问浏览器窗口和文档对象时,必须将其分别作为
$wnd 和 $doc
加以引用。而所编译的脚本则在嵌套的框架中运行,$wnd 和
$doc 会自动初始化以正确指代宿主页面的窗口和文档。

示例代码展示了一种很好的技巧,即使用 JSNI 来将一维或二维的 Java
字符串数组转换成 JavaScript 数组,以便于用数据填充数组,如清单 2
所示:

清单2. Java 到 JavaScript
数组的转换

public static JavaScriptObject arrayConvert(String[] array) {   
JavaScriptObject result = newJSArray(array.length);
for (int i = 0; i<array.length; i++) {
arraySet(result, i, array[i]);
}
return result;
}

private static native JavaScriptObject newJSArray(int length) /*-{
return new Array(length);
}-*/;

public static native int arrayLength(JavaScriptObject array) /*-{
return array.length;
}-*/;

public static native String arrayGetObject(JavaScriptObject array, int index) /*-{
return array[index];
}-*/;

public static native void arraySet(JavaScriptObject array,int index,String value) /*-{
array[index] = value;
}-*/;

public static JavaScriptObject arrayConvert(String[] array) {
JavaScriptObject result = newJSArray(array.length);
for (int i = 0; i<array.length; i++) {
arraySet(result, i, array[i]);
}
return result;
}

private static native JavaScriptObject newJSArray(int length) /*-{
return new Array(length);
}-*/;

public static native int arrayLength(JavaScriptObject array) /*-{
return array.length;
}-*/;

public static native String arrayGetObject(JavaScriptObject array, int index) /*-{
return array[index];
}-*/;

public static native void arraySet(JavaScriptObject array,int index,String value) /*-{
array[index] = value;
}-*/;







处理事件

在 JavaScript 中定义的事件处理程序可与用 Java
代码实现的方法相关联。清单 3 展示了网格控件的
onRowClicked 事件是如何调用 onRowSelect
Java 函数的:


清单 3. 从 JavaScript 调用 Java
函数


public void onRowSelect(String index){
GWT.log("Row #" + index + "selected", null);
}

native JavaScriptObject init(JavaScriptObject myColumns, JavaScriptObject myData)/*-{
var widget = this;

try{
...
// set click action handler
$wnd.mygrid.onRowClicked = function(event, index){

widget.@com.mycompany.project.client.GwtGrid::onRowSelect(Ljava/lang/String;)(index);
};

...
}
catch(e){
$wnd.alert(e.description);
}
}-*/;

public void onRowSelect(String index){
GWT.log("Row #" + index + "selected", null);
}

native JavaScriptObject init(JavaScriptObject myColumns, JavaScriptObject myData)/*-{
var widget = this;

try{
...
// set click action handler
$wnd.mygrid.onRowClicked = function(event, index){

widget.@com.mycompany.project.client.GwtGrid::onRowSelect(Ljava/lang/String;)(index);
};

...
}
catch(e){
$wnd.alert(e.description);
}
}-*/;



您必须使用如下表示法在 JavaScript 中引用 Java 方法:
instance-expr.@class-name::method-name(param-signature)(arguments)


* instance-expr
在调用实例方法时必须使用,在调用静态方法时必须去掉。

* class-name
是类的完全限定名,方法在此类(或其子类)中声明。

* param-signature 是这里指定的内部 Java
方法签名,但无此方法返回类型的尾随签名(因为不需要选择重载)。

* arguments
是实际要传递给被调方法的参数列表。


使用
JavaScript 控件 API


清单 1 所示,实现 Java 类的 init 方法返回
JavaScriptObject,它代表一个网格实例。您可以将其作为一个类属性加以存储并随后在代码中引用,以调用
JavaScript 控件 API 方法。清单 4 展示了 Delete 按钮单击事件在 Java
代码中是如何处理的:


清单 4. JavaScript
方法调用

protected JavaScriptObject grid = null;   

...

public void onload(){
if(grid == null){
grid = init(...);
}
}

public void onDeleteButtonClick(){
delete(grid, getCurrentRow(grid));
}


public native void delete(JavaScriptObject obj, int index) /*-{

try{
obj.deleteRow(index);
}
catch(e){
$wnd.alert(e.description);
}

}-*/;

public native int getCurrentRow(JavaScriptObject obj) /*-{

try{
return obj.getCurrentRow();
}
catch(e){
$wnd.alert(e.description);
}

return -1;

}-*/;

protected JavaScriptObject grid = null;

...

public void onload(){
if(grid == null){
grid = init(...);
}
}

public void onDeleteButtonClick(){
delete(grid, getCurrentRow(grid));
}


public native void delete(JavaScriptObject obj, int index) /*-{

try{
obj.deleteRow(index);
}
catch(e){
$wnd.alert(e.description);
}

}-*/;

public native int getCurrentRow(JavaScriptObject obj) /*-{

try{
return obj.getCurrentRow();
}
catch(e){
$wnd.alert(e.description);
}

return -1;

}-*/;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值