Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
B U I L D I N G W E B A P P S I N J A V A
@ M A R C U S H E L L B E R G
5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N
Apache 2.0
150k+ active developers
Apache 2.0
40% of Fortune 100 companies use Vaadin
150k+ active developers
Apache 2.0
40% of Fortune 100 companies use Vaadin
150k+ active developers
#2 Java Web Framework
according to Open HUB stats
Apache 2.0
things you'll learn
1. What it takes to build a modern web app
2. The building blocks of Vaadin
3. How to build a full stack app in 30 minutes
M O D E R N W E B A P P S
demo.vaadin.com/dashboard
Building web apps with Vaadin 8
Building web apps with Vaadin 8
MyController.java
MyController.java
@RestController
@RequestMapping("/analytics")
public class AnalyticsController {
@Autowired
PatientsRepository patientsRepository;
@RequestMapping(path = "/age",
method = RequestMethod.GET)
public Response getByAge() {
...
}
@RequestMapping(path = "/length",
method = RequestMethod.GET)
public Response getByLength() {
...
}
...
MyController.java
my-view.template.html
@RestController
@RequestMapping("/analytics")
public class AnalyticsController {
@Autowired
PatientsRepository patientsRepository;
@RequestMapping(path = "/age",
method = RequestMethod.GET)
public Response getByAge() {
...
}
@RequestMapping(path = "/length",
method = RequestMethod.GET)
public Response getByLength() {
...
}
...
MyController.java
my-view.template.html
@RestController
@RequestMapping("/analytics")
public class AnalyticsController {
@Autowired
PatientsRepository patientsRepository;
@RequestMapping(path = "/age",
method = RequestMethod.GET)
public Response getByAge() {
...
}
@RequestMapping(path = "/length",
method = RequestMethod.GET)
public Response getByLength() {
...
}
...
<nav>
<a href="/analytics/age" routerLink
<a href="/analytics/doctor" routerL
<a href="/analytics/gender" routerL
</nav>
...
MyController.java
my-view.template.html
my-view.css
@RestController
@RequestMapping("/analytics")
public class AnalyticsController {
@Autowired
PatientsRepository patientsRepository;
@RequestMapping(path = "/age",
method = RequestMethod.GET)
public Response getByAge() {
...
}
@RequestMapping(path = "/length",
method = RequestMethod.GET)
public Response getByLength() {
...
}
...
<nav>
<a href="/analytics/age" routerLink
<a href="/analytics/doctor" routerL
<a href="/analytics/gender" routerL
</nav>
...
MyController.java
my-view.template.html
my-view.css
@RestController
@RequestMapping("/analytics")
public class AnalyticsController {
@Autowired
PatientsRepository patientsRepository;
@RequestMapping(path = "/age",
method = RequestMethod.GET)
public Response getByAge() {
...
}
@RequestMapping(path = "/length",
method = RequestMethod.GET)
public Response getByLength() {
...
}
...
<nav>
<a href="/analytics/age" routerLink
<a href="/analytics/doctor" routerL
<a href="/analytics/gender" routerL
</nav>
...
nav {
justify-content: center;
text-transform: uppercase;
margin-bottom: 50px;
} ...
MyController.java
my-view.template.html
my-view.css
my-view.js
@RestController
@RequestMapping("/analytics")
public class AnalyticsController {
@Autowired
PatientsRepository patientsRepository;
@RequestMapping(path = "/age",
method = RequestMethod.GET)
public Response getByAge() {
...
}
@RequestMapping(path = "/length",
method = RequestMethod.GET)
public Response getByLength() {
...
}
...
<nav>
<a href="/analytics/age" routerLink
<a href="/analytics/doctor" routerL
<a href="/analytics/gender" routerL
</nav>
...
nav {
justify-content: center;
text-transform: uppercase;
margin-bottom: 50px;
} ...
MyController.java
my-view.template.html
my-view.css
my-view.js
@RestController
@RequestMapping("/analytics")
public class AnalyticsController {
@Autowired
PatientsRepository patientsRepository;
@RequestMapping(path = "/age",
method = RequestMethod.GET)
public Response getByAge() {
...
}
@RequestMapping(path = "/length",
method = RequestMethod.GET)
public Response getByLength() {
...
}
...
<nav>
<a href="/analytics/age" routerLink
<a href="/analytics/doctor" routerL
<a href="/analytics/gender" routerL
</nav>
...
nav {
justify-content: center;
text-transform: uppercase;
margin-bottom: 50px;
} ...
getAnalytics(grouping: string = 'age'
return this.http
.get(`${this.config.API_URL}/analy
.map(res=>res.json());
}
F F S
F I G H T F O R S I M P L I C I T Y
new TextField();
new Button("Click me");
new HorizontalLayout(
new TextField(),
new Button("Click me")
);
new VerticalLayout(
new TextField(),
new Button("Click me")
);
layout = new VerticalLayout();
textField = new TextField();
button = new Button("Click Me");
layout = new VerticalLayout();
textField = new TextField();
button = new Button("Click Me");
button.addClickListener(click ->
layout.addComponent(
new Label(textField.getValue())
));
layout = new VerticalLayout();
textField = new TextField();
button = new Button("Click Me");
button.addClickListener(click ->
layout.addComponent(
new Label(textField.getValue())
));
private TextField firstName;
private TextField lastName;
private TextField firstName;
private TextField lastName;
person = new Person();
private TextField firstName;
private TextField lastName;
person = new Person();
binder = new BeanBinder<>(
Person.class);
private TextField firstName;
private TextField lastName;
person = new Person();
binder = new BeanBinder<>(
Person.class);
binder.bindInstanceFields(this);
save = new Button("Save", e -> {
// try-catch
binder.writeBean(person);
Notification.show(
person.toString());
});
private TextField firstName;
private TextField lastName;
person = new Person();
binder = new BeanBinder<>(
Person.class);
binder.bindInstanceFields(this);
save = new Button("Save", e -> {
// try-catch
binder.writeBean(person);
Notification.show(
person.toString());
});
private TextField firstName;
private TextField lastName;
person = new Person();
binder = new BeanBinder<>(
Person.class);
binder.bindInstanceFields(this);
@Autowired
private PersonService service;
@Autowired
private PersonService service;
Grid<Person> grid = new Grid<>();
@Autowired
private PersonService service;
Grid<Person> grid = new Grid<>();
grid.addColumn("First name",
Person::getFirstName);
grid.addColumn("Last name",
Person::getLastName);
grid.addColumn("Email",
Person::getEmail);
@Autowired
private PersonService service;
Grid<Person> grid = new Grid<>();
grid.addColumn("First name",
Person::getFirstName);
grid.addColumn("Last name",
Person::getLastName);
grid.addColumn("Email",
Person::getEmail);
grid.setItems(service.getPeople());
@Autowired
private PersonService service;
Grid<Person> grid = new Grid<>();
grid.addColumn("First name",
Person::getFirstName);
grid.addColumn("Last name",
Person::getLastName);
grid.addColumn("Email",
Person::getEmail);
grid.setItems(service.getPeople());
@Autowired
private PersonService service;
Grid<Person> grid = new Grid<>();
grid.addColumn("First name",
Person::getFirstName);
grid.addColumn("Last name",
Person::getLastName);
grid.addColumn("Email",
Person::getEmail);
grid.addColumn("First name",
Person::getFirstName);
grid.addColumn("Last name",
Person::getLastName);
grid.addColumn("Email",
Person::getEmail);
grid.addColumn("First name",
Person::getFirstName);
grid.addColumn("Last name",
Person::getLastName);
grid.addColumn("Email",
Person::getEmail);
grid.setDataSource(
new BackEndDataSource<>(
q -> service.getPeople(
q.getOffset(),
q.getLimit())
.stream(),
q -> service.count()));
grid.addColumn("First name",
Person::getFirstName);
grid.addColumn("Last name",
Person::getLastName);
grid.addColumn("Email",
Person::getEmail);
grid.setDataSource(
new BackEndDataSource<>(
q -> service.getPeople(
q.getOffset(),
q.getLimit())
.stream(),
q -> service.count()));
navBar = new HorizontalLayout();
navBar.addComponent(
new Button("view1",
click -> nav.navigateTo("")));
navBar.addComponent(
new Button("view2",
click -> nav.navigateTo("view2")));
navBar = new HorizontalLayout();
navBar.addComponent(
new Button("view1",
click -> nav.navigateTo("")));
navBar.addComponent(
new Button("view2",
click -> nav.navigateTo("view2")));
CssLayout navOutlet = new CssLayout();
addComponents(navBar, navOutlet);
nav = new Navigator(this, navOutlet);
nav.addView("",
new DemoView("Hello, I'm view 1"));
nav.addView("view2",
new DemoView("Hello, I'm view 2"));
navBar = new HorizontalLayout();
navBar.addComponent(
new Button("view1",
click -> nav.navigateTo("")));
navBar.addComponent(
new Button("view2",
click -> nav.navigateTo("view2")));
CssLayout navOutlet = new CssLayout();
addComponents(navBar, navOutlet);
nav = new Navigator(this, navOutlet);
nav.addView("",
new DemoView("Hello, I'm view 1"));
nav.addView("view2",
new DemoView("Hello, I'm view 2"));
navBar = new HorizontalLayout();
navBar.addComponent(
new Button("view1",
click -> nav.navigateTo("")));
navBar.addComponent(
new Button("view2",
click -> nav.navigateTo("view2")));
CssLayout navOutlet = new CssLayout();
addComponents(navBar, navOutlet);
$v-background-color:
hsl(210, 0%, 100%);
$v-background-color:
hsl(210, 0%, 33%);
$v-background-color:
hsl(210, 0%, 100%);
$v-border: 2px solid v-shade;
$v-border-radius: 0;
$v-bevel: false;
$v-gradient: false;
$v-shadow: false;
Building web apps with Vaadin 8
Building web apps with Vaadin 8
[insert code here]
github.com/vaadin-marcus/spring-boot-todo
TextField name = new TextField();
Button button = new Button("Greet");
layout.addComponents(name, button);
button.addClickListener(click -> {
Notification.show("Hi, " + name.getValue());
});
Initial HTML
CSS
JavaScript
~300k
Building web apps with Vaadin 8
Building web apps with Vaadin 8
{name: {value: 'Marcus'},
button: {event: 'clicked'}}
261 bytes

TextField name = new TextField();
Button button = new Button("Greet");
layout.addComponents(name, button);
button.addClickListener(click -> {
Notification.show("Hi, " + name.getValue());
});
TextField name = new TextField();
Button button = new Button("Greet");
layout.addComponents(name, button);
button.addClickListener(click -> {
Notification.show("Hi, " + name.getValue());
});
Building web apps with Vaadin 8
{name: {value: 'Marcus'},
button: {event: 'clicked'}}
261 bytes

{new: [
{notification: 'Hi, Marcus'}
]}
267 bytes

Building web apps with Vaadin 8
Building web apps with Vaadin 8
Building web apps with Vaadin 8
.v-ui[width-range~="0-800px"]{
/* Styles for small devices */
}
.v-ui[width-range~="801px-"]{
/* Styles for large devices */
}
.v-ui[width-range~="0-800px"]{
/* Styles for small devices */
}
.v-ui[width-range~="801px-"]{
/* Styles for large devices */
}
getPage().addBrowserWindowResizeListener( newSize -> {
if (newSize.getWidth() > LARGE_DEVICE_WIDTH){
setupLargeLayout();
} else {
setupSmallLayout();
}
});
W E B S O C K E T S
public class VaadinUI extends UI {
...
}
W E B S O C K E T S
public class VaadinUI extends UI {
...
}
@Push
W E B S O C K E T S
public class VaadinUI extends UI {
...
}
@Push
ui.access(() -> Notification.show("Alert!"));
Ɂ Ʌ ɂ Ƀ
Ɂ ɚ ɂ Ƀ
S T R O N G S E C U R I T Y
T H E J V M♥
E X T E N D A B L ELj
Building web apps with Vaadin 8
Building web apps with Vaadin 8
Building web apps with Vaadin 8
Building web apps with Vaadin 8
Building web apps with Vaadin 8
We'd be happy to help you.
T H A N K YO U
@ M A R C U S H E L L B E R G
5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N

More Related Content

Building web apps with Vaadin 8

  • 1. B U I L D I N G W E B A P P S I N J A V A @ M A R C U S H E L L B E R G 5 S T O R Y A N D P H I L O S O P H Y Software is eating the world and what most of us see of it is the user interface. The user interface has become the key component of how the users experience the business behind it. Competition is lost or won due to user experience. Simplicity is king and the users get frustrated by anything ugly, slow or not working on the device they happen to use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight. Together we want to build a user interface that puts a smile on the user’s face. Vaadin is the technology that empowers developers to build the best web-apps for business purposes. Our priority over everything else is developer productivity because we believe that by simplifying the developer experience and saving the developer’s time, they are best able to focus on building great user interfaces. Our brand is what we want everyone to think about us. When everyone - both us and the people around us - have a consistent understanding of what Vaadin is and what we stand for, it enables that image to spread and amplify. This book defines what we want that image to be. It defines what the Vaadin brand is. I hope that You are as excited and proud of living and breathing the Vaadin brand as I am. You are the one who is shaping what everyone thinks about Vaadin - using this brand as a tool and a guideline every day. Let’s fight for simplicity for both the users and the developers! Joonas Lehtinen Founder & CEO Vaadin I N T R O D U C T I O N
  • 4. 40% of Fortune 100 companies use Vaadin 150k+ active developers Apache 2.0
  • 5. 40% of Fortune 100 companies use Vaadin 150k+ active developers #2 Java Web Framework according to Open HUB stats Apache 2.0
  • 6. things you'll learn 1. What it takes to build a modern web app 2. The building blocks of Vaadin 3. How to build a full stack app in 30 minutes
  • 7. M O D E R N W E B A P P S
  • 12. MyController.java @RestController @RequestMapping("/analytics") public class AnalyticsController { @Autowired PatientsRepository patientsRepository; @RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... } @RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ...
  • 13. MyController.java my-view.template.html @RestController @RequestMapping("/analytics") public class AnalyticsController { @Autowired PatientsRepository patientsRepository; @RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... } @RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ...
  • 14. MyController.java my-view.template.html @RestController @RequestMapping("/analytics") public class AnalyticsController { @Autowired PatientsRepository patientsRepository; @RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... } @RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ... <nav> <a href="/analytics/age" routerLink <a href="/analytics/doctor" routerL <a href="/analytics/gender" routerL </nav> ...
  • 15. MyController.java my-view.template.html my-view.css @RestController @RequestMapping("/analytics") public class AnalyticsController { @Autowired PatientsRepository patientsRepository; @RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... } @RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ... <nav> <a href="/analytics/age" routerLink <a href="/analytics/doctor" routerL <a href="/analytics/gender" routerL </nav> ...
  • 16. MyController.java my-view.template.html my-view.css @RestController @RequestMapping("/analytics") public class AnalyticsController { @Autowired PatientsRepository patientsRepository; @RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... } @RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ... <nav> <a href="/analytics/age" routerLink <a href="/analytics/doctor" routerL <a href="/analytics/gender" routerL </nav> ... nav { justify-content: center; text-transform: uppercase; margin-bottom: 50px; } ...
  • 17. MyController.java my-view.template.html my-view.css my-view.js @RestController @RequestMapping("/analytics") public class AnalyticsController { @Autowired PatientsRepository patientsRepository; @RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... } @RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ... <nav> <a href="/analytics/age" routerLink <a href="/analytics/doctor" routerL <a href="/analytics/gender" routerL </nav> ... nav { justify-content: center; text-transform: uppercase; margin-bottom: 50px; } ...
  • 18. MyController.java my-view.template.html my-view.css my-view.js @RestController @RequestMapping("/analytics") public class AnalyticsController { @Autowired PatientsRepository patientsRepository; @RequestMapping(path = "/age", method = RequestMethod.GET) public Response getByAge() { ... } @RequestMapping(path = "/length", method = RequestMethod.GET) public Response getByLength() { ... } ... <nav> <a href="/analytics/age" routerLink <a href="/analytics/doctor" routerL <a href="/analytics/gender" routerL </nav> ... nav { justify-content: center; text-transform: uppercase; margin-bottom: 50px; } ... getAnalytics(grouping: string = 'age' return this.http .get(`${this.config.API_URL}/analy .map(res=>res.json()); }
  • 19. F F S
  • 20. F I G H T F O R S I M P L I C I T Y
  • 24. layout = new VerticalLayout(); textField = new TextField(); button = new Button("Click Me");
  • 25. layout = new VerticalLayout(); textField = new TextField(); button = new Button("Click Me"); button.addClickListener(click -> layout.addComponent( new Label(textField.getValue()) ));
  • 26. layout = new VerticalLayout(); textField = new TextField(); button = new Button("Click Me"); button.addClickListener(click -> layout.addComponent( new Label(textField.getValue()) ));
  • 28. private TextField firstName; private TextField lastName; person = new Person();
  • 29. private TextField firstName; private TextField lastName; person = new Person(); binder = new BeanBinder<>( Person.class);
  • 30. private TextField firstName; private TextField lastName; person = new Person(); binder = new BeanBinder<>( Person.class); binder.bindInstanceFields(this);
  • 31. save = new Button("Save", e -> { // try-catch binder.writeBean(person); Notification.show( person.toString()); }); private TextField firstName; private TextField lastName; person = new Person(); binder = new BeanBinder<>( Person.class); binder.bindInstanceFields(this);
  • 32. save = new Button("Save", e -> { // try-catch binder.writeBean(person); Notification.show( person.toString()); }); private TextField firstName; private TextField lastName; person = new Person(); binder = new BeanBinder<>( Person.class); binder.bindInstanceFields(this);
  • 35. @Autowired private PersonService service; Grid<Person> grid = new Grid<>(); grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail);
  • 36. @Autowired private PersonService service; Grid<Person> grid = new Grid<>(); grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail); grid.setItems(service.getPeople());
  • 37. @Autowired private PersonService service; Grid<Person> grid = new Grid<>(); grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail); grid.setItems(service.getPeople());
  • 38. @Autowired private PersonService service; Grid<Person> grid = new Grid<>(); grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail);
  • 40. grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail); grid.setDataSource( new BackEndDataSource<>( q -> service.getPeople( q.getOffset(), q.getLimit()) .stream(), q -> service.count()));
  • 41. grid.addColumn("First name", Person::getFirstName); grid.addColumn("Last name", Person::getLastName); grid.addColumn("Email", Person::getEmail); grid.setDataSource( new BackEndDataSource<>( q -> service.getPeople( q.getOffset(), q.getLimit()) .stream(), q -> service.count()));
  • 42. navBar = new HorizontalLayout(); navBar.addComponent( new Button("view1", click -> nav.navigateTo(""))); navBar.addComponent( new Button("view2", click -> nav.navigateTo("view2")));
  • 43. navBar = new HorizontalLayout(); navBar.addComponent( new Button("view1", click -> nav.navigateTo(""))); navBar.addComponent( new Button("view2", click -> nav.navigateTo("view2"))); CssLayout navOutlet = new CssLayout(); addComponents(navBar, navOutlet);
  • 44. nav = new Navigator(this, navOutlet); nav.addView("", new DemoView("Hello, I'm view 1")); nav.addView("view2", new DemoView("Hello, I'm view 2")); navBar = new HorizontalLayout(); navBar.addComponent( new Button("view1", click -> nav.navigateTo(""))); navBar.addComponent( new Button("view2", click -> nav.navigateTo("view2"))); CssLayout navOutlet = new CssLayout(); addComponents(navBar, navOutlet);
  • 45. nav = new Navigator(this, navOutlet); nav.addView("", new DemoView("Hello, I'm view 1")); nav.addView("view2", new DemoView("Hello, I'm view 2")); navBar = new HorizontalLayout(); navBar.addComponent( new Button("view1", click -> nav.navigateTo(""))); navBar.addComponent( new Button("view2", click -> nav.navigateTo("view2"))); CssLayout navOutlet = new CssLayout(); addComponents(navBar, navOutlet);
  • 48. $v-background-color: hsl(210, 0%, 100%); $v-border: 2px solid v-shade; $v-border-radius: 0; $v-bevel: false; $v-gradient: false; $v-shadow: false;
  • 53. TextField name = new TextField(); Button button = new Button("Greet"); layout.addComponents(name, button); button.addClickListener(click -> { Notification.show("Hi, " + name.getValue()); });
  • 57. {name: {value: 'Marcus'}, button: {event: 'clicked'}} 261 bytes

