GWT integration with Vaadin

144
Peter Lehto @peter_lehto GWT integration with

Transcript of GWT integration with Vaadin

Peter Lehto @peter_lehto

GWT

integration

with

GWT &

Vaadin

GWT transport

mechanisms

Web Components?

Vaadin

ConnectorsPolymer

QA

> var foo = [0];> foo == !foo;

> var foo = [0];> foo == !foo;> true

> [] + [];

> var foo = [0];> foo == !foo;> true

> [] + [];>

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> {} + {};> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> {} + {};> NaN

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> {} + {};> NaN

> NaN == NaN;

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> {} + {};> NaN

> NaN == NaN;> false

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> {} + {};> NaN

> NaN == NaN;> false

> typeof NaN;

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> {} + {};> NaN

> NaN == NaN;> false

> typeof NaN;> number

> var foo = [0];> foo == !foo;> true

> [] + [];>

> [] + {};> [object Object]

> {} + [];> 0

> {} + {};> NaN

> NaN == NaN;> false

> typeof NaN;> number

> var foo = [0];> foo == !foo;> true

UI

Browser

UI

Browser

Widgets

Them

e UI

Browser

Widgets

Them

e UI

Browser

Backend

Server

Widgets

Them

e UI

Browser

Backend

Server

Widgets

Service (GWT-RPC)

GWT

Java -> JavaScript - Optimizing compiler

GWT

Browser specific compilation - No browser differences

GWT

Pure Java - Web apps without JavaScript

GWT

JSInterop - JavaScript integration

GWT

Server driven UI framework with GWT based thin client

Why ?

High abstraction level - Components & Events

Full stack Java - UI runs in JVM

Rapid development - No JavaScript compilation

Any JVM language - Java 8, Scala, Lambdas…

Transparent - Automated communication

Developer

Productivity

Rich

UX

User Interface Components

User Interface Components

How ?

Backend

Server

UI Backend

Server

Browser

UI Backend

Server

Widgets Components

Them

e

Browser

UI Backend

Server

Widgets Components

Them

e

Browser

UI Backend

Server

Widgets Components

Shared StateRPC

• Loader page • CSS Theme • Images • JavaScript

• Loader page • CSS Theme • Images • JavaScript

135k

Compressed & reduced thin client

• name=”Joonas” • button clicked

261 bytes

• name=”Joonas” • button clicked

261 bytes

• Add notification

267 bytes

GWT transport mechanisms

