SlideShare une entreprise Scribd logo
1  sur  66
Vaadin
Componentize your UI

extension points
Who am I
• Java (EE) Dev/Architect
• Vaadin enthusiast
• General blog
•

http://blog.frankel.ch

•

@nicolas_frankel

• Vaadin specific
•

http://morevaadin.com

•

@learnvaadin
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
Extension points
1.

Compose base components

2.

Wrap GWT widgets

3.

Extensions

4.

Wrap JavaScript

5.

Theme
Composition
• It can’t be that hard
 Just compose…

• Let’s create an Address component
 And see for ourselves
First step
public class Address extends VerticalLayout {
public Address() {

}

}

addComponent(new
addComponent(new
addComponent(new
addComponent(new

TextField("Ligne 1"));
TextField("Ligne 2"));
TextField("Ville"));
TextField("NPA"));
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);
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);
Problems?
 No choice between labels and input prompts
 No choice between spacing or not
 i18n
 Fixed layout
 And so on
 No configuration feature!
Configuration design
 Expose your configuration features
 Wrap the rest
 As for API

 Introduce middle-components for decoupling
 For layout, use CustomComponent
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
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
Simple data design
 An address component should display an address bean!
Better data design
 Enable data buffering
 Commit / discard
Even better data design
(Near-)Final data design

 Provide a default concrete class
 Help 80% of the time
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!
Extension points
1.

Compose base components

2.

Wrap GWT widgets

3.

Extensions

4.

Wrap JavaScript

5.

Theme
Connector architecture
Connector architecture
 This let us use a server-side component
 MyComponent

 Displayed client-side
 MyWidget
YouTubePlayer widget
 Simple widget displaying a
YouTube video
 For example purpose only
 Deprecated
YouTubePlayer server-side
public class YouTubePlayer extends AbstractComponent {
}
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");
}
Shared state
Shared state
 Create API server-side
 Create a getter/setter on the shared state
 Implement onStateChanged() on the connector
 Call widget’s methods accordingly
YouTubeState client-side
public class YouTubeState extends AbstractComponentState {
private String movieId;
public String getMovieId() {

}

return movieId;

public void setMovieId(String movieId) {

}

}

this.movieId = movieId;
YouTubePlayer server-side
public class YouTubePlayer extends AbstractComponent {
public YouTubePlayer(String movieId) {
}

getState().setMovieId(movieId);

@Override
public YouTubeState getState() {

}

}

return (YouTubeState ) super.getState();
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);
hasPropertyChanged
public void onStateChanged(StateChangeEvent e) {
super.onStateChanged(e);
if (e.hasPropertyChanged(“movieId”) {
String movieId = getState().getMovieId();
getWidget().setMovieID(movieId);
}
}
Project structure
<root-package>
client

ClientWidget

ServerComponent

ClientConnector

gwt.xml

SharedState
Configuration
 Reference widget(s) in gwt.xml
 Reference gwt.xml in servlet configuration
 Either web.xml
 Or annotation
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!
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
Extension points
1.

Compose base components

2.

Wrap GWT widgets

3.

Extensions

4.

Wrap JavaScript

5.

Theme
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.
Extension architecture
Extension server-side
public class Tooltip extends AbstractExtension {
public void extend(TextField field) {
super.extend(field);
}
}
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>"));
Extension client-side
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());

continued
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>"
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;
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);
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>"));
…
Dynamic usage
TextField tf = new TextField("Name");
new Tooltip().extend(tf, "really useful tooltip");
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
Wrap JavaScript
1.

Compose base components

2.

Wrap GWT widgets

3.

Extensions

4.

Wrap JavaScript

5.

Theme
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.”
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
JavaScript in 7
 To embed scripts client-side

1. JavaScript extension
 To improve existing widgets

2. JavaScript component
 To add
JavaScript extension architecture
@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
Calling JS function
 callFunction("functionName", arguments)
 Provides a way to call JavaScript scripts server-side
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);
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
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();
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() …
}
}
JavaScript component
 Very alike to extension
 But will create the HTML DIV
 Hopefully… never played with it 
JavaScript component architecture
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
Themes
1.

Compose base components

2.

Wrap GWT widgets

3.

Extensions

4.

Wrap JavaScript

5.

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

 @Theme
 Provided OOTB
 reindeer (default)
 runo
 chameleon
Theme structure
VAADIN/themes
mytheme.scss
styles.scss
img
layouts
Themes are undervalued
 SASS is extra-powerful
 Very easy to use
 Packaged in JARs
 Front-end and Java developers can work in parallel
