职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 972|回复: 16

如何使用GWT-Ext 进行RIA开发

  [复制链接]
broken 发表于 2011-7-17 09:49 | 显示全部楼层 |阅读模式
个人觉得,GWT的客户端表现并不是Gwt这个项目最关心的方向,所以要做出表现丰富的界面,要花去不少心思,当你为做一个“可排序的Grid”被搞得焦头烂额时,想想EXT,DOJO,只有艳羡地分了。
GWT-Ext 是sanjiv.jivan为了丰富GWT的客户端表现而贡献的开源项目。项目结合了当前客户端表现和用户体验都相当完善的Ext,提供了一种操作性很强的RIA开发方式。
作者应该花了不少心思在项目上,更新很频繁,大概不到1个月就有新的版本问世,目前项目的版本为GWT-Ext 0.9.3,是 Ext 1.1.1 和 GWT 1.4 Final 的结合,在 Ext 方面实现了大多数常用的控件,如Grid、Tree、Form、TabPanel等等。具体实现效果可以查看项目中的 Showcase Demo 。
以下结合一个例子来演示一下如何使用GWT-Ext 做实际开发。
一定要认真阅读项目中的 GettingStarted ,下面起初的几段其实就是该文的中文译本。
一、在Gwt项目中集成GWT-Ext
1.下载gwtext-0.9.3.zip,之后解压,将其中的 gwtext.jar 附加到当前GWT项目(Tree)的BuildPath中。
2.下载ext-1.1.1.zip (注意:暂时还不支持最新的2.0版本),将的ext-all.js、ext-core.js以及resources和adapter两个目录拷贝到module的public中的js/ext位置。对Ext熟悉的话,可以只拷贝需要的文件而不必载入所有的资源文件。
3.修改GWT项目中module的html页面,添加Ext资源,修改后的html页面可能是这样:
html代码
<html>   
    <head>   
        
        <title>Wrapper HTML for Treetitle>   
   
        <meta name='gwt:module' content='showcase.Tree'/>   
   
        <link type="text/css" rel='stylesheet' href='Tree.css'/>   
            
        <link rel="stylesheet" type="text/css" href="js/ext/resources/css/ext-all.css"/>   
        <link rel="stylesheet" type="text/css" href="js/ext/resources/css/xtheme-aero.css" />   
        <script type="text/javascript" src="js/ext/adapter/yui/yui-utilities.js">script>   
        <script type="text/javascript" src="js/ext/adapter/yui/ext-yui-adapter.js">script>   
        <script type="text/javascript" src="js/ext/ext-all.js">script>   
            
    head>   
   
    <body>   
   
        <script language="javascript" src="gwt.js">script>   
   
        <iframe id="__gwt_historyFrame" style="width:0;height:0;border:0">iframe>   
   
    body>   
html>   

4.编辑项目的Tree.gwt.xml文件,添加以下
xml 代码
<inherits name='com.gwtext.GwtExt'/>   
通过以上步骤,你就可以写接近Ext功能的客户端界面了,同时也具有了Gwt的各种开发优势了,比如Java方式开发,清晰的RPC(这点尤其是在客户端需要获取服务器端数据信息时尤其方便)等等。
二、实例
下面我们就编写Showcase Demo 中的Tree节点下的Two Trees Drag & Drop,例子实现的是两个Tree中节点的任意拖放(再次感叹Ext的丰富表现)。
Tree.java代码如下,可直接拷贝到查看效果。
java 代码
package showcase.client;   
   
