softshake 2013 - vaadin componentization

66
Vaadin extension points Componentize your UI 7

Upload: nicolas-frankel

Post on 10-May-2015

907 views

Category:

Self Improvement


2 download

TRANSCRIPT

Page 1: SoftShake 2013 - Vaadin componentization

Vaadin extension points

Componentize your UI

7

Page 2: SoftShake 2013 - Vaadin componentization

Who am I

• Java (EE) Dev/Architect

• Vaadin enthusiast

• General blog• http://blog.frankel.ch

• @nicolas_frankel

• Vaadin specific• http://morevaadin.com

• @learnvaadin

Page 3: SoftShake 2013 - Vaadin componentization
Page 4: SoftShake 2013 - Vaadin componentization

Extension points

1. Compose base components

2. Wrap GWT widgets

3. Extensions

4. Wrap JavaScript

5. Theme

This presentation requires you have a bare minimum knowledge of Vaadin and how it works

Page 5: SoftShake 2013 - Vaadin componentization

Extension points

1. Compose base components

2. Wrap GWT widgets

3. Extensions

4. Wrap JavaScript

5. Theme

Page 6: SoftShake 2013 - Vaadin componentization

Composition

• It can’t be that hard Just compose…

• Let’s create an Address component And see for ourselves

Page 7: SoftShake 2013 - Vaadin componentization

First step

public class Address extends VerticalLayout {

public Address() {

addComponent(new TextField("Ligne 1")); addComponent(new TextField("Ligne 2")); addComponent(new TextField("Ville")); addComponent(new TextField("NPA")); }}

Page 8: SoftShake 2013 - Vaadin componentization

Input vs label

TextField ligne1 = new TextField();TextField ligne2 = new TextField();TextField ville = new TextField();TextField npa = new TextField();

ligne1.setInputPrompt("Ligne 1");ligne2.setInputPrompt("Ligne 2");ville.setInputPrompt("Ville");npa.setInputPrompt("NPA");

addComponent(ligne1);addComponent(ligne2);addComponent(ville);addComponent(npa);

Page 9: SoftShake 2013 - Vaadin componentization

Spacing

setSpacing(true);

TextField ligne1 = new TextField();TextField ligne2 = new TextField();TextField ville = new TextField();TextField npa = new TextField();

ligne1.setInputPrompt("Ligne 1");ligne2.setInputPrompt("Ligne 2");ville.setInputPrompt("Ville");npa.setInputPrompt("NPA");

addComponent(ligne1);addComponent(ligne2);addComponent(ville);addComponent(npa);

Page 10: SoftShake 2013 - Vaadin componentization

Problems?

No choice between labels and input prompts

No choice between spacing or not

i18n

Fixed layout

And so on

No configuration feature!

Page 11: SoftShake 2013 - Vaadin componentization

Configuration design

Expose your configuration features

Wrap the rest As for API

Introduce middle-components for decoupling For layout, use CustomComponent

Page 12: SoftShake 2013 - Vaadin componentization

