Vaadin 是一個基於GWT的框架,其中各類add-on,還能夠與Spring等集成,可是當用戶數量達到必定程度,或者須要提升反應速度,則要使用Vaadin進行Client端的開發了,由於Vaadin的自身組件會頻繁的與服務端交互(甚至一個按鈕的點擊),有時候咱們僅僅想要一個樣式變換的效果,但願直接在Client端(即瀏覽器)進行,咱們就須要用GWT進行Vaadin 的Client端開發。html
而Vaadin的許多組件add-on(純客戶端的也能夠叫widget)都是使用這種方式開發java
首先,widget的開發必須遵循以下結構(圖來自Vaain官網,由Ying Li大大徹底翻譯了的官方教程!!連接:https://vaadin.com/book/zh/-/page/gwt.html#figure.gwt.overview.project)。
web
而我所作的簡單Demo結果以下:瀏覽器
MyComponentWidget.java 這是一個GWT類,繼承一個GWT的Button,其中類中定義了一個ComponentListener的內部接口,是爲了在鏈接器(MyComponentConnector.java)中實現Widget中的事件傳到鏈接器中。app
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接口:dom
package component.client; import com.vaadin.shared.communication.ServerRpc; //ServerRpc 是定義 Client到Server段 public interface MyComponentServerRpc extends ServerRpc { void alertCaption(String caption); }
4.MyComponentState 是組件的狀態,繼承AbstractComponentState類,分別爲你但願的屬性:ide
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:svn
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:ui
<?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了=。=沒找到如何上傳附件啊!