Top Banner
Building Vaadin add-ons Sami Ekblad, Vaadin @samiekblad
77

Workshop: Building Vaadin add-ons

May 10, 2015

Download

Technology

Sami Ekblad

Workshop on how to build Vaadin Add-ons. We introduce two styles of building Vaadin add-on components for Vaadin: integrating an existing GWT widget (DatePicker), and integrating an existing JavaScript library (three.js).
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: Workshop: Building Vaadin add-ons

Building Vaadin add-ons

Sami Ekblad, Vaadin@samiekblad

Page 2: Workshop: Building Vaadin add-ons

What are

add-ons?

Page 3: Workshop: Building Vaadin add-ons

add-onarchitecture

Page 4: Workshop: Building Vaadin add-ons

devtools

Page 5: Workshop: Building Vaadin add-ons

GWTadd-on

JSadd-on

Page 6: Workshop: Building Vaadin add-ons

packagingand distribution

Page 7: Workshop: Building Vaadin add-ons

this is a workshop✎

Page 8: Workshop: Building Vaadin add-ons

What we do here

Eclipse Kepler - eclipse.org

Vaadin plugin for Eclipse - vaadin.com/eclipse

Jetty Server - run-Jetty-run plugin

DatePicker - simple GWT or JavaScript add-on

... or something else.

New Vaadin project - testing and development

Page 9: Workshop: Building Vaadin add-ons

what is a

Vaadin add-on?

Page 10: Workshop: Building Vaadin add-ons

htmljava

Page 11: Workshop: Building Vaadin add-ons

Browser

Javascripthandling

Cross-browser issues

Typical Java EE web application:

JavaScript + Server-side JSF (or something)

Server

UI business logic

View config XMLs

Backend API

AJAX request handling & protocol

Security

Page 12: Workshop: Building Vaadin add-ons

Vaadin

Focus on business logic

Browser

Javascripthandling

Cross-browser issues

Server

UI business logic

View config XMLs

Backend API

AJAX request handling & protocol

Security

Javascripthandling

Cross-browser issues

View config XMLs

AJAX request handling & protocol

Security

Handled

by Vaadin

Page 13: Workshop: Building Vaadin add-ons

Client-server UI components

“UI Component”• Button, Table, Tree, ...• Server-side data• Full Java API

“Widget”• Client-side peer for the

component• Runs on JavaScript

HTTP(S)

Java

• Google Web Toolkit

Java

• Compiled with JDK

Page 14: Workshop: Building Vaadin add-ons

This is add-on

“UI Component”• Button, Table, Tree, ...• Server-side data• Full Java API

“Widget”• Client-side peer for the

component• Runs on JavaScript

HTTP(S)

Java

• Google Web Toolkit

Java

• Compiled with JDK

Add-on JAR file

Page 15: Workshop: Building Vaadin add-ons

Vaadin Directory

Page 16: Workshop: Building Vaadin add-ons

Vaadin Directory

Channel to all Vaadin developers

Find, download and rate add-ons

Automatic Maven integration

Page 17: Workshop: Building Vaadin add-ons
Page 18: Workshop: Building Vaadin add-ons
Page 19: Workshop: Building Vaadin add-ons

Webcam allows you to capture images from the web camera.

Webcam

webcam.addCaptureSucceededListener(new CaptureSucceededListener() {

@Override public void captureSucceeded(CaptureSucceededEvent event) { Image img = new Image("Captured image", new FileResource( targetFile)); img.setWidth("200px"); layout.addComponent(img); } });

Page 20: Workshop: Building Vaadin add-ons

A wrapper component for ReCaptcha.Recaptcha4j used for the server side validation of the captcha.

ReCaptcha

ReCaptcha captcha = new ReCaptcha( MY_PRIVATE_KEY, MY_PUBLIC_KEY, new ReCaptchaOptions() {{ theme = "white"; }});layout.addComponent(captcha);

Page 21: Workshop: Building Vaadin add-ons

Enables Google Maps support in Vaadin 7 projects.

GoogleMaps

