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结果如下:
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了=。=没找到如何上传附件啊!