GWT Developer's Guide随记

比Getting Started介绍的更详细一下

HTML Host Pages----用于加载GWT程序的html页面上的结构

<meta name='gwt:property' content='locale=en_UK'>
用于设置GWT语言

<link rel="stylesheet" href="Calendar.css">
GWT程序需要用的样式

<script language="javascript" src="calendar/calendar.nocache.js"></script>
用于加载主程序

<iframe src="javascript:''" id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
用于提供历史记录的支持

在HTML元素中使用id进行元素选择,然后进行添加
RootPanel.get("slot1").add(button); //

一些目录需要注意的东西
DynaTable/war/WEB-INF/classes 需要将IDE生成的代码指向该目录
DynaTable/war/WEB-INF/lib 需要将gwt-servlet.jar 放置在该目录

GWT.getModuleBaseURL() 常用于获取module所在的web路径

在xml文件中,可以使用 <set-property name="user.agent" value="ie6" /> 设置需要的属性

读取多个module在一个html页面中的方法有两种,
1:使用多个不同的xml,然后使用多个<script>进行载入到html中
2:使用一个顶级的module,include包含多个需要载入的module,然后添加到页面中(推荐)
使用inherits 进行包含

XML 元素说明
<inherits name="logical-module-name" /> module类名
<entry-point class="classname" /> module类所在路径
<source path="path" /> 带默认值
<public path="path" /> 带默认值
<servlet path="url-path" class="classname" /> 用于GWT RPC
<script src="js-url" /> 带默认值
<stylesheet src="css-url" /> 带默认值
<extend-property name="client-property-name" values="comma-separated-values" /> 可用于国际化

还有一些标签用于不同浏览器的编译
<replace-with class="com.google.gwt.user.client.ui.impl.FocusImplIE6">
<when-type-is class="com.google.gwt.user.client.ui.impl.FocusImpl" />
<any>
<when-property-is name="user.agent" value="ie6" />
</any>
</replace-with>

常用的GWT module,需要手动inherit到xml中.

User---包含了GWT核心的功能,包括了widgets and panels等
HTTP---底层的http通信类库
JSON---JSON创建和转换
JUnit--Junit测试框架
XML-- xml创建和转换

其他的三种用于皮肤的module
chrome,dark,standard

使用的例子
<inherits name="com.google.gwt.junit.JUnit"/>

载入自定义的js和css,这样就不需要手动维护html的标签
<script src="_js-url_"/>
<stylesheet src="_css-url_"/>

客户端 java类---用于自动转换成js类,继承自EntryPoint Class
主要方法为onModuleLoad()

GWT历史机制---用于控制后退和前进按钮
GWT's history mechanism

