Top Banner
Introduction to Vaadin Building server-side RIA applications Thomas Neidhart https://github.com/netomi http://people.apache.org/~tn March 29, 2012 T. Neidhart Introduction to Vaadin March 29, 2012 1 / 46
49

Introduction to Vaadin

May 10, 2015

Download

Technology

netomi

An introduction to Vaadin, with a demo application showing how to integrate Spring 3, JPA and Vaadin to quickly build interactive web applications.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Introduction to Vaadin

Introduction to VaadinBuilding server-side RIA applications

Thomas Neidhart

https://github.com/netomihttp://people.apache.org/~tn

March 29, 2012

T. Neidhart Introduction to Vaadin March 29, 2012 1 / 46

Page 2: Introduction to Vaadin

Overview of the talk

Motivation

Comparison to GWT

Why Vaadin?

How does it work?

What does Vaadin offer me?

How can I use it?

An integrated example: Satellite Tracker

T. Neidhart Introduction to Vaadin March 29, 2012 2 / 46

Page 3: Introduction to Vaadin

What is the problem?

We want to build web-applications◮ fast development◮ interactive UI (using AJAX)◮ strongly-typed (maintainability)◮ lots of widgets

T. Neidhart Introduction to Vaadin March 29, 2012 3 / 46

Page 4: Introduction to Vaadin

Solution: GWT

Coded in Java (subset of J2SE supported)

Compiled to Javascript

Uses (asynchronous) RPC mechanism for client-server communication

T. Neidhart Introduction to Vaadin March 29, 2012 4 / 46

Page 5: Introduction to Vaadin

Solution: GWT

Coded in Java (subset of J2SE supported)

Compiled to Javascript

Uses (asynchronous) RPC mechanism for client-server communication

It is great!

T. Neidhart Introduction to Vaadin March 29, 2012 4 / 46

Page 6: Introduction to Vaadin

Solution: GWT

Coded in Java (subset of J2SE supported)

Compiled to Javascript

Uses (asynchronous) RPC mechanism for client-server communication

It is great!

But also painful if you happen to work on large projects!◮ slow compilation◮ difficult to debug

T. Neidhart Introduction to Vaadin March 29, 2012 4 / 46

Page 7: Introduction to Vaadin

What about Vaadin?1

1taken from Book of VaadinT. Neidhart Introduction to Vaadin March 29, 2012 5 / 46

Page 8: Introduction to Vaadin

Pros

100% Java

Strong typing

Object-oriented

Browser independent

Secure◮ business logic on server-side◮ no UI services required

Fast development

T. Neidhart Introduction to Vaadin March 29, 2012 6 / 46

Page 9: Introduction to Vaadin

Cons

No offline mode (network connection required)

Scalability concerns◮ Client-side UI state stored on server

Most UI interactions are executed on the server-side (latency!)

Are there more?

T. Neidhart Introduction to Vaadin March 29, 2012 7 / 46

Page 10: Introduction to Vaadin

Cons

No offline mode (network connection required)

Scalability concerns◮ Client-side UI state stored on server

Most UI interactions are executed on the server-side (latency!)

Are there more?

Same cons as for other RIA frameworks◮ limited support for browser history◮ state-ful vs. state-less application◮ limited bookmark support

T. Neidhart Introduction to Vaadin March 29, 2012 7 / 46

Page 11: Introduction to Vaadin

Used Technologies

Java: server-side API

AJAX: async communication

GWT: client-side widgets

JSON: data exchange

Servlet API: serve HTTP content

T. Neidhart Introduction to Vaadin March 29, 2012 8 / 46

Page 12: Introduction to Vaadin

Toolchain

Java SDK

Eclipse IDE

Browser of choice (Firefox, Chrome)

Firebug (optional)

Vaadin Eclipse plugin

GWT Eclipse plugin

Maven

T. Neidhart Introduction to Vaadin March 29, 2012 9 / 46

Page 13: Introduction to Vaadin

Helpful Resources

Book of Vaadin http://vaadin.com/book

Vaadin Sampler http://demo.vaadin.com/sampler

Addon Directory https://vaadin.com/directory

Vaadin Forum https://vaadin.com/forum

Sat-Tracker Demo Application https://github.com/netomi/sat-tracker

T. Neidhart Introduction to Vaadin March 29, 2012 10 / 46

Page 14: Introduction to Vaadin

How does Vaadin actually work?

Do not worry, it’s not magic

Uses GWT for client-side widgets