Summary
 Vaadin is Component-Oriented
 Create your own
 Design for reusability

 Use it to your advantage!
Thanks for your attention

Contenu connexe

Tendances

Angular based enterprise level frontend architecture
Angular based enterprise level frontend architectureAngular based enterprise level frontend architecture
Angular based enterprise level frontend architectureHimanshu Tamrakar
 
How to Build ToDo App with Vue 3 + TypeScript
How to Build ToDo App with Vue 3 + TypeScriptHow to Build ToDo App with Vue 3 + TypeScript
How to Build ToDo App with Vue 3 + TypeScriptKaty Slemon
 
How to create an Angular builder
How to create an Angular builderHow to create an Angular builder
How to create an Angular builderMaurizio Vitale
 
Java Intro: Unit1. Hello World
Java Intro: Unit1. Hello WorldJava Intro: Unit1. Hello World
Java Intro: Unit1. Hello WorldYakov Fain
 
Mulesoft kochi meetup 8 custom connector
Mulesoft kochi meetup 8   custom connectorMulesoft kochi meetup 8   custom connector
Mulesoft kochi meetup 8 custom connectorSupriya Pawar
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfKaty Slemon
 
Ingress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway APIIngress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway APIVMware Tanzu
 
BMO - Intelligent Projects with Maven
BMO - Intelligent Projects with MavenBMO - Intelligent Projects with Maven
BMO - Intelligent Projects with MavenMert Çalışkan
 
Go swagger tutorial how to create golang api documentation using go swagger (1)
Go swagger tutorial how to create golang api documentation using go swagger (1)Go swagger tutorial how to create golang api documentation using go swagger (1)
Go swagger tutorial how to create golang api documentation using go swagger (1)Katy Slemon
 
Angular elements - embed your angular components EVERYWHERE
Angular elements - embed your angular components EVERYWHEREAngular elements - embed your angular components EVERYWHERE
Angular elements - embed your angular components EVERYWHERENadav Mary
 
Tech Webinar: Angular 2, Introduction to a new framework
Tech Webinar: Angular 2, Introduction to a new frameworkTech Webinar: Angular 2, Introduction to a new framework
Tech Webinar: Angular 2, Introduction to a new frameworkCodemotion
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java DevelopersYakov Fain
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2Knoldus Inc.
 
Microservices in a netshell
Microservices in a netshellMicroservices in a netshell
Microservices in a netshellKnoldus Inc.
 
Angular - Chapter 1 - Introduction
 Angular - Chapter 1 - Introduction Angular - Chapter 1 - Introduction
Angular - Chapter 1 - IntroductionWebStackAcademy
 
Single Page Applications with AngularJS 2.0
Single Page Applications with AngularJS 2.0 Single Page Applications with AngularJS 2.0
Single Page Applications with AngularJS 2.0 Sumanth Chinthagunta
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsSpeed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsYakov Fain
 

Tendances (20)

Angular based enterprise level frontend architecture
Angular based enterprise level frontend architectureAngular based enterprise level frontend architecture
Angular based enterprise level frontend architecture
 
How to Build ToDo App with Vue 3 + TypeScript
How to Build ToDo App with Vue 3 + TypeScriptHow to Build ToDo App with Vue 3 + TypeScript
How to Build ToDo App with Vue 3 + TypeScript
 
How to create an Angular builder
How to create an Angular builderHow to create an Angular builder
How to create an Angular builder
 
Angular 5
Angular 5Angular 5
Angular 5
 
Java Intro: Unit1. Hello World
Java Intro: Unit1. Hello WorldJava Intro: Unit1. Hello World
Java Intro: Unit1. Hello World
 
Mulesoft kochi meetup 8 custom connector
Mulesoft kochi meetup 8   custom connectorMulesoft kochi meetup 8   custom connector
Mulesoft kochi meetup 8 custom connector
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
 
Ingress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway APIIngress? That’s So 2020! Introducing the Kubernetes Gateway API
Ingress? That’s So 2020! Introducing the Kubernetes Gateway API
 
BMO - Intelligent Projects with Maven
BMO - Intelligent Projects with MavenBMO - Intelligent Projects with Maven
BMO - Intelligent Projects with Maven
 