底层就是添加指定的url到浏览器的历史记录中去,(#xx)
在页面中使用<iframe src=...>进行启用

使用History类进行控制
History.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String historyToken = event.getValue();

添加的方式
History.newItem("page" + event.getSelectedItem());

数字与日期的格式化
Number and Date Formatting in GWT

需要加载指定的module
<inherits name="com.google.gwt.i18n.I18N"/>

Number Format的例子
1: NumberFormat fmt = NumberFormat.getDecimalFormat();
double value = 12345.6789;
String formatted = fmt.format(value);

2: double value = NumberFormat.getDecimalFormat().parse("12345.6789");

3: double value = 12345.6789;
String formatted = NumberFormat.getScientificFormat().format(value);

4: String formatted = NumberFormat.getFormat("000000.000000").format(value)

可以用自定义的模式进行代替
NumberFormat.getFormat(pattern). 这个方法需要带参数

DateTimeFormat提供了多种内置的格式进行格式化操作
如:DateTimeFormat.getShortDateFormat().format(today)

Timer的使用,用于生成需要定时调用方法
Timer timer = new Timer() {
public void run() {
Window.alert ("Timer expired!");
}
};

// Execute the timer to expire 2 seconds in the future
timer.schedule(2000); //毫秒

time的另外个方法scheduleRepeating(500),用于快速的循环

DeferredCommand对象,用于添加一些命令对象---具体用途未知
DeferredCommand.addCommand()


JSON格式的使用
<inherits name="com.google.gwt.json.JSON" />

主要包括JSONValue JSONObject JSONArray 等对象
JSONValue is the superclass of all JSON types
JSONObject has get(String) and put(String, JSONValue) methods
JSONArray has corresponding methods named get(int) and set(int, JSONValue).

XML格式的使用 Working with XML
<inherits name="com.google.gwt.xml.XML" />

1:加载字符串
Document messageDom = XMLParser.parse(messageXml);
获取值的方式
Node fromNode = messageDom.getElementsByTagName("from").item(0);
String from = ((Element)fromNode).getAttribute("displayName");
String subject = messageDom.getElementsByTagName("subject").item(0).getFirstChild

().getNodeValue();
Text bodyNode = (Text)messageDom.getElementsByTagName("body").item(0).getFirstChild();
String body = bodyNode.getData();

主要包含了四种元素
Element,Text,Comment,Attr

JSNI的使用
Writing Native JavaScript Methods
使用的格式如下

public static native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
注意static,native关键字,以及/*-{}-*/的使用
该类型方法在java代码时,可能会出现错误,不过在web运行时,将会正常

本地方法中调用java方法
[instance-expr.]@class-name::method-name(param-signature)(arguments)

构建一个对象的方式
new TopLevel() becomes @pkg.TopLevel::new()()

访问java对象的方法
// Read instance field on this
var val = this.@com.google.gwt.examples.JSNIExample::myInstanceField;

// Write instance field on x
x.@com.google.gwt.examples.JSNIExample::myInstanceField = val + " and stuff";

通过继承JavaScriptObject 可以创建自己的Js对象,以json的形式
在java中创建访问的方式,
public final native String getFirstName() /*-{ return this.FirstName; }-*/;
public final native String getLastName() /*-{ return this.LastName; }-*/;

对象格式如下
{ { "FirstName" : "Emily", "LastName" : "Rudnick" },{....}}

$wnd 用于在native方法中获取dom对象的引用
$wnd.alert();

开发过程中会使用Hosted Mode,使用内置的服务器与浏览器

测试时候,使用 GWT.log("User Pressed a button.", null); 记录信息在内置服务器上,
用于进行调试

Web Mode 需要编译后.才可以在普通的浏览器中进行访问


了解布局
Understanding Layout

常见的容器
RootPanel--顶级容器,默认为body,可以使用RootPanel.get(String).来获取指定的html元素,空为body

CellPanel--为其他布局的抽象父类

DockPanel 东西南北的方向布局 ock.add(new HTML("This is the west component"), DockPanel.WEST);
HorizontalPanel 横向布局
VerticalPanel 竖向布局

TabPanel tab标签式容器
HTML moreInfo = new HTML("Tabs are highly customizable using CSS");
tabPanel.add(moreInfo, "More Info");
可以add添加字符串,组件,容器

可以移动大小的panel,通过鼠标自由控制大小
Horizontal and Vertical Split panels
如:VerticalSplitPanel vSplit = new VerticalSplitPanel();
vSplit.setSize("500px", "350px");
vSplit.setSplitPosition("30%");

其他Panels容器
FlowPanel
HTMLPanel
PopupPanel
Grid
FlexTable
AbsolutePanel

大小设置的方法,因为值设置成css,需要带px等单位,所以值均为字符串
常用的方法有 setWidth(), setHeight(), and setSize().

常用组件,用于提供交互
Widgets

Button 按钮
TextBox 单行输入框
Tree 树形菜单
RichTextArea 富编辑器


自定义组件

可以通过继承Composite 的内部类,用于实现现成组件的拼装成自定义组件,可以包含panel与widget

可以通过GWT提供的DOM类操作DOM元素

访问的方法如:
private HTML htmlWidget;
DOM.setStyleAttribute(htmlWidget.getElement(), "backgroundColor", "#fffe80")

也可以使用其他的setStylePrimaryName() or setStyleName() 方法

获取指定id的元素 ,Element类型
Element elt = DOM.getElementById("..")
获取元素的属性
String href = DOM.getElementProperty(element, "href")

也可以使用提供的浏览器事件支持
DOM.addEventPreview(....) //较复杂

事件监听的方式,常用的有两种
匿名事件监听器对象
Button b = new Button("Click Me");
b.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// handle the click event
}
});

