Vaadin 简单集合 GWT示例

原创
2015/01/29 22:13
阅读数 1.5W

    Vaadin 是一个基于GWT的框架,其中各种add-on,还可以与Spring等集成,但是当用户数量达到一定程度,或者需要提高反应速度,则要使用Vaadin进行Client端的开发了,因为Vaadin的自身组件会频繁的与服务端交互(甚至一个按钮的点击),有时候我们仅仅想要一个样式变换的效果,希望直接在Client端(即浏览器)进行,我们就需要用GWT进行Vaadin 的Client端开发。

    而Vaadin的许多组件add-on(纯客户端的也可以叫widget)都是使用这种方式开发

    首先,widget的开发必须遵循如下结构(图来自Vaain官网,由Ying Li大大完全翻译了的官方教程!!链接:https://vaadin.com/book/zh/-/page/gwt.html#figure.gwt.overview.project)。

   

而我所做的简单Demo结果如下:



  1. MyComponentWidget.java 这是一个GWT类,继承一个GWT的Button,其中类中定义了一个ComponentListener的内部接口,是为了在连接器(MyComponentConnector.java)中实现Widget中的事件传到连接器中。

    package component.client;
    
    import com.google.gwt.event.dom.client.ClickEvent;
    import com.google.gwt.event.dom.client.ClickHandler;
    import com.vaadin.client.ui.VButton;
    
    public class MyComponentWidget extends VButton {
    
        private ComponentListener listener;
    
        //一个接口,为了在Connector监听到点击事件
        public interface ComponentListener {
            void persistClick(String caption);
        }
        
        public MyComponentWidget() {
            super();
            setText("Button");
            setTitle("Button");
            
            //添加一个简单的点击事件
            addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    listener.persistClick("Title:"+getTitle());
                }
            });
        }
        
        //设置监听器
        public final void setWidgetClickListener(final ComponentListener listener) {
            this.listener = listener;
        }
    
    }

    2.MyComponentConnector.java是定义一个连接器,固定继承AbstractComponentConnector类,接口ComponentListener是之前在MyComponentWidget类中定义的接口。

package component.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.communication.RpcProxy;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.shared.ui.Connect;
import component.MyComponent;
import component.client.MyComponentWidget.ComponentListener;
//连接器
@Connect(MyComponent.class)
public class MyComponentConnector extends AbstractComponentConnector implements ComponentListener {
    
    //定义一个rpc通信,从客户端到服务端
    private MyComponentServerRpc rpc = RpcProxy.create(MyComponentServerRpc.class, this);
    public MyComponentConnector() {
        super();
    }
    
    /* 获得定义的widget */
    @Override
    public MyComponentWidget getWidget() {
        return (MyComponentWidget) super.getWidget();
    }
    
    /* 获取定义的Component的state */
    @Override
    public MyComponentState getState() {
        return (MyComponentState) super.getState();
    }
    
    /* 创建widget */
    @Override
    protected Widget createWidget() {
        final MyComponentWidget widget = GWT.create(MyComponentWidget.class);
        /* 设置点击事件 */
        widget.setWidgetClickListener(this);
        return widget;
    }
    
    /* state改变触发的事件,可以根据state的每个属性定义,详见官方文档 */
    @Override
    public void onStateChanged(StateChangeEvent stateChangeEvent) {
        super.onStateChanged(stateChangeEvent);
        getWidget().setText(getState().getMyComponentCaption());
        getWidget().setTitle(getState().getMyComponentCaption());
    }
    @Override
    public void persistClick(String caption) {
        rpc.alertCaption(caption);
    }
}

3.MyComponentServerRpc 是clinet到server的rpc接口:

package component.client;
import com.vaadin.shared.communication.ServerRpc;
//ServerRpc 是定义 Client到Server段
public interface MyComponentServerRpc extends ServerRpc {
    
    void alertCaption(String caption);
    
}

4.MyComponentState 是组件的状态,继承AbstractComponentState类,分别为你希望的属性:

package component.client;
import com.vaadin.shared.AbstractComponentState;
public class MyComponentState extends AbstractComponentState {
    //这里简单的定义Component的标题
    private String myComponentCaption;
    public MyComponentState() {
        super();
    }
    public String getMyComponentCaption() {
        return myComponentCaption;
    }
    public void setMyComponentCaption(String myComponentCaption) {
        this.myComponentCaption = myComponentCaption;
    }
}

5.MyComponent 就是服务端控制的component,要继承AbstractComponent类和implements server端RPC通信MyComponentServerRpc:

package component;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Notification;
import component.client.MyComponentServerRpc;
import component.client.MyComponentState;
public class MyComponent extends AbstractComponent implements MyComponentServerRpc {
    public MyComponent() {
        super();
        /* 注册rpc */
        registerRpc(this);
    }
    //显示标题
    @Override
    public void alertCaption(String caption) {
        Notification.show(caption);
    }
    