Communication between client / server using UIDL◮ User Interface Definition Language◮ json-like format◮ describes the user interface

Only changes are transmitted (ideally - not completely true)

Server-side components acting as stub

T. Neidhart Introduction to Vaadin March 29, 2012 11 / 46

Page 15: Introduction to Vaadin

Client-side Engine2

2taken from Book of VaadinT. Neidhart Introduction to Vaadin March 29, 2012 12 / 46

Page 16: Introduction to Vaadin

Application Architecture3

3taken from Book of VaadinT. Neidhart Introduction to Vaadin March 29, 2012 13 / 46

Page 17: Introduction to Vaadin

Application

Entry point of the web-application

Similar to a session object

One instance per session / user

Initializes the user interface components for the client

T. Neidhart Introduction to Vaadin March 29, 2012 14 / 46

Page 18: Introduction to Vaadin

Application - Code

1 @Component(value = "trackerApplication")

2 @Scope(value = "prototype")

3 public class TrackerApplication extends BaseApplication {

4

5 public void init() {

6 setTheme(Runo.THEME_NAME);

7

8 final MainLayout layout = new MainLayout();

9 final Window main = new Window(app.getMessage("application.name"),

10 layout);

11 main.setSizeFull();

12 setMainWindow(main);

13 }

14 }

T. Neidhart Introduction to Vaadin March 29, 2012 15 / 46

Page 19: Introduction to Vaadin

Application - Code

1 public abstract class BaseApplication extends Application

2 implements HttpServletRequestListener {

3

4 public final void onRequestStart(HttpServletRequest request,

5 HttpServletResponse response) {

6 ApplicationHolder.setApplication(this);

7 requestStart(request, response);

8 }

9

10 public final void onRequestEnd(HttpServletRequest request,

11 HttpServletResponse response) {

12 try {

13 requestEnd(request, response);

14 } finally {

15 ApplicationHolder.resetApplication();

16 }

17 }

18

19 ..

20 }

T. Neidhart Introduction to Vaadin March 29, 2012 16 / 46

Page 20: Introduction to Vaadin

Web.xml1 <context-param>

2 <description>Vaadin production mode</description>

3 <param-name>productionMode</param-name>

4 <param-value>false</param-value>

5 </context-param>

6

7 <servlet>

8 <servlet-name>Myproject Application</servlet-name>

9 <servlet-class>

10 com.vaadin.terminal.gwt.server.ApplicationServlet

11 </servlet-class>

12 <init-param>

13 <description>Vaadin application class to start</description>

14 <param-name>application</param-name>

15 <param-value>

16 com.example.myproject.MyprojectApplication

17 </param-value>

18 </init-param>

19 </servlet>

20

21 <servlet-mapping>

22 <servlet-name>Myproject Application</servlet-name>