class类本身实现监听器接口implements ClickHandler
b1.addClickHandler(this);进行注册,然后实现指定的方法

样式的使用
Applying Style
GWT使用的还是传统的dom模型,可以方便进行样式修改

如: 设置指定元素的id属性
Button b = new Button();
DOM.setElementAttribute(b.getElement(), "id", "my-button-id")

也可以直接使用link的样式载入样式
<link rel="stylesheet" href="mystyles.css" type="text/css"/>

也可以在xml配置中,使用 <stylesheet>加载css文件,xml的配置,更方便组件的重用

注意:css文件的名称不能重复

打包图片:用于将多个小图片,打包成一个文件进行下载,减少下载所需要的时间
ImageBundles

相同文件名,不同扩展名的情况下,会优先考虑png

实现的方法:通过继承ImageBundle,然后实现不同的方法,根据方法不同的名称,读取不同的图片

/**
* Would match the file 'open_file_icon.gif' located in the same
* package as this type.
*
* @gwt.resource open_file_icon.gif
*/
public AbstractImagePrototype openFileIcon();

/**
* Would match the file 'new_file_icon.png', 'new_file_icon.gif', or
* 'new_file_icon.png' located in the same package as this type.
*/
public AbstractImagePrototype new_file_icon();

/**
* Would match the file 'savefile.gif' located in the package
* 'com.mycompany.mygwtapp.icons', provided that this package is part
* of the module's classpath.
*
* @gwt.resource com/mycompany/mygwtapp/icons/savefile.gif
*/
public AbstractImagePrototype saveFileIcon();

接口方法的命名规则: 文件名+Icon(),如果文件名中包含了_,那么可以匹配全名

使用的方法
WordProcessorImageBundle wpImageBundle = (WordProcessorImageBundle) GWT.create

(WordProcessorImageBundle.class);
HorizontalPanel tbPanel = new HorizontalPanel();
tbPanel.add(wpImageBundle.new_file_icon().createImage());
tbPanel.add(wpImageBundle.openFileIcon().createImage());
tbPanel.add(wpImageBundle.saveFileIcon().createImage())

可以通过接口的重载方法,进行国际化操作,类名后带_cn等,与下面了中配置有关

GWT国际化功能,提供了三种可使用的方法
Static string internationalization 静态字符串
Dynamic string internationalization 动态字符串
Extending or implementing Localizable 继承或者实现本地化,Localizable为一个类

在xml配置中需要载入
<inherits name="com.google.gwt.i18n.I18N"/>,在1.5以上,user module中已经包含了该module,可以选择性
加载


Static String Internationalization ---使用java的properties资源文件

使用方式:也是用接口继承接口的方式,其中属性使用接口的方法进行包装
public interface MyConstants extends Constants {
String helloWorld();
String goodbyeWorld();
}

properties资源文件的命名与类名必须有关联,使用_en等进行区分.

在类中使用的方式为,均为GWT.create的静态方法
public void useMyConstants() {
MyConstants myConstants = (MyConstants) GWT.create(MyConstants.class);
Window.alert(myConstants.helloWorld());
}

其他方式---{0}带参数形式,资源文件定义与静态相同
Using the Messages Interface

public interface ErrorMessages extends Messages {
String permissionDenied(int errorCode, String username);
}
ErrorMessages msgs = GWT.create(ErrorMessages.class)

void permissionDenied(int errorVal, String loginId) {
Window.alert(msgs.permissionDenied(errorVal, loginId));
}

使用方式上,比静态的多一个步骤,使用中间对象进行结果的生成. 需要继承Message接口,注意
字符串中的{}数量需要与接口方法数量中的参数数量一致


动态方式
Dynamic String Internationalization

使用Dictionary class类

添加一种本地化支持,需要在xml中进行配置
<extend-property name="locale" values="fr_FR"/>

使用html代码选择区域的方式
<meta name="gwt:property" content="locale=ja_JP">
也可以直接使用超链接的方式
http://www.example.org/myapp.html?locale=fr_CA

注意资源文件需要与module同一目录下,并且编码需要均为utf-8


ARIA和Accessibility Support 这一块比较复杂,稍后再研究


与服务器进行沟通
Communicating with a Server

GWT RPC
Remote Procedure Calls

