Vaadin 7
-
Upload
joonas-lehtinen -
Category
Technology
-
view
3.854 -
download
0
description
Transcript of Vaadin 7
![Page 1: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/1.jpg)
![Page 2: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/2.jpg)
Vaadin 7
Joonas Lehtinen, CEO@joonaslehtinen
![Page 3: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/3.jpg)
Intro toVaadin
new Label(“Hello world”)
![Page 4: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/4.jpg)
New in
7
![Page 5: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/5.jpg)
Gettingstarted
QA
![Page 6: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/6.jpg)
![Page 7: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/7.jpg)
User interface framework for rich
web applications
![Page 8: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/8.jpg)
![Page 9: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/9.jpg)
htmljava
![Page 10: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/10.jpg)
Why on earth?
![Page 11: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/11.jpg)
consumerEE
![Page 12: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/12.jpg)
![Page 13: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/13.jpg)
expectations
![Page 14: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/14.jpg)
reality
![Page 15: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/15.jpg)
businessconsumer
“million” users10 views1!/user
“500” users50 views500!/user
>>100,000! / view 5,000! / view
![Page 16: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/16.jpg)
ProblemHow to build consumer
grade UX with business system budget
![Page 17: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/17.jpg)
How?
![Page 18: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/18.jpg)
123Key Ideas
![Page 19: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/19.jpg)
1RichComponents
![Page 20: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/20.jpg)
User IntefaceData Source
Theme
![Page 24: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/24.jpg)
![Page 25: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/25.jpg)
![Page 26: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/26.jpg)
![Page 27: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/27.jpg)
User IntefaceData Source
Theme
![Page 32: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/32.jpg)
User IntefaceData Source
Theme
![Page 33: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/33.jpg)
![Page 34: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/34.jpg)
InMemory, Bean, Method, Collection, JDBC, JPA, Hibernate, TextFile, FileSystem, Properties, EclipseLink, Lucene, Mockups, GAE, ...
![Page 35: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/35.jpg)
2Server + Client
![Page 36: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/36.jpg)
Layers of abstraction
JavaScriptJava toJavaScript
Webserver
Backendserver
required optional optionalrequired
RPC
optional
Vaa
din
required optionalrequired
GW
T
requiredrequiredJS
requiredrequired
required required
![Page 37: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/37.jpg)
How does it work, really?
![Page 38: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/38.jpg)
![Page 39: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/39.jpg)
• Initial HTML• CSS (theme)• Images• JavaScript
830k total
250k
compress
120k
reducedwidgetset
![Page 40: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/40.jpg)
![Page 41: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/41.jpg)
• name=”Joonas”• button clicked
150 bytes
![Page 42: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/42.jpg)
![Page 43: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/43.jpg)
• name=”Joonas”• button clicked
150 bytes
• Add notification
466 bytes
![Page 44: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/44.jpg)
Trying it out
![Page 45: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/45.jpg)
![Page 46: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/46.jpg)
https://github.com/jojule/NotesDemo
![Page 47: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/47.jpg)
3EmbracingJava
![Page 48: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/48.jpg)
Any JVMLanguage
![Page 49: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/49.jpg)
Internet ExplorerChromeFirefoxSafariOpera
iOSAndroid
![Page 50: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/50.jpg)
Nobrowserplugins
Nothing toinstall
![Page 51: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/51.jpg)
Servlet Portlet
(most) clouds
![Page 52: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/52.jpg)
EclipseIntelliJ IDEA
NetbeansMaven
AntSpring Roo
∙ ∙ ∙
![Page 53: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/53.jpg)
![Page 54: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/54.jpg)
Vaadin Framework7
![Page 55: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/55.jpg)
Empower Developers
Embrace Extendability
Clean Up
![Page 56: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/56.jpg)
Vaadin += GWT
![Page 57: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/57.jpg)
![Page 58: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/58.jpg)
![Page 59: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/59.jpg)
![Page 60: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/60.jpg)
GWTCompatible
![Page 61: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/61.jpg)
Server-
Client-
side
Optim
ized for
Productivity
Opt
imiz
ed fo
r
Cont
rol
![Page 62: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/62.jpg)
Server-
Client-
sideO
ptim
ized
for
Prod
uctiv
ity
Optim
ized for
Control
![Page 63: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/63.jpg)
Architecture
![Page 64: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/64.jpg)
![Page 65: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/65.jpg)
Refactored windowing
![Page 66: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/66.jpg)
![Page 67: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/67.jpg)
public class Vaadin6App extends Application {
public void init() { setMainWindow(createWindow()); }
public Window getWindow(String name) { Window window = super.getWindow(name); if (window == null) { window = createWindow(); window.setName(name); addWindow(window); } return window; }
private Window createWindow() { Window window = new Window("Vaadin 6 Application"); window.addComponent(new TextField("What is your name")); window.addComponent(new Button("Do not push me")); return window; }
}
![Page 68: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/68.jpg)
@Title("Vaadin 7 Application")public class Vaadin7uiUI extends UI {
@Override public void init(VaadinRequest request) { addComponent(new TextField("What is your name")); addComponent(new Button("Do not push me")); }
}
![Page 69: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/69.jpg)
SASS
![Page 70: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/70.jpg)
Variables & functions
![Page 71: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/71.jpg)
Mixins
![Page 72: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/72.jpg)
Nesting
![Page 73: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/73.jpg)
Selector Inheritance
![Page 74: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/74.jpg)
RedesignedForms
![Page 75: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/75.jpg)
public class Employee { String firstName; String lastName; double salary; Date birthDate; // Getters, setters, …}
Form form = new Form();form.setItemDataSource( new BeanItem<Employee>(employee));
6
![Page 76: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/76.jpg)
![Page 77: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/77.jpg)
![Page 78: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/78.jpg)
form.setFormFieldFactory(new FormFieldFactory() {
public Field createField(Item item, Object propertyId, Component uiContext) {
if ("birthDate".equals(propertyId)) { DateField df = new DateField(); df.setResolution(DateField.RESOLUTION_DAY); return df; }
// ..
return DefaultFieldFactory.createFieldByPropertyType(item .getItemProperty(propertyId).getType()); } });
6
![Page 79: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/79.jpg)
GridLayout form = new GridLayout(2,2) {
TextField firstName = new TextField("First name"); TextField lastName = new TextField("Last name"); TextField salary = new TextField("Salary"); DateField birthDate = new DateField("Birth date");
{ birthDate.setResolution(Resolution.DAY); setSpacing(true); addComponent(firstName); addComponent(lastName); addComponent(birthDate); addComponent(salary); } };
BeanFieldGroup<Employee> fieldGroup = new BeanFieldGroup<Employee>(Employee.class); fieldGroup.bindMemberFields(form); fieldGroup.setItemDataSource(new BeanItem<Employee>(employee));
7
![Page 80: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/80.jpg)
public class Person {
@Size(min = 5, max = 50) private String name;
@Min(0) @Max(100) private int age;
// + constructor + setters + getters}
![Page 81: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/81.jpg)
model
presentation
“Joonas Lehtinen”
Component
firstName = “Joonas”lastName = “Lehtinen”
![Page 82: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/82.jpg)
final TextField textField = new TextField("Name");textField.setConverter(new StringToNameConverter());
// ....
Name name = (Name) textField.getConvertedValue();
![Page 83: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/83.jpg)
public class StringToNameConverter implements Converter<String, Name> {
public Name convertToModel(String text, Locale locale) throws ConversionException {
// do the conversion }
public String convertToPresentation(Name name, Locale locale) throws ConversionException {
// do the conversion }
public Class<Name> getModelType() { return Name.class; }
public Class<String> getPresentationType() { return String.class; }}
![Page 84: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/84.jpg)
Renewed communication
![Page 85: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/85.jpg)
Component
Widget
Paintable
server
clientVariable
Changes
UIDL
6
![Page 86: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/86.jpg)
server
client
Component
Widget
Connector
RPC
7State
![Page 87: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/87.jpg)
public interface ButtonRpc extends ServerRpc { public void click(MouseEventDetails details);}
private ButtonRpc rpc = RpcProxy.create(ButtonRpc.class, this);
public void onClick(ClickEvent event) { rpc.click( new MouseEventDetails(event));}
serverclient
private ButtonRpc rpc = new ButtonRpc() { public void click( MouseEventDetails details) { // do stuff }};
public Button() { registerRpc(rpc);}
![Page 88: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/88.jpg)
JavaScriptAdd-ons
![Page 89: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/89.jpg)
getPage().getJavaScript().addCallback("myCallback", new JavaScriptCallback() { public void call(JSONArray arguments) throws JSONException { // Do something with the arguments } });
Publish API from Java
window.myCallback('foo', 100);
Use from JavaScript
![Page 90: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/90.jpg)
window.com_example_MyWidget = function() { var element = $(this.getWidgetElement());
// Draw a plot for any server-side (plot data) state change this.onStateChange = function() { $.plot(element, this.getState().series, {grid: {clickable: true}}); }
// Communicate local events back to server-side component element.bind('plotclick', function(event, point, item) { if (item) {
var onPlotClick = this.getCallback("plotClick"); onPlotClick(item.seriesIndex, item.dataIndex); } });}
Widget implementation in JavaScript
![Page 91: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/91.jpg)
public class MyWidget extends AbstractJavaScriptComponent {
public MyWidget() { registerCallback("plotClick", new JavaScriptCallback() { public void call(JSONArray arguments) throws JSONException { // Do something with the event } }); }
public static class MyWidgetState extends ComponentState { public List<List<List<Double>>> plotSeriesData = new ArrayList<List<List<Double>>>(); // getters & setters }
}
Server-side Java API for Widget
![Page 92: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/92.jpg)
gettingstarted
![Page 93: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/93.jpg)
![Page 94: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/94.jpg)
mvn archetype:generate-DarchetypeGroupId=com.vaadin -DarchetypeArtifactId= vaadin-archetype-application-DarchetypeVersion=7.0.0.beta8
Maven
yourproject-1.0.warmvn package
![Page 95: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/95.jpg)
Eclipse
http://vaadin.com/
eclipse/experimental
![Page 96: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/96.jpg)
Download for Freevaadin.com/book
~700 pages
Vaadin 7 Draft Edition
US $29.95
Vaadin is an open source Java framework for building modern web applications that look great, perform well and make you and
your users happy. http://vaadin.com/
2675387895299
ISBN 978-952-92-6753-890000
![Page 97: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/97.jpg)
�
By Marko Grönroos
ABOUT VAADIN
ww
w.d
zone
.com
Get
Mo
re R
efca
rdz!
Vis
it re
fcar
dz.c
om
#85
Getting Started with Vaadin
CONTENTS INCLUDE:
�� About Vaadin
�� Creating An Application
�� Components
�� Layout Components
�� Themes
�� Data Binding and more...
Vaadin is a server-side Ajax web application development
framework that allows you to build web applications just like
with traditional desktop frameworks, such as AWT or Swing. An
application is built from user interface components contained
hierarchically in layout components.
In the server-driven model, the application code runs on
a server, while the actual user interaction is handled by a
client-side engine running in the browser. The client-server
communications and any client-side technologies, such as
HTML and JavaScript, are invisible to the developer. As the
client-side engine runs as JavaScript in the browser, there is no
need to install plug-ins. Vaadin is released under the Apache
License 2.0.
Vaadin Client-Server Architecture
If the built-in selection of components is not enough, you can
develop new components with the Google Web Toolkit (GWT)
Figure 2: Architecture for Vaadin Applications
Hot Tip
You can get a reference to the application object
from any component attached to the application with
��$!!��
��$� ���
Event Listeners
In the event-driven model, user interaction with user interface
components triggers server-side events, which you can handle
with event listeners.
In the example below, we handle click events for a button with
an anonymous class:
�%$$ ��
*�������
��+��
�%$$ ��
�������#
$���"���
(
��%$$ ��
��������
���&��$�
�&��$��(
*�������
%�+��
Web
Browser
Client-Side
Engine
Java
Web
Server
Vaadin
UIComponents
Your
Java
Application
Web
Service
EJB
DB
Servlet Container
User
Application
Event
Listener
Data
Model
Application
Themes
Application
Resources
Default
Theme
FileResources
External
Resources
Database
DataBinding
InheritsEvents
Changes
AJAX Requests
InheritsUIComponent
Java
Servlet
Application
Class
Web
Browser
Client-Side
Engine
![Page 98: Vaadin 7](https://reader036.fdocuments.us/reader036/viewer/2022062418/554f4b43b4c905524c8b498c/html5/thumbnails/98.jpg)
Q&A