Go swagger tutorial how to create golang api documentation using go swagger (1)
Go swagger tutorial how to create golang api documentation using go swagger (1)Go swagger tutorial how to create golang api documentation using go swagger (1)
Go swagger tutorial how to create golang api documentation using go swagger (1)
 
Angular elements - embed your angular components EVERYWHERE
Angular elements - embed your angular components EVERYWHEREAngular elements - embed your angular components EVERYWHERE
Angular elements - embed your angular components EVERYWHERE
 
Tech Webinar: Angular 2, Introduction to a new framework
Tech Webinar: Angular 2, Introduction to a new frameworkTech Webinar: Angular 2, Introduction to a new framework
Tech Webinar: Angular 2, Introduction to a new framework
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java Developers
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2
 
Microservices in a netshell
Microservices in a netshellMicroservices in a netshell
Microservices in a netshell
 
Angular - Chapter 1 - Introduction
 Angular - Chapter 1 - Introduction Angular - Chapter 1 - Introduction
Angular - Chapter 1 - Introduction
 
Introduction to angular 4
Introduction to angular 4Introduction to angular 4
Introduction to angular 4
 
Single Page Applications with AngularJS 2.0
Single Page Applications with AngularJS 2.0 Single Page Applications with AngularJS 2.0
Single Page Applications with AngularJS 2.0
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsSpeed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSockets
 
Vue.js Use Cases
Vue.js Use CasesVue.js Use Cases
Vue.js Use Cases
 

En vedette

板金修理 白河市の新車販売店・車検整備工場・板金塗装工場
板金修理 白河市の新車販売店・車検整備工場・板金塗装工場板金修理 白河市の新車販売店・車検整備工場・板金塗装工場
板金修理 白河市の新車販売店・車検整備工場・板金塗装工場ken hozu
 
Paradise resort
Paradise resortParadise resort
Paradise resortivekelly
 
Vindecarea cancerului
Vindecarea canceruluiVindecarea cancerului
Vindecarea canceruluiElvira Jianu
 
αγγελωνα
αγγελωνα αγγελωνα
αγγελωνα dimandres
 
οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016
οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016
οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016gina zaza
 
Aina sadaqat ahlesunnat
Aina sadaqat ahlesunnatAina sadaqat ahlesunnat
Aina sadaqat ahlesunnatsunninews92
 
La importancia de las redes sociales en la educación
La importancia de las redes sociales en la educaciónLa importancia de las redes sociales en la educación
La importancia de las redes sociales en la educaciónestefanipolet
 
Tanggung jawab sosial perusahaan
Tanggung jawab sosial perusahaanTanggung jawab sosial perusahaan
Tanggung jawab sosial perusahaanArini Nurmala Sari
 
Krishna Ashtothara Sata Namavali Malayalam
Krishna Ashtothara Sata Namavali MalayalamKrishna Ashtothara Sata Namavali Malayalam
Krishna Ashtothara Sata Namavali MalayalamRavi Ramakrishnan
 
diabetes controlada bonus
diabetes controlada bonusdiabetes controlada bonus
diabetes controlada bonuslandim38
 
Sistema Nervioso Presentacion
Sistema Nervioso PresentacionSistema Nervioso Presentacion
Sistema Nervioso Presentacionbichis98
 

En vedette (18)

板金修理 白河市の新車販売店・車検整備工場・板金塗装工場
板金修理 白河市の新車販売店・車検整備工場・板金塗装工場板金修理 白河市の新車販売店・車検整備工場・板金塗装工場
板金修理 白河市の新車販売店・車検整備工場・板金塗装工場
 
Paradise resort
Paradise resortParadise resort
Paradise resort
 
Vindecarea cancerului
Vindecarea canceruluiVindecarea cancerului
Vindecarea cancerului
 
Cuaderno 2
Cuaderno 2Cuaderno 2
Cuaderno 2
 
αγγελωνα
αγγελωνα αγγελωνα
αγγελωνα
 
Funções do
Funções doFunções do
Funções do
 
uio
uiouio
uio
 
οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016
οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016
οδηγίες αξιολόγησης ΓΕΛ 2015 - 2016
 
Aina sadaqat ahlesunnat
Aina sadaqat ahlesunnatAina sadaqat ahlesunnat
Aina sadaqat ahlesunnat
 
La importancia de las redes sociales en la educación
La importancia de las redes sociales en la educaciónLa importancia de las redes sociales en la educación
La importancia de las redes sociales en la educación
 