23 <url-pattern>/*</url-pattern>

24 </servlet-mapping>

T. Neidhart Introduction to Vaadin March 29, 2012 17 / 46

Page 21: Introduction to Vaadin

Web.xml - Spring version

1 <servlet>

2 <servlet-name>SatTracker</servlet-name>

3 <servlet-class>

4 org.netomi.tracker.util.SpringApplicationServlet

5 </servlet-class>

6 <init-param>

7 <description>Vaadin application bean to start</description>

8 <param-name>applicationBean</param-name>

9 <param-value>trackerApplication</param-value>

10 </init-param>

11 <init-param>

12 <description>Application widgetset</description>

13 <param-name>widgetset</param-name>

14 <param-value>org.netomi.tracker.ui.widgetset.TrackerWidgetset</param-value>

15 </init-param>

16 </servlet>

T. Neidhart Introduction to Vaadin March 29, 2012 18 / 46

Page 22: Introduction to Vaadin

Widgetset

1 <?xml version="1.0" encoding="UTF-8"?>

2 <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.3.0//EN"

3 "http://google-web-toolkit.googlecode.com/svn/tags/2.3.0/distro-source/core/src/gwt-m

4 <module>

5 <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />

6

7 <!-- Use a custom widget map generator to reduce resulting js size, optional-->

8 <generate-with>

9 <class ="org.netomi.tracker.ui.widgetset.CustomWidgetMapGenerator" >

10 <when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap" />

11 </generate-with>

12

13 <!-- The supported user agents at the moment of writing were:

14 ie6,ie8,gecko,gecko1_8,safari,opera

15 The value gecko1_8 is used for Firefox 3 and later and safari is used

16 for webkit based browsers including Google Chrome. -->

17 <!-- <set-property name="user.agent" value="gecko1_8" /> -->

18

19 <!-- any addons that are used and define a widget -->

20 <inherits name="org.vaadin.vol.VolWidgetsetWithHostedScript" />

21 <inherits name="com.github.wolfie.refresher.RefresherApplicationWidgetset"

22 /> </module>

T. Neidhart Introduction to Vaadin March 29, 2012 19 / 46

Page 23: Introduction to Vaadin

Widgetset Compilation - maven1 <plugin>

2 <!-- Compile the vaadin widgetset using the GWT compiler -->

3 <groupId>org.codehaus.mojo</groupId>

4 <artifactId>gwt-maven-plugin</artifactId>

5 <version>2.3.0</version>

6 <configuration>

7 <modules>

8 <module>org.netomi.tracker.ui.widgetset.TrackerWidgetset</module>

9 </modules>

10 <webappDirectory>${project.build.directory}/${project.build.finalName}/VAAD

11 <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>

12 <runTarget>clean</runTarget>

13 <noServer>true</noServer>

14 <port>8080</port>

15 <soyc>false</soyc>

16 </configuration>

17 <executions>

18 <execution>

19 <goals>

20 <goal>resources</goal>

21 <goal>compile</goal>

22 </goals>

23 </execution>

24 </executions>

25 </plugin>

T. Neidhart Introduction to Vaadin March 29, 2012 20 / 46

Page 24: Introduction to Vaadin

Widgetset Update - maven - optional

1 <plugin>

2 <!-- Used to automatically update the widgetset, can be omitted -->

3 <groupId>com.vaadin</groupId>

4 <artifactId>vaadin-maven-plugin</artifactId>

5 <version>1.0.2</version>

6 <executions>

7 <execution>

8 <configuration />

9 <goals>

10 <goal>update-widgetset</goal>

11 </goals>

12 </execution>

13 </executions>

14 </plugin>

T. Neidhart Introduction to Vaadin March 29, 2012 21 / 46

Page 25: Introduction to Vaadin

How do I find the available widgetsets myself?

1 Manifest-Version: 1.0

2 Vaadin-License-Title: Apache License 2.0

3 Implementation-Vendor: Henrik Paul

4 Implementation-Title: Refresher

5 Implementation-Version: 1.1.1

6 Vaadin-License-File: http://www.apache.org/licenses/LICENSE-2.0.html

7 Vaadin-Package-Version: 1

8 Vaadin-Widgetsets: com.github.wolfie.refresher.RefresherApplicationWid

9 getset

10 Class-Path:

T. Neidhart Introduction to Vaadin March 29, 2012 22 / 46

Page 26: Introduction to Vaadin

Back to our application

T. Neidhart Introduction to Vaadin March 29, 2012 23 / 46

Page 27: Introduction to Vaadin

UI Components

1 public class MainLayout extends VerticalLayout {

2

3 private TabSheet tabSheet;

4

5 public MainLayout() {

6 setMargin(true);

7 setSizeFull();

8

9 Label title = new Label("Satellite Tracker"));

10 title.addStyleName(Runo.LABEL_H1);

11 title.setSizeUndefined();

12 addComponent(title);

13 setComponentAlignment(title, Alignment.TOP_CENTER);

14

15 ..

16 }

17 }

T. Neidhart Introduction to Vaadin March 29, 2012 24 / 46

Page 28: Introduction to Vaadin

UI Components

Coding the UI feels very much like Swing

Use Layouts for composition of UI components◮ (Vertical|Horizontal)Layout◮ GridLayout◮ FormLayout◮ CssLayout◮ AbsoluteLayout◮ TabSheet◮ Accordion◮ Panel◮ (Vertical|Horizontal)SplitPanel

Event listener support

(modal) Sub-window support

T. Neidhart Introduction to Vaadin March 29, 2012 25 / 46

Page 29: Introduction to Vaadin

Event Listener

1 public class TrackingScreen extends HorizontalLayout {

2

3 public TrackingScreen() {

4 setMargin(true);

5 setSpacing(true);

6 setSizeFull();

7

8 Button compute = new Button("Track", new Button.ClickListener() {

9

10 public void buttonClick(ClickEvent event) {

11 getApplication().getMainWindow()

12 .showNotification("Button_clicked");

13 }

14 });

15

16 addComponent(compute);

17 ..

18 }

19 }

T. Neidhart Introduction to Vaadin March 29, 2012 26 / 46

Page 30: Introduction to Vaadin

Notification Example

T. Neidhart Introduction to Vaadin March 29, 2012 27 / 46

Page 31: Introduction to Vaadin

Sub-Windows

1 public class TrackingScreen extends HorizontalLayout {

2

3 public TrackingScreen() {

4 setMargin(true);

5 setSpacing(true);

6 setSizeFull();

7

8 Button compute = new Button("Track", new Button.ClickListener() {

9

10 public void buttonClick(ClickEvent event) {

11 Window w = new Window("My_window");

12 w.setContent(new MySubWindowContent());

13 w.setModal(true);

14 getApplication().getMainWindow()

15 .addWindow(w);

16 }

17 });

18

19 addComponent(compute);

20 ..

21 }

22 }

T. Neidhart Introduction to Vaadin March 29, 2012 28 / 46

Page 32: Introduction to Vaadin

Sub-Window example

T. Neidhart Introduction to Vaadin March 29, 2012 29 / 46

Page 33: Introduction to Vaadin

More UI Components

T. Neidhart Introduction to Vaadin March 29, 2012 30 / 46

Page 34: Introduction to Vaadin

Data Binding

Allows a view to access a model

View = any UI component

Model = can be anything

3 Level of Aggregation◮ Property◮ Item◮ Container

corresponding DataSources for each component◮ PropertyDataSource: TextField◮ ItemDataSource: Form◮ ContainerDataSource: Table

T. Neidhart Introduction to Vaadin March 29, 2012 31 / 46

Page 35: Introduction to Vaadin

Data Model4

4taken from Book of VaadinT. Neidhart Introduction to Vaadin March 29, 2012 32 / 46

Page 36: Introduction to Vaadin

Property

1 // Have a data model

2 ObjectProperty property = new ObjectProperty("Hello", String.class);

3

4 // Have a component that implements Viewer

5 Label viewer = new Label();

6

7 // Bind it to the data

8 viewer.setPropertyDataSource(property);

9

10 final TextField tf = new TextField("Name");

11

12 // Set the value

13 tf.setValue("The text field value");

14

15 // When the field value is edited by the user

16 tf.addListener(new Property.ValueChangeListener() {

17 public void valueChange(ValueChangeEvent event) {

18 // Get the value and cast it to proper type

19 String value = (String) tf.getValue();

20 getApplication().getMainWindow().showNotification("Value_changed");

21 }

22 });

T. Neidhart Introduction to Vaadin March 29, 2012 33 / 46

Page 37: Introduction to Vaadin

BeanItemContainer

1 // Create a container for such beans with

2 // strings as item IDs.

3 BeanContainer<String, Bean> beans =

4 new BeanContainer<String, Bean>(Bean.class);

5

6 // Use the name property as the item ID of the bean

7 beans.setBeanIdProperty("name");

8

9 // Add some beans to it

10 beans.addBean(new Bean("Mung bean", 1452.0));

11 beans.addBean(new Bean("Chickpea", 686.0));

12 beans.addBean(new Bean("Lentil", 1477.0));

13 beans.addBean(new Bean("Common bean", 129.0));

14 beans.addBean(new Bean("Soybean", 1866.0));

15

16 // Bind a table to it

17 Table table = new Table("Beans of All Sorts");

18 table.setContainerDataSource(beans);

T. Neidhart Introduction to Vaadin March 29, 2012 34 / 46

Page 38: Introduction to Vaadin

Containers

BeanItemContainer: for POJOs

IndexedContainer: for indexed data

LazyQueryContainer (addon): lazy loading from various data sources

HbnContainer (addon): for hibernate

Vaadin SQLContainer (addon): for SQL tables

Vaadin JPAContainer (commercial addon): for JPA entities

MockupContainer (addon): for mocking containers

CollectionContainer (addon): for Java Collections

T. Neidhart Introduction to Vaadin March 29, 2012 35 / 46

Page 39: Introduction to Vaadin

LazyQueryContainer example

1 entityContainer = new EntityContainer<Satellite>

2 (satService.getEntityManager(), true, false, false,

3 Satellite.class, 100, new Object[] {

4 "catalogNumber", "commonName"

5 }, new boolean[] {

6 true, true

7 });

8

9 entityContainer.addContainerProperty("catalogNumber", Long.class, 0, true, true);

10 entityContainer.addContainerProperty("type", String.class, "", true, true);

11 entityContainer.addContainerProperty("country", String.class, "", true, true);

12 entityContainer.addContainerProperty("launchDate", Date.class, null, true, true);

13 entityContainer.addContainerProperty("perigee", Double.class, 0.0d, true, true);

14 ..

15

16 // add a custom date formatter for the launch date

17 table.addGeneratedColumn("launchDate", new DateColumnGenerator());

18 table.setContainerDataSource(entityContainer);

T. Neidhart Introduction to Vaadin March 29, 2012 36 / 46

Page 40: Introduction to Vaadin

Themes

Based on CSS (Cascading Style Sheets)

Pre-defined themes◮ Reindeer◮ Runo◮ More theme addons

Custom themes

T. Neidhart Introduction to Vaadin March 29, 2012 37 / 46

Page 41: Introduction to Vaadin

Theme structure5

5taken from Book of VaadinT. Neidhart Introduction to Vaadin March 29, 2012 38 / 46

Page 42: Introduction to Vaadin

How does a theme css look like?

1 @import "../reindeer/styles.css";

2

3 .v-panel .v-panel-caption {

4 background: #80ff80; /* pale green */

