[转载]借助传统方法使用高级 GWT 控件

借助传统方法使用高级 GWT 控件


2007 年 5 月 28 日

Google Web Toolkit (GWT) 提供了很多库和工具让您可以在 Java™ 编程语言中开发 Ajax 应用程序。但是 GWT 的 UI 控件(小部件)标准库并不提供现代企业应用程序所需的高级特性。本文意在展示可以弥补这一不足的一些技巧。通过本文,您可以学习如何将流行的 JavaScript 网格组件集成到 GWT 应用程序中,从而通过较为简单的编码为 GWT 控件提供高级功能。

各种开源 Ajax 框架和商业工具箱都试图通过隐藏复杂性以及隐藏底层的 JavaScript 和文档对象模型(Document Object Model,DOM)操作的负担来简化 Ajax 开发。这样做的确可以减少开发时间,但如果想利用它们来实现高级功能,常常需要具备一定的 JavaScript 专业知识和技能,这些技能和知识往往不易习得。所幸的是 Google 现已提出一种创新技术,将 Ajax 应用程序开发带到了一个全新的阶段。GWT 是用途广泛的 API 和工具集,可以让您在 Java 代码中创建动态 Web 应用程序。GWT 是通过代码生成实现上述目标的:GWT 编译器可从客户端 Java 代码生成跨浏览器兼容的 JavaScript。

不幸的是,Google 提供的标准 UI 控件(小部件)的功能集十分有限,而且在大多数情况下尚不能满足现代企业级应用程序的需求。虽然您可以利用一组定制属性扩展基本的 GWT 控件,但这种方法常常会需要很多的开发工作。所幸的是,现在已经有了一种简便的方法。本文通过一个示例应用程序(参见 下载)展示了如何将流行的 ActiveWidgets JavaScript 网格组件集成到 GWT 应用程序中,从而通过较为简单的编码获得高级功能。

动态 Web UI 控件

JavaScript Web UI 控件旨在通过在浏览器内部动态生成 HTML 来消除服务器往返。服务器会将动态组件的数据结构和 JavaScript 代码添加到页面内容中,而非发送静态 HTML。在页面加载阶段,浏览器运行这些脚本来创建活动组件,配置这些组件,然后将每个组件生成的 HTML 字符串插入到页面的适当位置。就这一点而言,JavaScript 组件代码与此页面上的 HTML 片段是相联系的。组件可管理用户交互、根据数据更改升级 HTML 并提供一个 API 来处理其内容、行为和可视样式。

用 Java 代码编写并在 JavaScript 内编译的 GWT 控件与此类似。这就让 GWT 控件能够与商业控件及 JavaScript 库完全兼容。JavaScript 库则更为成熟,并能提供更全面的跨浏览器高级功能,比如智能滚动、列大小重置、排序、动态加载和针对大型数据集的分页。GWT 的开放架构让您能够将商业控件及传统 JavaScript 库与新应用程序相集成,这样一来,工作的重点就是解决企业面临的挑战和问题,而不是重头开始重复创建。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


自动资源注入

本文随带的示例 GWT 应用程序(参见 下载 部分)使用了一个简单的 GWT 特性,即 自动资源注入。 项目模块包括对外部 JavaScript 和层叠样式表 (CSS) 文件的引用,这样,当模块自身在加载时,外部 JavaScript 和层叠样式表 (CSS) 文件也可以自动加载。清单 1 显示了在示例应用程序的模块定义 XML 文件 (GridDemo.gwt.xml)中的声明,该声明可实现此目的:


清单 1. GWT 模块定义
                











JavaScript 文件和样式表的注入是一种极为方便的手段,可用来自动关联外部文件和 GWT 模块。所有注入了的资源均应放在 commycompanyprojectpublic 目录中,该目录定义了 GWT Web 服务器的根。

AW.Grid.Control.create 是脚本就绪函数,它在网格控件脚本将被初始化时,返回 true。就绪函数的作用是要清楚地断定脚本完全被加载以便 GWT 代码可以使用此脚本,并要确保引用标识符可用。在清单 1 所示的示例中,AW.Grid.Control.create 函数的存在表明脚本已就绪。此函数是控件库的一部分并可作为外部资源,它必须以 $wnd 为前缀。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


救难的 JavaScript Native Interface

JavaScript 网格控件本身的集成基于 JavaScript Native Interface (JSNI) 的 GWT 实现,JSNI 功能强大,您可以在 Java 源代码中加入 JavaScript 代码。清单 2 展示了 JavaScript 网格控件是如何通过 JSNI 进行实例化和初始化的:


清单 2. 网格控件的初始化(片段)
                

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

// 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 数组,以便于用数据填充数组,如清单 3 所示:


清单 3. Java 到 JavaScript 数组的转换
                
public static JavaScriptObject arrayConvert(String[] array) {
JavaScriptObject result = newJSArray(array.length);
for (int i = 0; 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;
}-*/;


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


处理事件

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


清单 4. 从 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);
}
}-*/;

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

  • instance-expr 在调用实例方法时必须使用,在调用静态方法时必须去掉。
  • class-name 是类的完全限定名,方法在此类(或其子类)中声明。
  • param-signature 是这里指定的内部 Java 方法签名,但无此方法返回类型的尾随签名(因为不需要选择重载)。
  • arguments 是实际要传递给被调方法的参数列表。

blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


使用 JavaScript 控件 API

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


清单 5. 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;

}-*/;

在清单 5 中,Java 事件处理程序调用 JavaScript 控件 API 方法。这充分展示了与控件实例交互的能力。您可以为所有的 JavaScript 控件 API 定义类似的 Java 包装程序,并使其对 GWT 可用。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


运行时配置

演示的应用程序要求必须在系统上安装 GWT SDK。为了运行实例代码,只需将下载的带有源代码和编译脚本的归档文件解压缩到 GWT SDK 发布目录的示例文件夹。如果可以运行 GWT 示例,就可以利用如下命令(在 Windows 平台上)启动示例应用程序:

                your_local_pathgwt-windows-1.3.3samplesGridDemoGridDemo-shell.cmd

示例 GWT 应用程序演示了集成的商业 JavaScript 网格组件,该组件由 ActiveWidgets 开发,可在该公司的站点下载评估版(参阅 参考资料)。图 1 给出了对应的结果:


图 1. 示例 GWT 应用程序中的高级网格控件
使用中的网格控件

示例应用程序归档文件包含了除 GWT 外的所有必需的库。我已经用所有的主流 GWT 发布版本测试过(包括 1.3 版本)。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


结束语

本 文通过一个示例展示了如何将传统的 JavaScript 网格控件与 GWT 应用程序进行集成。您可以将同样的方法应用于市面上可用的其他高级控件。除了商业 JavaScript 控件外,您还可以参考 Yahoo! User Interface Library,内含大量开源 JavaScript 实用工具和控件,可用来借助 DOM 脚本、DHTML 和 Ajax(参阅 参考资料)构建高交互性的 Web 应用程序。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130067/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130067/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值