import com.google.gwt.core.client.EntryPoint;   
import com.google.gwt.user.client.ui.HorizontalPanel;   
import com.google.gwt.user.client.ui.RootPanel;   
import com.gwtext.client.widgets.tree.AsyncTreeNode;   
import com.gwtext.client.widgets.tree.AsyncTreeNodeConfig;   
import com.gwtext.client.widgets.tree.TreePanel;   
import com.gwtext.client.widgets.tree.TreeNode;   
import com.gwtext.client.widgets.tree.DropNodeCallback;   
import com.gwtext.client.widgets.tree.TreePanelConfig;   
import com.gwtext.client.widgets.tree.XMLTreeLoader;   
import com.gwtext.client.widgets.tree.XMLTreeLoaderConfig;   
import com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter;   
import com.gwtext.client.dd.*;   
/**   
* Entry point classes define onModuleLoad().   
*/   
public class Tree implements EntryPoint {   
    public void onModuleLoad() {   
        RootPanel rootPanel = RootPanel.get();   
        HorizontalPanel horizontalPanel = new HorizontalPanel();   
        rootPanel.add(horizontalPanel);   
//      create source countried tree   
        final TreePanel treePanel = new TreePanel("coutries-grouped", new TreePanelConfig() {   
            {   
                setAnimate(true);   
                setEnableDD(true);   
                setContainerScroll(true);   
                setRootVisible(true);   
            }   
        });   
   
        final XMLTreeLoader loader = new XMLTreeLoader(new XMLTreeLoaderConfig() {   
            {   
                setDataUrl("countries-grouped.xml");   
                setMethod("get");   
                setRootTag("countries");   
                setFolderTitleMapping("@title");   
                setFolderTag("continent");   
                setLeafTitleMapping("@title");   
                setLeafTag("country");   
                setQtipMapping("@qtip");   
                setIconMapping("@icon");   
            }   
        });   
   
        AsyncTreeNode root = new AsyncTreeNode("Countries", new AsyncTreeNodeConfig() {   
            {   
                setLoader(loader);   
            }   
        });   
   
        treePanel.setRootNode(root);   
        treePanel.render();   
   
        root.expand();   
        treePanel.expandAll();   
   
//      create target vacation tree   
        final TreePanel tripTreePanel = new TreePanel("vacation-tree", new TreePanelConfig() {   
            {   
                setAnimate(true);   
                setEnableDD(true);   
                setContainerScroll(true);   
                setRootVisible(true);   
            }   
        });   
   
        final XMLTreeLoader tripLoader = new XMLTreeLoader(new XMLTreeLoaderConfig() {   
            {   
                setDataUrl("trip.xml");   
                setMethod("get");   
                setRootTag("vacations");   
                setFolderIdMapping("@title");   
                setFolderTag("trip");   
                setQtipMapping("@qtip");   
                setIconMapping("@icon");   
                setAttributeMappings(new String[]{"@trip"});   
            }   
        });   
   
        AsyncTreeNode tripRoot = new AsyncTreeNode("Places to Visit", new AsyncTreeNodeConfig() {   
            {   
                setLoader(tripLoader);   
            }   
        });   
   
        tripTreePanel.setRootNode(tripRoot);   
        tripTreePanel.render();   
   
        tripRoot.expand();   
        tripTreePanel.expandAll();   
   
//      add trip tree listener that handles move / copy logic   
        tripTreePanel.addTreePanelListener(new TreePanelListenerAdapter() {   
            public boolean doBeforeNodeDrop(TreePanel treePanel, TreeNode target, String point, DragDrop source, TreeNode dropNode, DropNodeCallback dropDropNodeCallback) {   
                if("true".equals(target.getAttribute("trip"))) {   
                }   
                return true;   
            }   
        });   
        horizontalPanel.add(treePanel);   
        horizontalPanel.add(tripTreePanel);   
    }   
}   
注意:例子中需要的两个数据文件需放置于public目录,熟悉Ext的应该很清楚。
编译后执行的效果如下图:
以上示例只是将该种开发方式的流程顺了一下,窥一斑以示全貌,Ext各种丰富的表现都可以实现。闲下来,再写一下将数据提供(其实就是一些多维数据而已)方式改为RPC,这样开发流程就完整了。
可以下载示例程序运行一下,证明我没骗你[img]
愚人 发表于 2011-7-17 09:49 | 显示全部楼层
呵呵,使用gwt就尽量不要再粘上其他js的东东,当然那个gwt.js例外。
如果楼主觉得extjs不错的话,倒是推荐使用mygwt这个在extjs上构建的gwt framework,它将extjs的组件完全用gwt实现,而不是使用extjs的js脚本

爱车车 发表于 2011-7-17 09:50 | 显示全部楼层
@stone
mygwt同样是一个不错的GWT扩展,只是发展的时间短了些,功能还不是很多,希望能有个好的势头,毕竟不需要JSObject来连接了,结构简单了许多。

jinchang 发表于 2011-7-17 09:50 | 显示全部楼层
还是比较喜欢mygwt,毕竟它是gwt的扩展

有烟没火 发表于 2011-7-17 09:50 | 显示全部楼层
编译是成功的,但是shell的时候会报错,因为找不到GWT.ext.xml,jar也放进相应路径了,inherits也写了


北大青鸟 发表于 2011-7-17 09:50 | 显示全部楼层
找不到GWT.ext.xml,jar也放进相应路径了,inherits也写了
不知道怎么回事

木已 发表于 2011-7-17 09:50 | 显示全部楼层
我也是这样,为什么?好奇怪
找不到GWT.ext.xml,jar也放进相应路径了,inherits也写了
不知道怎么回事

醉倚西风 发表于 2011-7-17 09:50 | 显示全部楼层
我也比较喜欢gwt本身

天上智喜 发表于 2011-7-17 09:51 | 显示全部楼层
@zhangcheng
感觉GWT还有一段路要走,现在还不能得到普遍的接受

shmilyyu 发表于 2011-7-17 09:51 | 显示全部楼层
sheva.wen
@zhangcheng
感觉GWT还有一段路要走,现在还不能得到普遍的接受


对js实现的模拟桌面效果的框架怕怕 狂耗内存和cpu 老机器跑起来很吃力 不利于推广


秋秋 发表于 2011-7-21 11:18 | 显示全部楼层
一个子 没看懂
找不到我 发表于 2011-7-21 11:19 | 显示全部楼层
HOHO~~~~~~
北大青鸟 发表于 2011-7-21 14:45 | 显示全部楼层
哈哈 我支持你
紫衿 发表于 2011-7-24 10:43 | 显示全部楼层
也有啊,前天不是你也到一个很狂的贴里去了吗?
紫衿 发表于 2011-7-29 10:58 | 显示全部楼层
楼猪.重量级人物阿.
醉倚西风 发表于 2011-8-18 13:51 | 显示全部楼层
哈哈~~~相比现在没人在了 吧 哈哈~~~~
能文能武 发表于 2011-8-18 13:51 | 显示全部楼层
你你你你 呵呵~~~~别这样哦.....
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-28 03:20 , Processed in 0.157840 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表