Vaadin 简单集合 GWT示例

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();
    }
}

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

时间: 2024-10-11 06:58:02

Vaadin 简单集合 GWT示例的相关文章

[MySQL5.6] 一个简单的optimizer_trace示例

[MySQL5.6] 一个简单的optimizer_trace示例 前面已经介绍了如何使用和配置MySQL5.6中optimizer_trace(点击博客),本篇我们以一个相对简单的例子来跟踪optimizer_trace的产生过程. 本文的目的不是深究查询优化器的实现,只是跟踪optimizer trace在优化器的那一部分输出,因此很多部分只是一带而过,对于需要深究的部分,暂时标注为红色,后续再扩展阅读;之前一直没看过这部分代码,理解起来还是比较困难的… 我们以一个简单的表为例过一下opti

unity Dotween插件的简单介绍及示例代码

unity里面做插值动画的插件有许多,比较常见的有itween.hotween.dotween.根据大家的反馈和实际体验来说,dotween插件在灵活性.稳定性.易用性上都十分突出.这里简单介绍下它的用法,并在后文做了一些效果示例,还是不错的. 所谓"插值动画",顾名思义就是在两个值中插入其他的值来实现动画.原理非常简单,比如想让某个物体从A地到达B地,我们只知道A和B的坐标,插值动画就可以根据"缓动函数"确定A.B间的其他值,来实现物体从A到B的"运动过

一个简单的CRUD示例:使用PHP+MySQL

一个简单的CRUD示例:使用PHP+MySQL 前情 总是听说CRUD,但一直不清楚是做什么的,就去查了一下,大概的意思是一组常见的数据库操作:增(create).查(read).改(update)删(delete),大概是,也有其他的翻译,这里大概了解一下就好.截止到现在,网上好像没有什么很小的示例来阐述CRUD这个概念的,然后就去查了一番资料,写了一个真的很小白的.很简单.未使用任何框架的案例. 前端准备 由于笔者对前端知识并不熟悉,这里只贴容器(传输/返回数据的容器)代码,在服务器根目录下

Android高级编程笔记(七)两个Fragment简单跳转示例

在前两篇博文中分别介绍了Fragment得基础和Fragment的生命周期,然而说了这么多Fragment到底怎么用呢以及我们为什么要使用Fragment?本篇博文将主要探讨这两个问题,首先说下在APP中有这好好Activity,跳转起来有那么简单,我们为什么还要使用Fragment呢?这是因为Fragment相对Activity而言更加的轻量级,使用起来也更加灵活,在一个程序的内部界面切换,尽可能的用Fragment代替Activity会让我们的APP运行起来更加的流畅,更加的高效,同时也提高

最简单的视频播放示例8:DirectSound播放PCM

本文记录DirectSound播放音频的技术.DirectSound是Windows下最常见的音频播放技术.目前大部分的音频播放应用都是通过DirectSound来播放的.本文记录一个使用DirectSound播放PCM的例子.注:一位仁兄已经提醒我DirectSound已经计划被XAudio2取代了.后来考证了一下发现确有此事.因此在下次更新中考虑加入XAudio2播放PCM的例子.本文仍然记录一下DirectSound这位"元老". DirectSound简介 DirectSoun

最简单的视频播放示例7:SDL2播放YUV

本文记录SDL播放视频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API用于播放视频:封装了DirectSound这类的API用于播放音频.因为SDL的编写目的就是简化视音频播放的开发难度,所以使用SDL播放视频(YUV/RGB)和音频(PCM)数据非常的容易.下文记录一下使用SDL播放视频数据的技术. SDL简介 SDL(Simple DirectMedia Laye

Echarts环形进度使用 【1 简单的使用示例】

使用中说明几点属性:  hoverAnimation:false,//此处查了好久属性//控制鼠标放置在环上时候的交互下面会在总结一篇,采用实际开发中的一个示例(稍微复杂点)根据不同任务状态渲染加载不同环颜色及圈内显示不同文字的实现方式////这里一个简单的示例使用Echarts 环形图使用方式//常用于统计完成进度等等 function RenderNut(res, UserType) { 2 3 //数据处理 4 var donum = parseFloat(res.TaskProgress

一个简单网络爬虫示例(转载)

在学生时期,可能听到网络爬虫这个词会觉得很高大上,但是它的简单实现可能学生都不难懂. 网络爬虫应用,就是把整个互联网真的就当做一张网,像蜘蛛网那样,应用就像一个虫子,在网上面按照一定的规则爬动. 现在互联网应用最广的就是http(s)协议了,本文例子就是基于使用http(s)协议的,只作为示例,不涉及复杂的算法(实际上是最重要的). 设计思路: 程序入口从一个或多个url开始,通过http(s)获取url的内容,对获取到内容处理,获取内容中需要爬取的信息,获取到内容中的url链接,再重复以上步骤

IDDD 实现领域驱动设计-一个简单的 CQRS 示例

上一篇:<IDDD 实现领域驱动设计-CQRS(命令查询职责分离)和 EDA(事件驱动架构)> 学习架构知识,需要有一些功底和经验,要不然你会和我一样吃力,CQRS.EDA.ES.Saga 等等,这些是实践 DDD 所必不可少的架构,所以,如果你不懂这些,是很难看懂上篇所提到的 CQRS Journey 和 ENode 项目,那怎么办呢?我们可以从简单的 Demo 一点一滴开始. 代码地址:https://github.com/yuezhongxin/CQRS.Sample 说明:一张很丑陋的