zoukankan      html  css  js  c++  java
  • 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控件可以创建丰富的客户端画面。

    GWTweb组件主要分为两类:输入控件和Layout控件。

    输入控件主要是指向服务器提交数据,处理操作,显示服务器数据的空间,主要包括:

    ButtonRadionButtonPushButtonToggleButtonCheckBoxTextBoxPasswordBox

    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 Stringjava.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中的元素的KeyValue的类型都是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);

    }

  • 相关阅读:
    Excel入门
    夹缝中求和
    移动撤销
    CSP2020-j2 T4 方格取数
    CSP2020-j2 T3表达式(expr)
    直播 获奖(live)
    优秀的拆分(power)
    P5661 公交换乘
    P1160 队列安排
    P1083 借教室
  • 原文地址:https://www.cnblogs.com/zping/p/1524243.html
Copyright © 2011-2022 走看看