49
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

Introduction to Vaadin

  • Upload
    netomi

  • View
    4.440

  • Download
    2

Embed Size (px)

DESCRIPTION

An introduction to Vaadin, with a demo application showing how to integrate Spring 3, JPA and Vaadin to quickly build interactive web applications.

Citation preview

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