GoogleMap googleMap = new GoogleMap(new LatLon(60.440963, 22.25122), 10.0, apiKey);googleMap.setSizeFull();googleMap.addMarker("DRAGGABLE: Paavo Nurmi Stadion", new LatLon( 60.442423, 22.26044), true, "VAADIN/1377279006_stadium.png");kakolaMarker = googleMap.addMarker("DRAGGABLE: Kakolan vankila", new LatLon(60.44291, 22.242415), true, null);googleMap.addMarker("NOT DRAGGABLE: Iso-Heikkilä", new LatLon( 60.450403, 22.230399), false, null);googleMap.setMinZoom(4.0);googleMap.setMaxZoom(16.0);

Page 22: Workshop: Building Vaadin add-ons

This add-on contains classes that add some missing "glue" between Vaadin and Spring.

Spring stuff

<!-- Activate Spring annotation support --> <context:annotation-config/>

<!-- Example of an application-specific bean which gets created and autowired when the

application starts and destroyed when the application stops --> <bean class="com.example.MyApplicationBean"/>

<!-- This makse the Vaadin application instance itself available in, and autowired by, this context -->

<bean class="org.dellroad.stuff.vaadin.ContextApplicationFactoryBean"p:autowire="true"/>

Page 23: Workshop: Building Vaadin add-ons

Authorize the Vaadin application to do things on the users' behalf on various services such as Facebook, Twitter, etc.

OAuth Popup

OAuthPopupButton ob = new TwitterButton(TW_KEY, TW_SECRET);