创建GWT RPC连接的三个步骤
1:创建接口继承RemoteServive接口,并且创建自定义的RPC接口方法---服务接口

2:创建指定Servlet服务,通过继承RemoteServiceServlet,并且实现1中创建的接口,并实现自定义方法

3:创建异步接口,与类名,方法名,参数相关的方式去创建接口方法,然后使用AsyncCallback<String> arg的方

式,给接口方法添加参数,用于回调函数.注意方法返回void

注意命名规范
服务接口与异步接口中类名必须符合规范
MyService ---实现的Servlet命名为MyServiceImpl
MyServiceAsync --异步接口

在定义异步接口的方法时,必须保证方法名,参数名一致的情况下,在参数部分再添加一个AsyncCallback参数

远程的Servlet需要进行配置注解,以及需要在web.xml中进行配置Servlet,注意注解值需要和url-pattern一样
@RemoteServiceRelativePath("myService").

<servlet>
<servlet-name>myServiceImpl</servlet-name>
<servlet-class>
com.example.foo.server.MyServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServiceImpl</servlet-name>
<url-pattern>/com.example.foo.Foo/myService</url-pattern>
</servlet-mapping>

如果module在xml文件中使用了别名(rename-to attribute),那么可以不用包名

特别注意:需要将gwt-servlet.jar拷贝到web-inf/lib目录下,以及将java输出目录为/WEB-INF/classes.

编写客户端代码进行调用RPC
创建的方式还是为GWT.create()

1:声明一个RPC接口对象的实例
MyEmailServiceAsync emailService = (MyEmailServiceAsync) GWT.create(MyEmailService.class);

2:编写对应回调方法的实例

AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Void result) {
// do some UI stuff to show success
}

public void onFailure(Throwable caught) {
// do some UI stuff to show failure
}
};

3:调用接口实例的方法
emailService.emptyMyInbox(fUsername, fPassword, callback);

也可以直接使用参数中加入匿名实例的方式进行调用

使用集合时,需要使用@gwt.typeArgs <java.lang.String> 注释指明返回结果,参数集合类型

/**
* The first annotation indicates that the parameter named 'c' is a List
* that will only contain Integer objects. The second annotation
* indicates that the returned List will only contain String objects
* (notice there is no need for a name, since it is a return value).
*
* @gwt.typeArgs c <java.lang.Integer>
* @gwt.typeArgs <java.lang.String>
*/
List reverseListAndConvertToStrings(List c);

监听RPC中的异常---包括 Checked Exceptions 和Unexpected Exceptions


手动发起异步的http请求---可用于json
Using HTTP in GWT

1:需要在xml文件加载<inherits name="com.google.gwt.http.HTTP" />

2:RequestBuilder是用于HTTP请求的核心类

RequestBuilder使用的方法
1:创建一个对象的实例
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
构造方法的参数为:请求方式,URL地址...(URL.encode()用于过滤URL)

2:创建对应的监听函数对象 Request对象
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Couldn't connect to server (could be timeout, SOP violation, etc.)
} //错误监听

public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
} else {
// Handle the error. Can get the status text from response.getStatusText()
}
} //接收到返回信息
});

接收后可以使用Response.getText(),来获取内容.如果是xml或者json可以使用类库进行转换


在RPC中调用时,如果有返回值,可以使用onSuccess()方法的重载来实现
calService.getPeople(startRow, maxRows, new AsyncCallback<Person[]>() {

// When the RPC returns, this code will be called if the RPC fails
public void onFailure(Throwable caught) {
statusLabel.setText("Query failed: " + caught.getMessage());
acceptor.failed(caught);
}

// When the RPC returns, this code is called if the RPC succeeds
public void onSuccess(Person[] result) {
lastStartRow = startRow;
lastMaxRows = maxRows;
lastPeople = result;
pushResults(acceptor, startRow, result);
statusLabel.setText("Query reutrned " + result.length + " rows.");
}
});


使用Junit测试GWT
Unit Testing With JUnit

可以使用junitCreator自动创建测试用例,也可以手动进行创建

手动创建的过程
1:在module所在目录创建一个继承GWTTestCase的子类
2:需要加载Junit包

还提供一种Benchmark用于提供图表的测试

....余下较麻烦,稍后再看
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值