1、GWT开发教程第一章 编码基础在eclipse中添加GWT插件。升级安装源如下:Eclipse 3.5 (Galileo)/plugin/3.5Eclipse 3.4 (Ganymede)/plugin/3.4Eclipse 3.3 (Europa)/plugin/3.3第一节 客户端代码1.1.1 创建入口点新建GWT工程之后将生成的类文件都删除。并删除web.xml中如下的部分: greetServlet com.example.smallgwt.server.GreetingServiceImpl greetServlet /smallgwt/greet 然后观察生成的模块配置文件 !-
2、 - !- - 每一个模块都有一个入口点。这个模块的入口点就是“Smallgwt”类。现在使用eclipse在com.example.smallgwt.client中创建这个类Smallgwt。同时指定接口为com.google.gwt.core.client.EntryPoint。自动生成的代码如下:package com.example.smallgwt.client;import com.google.gwt.core.client.EntryPoint;public class Smallgwt implements EntryPoint Override public void on
3、ModuleLoad() / TODO Auto-generated method stub 入口点类入口点类是整个GWT应用程序的入口,也就是说,GWT应用程序运行时会首先调用这段代码,工程的入口点类在工程模块的标签中指定。在入口点类中必须实现入口点方法onModuleLoad(),这个入口点方法是整个GWT应用程序开始执行的地方。这个方法中主要做的事情是: 创建可视组件 设置事件处理句柄 将可视组件添加到网页上package com.example.smallgwt.client;import com.google.gwt.core.client.EntryPoint;import com
4、.google.gwt.core.client.GWT;import com.google.gwt.event.dom.client.ClickEvent;import com.google.gwt.event.dom.client.ClickHandler;import com.google.gwt.user.client.Window;import com.google.gwt.user.client.ui.Button;import com.google.gwt.user.client.ui.RootPanel;public class Smallgwt implements Entry
5、Point Override public void onModuleLoad() / TODO Auto-generated method stub/创建一个按钮,按钮标题是Click me.创建一个事件接收类,当用户点按钮的时候,这个类的方法被调用 final Button b = new Button(Click me, new ClickHandler() Override public void onClick(ClickEvent event) / TODO Auto-generated method stub/弹出警告窗口,显示Hello, AJAX Window.alert(H
6、ello, AJAX); );/将这个按钮添加到网页上。 RootPanel.get().add(b); GWT.log(Hello World!, null); RootPanel.get(“soltName”).add(widget)。如果get中为空。则得到整个网页,将组件添加到网页上。如果不为空。则将组件添加到get中的名字指定的位置。1.1.2 HTML页面HTML页面和普通的HTML页面没有什么区别,可以使用一切HTML标签。有几个特别的地方如下:1、这个HTML中必须引入下面的JavaScript代码,用来加载GWT工程模块,之后GWT读入模块文件(*.gwt.xml)来查找入口
7、点(EntryPoint)类,整个GWT程序才得以运行。另外,所有GWT的标签都应该出现在这段JavaScript代码之前。下面是在模块中没有定义模块别名的时候使用完整的长名字的情形:这个nocache.js文件位于编译后的www目录下,并且其命名规则为:模块的全路径名.nocache.js2、在HTML的中可以加入下面这个iframe标签,其作用是为GWT提供历史支持,但这个标签是可选的。这里的id属性值必须为“_gwt_historyFrame”。3、如果在MyApplication.java的RootPanel中指定了使用某些id,比如这里的“solt1”和“slot2”,那么在HTML
8、页面中也必须明确指定以这些id命名的HTML标签,否则程序将抛出NullPointerException异常。1.1.3 模块前面提到那段nocache.js代码用来加载GWT工程的模块。Smallgwt.gwt.xml中的内容:!- - GWT模块名都是以.gwt.xml结尾的XML文件,用来配置这个工程,位于工程根目录下。1.1.4 标准GWT工程结构使用标准的GWT工程结构可以有效的区分客户端和服务器端的代码,所以推荐使用标准的GWT工程结构。如下表:包名作用工程的根目录,包含模块XML文件client存放客户端代码server存放服务器端代码public存放静态资源,如.html,.c
9、ss,图片等第二节 Java语言和库的兼容性1.2.1 语言支持GWT支持大部分的Java核心语言的语法和语义,但是还有一些小小的不同。GWT程序的目标语言是JavsScript,所以在开发模式和发布模式运行之间还是有一些需要注意的地方。 内置类型:简单类型(boolean, byte, char, short, int, long, float, 和double),Object, String, arrays,用户定义类等,都是被支持的。只是有点注意。 数学类型:JavaScript中只有64位浮点型。所有的java基本算术类型(除了长整数)在发布模式下都要转换到这个64位浮点数。这就意味着
10、byte、char、short和int等类型的不会象在java中一样溢出。也就是说,这些数据类型的值可以超出合法的取值范围。浮点数运算将作为double运算进行,并且结果的精度将更高。整数除法的执行结果将被四舍五入到整数值。 long类型:Javascript没有64位整数类型。GWT使用两个32位整数类型完成64为整数的模拟。这就有两个问题:首先是性能问题,另外就是JSNI code代码是不支持的。 异常:try, catch, finally和用户定义的异常还是正常支持的,不过Throwable.getStackTrace()是不被发布模式支持的。注意:有几个Java VM中最基本的异常是
11、不会在发布模式中支持的,那就是NullPointerException、 StackOverflowError和OutOfMemoryError。取而代之的是JavaScriptException异常。 断言:在开发模式中断言语句总是不起作用的,因为它和在调试的时候GWT库提供的众多很有帮助的错误检测差的很远。GWT编译器默认移除和忽略所有的断言。但是可以通过为编译器指定-ea标志在发布模式下打开这些断言。 多线程和同步:Javascript解释器是单线程的,所以GWT只是单纯的接收同步的关键字,而不起任何作用。同步相关的方法也不被接收,包括Object.wait()、Object.notif
12、y()和Object.notifyAll()。编译器将忽略同步关键字除非对象关联一个同步方法被调用。 反射(Reflection):为了最大化效率,GWT编译Java源代码到一个整块的script,不支持类的连续动态调入。对这个的优化通常使用反射机制。不管如何,通过类的名字Object.getClass().getName()得到一个类对象是可以的。 Java析构函数(Finalization):JavaScript不支持对象被回收时的析构函数调用,所以GWT在发布模式中不会支持Java析构函数。 精确浮点数:Java语言规范定义浮点数支持,包括单精度和上精度都支持精确浮点(strictf)关
13、键字。GWT不支持这个关键字,不能保证任何精度的浮点运算,所以不要再客户端进行类似的精度要求较高的浮点运算。1.2.2 运行库支持GWT只支持J2SE和J2EE类库的一个小的子集,一个大的完整的集合是不可能被浏览器支持的。要知道那些核心Java运行包被支持,需要查询JRE Emulation Reference。网址是/zh-CN/webtoolkit/doc/latest/RefJreEmulation.html提示:一定要搞清楚那些类是可以转换到客户端代码的。否则会出现很多问题。建议多看这个网页。另外开发模式会帮助你检查那些是可以用的,那些是不可以用的。所以要经常的,尽量早的运行程序。1.
14、2.3 JRE和模拟类的不同GWT模拟类和标准的Java运行时有一些差别: 正则表达式:Java正则表达式的语法和JavaScript正则表达式的语法基本相似。但是还是有一点儿不同,例如:replaceAll和split方法正则表达式。所以使用的时候要注意你的Java正则表达式在JavaScript中要有相同的意义。 串行化:Java的串行化机制有一部分不支持编译到JavaScript,例如动态类的调入和反射。结果是,GWT不支持标准的Java串行化。代之的是GWT提供一个简单的自动对象串行化用于调用服务器端的远程方法。1.2.4 提供的相似功能的类有一些类的功能对虚拟机来说太复杂,所以提供另
15、一个包来提供相似的功能。这有一些本地JRE的功能子集。 com.google.gwt.i18n.client.DateTimeFormat : 支持java.util.DateTimeFormat的子集。 com.google.gwt.i18n.client.NumberFormat : 支持java.util.NumberFormat的子集。 com.google.gwt.user.client.rpc :一个标记类,提供GWT RPC中使用java.io.Serializable。 com.google.gwt.user.client.Timer :一个简单的,浏览器安全的定时器类。这个类
16、提供与java.util.Timer相似的功能,但是更简单,因为是单线程环境的。第三节 历史1.3.1 GWT的历史机制GWT的历史机制和其它Ajax的历史实现是基本一样的,都是RSH (Really Simple History)。基本前提的在url标示符片段中保持跟踪程序的内部状态。这种更新操作不会触发页面的重新调入。这个步骤有一系列的好处: 这种方法是仅有的一个方法可以可靠的控制浏览器的历史。 这种方法可以给用户一个很好的反馈。 这种方法支持收藏夹(也叫书签)机制。也就是说可以创建当前状态的收藏夹,保存它,email它等。1.3.2 历史记号GWT包含一个机制帮助Ajax开发者激活浏览器
17、的历史功能。为了是每一个页面是可以在历史中导航的,程序为每一个页面生成一个唯一的历史标记。一个标记是一个简单的字符串,程序能够分解这个字符串返回一个详细的状态。这个标记将以URL片段(在地址栏中,在#的后面)的形式保存在浏览器的历史中。这个片段将在用户点击回退和前进的时候返回给程序。例如,一个名字为page1的历史标记添加到了URL中,如下所示:/HistoryExample.html#page1当程序要将一个历史标记添加到浏览器的历史栈中的时候,只需要简单的调用History.newItem(token)。当用户点击回退的时候,会调用任意设置了History.addValueChangeHa
18、ndler()事件句柄的对象的相关方法。1.3.3 历史实例要使用GWT的历史支持,你必须首先嵌入一个iframe到host HTML页面中。然后,在GWT程序中完成下面的步骤:当想要使用历史事件的时候添加历史标记的历史栈。创建一个实现了ValueChangeHandler接口的对象,调用ValueChangeEvent.getValue()解析一个新的标记并改变程序的状态到匹配的那个位置。下面是一个简单的例子演示一个TabPanel中如何在用户选择新的页时添加相应的历史事件。package com.example.smallgwt.client;import com.google.gwt.c
19、ore.client.EntryPoint;import com.google.gwt.core.client.GWT;import com.google.gwt.event.dom.client.ClickEvent;import com.google.gwt.event.dom.client.ClickHandler;import com.google.gwt.event.logical.shared.SelectionEvent;import com.google.gwt.event.logical.shared.SelectionHandler;import com.google.gw
20、t.event.logical.shared.ValueChangeEvent;import com.google.gwt.event.logical.shared.ValueChangeHandler;import com.google.gwt.user.client.History;import com.google.gwt.user.client.Window;import com.google.gwt.user.client.ui.Button;import com.google.gwt.user.client.ui.HTML;import com.google.gwt.user.cl
21、ient.ui.RootPanel;import com.google.gwt.user.client.ui.TabPanel;public class Smallgwt implements EntryPoint TabPanel tabPanel; /* * This is the entry point method. */ public void onModuleLoad() tabPanel = new TabPanel(); tabPanel.add(new HTML(Page 0 Content: Llamas), Page 0 ); tabPanel.add(new HTML(
22、Page 1 Content: Alpacas), Page 1 ); tabPanel.add(new HTML(Page 2 Content: Camels), Page 2 ); tabPanel.addSelectionHandler(new SelectionHandler() public void onSelection(SelectionEvent event) / TODO Auto-generated method stub History.newItem(page + event.getSelectedItem(); ); History.addValueChangeHa
23、ndler(new ValueChangeHandler() public void onValueChange(ValueChangeEvent event) String historyToken = event.getValue(); / Parse the history token try if (historyToken.substring(0, 4).equals(page) String tabIndexToken = historyToken.substring(4, 5); int tabIndex = Integer.parseInt(tabIndexToken); /
24、Select the specified tab panel tabPanel.selectTab(tabIndex); else tabPanel.selectTab(0); catch (IndexOutOfBoundsException e) tabPanel.selectTab(0); ); tabPanel.selectTab(0); RootPanel.get().add(tabPanel); 1.3.4 超链接组件(Hyperlink Widgets)一个程序当中超链接可以很容易的整合历史支持。GWT的超链接(Hyperlink)组件看起来就是普通的HTML锚。可以将这个锚关联一个历史标记,当点击这个锚的时候历史标记就自动的添加到浏览器的历史栈中。History.newItem(token)调用将是自动的。观察上面的例子,程序添加形如“page(n)”的历史标记。在这个程序中基本可以完成任务。不过更复杂的情况就无法完成了。所以推荐象下面一样使用历史标记:page=;session=可以告诉程序到第几页去同时sessionname
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1