5 }

6

7 .v-panel .v-panel-content {

8 background: yellow;

9 }

10

11 .v-panel .v-textfield {

12 background: #e0e0ff; /* pale blue */

13 }

14

15 .v-panel .v-button {

16 background: pink;

17 }

T. Neidhart Introduction to Vaadin March 29, 2012 39 / 46

Page 43: Introduction to Vaadin

Setting the theme to be used

1 public class MyApplication extends com.vaadin.Application {

2

3 public void init() {

4 // use the Runo theme

5 setTheme(Runo.THEME_NAME);

6 // or my own theme

7 setTheme("mytheme")

8 }

9 }

T. Neidhart Introduction to Vaadin March 29, 2012 40 / 46

Page 44: Introduction to Vaadin

Client-side widgets

To extend the existing widget collection

Requires a server-side component and a client-side widget (in GWT)

Allows custom css styles and other resources (e.g. images)

Warning: It can be tedious

Let’s see an example: a updating Time Label synchronized with the server

T. Neidhart Introduction to Vaadin March 29, 2012 41 / 46

Page 45: Introduction to Vaadin

Server-side component

1 /**

2 * The server-side part of the time label.

3 */

4 @ClientWidget(VTimeLabel.class)

5 public class TimeLabel extends Label {

6 private static final long serialVersionUID = 1L;

7

8 public TimeLabel(String text) {

9 super(text, Label.CONTENT_TEXT);

10 }

11

12 @Override

13 public void paintContent(PaintTarget target) throws PaintException {

14 target.addText(toString());

15 }

16 }