Tanggung jawab sosial perusahaan
Tanggung jawab sosial perusahaanTanggung jawab sosial perusahaan
Tanggung jawab sosial perusahaan
 
PAUD
PAUDPAUD
PAUD
 
Krishna Ashtothara Sata Namavali Malayalam
Krishna Ashtothara Sata Namavali MalayalamKrishna Ashtothara Sata Namavali Malayalam
Krishna Ashtothara Sata Namavali Malayalam
 
Cuaderno 1
Cuaderno 1Cuaderno 1
Cuaderno 1
 
Untitled Presentation
Untitled PresentationUntitled Presentation
Untitled Presentation
 
diabetes controlada bonus
diabetes controlada bonusdiabetes controlada bonus
diabetes controlada bonus
 
Sistema Nervioso Presentacion
Sistema Nervioso PresentacionSistema Nervioso Presentacion
Sistema Nervioso Presentacion
 
Untitled Presentation
Untitled PresentationUntitled Presentation
Untitled Presentation
 

Similaire à SoftShake 2013 - Vaadin componentization

Wicket Introduction
Wicket IntroductionWicket Introduction
Wicket IntroductionEyal Golan
 
GWT Training - Session 1/3
GWT Training - Session 1/3GWT Training - Session 1/3
GWT Training - Session 1/3Faiz Bashir
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitJava Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitIMC Institute
 
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13Fred Sauer
 
VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...
VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...
VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...VMworld
 
Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2JooinK
 
Google Web Toolkit Introduction - eXo Platform SEA
Google Web Toolkit Introduction - eXo Platform SEAGoogle Web Toolkit Introduction - eXo Platform SEA
Google Web Toolkit Introduction - eXo Platform SEAnerazz08
 
GWT 2 Is Smarter Than You
GWT 2 Is Smarter Than YouGWT 2 Is Smarter Than You
GWT 2 Is Smarter Than YouRobert Cooper
 
GWT training session 1
GWT training session 1GWT training session 1
GWT training session 1SNEHAL MASNE
 
Java EE 7 Recipes
Java EE 7 RecipesJava EE 7 Recipes
Java EE 7 RecipesJosh Juneau
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersJiaxuan Lin
 
Introduction to Google Web Toolkit
Introduction to Google Web ToolkitIntroduction to Google Web Toolkit
Introduction to Google Web ToolkitDidier Girard
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]GDSC UofT Mississauga
 
GWT + Gears : The browser is the platform
GWT + Gears : The browser is the platformGWT + Gears : The browser is the platform
GWT + Gears : The browser is the platformDidier Girard
 
Using And Extending The DotNetNuke Widget Framework
Using And Extending The DotNetNuke Widget FrameworkUsing And Extending The DotNetNuke Widget Framework
Using And Extending The DotNetNuke Widget FrameworkNik Kalyani
 
Module 4: Introduction to ASP.NET 3.5 (Material)
Module 4: Introduction to ASP.NET 3.5 (Material)Module 4: Introduction to ASP.NET 3.5 (Material)
Module 4: Introduction to ASP.NET 3.5 (Material)Mohamed Saleh
 
D22 Portlet Development With Open Source Frameworks
D22 Portlet Development With Open Source FrameworksD22 Portlet Development With Open Source Frameworks
D22 Portlet Development With Open Source FrameworksSunil Patil
 

Similaire à SoftShake 2013 - Vaadin componentization (20)

Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
Wicket Introduction
Wicket IntroductionWicket Introduction
Wicket Introduction
 
GWT Training - Session 1/3
GWT Training - Session 1/3GWT Training - Session 1/3
GWT Training - Session 1/3
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitJava Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
 
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
 
VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...
VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...
VMworld 2013: vSphere UI Platform Best Practices: Putting the Web Client SDK ...
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2
 
Google Web Toolkit Introduction - eXo Platform SEA
Google Web Toolkit Introduction - eXo Platform SEAGoogle Web Toolkit Introduction - eXo Platform SEA
Google Web Toolkit Introduction - eXo Platform SEA
 
Custom PrimeFaces components
Custom PrimeFaces componentsCustom PrimeFaces components
Custom PrimeFaces components
 
GWT 2 Is Smarter Than You
GWT 2 Is Smarter Than YouGWT 2 Is Smarter Than You
GWT 2 Is Smarter Than You
 
GWT training session 1
GWT training session 1GWT training session 1
GWT training session 1
 
Java EE 7 Recipes
Java EE 7 RecipesJava EE 7 Recipes
Java EE 7 Recipes
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for Beginners
 