public class Address extends CustomComponent {

private Layout layout; private TextField ligne1 = new TextField(); // Declare other components

public Address(Layout layout) {

this.layout = layout; setCompositionRoot(layout);

layout.addComponent(ligne1); // Add other components}

public void setSpacing(boolean spacing) {…} public boolean isSpacing() {…} public String getLigne1Caption() {…} // Other getters and setters}

Generic component

Configurable layout

Delegate to layout

Delegate to TextField

Page 13: SoftShake 2013 - Vaadin componentization

UI design vs data design

Address address = new Address();

address.getLigne1().setValue("M. Nicolas Frankel");address.getLigne2().setValue("Route du Simplon 1");address.getVille().setValue("Paudex");address.getNpa().setValue("1094");

Tight coupling No abstraction

No validation as a whole No JSR-303

Page 14: SoftShake 2013 - Vaadin componentization

Simple data design

An address component should display an address bean!

Page 15: SoftShake 2013 - Vaadin componentization

Better data design

Enable data buffering Commit / discard

Page 16: SoftShake 2013 - Vaadin componentization

Even better data design

Page 17: SoftShake 2013 - Vaadin componentization

(Near-)Final data design

Provide a default concrete class Help 80% of the time

Page 18: SoftShake 2013 - Vaadin componentization

Composition summary

Think about UI configuration

Think about the wrapped model

Make it easy for your developers, they are your users This makes it hard for you as the designer!

Page 19: SoftShake 2013 - Vaadin componentization

Extension points

1. Compose base components

2. Wrap GWT widgets

3. Extensions

4. Wrap JavaScript

5. Theme

Page 20: SoftShake 2013 - Vaadin componentization

Connector architectureServer-

side

"Glue" between server and client

Client-side

Page 21: SoftShake 2013 - Vaadin componentization

Connector architecture

This let us use a server-side component MyComponent

Displayed client-side MyWidget

Page 23: SoftShake 2013 - Vaadin componentization

YouTubePlayer server-side

public class YouTubePlayer extends AbstractComponent {}

Page 24: SoftShake 2013 - Vaadin componentization

YouTubeConnector client-side

@Connect(YouTubePlayer.class)public class YouTubeConnector extends AbstractComponentConnector {

public YouTubeViewer getWidget() { return (YouTubeViewer) super.getWidget(); }

protected Widget createWidget() { return new YouTubeViewer("GOKX-bGmi0k"); }}

Page 25: SoftShake 2013 - Vaadin componentization

Shared state

Communication between server and client

Page 26: SoftShake 2013 - Vaadin componentization

Shared state

Create API server-side

Create a getter/setter on the shared state

Implement onStateChanged() on the connector Call widget’s methods accordingly

Page 27: SoftShake 2013 - Vaadin componentization

YouTubeState client-side

public class YouTubeState extends AbstractComponentState {

private String movieId;

public String getMovieId() {

return movieId; }

public void setMovieId(String movieId) {

this.movieId = movieId; } }

Page 28: SoftShake 2013 - Vaadin componentization

YouTubePlayer server-side

public class YouTubePlayer extends AbstractComponent {

public YouTubePlayer(String movieId) {

getState().setMovieId(movieId); }

@Override public YouTubeState getState() {

   return (YouTubeState ) super.getState(); }}

Doesn’t necessarily mirror state nor client

Page 29: SoftShake 2013 - Vaadin componentization

YouTubeConnector client-side

@Connect(YouTubePlayer.class)public class YouTubeConnector extends AbstractComponentConnector {

// get & create widget as previously public void onStateChanged(StateChangeEvent e) {

super.onStateChanged(e); String movieId = getState().getMovieId(); getWidget().setMovieID(movieId); }}

What happens with more than one possible

state attribute?

Because it’s pays to play on the safe side

Page 30: SoftShake 2013 - Vaadin componentization

hasPropertyChanged

public void onStateChanged(StateChangeEvent e) {

super.onStateChanged(e);

if (e.hasPropertyChanged(“movieId”) {

String movieId = getState().getMovieId(); getWidget().setMovieID(movieId); } }

A constant is in order

Page 31: SoftShake 2013 - Vaadin componentization

Project structure

<root-package>

client

ClientWidget

ClientConnector

SharedState

ServerComponent

gwt.xml

Page 32: SoftShake 2013 - Vaadin componentization

Configuration

Reference widget(s) in gwt.xml

Reference gwt.xml in servlet configuration Either web.xml Or annotation

Page 33: SoftShake 2013 - Vaadin componentization

Client compilation

Only a single GWT compiled package per WAR

Compile once in the final WAR whatever the number of widgets And be done with it!

Page 34: SoftShake 2013 - Vaadin componentization

GWT widget wrap summary

1. Create server-side component API

2. Then develop what is needed Client-side widget (if necessary) Connector State

3. No need to package compiled-client code more than once

Page 35: SoftShake 2013 - Vaadin componentization

Extension points

1. Compose base components

2. Wrap GWT widgets

3. Extensions

4. Wrap JavaScript

5. Theme

Page 36: SoftShake 2013 - Vaadin componentization

Extensions

Extensions are a way to add client-side features to an existing component

Examples: Tooltip on labels Icon on text fields Caps lock warning on password fields Etc.

7

Page 37: SoftShake 2013 - Vaadin componentization

Extension architecture

Page 38: SoftShake 2013 - Vaadin componentization

Extension server-side

public class Tooltip extends AbstractExtension {

public void extend(TextField field) {

super.extend(field);

}

}

Page 39: SoftShake 2013 - Vaadin componentization

Extension client-side

@Connect(Tooltip.class)public class TooltipConnector extends AbstractExtensionConnector { @Override protected void extend(ServerConnector target) { final Widget tf = ((ComponentConnector) target).getWidget(); final VOverlay tooltip = new VOverlay(); tooltip.add(new HTML("<div class='c-tooltip'>Static tooltip</div>"));

Page 40: SoftShake 2013 - Vaadin componentization

Extension client-side continued

tf.addDomHandler(new MouseOverHandler() { @Override public void onMouseOver(MouseOverEvent event) { tooltip.showRelativeTo(tf); } }, MouseOverEvent.getType()); tf.addDomHandler(new MouseOutHandler() { @Override public void onMouseOut(MouseOutEvent event) { tooltip.hide(); } }, MouseOutEvent.getType()); }}

Page 41: SoftShake 2013 - Vaadin componentization

Usage

TextField tf = new TextField("Name");

new Tooltip().extend(tf);

And that’s all! But you need GWT skills...

Noticed the tooltip is static? "<div class='c-tooltip'>Static tooltip</div>"

Reversed order

Page 42: SoftShake 2013 - Vaadin componentization

Client-side state extension

public class TooltipState extends SharedState { private String tooltip; public String getTooltip() { return tooltip; } public void setTooltip (String tooltip) { this.tooltip = tooltip; }}

Page 43: SoftShake 2013 - Vaadin componentization

Dynamic extension server-side

public class Tooltip extends AbstractExtension { @Override public TooltipState getState() { return (TooltipState) super.getState(); } public void extend(TextField tf, String tooltip) { getState().setTooltip(tooltip); super.extend(link); }}

Page 44: SoftShake 2013 - Vaadin componentization

Dynamic Extension client-side

@Connect(TooltipExtension.class)public class TooltipConnector extends AbstractExtensionConnector { @Override public TooltipState getState() { return (TooltipState) super.getState(); }

@Override protected void extend(ServerConnector target) { … String text = getState().getTooltip(); tooltip.add(new HTML("<div class='c-tooltip'>" + text + "</div>")); … }}

Page 45: SoftShake 2013 - Vaadin componentization

Dynamic usage

TextField tf = new TextField("Name");

new Tooltip().extend(tf, "really useful tooltip");

Page 46: SoftShake 2013 - Vaadin componentization

Extension summary

1. For added client-side capacity

2. Simple usage server-side

3. Requires GWT skills

4. State to the rescue For runtime changes

Page 47: SoftShake 2013 - Vaadin componentization

Wrap JavaScript

1. Compose base components

2. Wrap GWT widgets

3. Extensions

4. Wrap JavaScript

5. Theme

7

Page 48: SoftShake 2013 - Vaadin componentization

JavaScript before 7

window.executeJavascript(String script)

“ Executes JavaScript in this window.

This method allows one to inject JavaScript from the server to client. A client implementation is not required to implement this functionality, but currently all web-based clients do implement this.

Use of this method should be avoided and instead it is recommended to create new widgets with GWT.”

Page 49: SoftShake 2013 - Vaadin componentization

JavaScript before 7

Not always feasible to wrap JavaScript in GWT

Not always available GWT skills

Not always possible to use JavaScript directly Nor maintainable when it is

Page 50: SoftShake 2013 - Vaadin componentization

JavaScript in 7

To embed scripts client-side

1. JavaScript extension To improve existing widgets

2. JavaScript component To add

Page 51: SoftShake 2013 - Vaadin componentization

JavaScript extension architecture

Page 52: SoftShake 2013 - Vaadin componentization

@JavaScript usage

On server-side JavaScript extension

Absolute resources https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js

Local resources bootstrap.js bootstrap_connector.js

Page 53: SoftShake 2013 - Vaadin componentization

Calling JS function

callFunction("functionName", arguments) Provides a way to call JavaScript scripts server-side

Page 54: SoftShake 2013 - Vaadin componentization

JavaScript extension server-side

@JavaScript({ "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js", "bootstrap.js", "bootstrap_connector.js" })public class JsTooltipExtension extends AbstractJavaScriptExtension { public void extend(TextField tf, String tooltip) { super.extend(tf); callFunction("attach", tooltip); }}

Page 55: SoftShake 2013 - Vaadin componentization

Binding with JavaScript

There’s no connector per se As there’s no GWT widget But we still need to bind betwen server and client

All local scripts have to be in the same package as the extension

Page 56: SoftShake 2013 - Vaadin componentization

JavaScript extension client-side

window.package_JavascriptTooltipExtension = function() { this.attach = function(options) { var connectorId = this.getParentId(); var element = this.getElement(connectorId); var tf = element.childNodes[0]; tf.rel = "tooltip"; tf.title = options[0]; $(tf).tooltip(); }}

Anonymous function

Namespace as underscore separated package name

Called server-

side

Page 57: SoftShake 2013 - Vaadin componentization

JavaScript and state

State as seen previously applies com.vaadin.shared.ui.JavaScriptComponentState

On client-side

window.package_JavascriptExtension = function() { this.onChange = function() { this.getState() … }}

Page 58: SoftShake 2013 - Vaadin componentization

JavaScript component

Very alike to extension But will create the HTML DIV Hopefully… never played with it

Page 59: SoftShake 2013 - Vaadin componentization

JavaScript component architecture

Page 60: SoftShake 2013 - Vaadin componentization

Wrap JavaScript summary

When JavaScript is available Just need a JS connector script

Pros No need to use GWT Can still be packaged as JARs

Cons Loses all static typing

Page 61: SoftShake 2013 - Vaadin componentization

Themes

1. Compose base components

2. Wrap GWT widgets

3. Extensions

4. Wrap JavaScript

5. Theme

7

Page 62: SoftShake 2013 - Vaadin componentization

Themes

Themes are an easy way to change applications appearance CSS / SASS Images HTML layouts

@Theme

Provided OOTB reindeer (default) runo chameleon

7

Page 63: SoftShake 2013 - Vaadin componentization

Theme structure

VAADIN/themes

mytheme.scss

styles.scss

img

layouts

Page 64: SoftShake 2013 - Vaadin componentization

Themes are undervalued

SASS is extra-powerful

Very easy to use

Packaged in JARs

Front-end and Java developers can work in parallel

Page 65: SoftShake 2013 - Vaadin componentization

Summary

Vaadin is Component-Oriented Create your own Design for reusability

Use it to your advantage!

Page 66: SoftShake 2013 - Vaadin componentization

Thanks for your attention ?