T. Neidhart Introduction to Vaadin March 29, 2012 42 / 46

Page 46: Introduction to Vaadin

Client-side widget

1 public class VTimeLabel extends VLabel {

2 private long date;

3

4 public VTimeLabel() {

5 date = -1;

6

7 ..

8 }

9

10 @Override

11 public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {

12 if (client.updateComponent(this, uidl, true)) { return; }

13

14 final String mode = uidl.getStringAttribute("mode");

15 if (mode == null || "text".equals(mode)) {

16 String dateString = uidl.getChildString(0);

17 try {

18 date = Long.parseLong(dateString);

19 } catch (Exception e) {

20 }

21 }

22 }

23 }

T. Neidhart Introduction to Vaadin March 29, 2012 43 / 46

Page 47: Introduction to Vaadin

Advanced Topics

Multiple Windows (see Navigator addon)

URI Fragment and History (see Navigator addon)

Portlets

Debugging Vaadin Application

T. Neidhart Introduction to Vaadin March 29, 2012 44 / 46

Page 48: Introduction to Vaadin

Common Pitfalls

UI components / layouts have different defaults wrt sizes

Do not forget to setSizeUndefined for a component to be able to expand

Try to keep your layouts slim / use CssLayout if possible

Keep an eye on re-usable components - no real MVC architecture

Multi-window support is not enabled by default

Immediate / Non-immediate components

T. Neidhart Introduction to Vaadin March 29, 2012 45 / 46

Page 49: Introduction to Vaadin

Outlook - Vaadin 7

Drop support for IE 6 and 7◮ Great news!◮ Reduces DOM tree size/depth◮ Makes layouts faster

Simplify addon development

Core support for server-push (was an addon before)

Improve and add core navigation support (was an addon before)◮ View concept◮ Browser History◮ Multi-window support

T. Neidhart Introduction to Vaadin March 29, 2012 46 / 46