Introduction to Google Web Toolkit
Introduction to Google Web ToolkitIntroduction to Google Web Toolkit
Introduction to Google Web Toolkit
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]
 
GWT + Gears : The browser is the platform
GWT + Gears : The browser is the platformGWT + Gears : The browser is the platform
GWT + Gears : The browser is the platform
 
Using And Extending The DotNetNuke Widget Framework
Using And Extending The DotNetNuke Widget FrameworkUsing And Extending The DotNetNuke Widget Framework
Using And Extending The DotNetNuke Widget Framework
 
Module 4: Introduction to ASP.NET 3.5 (Material)
Module 4: Introduction to ASP.NET 3.5 (Material)Module 4: Introduction to ASP.NET 3.5 (Material)
Module 4: Introduction to ASP.NET 3.5 (Material)
 
D22 Portlet Development With Open Source Frameworks
D22 Portlet Development With Open Source FrameworksD22 Portlet Development With Open Source Frameworks
D22 Portlet Development With Open Source Frameworks
 

Plus de Nicolas Fränkel

SnowCamp - Adding search to a legacy application
SnowCamp - Adding search to a legacy applicationSnowCamp - Adding search to a legacy application
SnowCamp - Adding search to a legacy applicationNicolas Fränkel
 
Un CV de dévelopeur toujours a jour
Un CV de dévelopeur toujours a jourUn CV de dévelopeur toujours a jour
Un CV de dévelopeur toujours a jourNicolas Fränkel
 
Zero-downtime deployment on Kubernetes with Hazelcast
Zero-downtime deployment on Kubernetes with HazelcastZero-downtime deployment on Kubernetes with Hazelcast
Zero-downtime deployment on Kubernetes with HazelcastNicolas Fränkel
 
jLove - A Change-Data-Capture use-case: designing an evergreen cache
jLove - A Change-Data-Capture use-case: designing an evergreen cachejLove - A Change-Data-Capture use-case: designing an evergreen cache
jLove - A Change-Data-Capture use-case: designing an evergreen cacheNicolas Fränkel
 
BigData conference - Introduction to stream processing
BigData conference - Introduction to stream processingBigData conference - Introduction to stream processing
BigData conference - Introduction to stream processingNicolas Fränkel
 
ADDO - Your own Kubernetes controller, not only in Go
ADDO - Your own Kubernetes controller, not only in GoADDO - Your own Kubernetes controller, not only in Go
ADDO - Your own Kubernetes controller, not only in GoNicolas Fränkel
 
TestCon Europe - Mutation Testing to the Rescue of Your Tests
TestCon Europe - Mutation Testing to the Rescue of Your TestsTestCon Europe - Mutation Testing to the Rescue of Your Tests
TestCon Europe - Mutation Testing to the Rescue of Your TestsNicolas Fränkel
 
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java applicationOSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java applicationNicolas Fränkel
 
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cache
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cacheGeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cache
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cacheNicolas Fränkel
 
JavaDay Istanbul - 3 improvements in your microservices architecture
JavaDay Istanbul - 3 improvements in your microservices architectureJavaDay Istanbul - 3 improvements in your microservices architecture
JavaDay Istanbul - 3 improvements in your microservices architecture Nicolas Fränkel
 
OSCONF Hyderabad - Shorten all URLs!
OSCONF Hyderabad - Shorten all URLs!OSCONF Hyderabad - Shorten all URLs!
OSCONF Hyderabad - Shorten all URLs!Nicolas Fränkel
 
Devclub.lv - Introduction to stream processing
Devclub.lv - Introduction to stream processingDevclub.lv - Introduction to stream processing
Devclub.lv - Introduction to stream processingNicolas Fränkel
 
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring Boot
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring BootOSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring Boot
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring BootNicolas Fränkel
 
JOnConf - A CDC use-case: designing an Evergreen Cache
JOnConf - A CDC use-case: designing an Evergreen CacheJOnConf - A CDC use-case: designing an Evergreen Cache
JOnConf - A CDC use-case: designing an Evergreen CacheNicolas Fränkel
 
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...Nicolas Fränkel
 
JUG Tirana - Introduction to data streaming
JUG Tirana - Introduction to data streamingJUG Tirana - Introduction to data streaming
JUG Tirana - Introduction to data streamingNicolas Fränkel
 
