GWT 学习总结
?????? 最近領導讓研究GWT,學習這個AJAX框架,看看對我們的系統能否集成進去,花了1周多時間研究啊。照葫蘆畫瓢,做了一個Demo,對這個框架也有了一個初步的認識, 感覺就是一個Web的 SWT。
? ?
GWT?學習筆記
?
?
一、用戶界面(User Interface)
在開發GWT應用程序時要注意一件事,它的開發非常像Swing,SWT,甚至是VB。你創建按鈕、列表、表單,經事件監聽器與之交互。你進行布局,試著讓它們在一定的屏幕分辨率和屏幕尺寸下看起來更好看。主要的不同之處在于GWT應用是顯示在Web瀏覽器上,它涉及到HTML頁面。
傳統的Web應用程序是以一系列的HTML頁面為結構,并以之導航的。
1、與HTML的聯系
每一個GWT應用程序里面都存在一個HTML頁面,它可以是一個靜態的頁面,或者是服務器端的頁面如JSP,Struts,Ruby on Rails等。
實際上,MyApp.html存在于public目錄,意味著它將被一字不差的復制到最終的服務器端的部署區域,如果頁面還鏈接著圖片,樣式表等,它們也都會復制到同樣的目錄下。
在HTML頁面代碼的頂部需要meta標簽來聯系GWT組件。
如:<meta name='gwt:module' content='com.xyz.MyApp'>
一個GWT組件是一個客戶端代碼和資源的集合。名為com.mycompany.MyApp的組件被定義到組件文件src/com/mycompany/MyApp.gwt.xml中。
-----------------------------------------------
<module>
? <!-- Inherit the core Web Toolkit stuff. -->
? <inherits name='com.google.gwt.user.User'/>
? <!-- Specify the app entry point class. -->
? <entry-point class='com.xyz.client.MyApp'/>
</module>
-----------------------------------------------
在邏輯上,當HTML頁面載入后,GWT查看meta標簽,讀入xml文件并得到類名,在入口點類中開始調用代碼。
2、入口點(Entry Point)
入口點類(MyApp)擴展了入口點接口并提供了一個方法onModuleLoad()。這個方法在構造GWT應用程序用戶界面中起作用。
MyProject/src/com/xyz/client/MyApp.java
-----------------------------------------------
public void onModuleLoad(){
? final Button button=new Button("Click me");
? final Label label=new Label();
? //...
-----------------------------------------------
上面的腳手架代碼創建了兩個GWT用戶界面元素,一個按鈕和一個標簽。
如果要追溯和瀏覽HTML文件,其代碼底部有兩個占位符用于動態內容:
MyProject/src/com/xyz/public/MyApp.html
-----------------------------------------------
<table align=center>
? <tr>
??? <td id="slot1"></td>
??? <td id="slot2"></td>
? </tr>
</table>
-----------------------------------------------
Java代碼將通過“id=”來引用并填充你創建的按鈕和標簽。
MyProject/src/com/xyz/client/MyApp.java
-----------------------------------------------
RootPanel.get("slot1").add(button);
RootPanel.get("slot2").add(label);
-----------------------------------------------
上面的表定義了怎樣使用小部件在屏幕上布局。
還有一個更好的布局方式是使用面板(Panel)。GWT面板也是一個小部件,它能容納一個或多個小部件并以特殊的方式管理它們。
例如:你可以創建一個水平面板(Horizontal Panel),在其上加入按鈕和標簽,再把該面板加入到RootPanel的頁面。即:
RootPanel.get().add(hPanel);
3、事件(Event)
繼續看剛才的例子,讓按鈕做一些事:
MyProject/src/com/xyz/client/MyApp.java
-----------------------------------------------
button.addClickListener(new ClickListener(){
? public void onClick(Widget sender){
??? ...
-----------------------------------------------
4、小部件(Widget)
(1)文件上傳 FileUpload
設置輸入element的名字并使用setName()方法提交到服務器。
(2)伸縮表和網格 FlexTable and Grid
表可以包含文本、HTML和其它任意小部件。網格總是相同的,有固定的尺寸。
使用setText(),setHTML(),setWidget()方法來加入單元項,使用getCellFormatter()來定制單元的外觀。單元可以跨越多行或多列。
(3)Frame and NamedFrame
此部件包裹在HTML的<iframe>元素中,包含于任意Web站點。
使用setUrl()方法來設置web頁面地址。
其CSS風格:.gwt-Frame{}
(4)HTML
其CSS風格:.gwt-HTML{}
(5)Image
在給定的URL顯示圖片的小部件。
使用setUrl()方法來設置圖片地址。使用addLoadListener()方法來檢測圖片是否載入或是否有錯。
其CSS風格:.gwt-Image{}
(6)Hyperlink
其CSS風格:.gwt-Hyperlink{}
(7)Label
其CSS風格:.gwt-Label{}
(8)ListBox
其CSS風格:.gwt-ListBox{}
(9)MenuBar and MenuItem
使用addItem()來加入菜單欄。
其CSS風格:
.gwt-MenuBar{the menu bar itself}
.gwt-MenuItem{menu items}
.gwt-MenuItem-selected{selected menu items}
.gwt-Frame{}
(10)PasswordTextBox
其CSS風格:.gwt-PasswordTextBox{}
(11)TabBar
常用于Tab面板的一部分。調用addTab()方法來加入TarBar,調用addTabListener()來檢測聚焦前(onBeforeTabSelected())和聚集后(onTabSelected())tab被選擇的情況。
其CSS風格:
.gwt-TarBar{the tab bar itself}
.gwt-TarBarFirst{the left side spacer of the bar}
.gwt-TabBarRest{the right side spacer of the bar}
.gwt-TabBarItem{tabs}
.gwt-TabBarItem-selected{additional style for selected tabs}
(12)TextArea
文本域允許顯示鍵入的多行文本。使用setCharacterWidth()和setVisibleLines()方法來設置文本域的尺寸。
調用getCursorPos(),getSelectionLength(),getSelectedText()來檢測當前所選擇的文本。
調用addKeyBoardListener()方法來監測按鍵情況。
其CSS風格:.gwt-TextArea{}
(13)TextBox
文本框顯示鍵入的單行文本。
設置文本框的尺寸用setVisibleLength()方法。
調用getCursorPos(),getSelectionLength(),getSelectedText()來檢測當前所選擇的文本。
調用addKeyBoardListener()方法來監測按鍵情況。
(14)Tree and TreeItem
調用addItem()方法增加樹子項。
其CSS風格:
.gwt-Tree{the tree itself}
.gwt-TreeItem{a tree item}
.gwt-TreeItem-selected{a selected tree item}
5、面板(Panel)
面板是一個包含多個小部件的部件。面板也可以包含其它面板。可以使用它在網格下、層面下(deck)、行、列下布局小部件。
(1)AbsolutePanel
允許面板重疊。
(2)DeckPanel
所有的小部件在一個“deck”中,一次只能顯示一個小部件。
用add()方法加入小部件,用showWidget()顯示某個小部件。
(3)DockPanel
面板的中央部分是保留部分,四周東西南北均可添加部件。
(4)FlowPanel
使用缺省的HTML布局。
(5)FocusPanel
(6)FormPanel
面板的內容對應HTML的<form>元素。
FormPanel只包含如下元素:TextBox,PasswordTextBox,RadioButton,CheckBox,TextArea,ListBox,FileUpload。
使用setName()方法把各元素名和表單域聯系在一起,傳遞到服務器。
使用setAction()方法設置URL用于提交表單。submit()實際提交表單。
調用addFormHandler()檢測表單是否已提交。
(7)HorizontalPanel
(8)HTMLPanel
(9)PopupPanel
popup面板可以彈出其它小部件。
(10)ScrollPanel
面板的內容可卷。使用構造器或者setWidget()函數定義包裹的部件。
(11)StackPanel
垂直的方式顯示,類似于子菜單。
(12)TabPanel
(13)VerticalPanel?
?
?
功能介紹(Web控件)
?
Web控件是GWT表示層的核心,通過使用GWT提供的Web控件可以創建豐富的客戶端畫面。
?
GWT的web組件主要分為兩類:輸入控件和Layout控件。
?
?
?
?
輸入控件主要是指向服務器提交數據,處理操作,顯示服務器數據的空間,主要包括:
?
Button,RadionButton,PushButton,ToggleButton,CheckBox,TextBox,PasswordBox
?
TextArea, HyperLink,ListBox,MenuBar,Tree,Table, TabBar,DialogBox, PopupPanel
?
RichTextArea, DisclosurePanel, SuggestBox
?
?
Layout 空間主要用來有規律地放置輸入控件,主要包括:
?
Stackpanel,HorizontalPanel,VerticalPanel, FlowPanel, VerticalSplitPanel, HorizontalSplitPanel,
?
DockPanel, TabPanel,
?
?
?
事件模型(Event & Listener)
如何處理頁面的事件呢,例如點擊按鈕,Textbox失去焦點等?
?
如下的代碼建立了一個按鈕,按鈕的名字是“Click Me”,當你點擊這個按鈕的時候處罰一個Click事件,Click事件觸發onClick(Widget sender)方法。
?
sender表示觸發onClick方法的組件,這里只是簡單的在頁面上顯示Hello World信息(相當于#的alert方法)。
?
?Button b = new Button("Click Me");
?b.addClickListener(new ClickListener() {
?public void onClick(Widget sender) {
??? Window.alert("Hello World");
?}
});
?
常見的Listener如下:
?
ChangeListener
ClickListener
FocusListener
KeyboardListener
MouseListener
MouseWheelListener
PopupListener
ScrollListener
TableListener
TreeListener
?
?
?
?
?
功能介紹(遠過程調用RPC)
?
??? 體系結構
?
GWT應用中頁面一旦加載,就再也不會向服務器請求HTML內容,所有的畫面遷移,轉換都在客戶端進行,但是數據還是會向服務器提交,或者從服務器獲取。
?
服務器上負責處理數據的對象在GWT中叫做Service,每個Service有三個類組成:服務方法定義接口(Service),異步調用接口(ServiceAsync)和服務器方法實現類ServiceImpl。
?
以Login為例子說明:
?
?
?
// 服務方法定義接口
?
public interface LoginService extends RemoteService {
??? public boolean login(LoginSO login) throws ApplicationException;
}
?
?
// 異步調用接口
?
public interface LoginServiceAsync {
??? void login(LoginSO login, AsyncCallback async);
}
?
?
// 服務器方法實現類
?
?public class LoginServiceImpl extends RemoteServiceServlet implements LoginService {
??? public boolean login(LoginSO login) throws ApplicationException {
??????? ...
?
??????? return true;?
?
??? }
}
?
?
?
其中前兩個接口在client包內部,最后一個實現在server包內部。
?
?
?
客戶端調用一個服務類的方法的代碼如下:
?
?
?
LoginServiceAsync ourInstance = (LoginServiceAsync) GWT.create(LoginService.class); //
((ServiceDefTarget) ourInstance).setServiceEntryPoint(GWT.getModuleBaseURL() + "/LoginService"); //
?
?
ourInstance.login(loginSO, new AsyncCallback() {?? //
?
??? public void onFailure(Throwable caught) {???????? //
??????? if(caught instanceof InvocationException) {
??????????? // system exception
??????? } else {
??????????? Window.alert(" " + GWTShowConstants.Messages.constants.maxQueryCount());
??????????? // aplication exception
??????? }
?
??? }
?
??? public void onSuccess(Object result) {??????????? //
??????? Window.alert("success");
??? }
?
});
?
?
?
//
?
?
?
?遠程調用
?
獲得服務器方法的調用接口(skeleton)。
?
設置服務位置。
?
遠程調用服務器上的方法,注意這里是異步調用,在和調用之前代碼可能先被調用了。
?
調用出錯,或者調用方法拋出異常的時候調用的方法。
?
調用成功返回時候調用的方法。
?
?
?
?
?
??? 參數和返回值系列化類型
?
這里的參數指的是Service方法調用的參數和返回值。
?
由于GWT的客戶端代碼都是#,而服務器代碼都是使用Java編寫的,這就涉及到#調用Java方法的時候
?
如何傳遞參數,如何取得返回值的問題。
?
?
?
?可序列化的類型包括:
?
(1) 原始類型,例如:char, byte, short, int, long, boolean, float, double;
?
(2) String,java.util.Date,或者原始類型的包裝類型,例如:?Character, Byte, Short, Integer, Long, Boolean, Float, or Double;
?
(3) 可序列化類型數組(包含(4)和(5)定義的類型)
?
(4) 用戶定義的可序列化類型
?
(5) 該類型至少有一個可序列化的子類型
?
?
?
針對上述(4)中說明的,什么是用戶自定義的可序列化類型呢?必須滿足以下亮點:
?
第一,必須直接或者間接(例如,父類型實現了這個接口)的實現了IsSerializable接口
?
第二,所有非transient類型都是可序列化的(final類型的屬性在GWT中被視為transient類型)
?
?
?
是否支持容器類型呢?那么又如何聲明呢?
?
支持容器類型,GWT可以使用Type 參數來表示容器類型內部的元素的類型,例如:
?
注意GWT暫時不支持使用 JDK 5.0 的模板容器
?
?
?
//用戶自定義序列化類型
?
public class MyClass implements IsSerializable {
?
?
?/**
?? * 這個Set中的元素的類型必須都是String類型
?? *
?? * @gwt.typeArgs
?? */
?public Set setOfStrings;
?
?/**
?? * Map中的元素的Key和Value的類型都是String類型。
?? *
?? * @gwt.typeArgs
?? */
?public Map mapOfStringToString;
}
?
?
// 服務器方法實現類
public interface MyService extends RemoteService {
?/**
?
?? * 第一個類型參數表示方法的參數c是一個List,并且其中只能放置Integer類型。
?? * 第二個類型參數表示返回值為List,并且其中的原書的類型為String類型。
?? *
?? * @gwt.typeArgs c
?? * @gwt.typeArgs
?? */
?List reverseListAndConvertToStrings(List c);
}
?
?
?
?
?
轉載于:https://www.cnblogs.com/zping/archive/2009/07/15/1524243.html
總結
- 上一篇: Windows server 2008文
- 下一篇: MDT2008部署之二LTI部署之一