    //设置标题
    @Override
    public void setCaption(String caption) {
        //通过state设置caption
        getState().setMyComponentCaption(caption);
    }
    
    @Override
    protected MyComponentState getState() {
        return (MyComponentState) super.getState();
    }
}


差点漏了很重要的MyComponentWidgetSet.gwt.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.5.1/distro-source/core/src/gwt-module.dtd">
<module>
    <!--
        This file is automatically updated based on new dependencies by the
        goal "vaadin:update-widgetset".
    -->
    <!-- Inherit DefaultWidgetSet -->
    <inherits name="com.vaadin.DefaultWidgetSet" /> 
    
    <!--
     Uncomment the following to compile the widgetset for one browser only.
     Multiple browsers can be specified as a comma separated list. The
     supported user agents at the moment of writing were:
     ie8,ie9,gecko1_8,safari,opera
     The value gecko1_8 is used for Firefox and safari is used for webkit
     based browsers including Google Chrome.
    -->
    <!-- <set-property name="user.agent" value="safari"/> -->
    <!--
     To enable SuperDevMode, uncomment this line.
     See https://vaadin.com/wiki/-/wiki/Main/Using%20SuperDevMode for more
     information and instructions.
    -->
    <!-- <set-configuration-property name="devModeRedirectEnabled" value="true" /> -->
    <inherits name="appWidgetSet.gwt.AppWidgetSet" />
</module>

这样就完成一个简单的Vaadin add-on了=。=没找到如何上传附件啊!

展开阅读全文
打赏
2
23 收藏
分享
加载中
Jian_Ming博主

引用来自“编程小Q”的评论

业务复杂你们用VAADIN看看,没有一套好的模式代码一团糟
这个确实是
2016/05/12 15:24
回复
举报
业务复杂你们用VAADIN看看,没有一套好的模式代码一团糟
2016/05/12 15:22
回复
举报

引用来自“loyal”的评论

GWT完全是个垃圾框架.太恶心了.让人吐血.
几年前用过一年,什么玩意...想实现一个什么功能,都要去查几天,最后有个功能还必须借助servlet,然后再用GWT的方式包装下,卧槽,这也叫框架?
而且里面的组件太少了,自己造组件也需要花费不少时间...珍惜生命远离GWT之类的框架.
应该是你没掌握用法,我们这边一个百万的项目就是用gwt做的。最后成型了。。组件丰富,不用写html。js。css。还是挺方便的。和spring集成使用。。。
2015/11/06 12:23
回复
举报
Jian_Ming博主

引用来自“loyal”的评论

GWT完全是个垃圾框架.太恶心了.让人吐血.
几年前用过一年,什么玩意...想实现一个什么功能,都要去查几天,最后有个功能还必须借助servlet,然后再用GWT的方式包装下,卧槽,这也叫框架?
而且里面的组件太少了,自己造组件也需要花费不少时间...珍惜生命远离GWT之类的框架.
用这些框架真的要考虑好自己的项目适不适合啊,如果要很复杂的组件就不大适合了,但是如果人少,项目的性能要求不高,还是能减少很多开发成本的
2015/02/04 17:20
回复
举报
GWT完全是个垃圾框架.太恶心了.让人吐血.
几年前用过一年,什么玩意...想实现一个什么功能,都要去查几天,最后有个功能还必须借助servlet,然后再用GWT的方式包装下,卧槽,这也叫框架?
而且里面的组件太少了,自己造组件也需要花费不少时间...珍惜生命远离GWT之类的框架.
2015/02/04 14:40
回复
举报

引用来自“焦头烂额的扣子”的评论

学习了几天  Vaadin ,
感觉完全是一个错误的框架。。

引用来自“首席贱人”的评论

为啥?
前台的事,就要交给前端专家来做。想降低前端开发难度,那得付出多少额外的工作。 你想,如果一个厨师,既要炒菜,还要担心吧台的账收的对不对,所以,就只能做快餐买卖,就是点餐即付款款,永远也成不了五星级厨师。谁的活谁干,回避不了,也不能忽略。
2015/02/04 13:37
回复
举报
和GXT差不多吧
2015/02/04 11:42
回复
举报
Jian_Ming博主

引用来自“焦头烂额的扣子”的评论

学习了几天  Vaadin ,
感觉完全是一个错误的框架。。
为啥?
2015/02/04 10:58
回复
举报
学习了几天  Vaadin ,
感觉完全是一个错误的框架。。
2015/02/04 10:38
回复
举报
Jian_Ming博主

引用来自“Cray”的评论

现在还有用到GWT的,以前用过,概念不错,就是编译的时间很蛋疼
而且官方文档很全面,有中文
2015/02/04 10:16
回复
举报
更多评论
打赏
14 评论
23 收藏
2
分享
返回顶部
顶部