Java.IL - Your own Kubernetes controller, not only in Go!
Java.IL - Your own Kubernetes controller, not only in Go!Java.IL - Your own Kubernetes controller, not only in Go!
Java.IL - Your own Kubernetes controller, not only in Go!Nicolas Fränkel
 
vJUG - Introduction to data streaming
vJUG - Introduction to data streamingvJUG - Introduction to data streaming
vJUG - Introduction to data streamingNicolas Fränkel
 
London Java Community - An Experiment in Continuous Deployment of JVM applica...
London Java Community - An Experiment in Continuous Deployment of JVM applica...London Java Community - An Experiment in Continuous Deployment of JVM applica...
London Java Community - An Experiment in Continuous Deployment of JVM applica...Nicolas Fränkel
 
OSCONF - Your own Kubernetes controller: not only in Go
OSCONF - Your own Kubernetes controller: not only in GoOSCONF - Your own Kubernetes controller: not only in Go
OSCONF - Your own Kubernetes controller: not only in GoNicolas Fränkel
 

Plus de Nicolas Fränkel (20)

SnowCamp - Adding search to a legacy application
SnowCamp - Adding search to a legacy applicationSnowCamp - Adding search to a legacy application
SnowCamp - Adding search to a legacy application
 
Un CV de dévelopeur toujours a jour
Un CV de dévelopeur toujours a jourUn CV de dévelopeur toujours a jour
Un CV de dévelopeur toujours a jour
 
Zero-downtime deployment on Kubernetes with Hazelcast
Zero-downtime deployment on Kubernetes with HazelcastZero-downtime deployment on Kubernetes with Hazelcast
Zero-downtime deployment on Kubernetes with Hazelcast
 
jLove - A Change-Data-Capture use-case: designing an evergreen cache
jLove - A Change-Data-Capture use-case: designing an evergreen cachejLove - A Change-Data-Capture use-case: designing an evergreen cache
jLove - A Change-Data-Capture use-case: designing an evergreen cache
 
BigData conference - Introduction to stream processing
BigData conference - Introduction to stream processingBigData conference - Introduction to stream processing
BigData conference - Introduction to stream processing
 
ADDO - Your own Kubernetes controller, not only in Go
ADDO - Your own Kubernetes controller, not only in GoADDO - Your own Kubernetes controller, not only in Go
ADDO - Your own Kubernetes controller, not only in Go
 
TestCon Europe - Mutation Testing to the Rescue of Your Tests
TestCon Europe - Mutation Testing to the Rescue of Your TestsTestCon Europe - Mutation Testing to the Rescue of Your Tests
TestCon Europe - Mutation Testing to the Rescue of Your Tests
 
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java applicationOSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application
 
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cache
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cacheGeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cache
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cache
 
JavaDay Istanbul - 3 improvements in your microservices architecture
JavaDay Istanbul - 3 improvements in your microservices architectureJavaDay Istanbul - 3 improvements in your microservices architecture
JavaDay Istanbul - 3 improvements in your microservices architecture
 
OSCONF Hyderabad - Shorten all URLs!
OSCONF Hyderabad - Shorten all URLs!OSCONF Hyderabad - Shorten all URLs!
OSCONF Hyderabad - Shorten all URLs!
 
Devclub.lv - Introduction to stream processing
Devclub.lv - Introduction to stream processingDevclub.lv - Introduction to stream processing
Devclub.lv - Introduction to stream processing
 
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring Boot
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring BootOSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring Boot
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring Boot
 
JOnConf - A CDC use-case: designing an Evergreen Cache
JOnConf - A CDC use-case: designing an Evergreen CacheJOnConf - A CDC use-case: designing an Evergreen Cache
JOnConf - A CDC use-case: designing an Evergreen Cache
 
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...
 
JUG Tirana - Introduction to data streaming
JUG Tirana - Introduction to data streamingJUG Tirana - Introduction to data streaming
JUG Tirana - Introduction to data streaming
 
Java.IL - Your own Kubernetes controller, not only in Go!
Java.IL - Your own Kubernetes controller, not only in Go!Java.IL - Your own Kubernetes controller, not only in Go!
Java.IL - Your own Kubernetes controller, not only in Go!
 
vJUG - Introduction to data streaming
vJUG - Introduction to data streamingvJUG - Introduction to data streaming
vJUG - Introduction to data streaming
 
London Java Community - An Experiment in Continuous Deployment of JVM applica...
London Java Community - An Experiment in Continuous Deployment of JVM applica...London Java Community - An Experiment in Continuous Deployment of JVM applica...
London Java Community - An Experiment in Continuous Deployment of JVM applica...
 