ob.addOAuthListener(new OAuthListener() { @Override public void authSuccessful(String accessToken, String accessTokenSecret) { Notification.show("Authorized"); // TODO: do something with the access token }

@Override public void authDenied(String reason) { Notification.show("Authorization denied"); }});

Page 24: Workshop: Building Vaadin add-ons

Scaladin makes easier to use Vaadin Framework with Scala programming language.

Scaladin

class ScaladinExampleApplication extends Application("Scaladin Example") {

override val main = new VerticalLayout { add(new Button { caption = "Click me!" icon = new ThemeResource("../runo/icons/16/globe.png") clickListeners += { mainWindow.showNotification("Hello World!") } }) }}

Page 25: Workshop: Building Vaadin add-ons

Basic Leapmotion gestures API for Vaadin.

LeapGestures

LeapGestures g = LeapGestures.extend(this);g.addSwipeDownListener(new SwipeDownListener() { @Override public void onSwipeDown(SwipeDownArgs args) { layout.addComponent(new Label("swipe down")); }});

Page 26: Workshop: Building Vaadin add-ons

Widgets - the most common add-ons

Extensions - invisible functionality

Data - integration to the backend

Tools - additional tools and components

Misc - something else

Page 27: Workshop: Building Vaadin add-ons

planning an add-on?

Page 28: Workshop: Building Vaadin add-ons

2 types of add-ons

1. Internal add-ons Used in foundation / platform

2. public open-source Shared with community

Page 29: Workshop: Building Vaadin add-ons

Idea =

how it is used (UX)+

how it works (Tech)

Page 30: Workshop: Building Vaadin add-ons

Aim for multilayereddesign that lets yourusers (developers)change behavior ofyour component

Page 31: Workshop: Building Vaadin add-ons

Demo applicationshould include all featuresand serve as examplefor your users

Page 32: Workshop: Building Vaadin add-ons

Javacomponents

Page 33: Workshop: Building Vaadin add-ons

Widgets - the most common add-ons

ConfirmDialog

Vaadin Charts PopupButton Calendar

GWT Graphics Switch

Page 34: Workshop: Building Vaadin add-ons

GWT

Vaadin

something.js

MyJSNI.java

ConnectorRPC + state

MyComponent.javaMyWidget.java

MyTestUI.java

Logical structureClient Communication Server

Page 35: Workshop: Building Vaadin add-ons

MyJSNI.java

MyComponent.java

MyWidget.java

MyTestUI.java

Java package structure

org.company.myaddon

org.company.myaddon.client

org.company.myaddon.client.public

something.js

ConnectorRPC + state

Page 36: Workshop: Building Vaadin add-ons

Extensions - invisible add-ons (or not)

final Refresher refresher = new Refresher();refresher.addListener(new DatabaseLazyLoader());addExtension(refresher);

Page 37: Workshop: Building Vaadin add-ons

Data - integration to the backend

Page 38: Workshop: Building Vaadin add-ons

getting started

developmenttools»

Page 39: Workshop: Building Vaadin add-ons

Tomcat 7 Jetty 8

Tools for add-on development

Java EEServer

JavaIDE

NetBeans 7.4 (+ Vaadin plugin) Eclipse Kepler (+Vaadin and Jetty plugin)

Browserdeveloper

tools

Google ChromeFirefoxSafari

Page 40: Workshop: Building Vaadin add-ons

Maven artifact for add-on

mvn -DarchetypeGroupId=com.vaadin \ -DarchetypeArtifactId=vaadin-archetype-widget \ -DarchetypeVersion=7.1.9 \ -DgroupId=org.vaadin.se \ -DartifactId= myaddon \ -DComponentClassName=MyAddon \ -Dversion=1.0-SNAPSHOT \ -Dpackage=org.vaadin.se.myaddon \archetype:generate

Page 41: Workshop: Building Vaadin add-ons

Eclipse plugin wizards

Page 42: Workshop: Building Vaadin add-ons

creating a GWT widget

add-onGWT

Page 43: Workshop: Building Vaadin add-ons

“The goal of this exercise is to practice the usage of RPC and shared state. In this exercise, we will take an existing GWT widget and make it compatible with server-side Vaadin applications.”

DatePicker component

DatePickercom.google.gwt.user.datepicker.client.

Page 44: Workshop: Building Vaadin add-ons

GWT

Vaadin

ConnectorRPC + state

DatePickerComponent.javaDatePicker

MyTestUI.java

DatePicker structureClient Communication Server

Page 45: Workshop: Building Vaadin add-ons

1. Create a new Vaadin7 project called DatePicker2. Create a new Vaadin 7 widget using the ”fullfledged” template, call your widget DatePickerComponent

3. In the server-side component, override getState to return a DatePickerState 4. Remove the client RPC interface 5. In the server RPC interface, define one method, dateChanged(Date date)

Page 46: Workshop: Building Vaadin add-ons

Eclipse plugin wizards

New project New widgetChoose

“Full fledged”

Page 47: Workshop: Building Vaadin add-ons

SuperDevModeclient-side debugging

Page 48: Workshop: Building Vaadin add-ons

SuperDevMode setup

<!-- Enabled by default: add-linker name="xsiframe"/ --><set-configuration-property name="devModeRedirectEnabled" value="true" />

<!-- also add compiler option --><set-property name="user.agent" value="safari"/>

.gwt.xml

Project properties view

Page 49: Workshop: Building Vaadin add-ons

SuperDevMode runtime

Start code serverVisit http://localhost:9876/

SuperDevMode code server for MyAddonProject.launch

Run application in

SuperDevMode

Debug as » Debug on server

Visit http://localhost:8080/MyAddOnProject?debug

Page 50: Workshop: Building Vaadin add-ons

6. The state object should have a field for the selected date 7. Set a default value for the date 8. Implement the server RPC in the server-side component.The dateChanged method should update the selected date in state 9. The connector should create a DatePicker widget10. The connector should register itself as a ValueChangeHandler<Date> to the widget, in order to listen to the selected date11. State changes should be passed to the widget

Page 51: Workshop: Building Vaadin add-ons

DatePickerConnectorDatePickerClientRpcDatePickerState

Client-side classes

Page 52: Workshop: Building Vaadin add-ons

DatePickerComponentMyTestUI

Server-side classes

Page 53: Workshop: Building Vaadin add-ons

to use the default

GWT theme

Include the following to the .gwt.xml

GWT widget theme

<inherits name="com.google.gwt.user.theme.standard.Standard" />

Page 54: Workshop: Building Vaadin add-ons

JSNI classes

public static native void alert(String msg) /*-{ $wnd.alert(msg);}-*/;

// Call instance method instanceFoo() on x [email protected]::myMethod(Ljava/lang/String;)(s);

Java to JavaScript:

JavaScript to Java:

Page 55: Workshop: Building Vaadin add-ons

JavaScript

shortcutjs

Page 56: Workshop: Building Vaadin add-ons

GWT

Vaadin

something.js

MyJSNI.java

RPC(+state)

MyComponent.javaMyWidget.java

MyTestUI.java

Logical structure

Page 57: Workshop: Building Vaadin add-ons

GWT

Vaadin

something.js

JSNI.java

RPC(+state)

MyComponent.javaJSWidget.java

MyTestUI.java

JavaScript components

Page 58: Workshop: Building Vaadin add-ons

something.js MyComponent.java MyTest.java

JavaScript shortcut

org.company.myaddon

Page 59: Workshop: Building Vaadin add-ons

JavaScript components

AbstractJavaScriptComponent

MyComponent.java

something.js

integration.js

Page 60: Workshop: Building Vaadin add-ons

Eclipse plugin wizard

New project New class

Page 61: Workshop: Building Vaadin add-ons

@JavaScript({"three.min.js", "cube_integration.js"})public class Cube extends AbstractJavaScriptComponent {

! ! public Cube() {! ! ! setWidth("200px");! ! ! setHeight("200px");! ! }

! ! public CubeState getState() {! ! ! return (CubeState) super.getState();! ! }! !! ! public boolean isAnimating() {! ! ! return getState().animate;! ! }

! ! public void stop() {! ! ! getState().animate = false;! ! }

! ! public void start() {! ! ! getState().animate = true;!! !! ! }! !}

Server codepublic class CubeState extends JavaScriptComponentState {

! public boolean animate = false;

}

Page 62: Workshop: Building Vaadin add-ons

window.com_example_threejs_Cube = function() { var element = this.getElement();

// This is Vaadin callback on state changes this.onStateChange = function() { !if (this.getState().animate) { !! this.start(); !} else { !! this.stop(); !} }

// React to resize events this.addResizeListener(this.getElement(), this.onResize);

// ... }

Client integration JavaScript

Page 63: Workshop: Building Vaadin add-ons

Could not initialize JavaScriptConnector because no JavaScript init function was found. Make sure one of these functions are defined:

• com_example_threejsaddon_Cube• com_vaadin_ui_AbstractJavaScriptComponent• com_vaadin_ui_AbstractComponent• com_vaadin_server_AbstractClientConnector

JavaScript not found

Page 64: Workshop: Building Vaadin add-ons

packaging

add-ons#

Page 65: Workshop: Building Vaadin add-ons

Export add-on jar

Page 66: Workshop: Building Vaadin add-ons

Add-on versions follow semver.org

Minorwhen you add functionality

Patch

MajorNew add-on version (start with 1.0.0)

when you make incompatible API changes

Do not break backward compatibility

when you make backwards-compatible bug fixes

No new features

Page 67: Workshop: Building Vaadin add-ons

Unique name

Vaadin XYZ

XYZ for Vaadin

[Use some time for the name, it is really really important]

Naming

Page 68: Workshop: Building Vaadin add-ons

Add-on jar

JAR manifest

WebContent/META-INF/MANIFEST.MF:

pom.xml

Vaadin-Package-Version: 1Vaadin-Widgetsets: com.example.myaddon.MyAddonWidgetset

META-INF/maven/com.example.myaddon/myaddon/pom.xml

NamingAdd-on Jar-name: myaddon-1.0.0.jar

Component class name: MyAddon.java

Specify external Maven dependencies

Page 69: Workshop: Building Vaadin add-ons

publishing

add-ons*

Page 70: Workshop: Building Vaadin add-ons

Vaadin Directory

1. Create user account to Vaadin.com

2. Upload your jar

3. Edit the add-on information

Page 71: Workshop: Building Vaadin add-ons
Page 72: Workshop: Building Vaadin add-ons
Page 73: Workshop: Building Vaadin add-ons
Page 74: Workshop: Building Vaadin add-ons

Publish add-ons in Directory

Gooddescription

Be descriptive and think of SEO.

Links anddocumentation

Demo isworth

a thousand words

Make screenshots and screencasts.

Example code, issue tracking, discussion

Publish sources (GitHub is good)

Show how it works. Remember code samples.

Works as test and validation for your add-on

Page 75: Workshop: Building Vaadin add-ons

what makes a

good add-on?★★★★⭐︎

Page 76: Workshop: Building Vaadin add-ons

Add-on ideas

Start fromyourself

There is aready one user for something that you need.

Common patterns and needs.

MaintainFix bugs

Follow discussion

Generalize Reuse existing JavaScript and GWT widgets.

Abstract functionality: Java API is your product

Combine client and server