Vaadin Widgetset Example
A widget set is a GWT application that can be used from Vaadin. You can get a GWT library in it’s jar form and use it from your Vaadin application, Vaadin widget set is very rich, but if you ever need a non standard widget that Vaadin doesn’t provide you can extend your widget set using GWT and is a very handy tool to have under your Vaadin tool belt.
1. The tools
- Java JDK 8
- Latest Eclipse Mars
- Vaadin 7.6.4
- gwtbootstrap3 jar file
- Tomcat Server 8
2. Introduction
In this example I am going to show how to use the gwtbootstrap3 button widget in your Vaadin application, for every GWT widget you want to use, you need to create a wrapper widget inside your Vaadin application, I’m going to show how to wrap the button because it have a common functionality with other widgets and if you need to use any other widget is easy to have this example as starting point.
3. Prerequisites
- JDK installed
- Eclipse Mars installed and working
- Vaadin plugin installed
- Tomcat 8 installed and running
4. Set up the project
4.1 Create the Vaadin Project
In the file menu choose File -> New -> Other
Now from the list choose Vaadin 7 project
Hit next and name your project then hit finish.
4.2 Download the library jar
I got the jar from here gwtbootstrap3, Its version 0.9.3 from Feb 24, 2016
4.3 Copy the jar into your project
Copy the downloaded gwtbootstrap3-0.9.3.jar
inside the WebContent/WEB-INF/lib
folder insider of your project.
4.4 Create a widget
Right click on your project folder and choose New->Other.
From the list choose Vaadin widget
Name the widget and hit finish.
4.5 Edit the widgetset xml file
Edit the file VaadinwidgetsetWidgetset.gwt.xml
under the com.example.vaadinwidgetset
package and add the inherits module line for the jar as follows:
VaadinwidgetsetWidgetset.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> <inherits name="com.vaadin.DefaultWidgetSet" /> <inherits name="org.gwtbootstrap3.GwtBootstrap3" /> <!-- 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" /> --> </module>
4.6 Compile the widgetset
Compile the widgetset, from the Vaadin toolbar choose compile widgetset
5. Coding the example
A Vaadin Widget is composed by various abstraction layers, first you have a server side component MyGwtbootstrap3.java
extending AbstractComponent
, on the client side you have a widget in this case MyGwtbootstrap3Widget.java
that is in charge of render the client side widget, a shared state MyGwtbootstrap3State.java
that handles the basic state communication between the client and the server, a connector MyGwtbootstrap3Connector.java
communicate the user interaction of the widget to the server side and receive state changes from the server and relay them to the widget and MyGwtbootstrap3ServerRpc.java
, MyGwtbootstrap3ClientRpc.java
that handles the remote procedure calls.
MyGwtbootstrap3Widget.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; import org.gwtbootstrap3.client.ui.Button; public class MyGwtbootstrap3Widget extends Button { public static final String CLASSNAME = "mygwtbootstrap3"; public MyGwtbootstrap3Widget() { setStyleName(CLASSNAME); } }
this is the widget class and is in charge of the client side render and extends the Gwt widget, in this case the button.
MyGwtbootstrap3State.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; public class MyGwtbootstrap3State extends com.vaadin.shared.AbstractComponentState { private static final long serialVersionUID = 1L; private String text = "Default"; private String type = "DEFAULT"; private String size = "DEFAULT"; public String getSize() { return size; } public String getText() { return text; } public String getType() { return type; } public void setSize(String size) { this.size = size; } public void setText(String text) { this.text = text; } public void setType(String type) { this.type = type; } }
This class is the shared-state and is in charge of keep the state of the widget and handle the serialization and communication of the state between the client and the server, it have the information about the properties of the widget, in this case text
, type
and size
and its getters and setters to handle these fields.
MyGwtbootstrap3Connector.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; import org.gwtbootstrap3.client.ui.constants.ButtonSize; import org.gwtbootstrap3.client.ui.constants.ButtonType; import com.example.vaadinwidgetset.MyGwtbootstrap3; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.MouseEventDetailsBuilder; import com.vaadin.client.communication.RpcProxy; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.Connect; @Connect(MyGwtbootstrap3.class) public class MyGwtbootstrap3Connector extends AbstractComponentConnector implements ClickHandler { private static final long serialVersionUID = 1L; MyGwtbootstrap3ServerRpc rpc = RpcProxy .create(MyGwtbootstrap3ServerRpc.class, this); public MyGwtbootstrap3Connector() { getWidget().addClickHandler(this); } @Override protected Widget createWidget() { return GWT.create(MyGwtbootstrap3Widget.class); } @Override public MyGwtbootstrap3Widget getWidget() { return (MyGwtbootstrap3Widget) super.getWidget(); } @Override public MyGwtbootstrap3State getState() { return (MyGwtbootstrap3State) super.getState(); } @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); MyGwtbootstrap3State state = getState(); MyGwtbootstrap3Widget button = getWidget(); button.setText(state.getText()); button.setSize(ButtonSize.valueOf(state.getSize())); button.setType(ButtonType.valueOf(state.getType())); } @Override public void onClick(ClickEvent event) { MouseEventDetails details = MouseEventDetailsBuilder.buildMouseEventDetails( event.getNativeEvent(), getWidget().getElement()); rpc.clicked(details); } }
MyGwtbootstrap3Connector.java
have the tasks to hook up to the widget and handle events from user interaction and changes received from the server, when the state of the widget changed is handled with the overridden public void onStateChanged(StateChangeEvent stateChangeEvent)
method also the method public void onClick(ClickEvent event)
handle the user clicks on the widget, because in this example I am wrapping a button, capture a click on the widget is very important.
MyGwtbootstrap3.java
package com.example.vaadinwidgetset; import com.example.vaadinwidgetset.client.mygwtbootstrap3.MyGwtbootstrap3ServerRpc; import com.example.vaadinwidgetset.client.mygwtbootstrap3.MyGwtbootstrap3State; import com.vaadin.shared.MouseEventDetails; public class MyGwtbootstrap3 extends com.vaadin.ui.AbstractComponent { private static final long serialVersionUID = 1L; private MyGwtbootstrap3ServerRpc rpc = new MyGwtbootstrap3ServerRpc() { private static final long serialVersionUID = 1L; @Override public void clicked(MouseEventDetails mouseDetails) { fireEvent(new Event(MyGwtbootstrap3.this)); } }; @Override public MyGwtbootstrap3State getState() { return (MyGwtbootstrap3State) super.getState(); } public MyGwtbootstrap3() { this("Default", "DEFAULT", "DEFAULT"); } public MyGwtbootstrap3(String text, String type, String size) { getState().setText(text); getState().setSize(size); getState().setType(type); setImmediate(true); registerRpc(rpc); } public String getMyGwtbootstrap3Text(){ return getState().getText(); } }
MyGwtbootstrap3.java
is the server counterpart of the widget and is in charge of create a widget that can be understood by Vaadin and use the client side to make sure everything works like a native Vaadin widget, we have here several constructors and handlers for the events of the widget, in this case only click events are handled, the constructor set the 3 basic properties we have defined to use our widget and the click event is wrapped inside a remote procedure call.
VaadinwidgetsetUI.java
package com.example.vaadinwidgetset; import javax.servlet.annotation.WebServlet; import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.GridLayout; import com.vaadin.ui.Notification; import com.vaadin.ui.UI; @SuppressWarnings("serial") @Theme("vaadinwidgetset") public class VaadinwidgetsetUI extends UI { @WebServlet(value = "/*", asyncSupported = true) @VaadinServletConfiguration(productionMode = false, ui = VaadinwidgetsetUI.class, widgetset = "com.example.vaadinwidgetset.VaadinwidgetsetWidgetset") public static class Servlet extends VaadinServlet { } @Override protected void init(VaadinRequest request) { final GridLayout layout = new GridLayout(3, 2); layout.setWidth("80%"); layout.setHeight("80%"); layout.setMargin(true); setContent(layout); Button button = new Button("Vaadin Button"); button.addClickListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { Notification.show("Clicked: Vaadin Button",Notification.Type.TRAY_NOTIFICATION); } }); layout.addComponent(button, 0, 0); Listener myListener = new Listener(){ @Override public void componentEvent(Event event) { MyGwtbootstrap3 gg = (MyGwtbootstrap3)event.getComponent(); Notification.show("Clicked: Bootstrap " + gg.getMyGwtbootstrap3Text(),Notification.Type.TRAY_NOTIFICATION); } }; MyGwtbootstrap3 b01 = new MyGwtbootstrap3("Info", "INFO", "DEFAULT"); b01.addListener(myListener); layout.addComponent(b01, 0, 1); MyGwtbootstrap3 b02 = new MyGwtbootstrap3("Primary", "PRIMARY", "DEFAULT"); b02.addListener(myListener); layout.addComponent(b02, 1, 0); MyGwtbootstrap3 b03 = new MyGwtbootstrap3("Success", "SUCCESS", "DEFAULT"); b03.addListener(myListener); layout.addComponent(b03, 1, 1); MyGwtbootstrap3 b04 = new MyGwtbootstrap3("Warning", "WARNING", "DEFAULT"); b04.addListener(myListener); layout.addComponent(b04, 2, 0); MyGwtbootstrap3 b05 = new MyGwtbootstrap3("Danger", "DANGER", "DEFAULT"); b05.addListener(myListener); layout.addComponent(b05, 2, 1); } }
This is our application once the widget is defined we can use it like a regular Vaadin widget.
Create the layout
final GridLayout layout = new GridLayout(3, 2); layout.setWidth("80%"); layout.setHeight("80%"); layout.setMargin(true); setContent(layout);
First I created the layout, a grid layout to put the different buttons on it.
Regular button
Button button = new Button("Vaadin Button"); button.addClickListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { Notification.show("Clicked: Vaadin Button",Notification.Type.TRAY_NOTIFICATION); } }); layout.addComponent(button, 0, 0);
I created a regular Vaadin button to compare it with our wrapped buttons.
Shared listener
Listener myListener = new Listener(){ @Override public void componentEvent(Event event) { MyGwtbootstrap3 gg = (MyGwtbootstrap3)event.getComponent(); Notification.show("Clicked: Bootstrap " + gg.getMyGwtbootstrap3Text(),Notification.Type.TRAY_NOTIFICATION); } };
A listener for all the wrapped buttons that fire a Notification identifying the button that is clicked.
gwtbootstrap3 buttons
MyGwtbootstrap3 b01 = new MyGwtbootstrap3("Info", "INFO", "DEFAULT"); b01.addListener(myListener); layout.addComponent(b01, 0, 1); MyGwtbootstrap3 b02 = new MyGwtbootstrap3("Primary", "PRIMARY", "DEFAULT"); b02.addListener(myListener); layout.addComponent(b02, 1, 0); MyGwtbootstrap3 b03 = new MyGwtbootstrap3("Success", "SUCCESS", "DEFAULT"); b03.addListener(myListener); layout.addComponent(b03, 1, 1); MyGwtbootstrap3 b04 = new MyGwtbootstrap3("Warning", "WARNING", "DEFAULT"); b04.addListener(myListener); layout.addComponent(b04, 2, 0); MyGwtbootstrap3 b05 = new MyGwtbootstrap3("Danger", "DANGER", "DEFAULT"); b05.addListener(myListener); layout.addComponent(b05, 2, 1);
And the gwtbootstrap3 wrapped buttons showing different buttons defined in the twitter bootstrap library, using the properties defined to create the buttons, the shared listener and the grid layout to show the buttons.
6. The complete source code
VaadinwidgetsetUI.java
package com.example.vaadinwidgetset; import javax.servlet.annotation.WebServlet; import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.GridLayout; import com.vaadin.ui.Notification; import com.vaadin.ui.UI; @SuppressWarnings("serial") @Theme("vaadinwidgetset") public class VaadinwidgetsetUI extends UI { @WebServlet(value = "/*", asyncSupported = true) @VaadinServletConfiguration(productionMode = false, ui = VaadinwidgetsetUI.class, widgetset = "com.example.vaadinwidgetset.VaadinwidgetsetWidgetset") public static class Servlet extends VaadinServlet { } @Override protected void init(VaadinRequest request) { final GridLayout layout = new GridLayout(3, 2); layout.setWidth("80%"); layout.setHeight("80%"); layout.setMargin(true); setContent(layout); Button button = new Button("Vaadin Button"); button.addClickListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { Notification.show("Clicked: Vaadin Button",Notification.Type.TRAY_NOTIFICATION); } }); layout.addComponent(button, 0, 0); Listener myListener = new Listener(){ @Override public void componentEvent(Event event) { MyGwtbootstrap3 gg = (MyGwtbootstrap3)event.getComponent(); Notification.show("Clicked: Bootstrap " + gg.getMyGwtbootstrap3Text(),Notification.Type.TRAY_NOTIFICATION); } }; MyGwtbootstrap3 b01 = new MyGwtbootstrap3("Info", "INFO", "DEFAULT"); b01.addListener(myListener); layout.addComponent(b01, 0, 1); MyGwtbootstrap3 b02 = new MyGwtbootstrap3("Primary", "PRIMARY", "DEFAULT"); b02.addListener(myListener); layout.addComponent(b02, 1, 0); MyGwtbootstrap3 b03 = new MyGwtbootstrap3("Success", "SUCCESS", "DEFAULT"); b03.addListener(myListener); layout.addComponent(b03, 1, 1); MyGwtbootstrap3 b04 = new MyGwtbootstrap3("Warning", "WARNING", "DEFAULT"); b04.addListener(myListener); layout.addComponent(b04, 2, 0); MyGwtbootstrap3 b05 = new MyGwtbootstrap3("Danger", "DANGER", "DEFAULT"); b05.addListener(myListener); layout.addComponent(b05, 2, 1); } }
MyGwtbootstrap3.java
package com.example.vaadinwidgetset; import com.example.vaadinwidgetset.client.mygwtbootstrap3.MyGwtbootstrap3ServerRpc; import com.example.vaadinwidgetset.client.mygwtbootstrap3.MyGwtbootstrap3State; import com.vaadin.shared.MouseEventDetails; public class MyGwtbootstrap3 extends com.vaadin.ui.AbstractComponent { private static final long serialVersionUID = 1L; private MyGwtbootstrap3ServerRpc rpc = new MyGwtbootstrap3ServerRpc() { private static final long serialVersionUID = 1L; @Override public void clicked(MouseEventDetails mouseDetails) { fireEvent(new Event(MyGwtbootstrap3.this)); } }; @Override public MyGwtbootstrap3State getState() { return (MyGwtbootstrap3State) super.getState(); } public MyGwtbootstrap3() { this("Default", "DEFAULT", "DEFAULT"); } public MyGwtbootstrap3(String text, String type, String size) { getState().setText(text); getState().setSize(size); getState().setType(type); setImmediate(true); registerRpc(rpc); } public String getMyGwtbootstrap3Text(){ return getState().getText(); } }
MyGwtbootstrap3Widget.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; import org.gwtbootstrap3.client.ui.Button; public class MyGwtbootstrap3Widget extends Button { public static final String CLASSNAME = "mygwtbootstrap3"; public MyGwtbootstrap3Widget() { setStyleName(CLASSNAME); } }
MyGwtbootstrap3State.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; public class MyGwtbootstrap3State extends com.vaadin.shared.AbstractComponentState { private static final long serialVersionUID = 1L; private String text = "Default"; private String type = "DEFAULT"; private String size = "DEFAULT"; public String getSize() { return size; } public String getText() { return text; } public String getType() { return type; } public void setSize(String size) { this.size = size; } public void setText(String text) { this.text = text; } public void setType(String type) { this.type = type; } }
MyGwtbootstrap3Connector.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; import org.gwtbootstrap3.client.ui.constants.ButtonSize; import org.gwtbootstrap3.client.ui.constants.ButtonType; import com.example.vaadinwidgetset.MyGwtbootstrap3; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.MouseEventDetailsBuilder; import com.vaadin.client.communication.RpcProxy; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.Connect; @Connect(MyGwtbootstrap3.class) public class MyGwtbootstrap3Connector extends AbstractComponentConnector implements ClickHandler { private static final long serialVersionUID = 1L; MyGwtbootstrap3ServerRpc rpc = RpcProxy .create(MyGwtbootstrap3ServerRpc.class, this); public MyGwtbootstrap3Connector() { getWidget().addClickHandler(this); } @Override protected Widget createWidget() { return GWT.create(MyGwtbootstrap3Widget.class); } @Override public MyGwtbootstrap3Widget getWidget() { return (MyGwtbootstrap3Widget) super.getWidget(); } @Override public MyGwtbootstrap3State getState() { return (MyGwtbootstrap3State) super.getState(); } @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); MyGwtbootstrap3State state = getState(); MyGwtbootstrap3Widget button = getWidget(); button.setText(state.getText()); button.setSize(ButtonSize.valueOf(state.getSize())); button.setType(ButtonType.valueOf(state.getType())); } @Override public void onClick(ClickEvent event) { MouseEventDetails details = MouseEventDetailsBuilder.buildMouseEventDetails( event.getNativeEvent(), getWidget().getElement()); rpc.clicked(details); } }
MyGwtbootstrap3ServerRpc.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.communication.ServerRpc; public interface MyGwtbootstrap3ServerRpc extends ServerRpc { public void clicked(MouseEventDetails mouseDetails); }
MyGwtbootstrap3ClientRpc.java
package com.example.vaadinwidgetset.client.mygwtbootstrap3; import com.vaadin.shared.communication.ClientRpc; public interface MyGwtbootstrap3ClientRpc extends ClientRpc { public void alert(String message); }
7. Running the example
Right click on the project folder and choose Run as -> Run on server choose Tomcat 8 server and hit finish.
8. Results
Now you can use the Bootstrap buttons inside Vaadin.
9. Download the Source Code
You can download the Eclipse project here: VaadinWidgetset