OSCONF - Your own Kubernetes controller: not only in Go
OSCONF - Your own Kubernetes controller: not only in GoOSCONF - Your own Kubernetes controller: not only in Go
OSCONF - Your own Kubernetes controller: not only in Go
 

Dernier

Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...
Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...
Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...JeylaisaManabat1
 
Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...
Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...
Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...Authentic No 1 Amil Baba In Pakistan
 
Inspiring Through Words Power of Inspiration.pptx
Inspiring Through Words Power of Inspiration.pptxInspiring Through Words Power of Inspiration.pptx
Inspiring Through Words Power of Inspiration.pptxShubham Rawat
 
南新罕布什尔大学毕业证学位证成绩单-学历认证
南新罕布什尔大学毕业证学位证成绩单-学历认证南新罕布什尔大学毕业证学位证成绩单-学历认证
南新罕布什尔大学毕业证学位证成绩单-学历认证kbdhl05e
 
integrity in personal relationship (1).pdf
integrity in personal relationship (1).pdfintegrity in personal relationship (1).pdf
integrity in personal relationship (1).pdfAmitRout25
 
Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?
Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?
Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?Mikko Kangassalo
 
(南达科他州立大学毕业证学位证成绩单-永久存档)
(南达科他州立大学毕业证学位证成绩单-永久存档)(南达科他州立大学毕业证学位证成绩单-永久存档)
(南达科他州立大学毕业证学位证成绩单-永久存档)oannq
 
Spiritual Life Quote from Shiva Negi
Spiritual Life Quote from Shiva Negi Spiritual Life Quote from Shiva Negi
Spiritual Life Quote from Shiva Negi OneDay18
 

Dernier (8)

Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...
Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...
Module-2-Lesson-2-COMMUNICATION-AIDS-AND-STRATEGIES-USING-TOOLS-OF-TECHNOLOGY...
 
Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...
Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...
Authentic No 1 Amil Baba In Pakistan Amil Baba In Faisalabad Amil Baba In Kar...
 
Inspiring Through Words Power of Inspiration.pptx
Inspiring Through Words Power of Inspiration.pptxInspiring Through Words Power of Inspiration.pptx
Inspiring Through Words Power of Inspiration.pptx
 
南新罕布什尔大学毕业证学位证成绩单-学历认证
南新罕布什尔大学毕业证学位证成绩单-学历认证南新罕布什尔大学毕业证学位证成绩单-学历认证
南新罕布什尔大学毕业证学位证成绩单-学历认证
 
integrity in personal relationship (1).pdf
integrity in personal relationship (1).pdfintegrity in personal relationship (1).pdf
integrity in personal relationship (1).pdf
 
Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?
Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?
Virtue ethics & Effective Altruism: What can EA learn from virtue ethics?
 
(南达科他州立大学毕业证学位证成绩单-永久存档)
(南达科他州立大学毕业证学位证成绩单-永久存档)(南达科他州立大学毕业证学位证成绩单-永久存档)
(南达科他州立大学毕业证学位证成绩单-永久存档)
 
Spiritual Life Quote from Shiva Negi
Spiritual Life Quote from Shiva Negi Spiritual Life Quote from Shiva Negi
Spiritual Life Quote from Shiva Negi
 