RequestBuilder RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);try { builder.sendRequest(requestDataString, new RequestCallback() { @Override

public void onResponseReceived(Request request, Response response) { int statusCode = response.getStatusCode(); String text = response.getText();

} @Override

public void onError(Request request, Throwable exception) { // TODO Handle asynchronous problems

} }); } catch (RequestException e) { // TODO Handle synchronous problems}

RequestBuilder

Good

• It just works

RequestBuilder

Good

• It just works

Bad

• Very low level

GWT Remote procedure calls public interface ContactService extends RemoteService { void saveContact(Contact contact); List<Contact> getContacts();}

public interface ContactServiceAsync { void saveContact(Contact contact, AsyncCallback<Void> callback); void getContacts(AsyncCallback<List<Contact>>}

GWT-RPC

Good

• Simple butpowerful concept

• Default solution • Optimized

GWT-RPC

Good

• Simple butpowerful concept

• Default solution • Optimized

Bad

• Sending largeobject graph

• Polymorphismproblems

Vaadin Connectors

State synchronization public class ContactState extends SharedState { public String name; @DelegateToWidget public int yearOfBirth;}

State synchronization public class ContactState extends SharedState { public String name; @DelegateToWidget public int yearOfBirth;}

@OnStateChange("name")protected void updateName() { doSomethingWithTheName(getState().name);}

Vaadin RPC public interface ContactRpc extends ServerRpc { public void deleteContact(int id);}

Vaadin RPC public interface ContactRpc extends ServerRpc { public void deleteContact(int id);} // Register RPC handler on the serverregisterRpc(new ContactRpc() { @Override public void deleteContact(int id) { ContactDAO.deleteById(id); } });

Vaadin RPC public interface ContactRpc extends ServerRpc { public void deleteContact(int id);} // Register RPC handler on the serverregisterRpc(new ContactRpc() { @Override public void deleteContact(int id) { ContactDAO.deleteById(id); } }); // Send RPC from the clientpublic void sendDelete(int contactId) { getRpcProxy(ContactRpc.class).deleteContact(contactId);}

Server

Button

Browser

Server

VButton

Button

Browser

Server

VButton

ButtonConnector

Button

Browser

Server

VButton

ButtonConnector

SharedState

Button

SharedState

Browser

Server

SharedState

SharedState

Button

VButton

ButtonConnector

Browser

Server

SharedState

SharedState

RPC

RPC

Button

VButton

ButtonConnector

Browser

Server

SharedState

SharedState

RPC

RPC

Button

VButton

ButtonConnector

Browser

Server

SharedState

SharedState

RPC

RPC

Button

VButton

ButtonConnector

Browser

Server

Button

VButton

ButtonConnector

SharedState

SharedState

RPC

RPC

@Connect(value = Button.class)public class ButtonConnector extends AbstractComponentConnector implements ClickHandler {

@Connect(value = Button.class)public class ButtonConnector extends AbstractComponentConnector implements ClickHandler {

@OnStateChange({ "caption", "captionAsHtml" })void setCaption() { getWidget().setCaptionText(getState().caption);}

@Connect(value = Button.class)public class ButtonConnector extends AbstractComponentConnector implements ClickHandler {

@OnStateChange({ "caption", "captionAsHtml" })void setCaption() { getWidget().setCaptionText(getState().caption);}

void onClick(ClickEvent event) { getRpcProxy(ButtonServerRpc.class).click();}

server

client

Component

Widget

Connector

RPC

State

Vaadin Connectors

Good

• Stateful server • Websocket

support • JSON

Vaadin Connectors

Good

• Stateful server • Websocket

support • JSON

Bad

• Stateful server • Tied to

framework

Web Components

<x-gangnam-style></x-gangnam-style>

<x-gangnam-style></x-gangnam-style>

<x-component></x-component>

var proto = Object.create(HTMLElement.prototype); proto.createdCallback = function() { var div = document.createElement('div'); div.textContent = 'This is Custom Element'; this.appendChild(div); }; var XComponent = document.registerElement('x-component', { prototype: proto });

var host = document.querySelector('#host'); var root = host.createShadowRoot(); // Create a Shadow Root var div = document.createElement('div'); div.textContent = 'This is Shadow DOM'; root.appendChild(div); // Append elements to the Shadow Root

index.html<link rel="import" href="component.html" >

component.html<link rel="stylesheet" href="css/style.css"> <script src="js/script.js"></script>

<template id="template"> <style> ... </style> <div> <h1>Web Components</h1> <img src="http://webcomponents.org/img/logo.svg"> </div> </template>

<script> var template = document.querySelector('#template'); var clone = document.importNode(template.content, true); var host = document.querySelector('#host'); host.appendChild(clone); </script> <div id="host"></div>

Components Components

Statically typed Java

Components

Statically typed Java

Components

Statically typed Java

Components

Automated Communication

Statically typed Java

Components

Statically typed Java

Automated Communication

Statically typed Java

Statically typed Java

Automated Communication

Statically typed Java

Problem ?

Problem ?

Do web components actually work?

Custom Elements Support by browser market share

Shadow DOM Support by browser market share

HTML Import Support by browser market share

HTML Template Support by browser market share

Summary

Custom Element

HTML Template

Shadow DOM

HTML Import

CHROME OPERA FIREFOX SAFARI IE

Do web components actually work? No, but Yes :)

webcomponents.js

Polyfill

http://webcomponents.org/polyfills/

Web Components Custom Elements HTML Imports Shadow DOM

DOM WeakMap Mutation Observers{

Vaadin Labs

Reusable HTML components

Encapsulation

What shadow DOM looks like?

<v-grid>

Vaadin Grid Client Widget

Vaadin Grid Client Widget

Exposed JavaScript API via

JsInterop from GWT 2.7+

Vaadin Grid Client Widget

Exposed JavaScript API via

JsInterop from GWT 2.7+

Wrapped as PolymerElement

@JsNamespace(JS.VAADIN_JS_NAMESPACE) @JsExport @JsType public class GridComponent… … private final com.vaadin.client.widgets.Grid grid; // Grid widget

public JSColumn addColumn(JSColumn jsColumn, Object beforeColumnId) { grid.addColumn } …

GridComponent

<link rel='import' href='../bower_components/polymer/polymer.html' /> <script type="text/javascript" language="javascript" src=“VaadinGridImport.nocache.js" />

<dom-module id="v-grid"> <template>

… </template> </dom-module>

<script> VGrid = Polymer({ is: “v-grid", properties: { … }, created: function() {

this._grid = new vaadin.GridComponent(); }, attached: function() {

this._grid.attached(this, Polymer.dom(this).querySelector(“table”), Polymer.dom(this.root)); …

},

vaadin-grid.html

<script src="../bower_components/webcomponentsjs/webcomponents-lite.js"></script> <script src="../VaadinGrid/VaadinGrid.nocache.js"></script>

<body> <v-grid rows=1> …

index.html

Grid Widget

Grid Component

Grid Widget

@JSType

vaadin-grid.html

Grid Component

Grid Widget

@JSType

index.html

vaadin-grid.html

Grid Component

Grid Widget

@JSType

Automated Communication

Statically typed Java

Components

Automated Communication

Statically typed Java

Componentsweb

Automated Communication

Statically typed Java

Components

Framework

Components web

Lessons learned today

Lessons learned today1. Vaadin is server driven high abstraction level UI framework

Lessons learned today1. Vaadin is server driven high abstraction level UI framework

2. GWT is used for client side rendering

Lessons learned today1. Vaadin is server driven high abstraction level UI framework

2. GWT is used for client side rendering

3. Vaadin connectors form a bridge between GWT and Vaadin

Lessons learned today1. Vaadin is server driven high abstraction level UI framework

2. GWT is used for client side rendering

3. Vaadin connectors form a bridge between GWT and Vaadin

4. Web Components will be the next big thing in the web!

Lessons learned today1. Vaadin is server driven high abstraction level UI framework

2. GWT is used for client side rendering

3. Vaadin connectors form a bridge between GWT and Vaadin

4. Web Components will be the next big thing in the web!

5. Polymer polyfills today’s browsers to support emerging features

Lessons learned today1. Vaadin is server driven high abstraction level UI framework

2. GWT is used for client side rendering

3. Vaadin connectors form a bridge between GWT and Vaadin

4. Web Components will be the next big thing in the web!

5. Polymer polyfills today’s browsers to support emerging features

6. Vaadin Components will utilize Polymer providing frameworkindependent way of using the best component library available

@peter_lehto expert & trainer

[email protected]

slides slideshare.net/peterlehto

Je zult maar letter wezen. Goed, ik ben niet ontevredet. Maar het valt niet mee in deze zeventiger jaren tot het vaderlandse alfabet te behoren. Foto-zetterijen wringen je steeds in steeds ingevikkelder. Je zult maar letter wezen. Goed, ik ben