  • 58. TextField name = new TextField(); Button button = new Button("Greet"); layout.addComponents(name, button); button.addClickListener(click -> { Notification.show("Hi, " + name.getValue()); });
  • 59. TextField name = new TextField(); Button button = new Button("Greet"); layout.addComponents(name, button); button.addClickListener(click -> { Notification.show("Hi, " + name.getValue()); });
  • 61. {name: {value: 'Marcus'}, button: {event: 'clicked'}} 261 bytes
 {new: [ {notification: 'Hi, Marcus'} ]} 267 bytes

  • 65. .v-ui[width-range~="0-800px"]{ /* Styles for small devices */ } .v-ui[width-range~="801px-"]{ /* Styles for large devices */ }
  • 66. .v-ui[width-range~="0-800px"]{ /* Styles for small devices */ } .v-ui[width-range~="801px-"]{ /* Styles for large devices */ } getPage().addBrowserWindowResizeListener( newSize -> { if (newSize.getWidth() > LARGE_DEVICE_WIDTH){ setupLargeLayout(); } else { setupSmallLayout(); } });
  • 67. W E B S O C K E T S public class VaadinUI extends UI { ... }
  • 68. W E B S O C K E T S public class VaadinUI extends UI { ... } @Push
  • 69. W E B S O C K E T S public class VaadinUI extends UI { ... } @Push ui.access(() -> Notification.show("Alert!"));
  • 70. Ɂ Ʌ ɂ Ƀ
  • 71. Ɂ ɚ ɂ Ƀ
  • 72. S T R O N G S E C U R I T Y
  • 73. T H E J V M♥
  • 74. E X T E N D A B L ELj
  • 80. We'd be happy to help you.
  • 81. T H A N K YO U @ M A R C U S H E L L B E R G 5 S T O R Y A N D P H I L O S O P H Y Software is eating the world and what most of us see of it is the user interface. The user interface has become the key component of how the users experience the business behind it. Competition is lost or won due to user experience. Simplicity is king and the users get frustrated by anything ugly, slow or not working on the device they happen to use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight. Together we want to build a user interface that puts a smile on the user’s face. Vaadin is the technology that empowers developers to build the best web-apps for business purposes. Our priority over everything else is developer productivity because we believe that by simplifying the developer experience and saving the developer’s time, they are best able to focus on building great user interfaces. Our brand is what we want everyone to think about us. When everyone - both us and the people around us - have a consistent understanding of what Vaadin is and what we stand for, it enables that image to spread and amplify. This book defines what we want that image to be. It defines what the Vaadin brand is. I hope that You are as excited and proud of living and breathing the Vaadin brand as I am. You are the one who is shaping what everyone thinks about Vaadin - using this brand as a tool and a guideline every day. Let’s fight for simplicity for both the users and the developers! Joonas Lehtinen Founder & CEO Vaadin I N T R O D U C T I O N