SoftShake 2013 - Vaadin componentization

  • 2. Who am I • Java (EE) Dev/Architect • Vaadin enthusiast • General blog • http://blog.frankel.ch • @nicolas_frankel • Vaadin specific • http://morevaadin.com • @learnvaadin
  • 3.
  • 4. 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
  • 5. Extension points 1. Compose base components 2. Wrap GWT widgets 3. Extensions 4. Wrap JavaScript 5. Theme
  • 6. Composition • It can’t be that hard  Just compose… • Let’s create an Address component  And see for ourselves
  • 7. First step public class Address extends VerticalLayout { public Address() { } } addComponent(new addComponent(new addComponent(new addComponent(new TextField("Ligne 1")); TextField("Ligne 2")); TextField("Ville")); TextField("NPA"));
  • 8. 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);
  • 9. 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);
  • 10. Problems?  No choice between labels and input prompts  No choice between spacing or not  i18n  Fixed layout  And so on  No configuration feature!
  • 11. Configuration design  Expose your configuration features  Wrap the rest  As for API  Introduce middle-components for decoupling  For layout, use CustomComponent
  • 12. 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
  • 13. 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
  • 14. Simple data design  An address component should display an address bean!
  • 15. Better data design  Enable data buffering  Commit / discard
  • 17. (Near-)Final data design  Provide a default concrete class  Help 80% of the time
  • 18. 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!
  • 19. Extension points 1. Compose base components 2. Wrap GWT widgets 3. Extensions 4. Wrap JavaScript 5. Theme
  • 21. Connector architecture  This let us use a server-side component  MyComponent  Displayed client-side  MyWidget
  • 22. YouTubePlayer widget  Simple widget displaying a YouTube video  For example purpose only  Deprecated
  • 23. YouTubePlayer server-side public class YouTubePlayer extends AbstractComponent { }
  • 24. 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"); }
  • 26. Shared state  Create API server-side  Create a getter/setter on the shared state  Implement onStateChanged() on the connector  Call widget’s methods accordingly
  • 27. YouTubeState client-side public class YouTubeState extends AbstractComponentState { private String movieId; public String getMovieId() { } return movieId; public void setMovieId(String movieId) { } } this.movieId = movieId;
  • 28. YouTubePlayer server-side public class YouTubePlayer extends AbstractComponent { public YouTubePlayer(String movieId) { } getState().setMovieId(movieId); @Override public YouTubeState getState() { } } return (YouTubeState ) super.getState();
  • 29. 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);
  • 30. hasPropertyChanged public void onStateChanged(StateChangeEvent e) { super.onStateChanged(e); if (e.hasPropertyChanged(“movieId”) { String movieId = getState().getMovieId(); getWidget().setMovieID(movieId); } }
  • 32. Configuration  Reference widget(s) in gwt.xml  Reference gwt.xml in servlet configuration  Either web.xml  Or annotation
  • 33. 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!
  • 34. 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
  • 35. Extension points 1. Compose base components 2. Wrap GWT widgets 3. Extensions 4. Wrap JavaScript 5. Theme
  • 36. 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.
  • 38. Extension server-side public class Tooltip extends AbstractExtension { public void extend(TextField field) { super.extend(field); } }
  • 39. 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>"));
  • 40. Extension client-side 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()); continued
  • 41. 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>"
  • 42. 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;
  • 43. 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);
  • 44. 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>")); …
  • 45. Dynamic usage TextField tf = new TextField("Name"); new Tooltip().extend(tf, "really useful tooltip");
  • 46. 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
  • 47. Wrap JavaScript 1. Compose base components 2. Wrap GWT widgets 3. Extensions 4. Wrap JavaScript 5. Theme
  • 48. 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.”
  • 49. 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
  • 50. JavaScript in 7  To embed scripts client-side 1. JavaScript extension  To improve existing widgets 2. JavaScript component  To add
  • 52. @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
  • 53. Calling JS function  callFunction("functionName", arguments)  Provides a way to call JavaScript scripts server-side
  • 54. 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);
  • 55. 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
  • 56. 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();
  • 57. 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() … } }
  • 58. JavaScript component  Very alike to extension  But will create the HTML DIV  Hopefully… never played with it 
  • 60. 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
  • 61. Themes 1. Compose base components 2. Wrap GWT widgets 3. Extensions 4. Wrap JavaScript 5. Theme
  • 62. Themes  Themes are an easy way to change applications appearance  CSS / SASS  Images  HTML layouts  @Theme  Provided OOTB  reindeer (default)  runo  chameleon
  • 64. Themes are undervalued  SASS is extra-powerful  Very easy to use  Packaged in JARs  Front-end and Java developers can work in parallel
  • 65. Summary  Vaadin is Component-Oriented  Create your own  Design for reusability  Use it to your advantage!
  • 66. Thanks for your attention

Notes de l'éditeur

  1. skinparam dpi 150package com::vaadin::client::ui { abstract class AbstractConnector}package com::vaadin::client::extensions { abstract class AbstractExtensionConnector}package com::vaadin::server { abstract class AbstractClientConnector abstract class AbstractComponent abstract class AbstractExtension { {abstract} extend(connector:AbstractClientConnector) }}MyExtension -up-|&gt; AbstractExtensionAbstractExtension -up-|&gt; AbstractClientConnectorAbstractComponent -up-|&gt; AbstractClientConnectorAbstractExtensionConnector -up-|&gt; AbstractConnectorMyExtensionConnector -up-|&gt; AbstractExtensionConnectorMyExtensionConnector .left.&gt; MyExtension