6. Web application layers
JavaScriptWeb serverBackend Communication
JS
required required required required
Vaadin
required optionalrequired optional
7. Web application layers
JavaScriptWeb serverBackend Communication
JS
required required required required
Vaadin
required optionalrequired optional
1 layer
vs
3 layers
Less code
Less bugs
Faster time-to-market
8. > 100.000 developers from
> 10.000 cities
> 450 add-ons in the
marketplace
Other
4 %Asia
20 %
Americas
22 %
Europe
54 %
Open Source community
Apache-licensed
19. New Java 8 Date API in action
public int monthAge() {
return (new Date().getYear() - date.getYear()) * 12
+ (new Date().getMonth() - date.getMonth());
}
// Java 8 version with the new Date API
public int monthAge() {
return (int) Period.between(date, LocalDate.now()).toTotalMonths();
}
22. Workout Tracker example
editor.clear.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
editor.clearValues();
updateRating();
}
});
// Java 8 version with a lambda
editor.clear.addClickListener(event -> {
editor.clearValues();
updateRating();
});
23. Method references with the :: notation
! private void eventHandler(Button.ClickEvent event) {
// do something about the button click
}
button.addClickListener(this::eventHandler);
// If the handler method is static
button.addClickListener(MyClass::eventHandler);
24. Workout Tracker example
!editor.activity.addValueChangeListener(new Property.ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
updateRating();
}
});
// Java 8 version with a method reference
editor.date.addValueChangeListener(this::updateRating);
30. Returns a new stream by
applying the given function to
all elements of this stream.
!
Map
Returns a new stream
consisting of the elements of
this stream that match the
given predicate.
Filter
SQL analogue: SELECT SQL analogue: WHERE
31. Workout Tracker Example
!
!
!
// Java 8 version with stream operations
private Stream<Workout> findByAge(int maxMonths) {
return workouts.stream()
.filter(w -> w.monthAge() < maxMonths)
.sorted(Comparator.comparing(Workout::monthAge).reversed());
}
private List<Workout> findByAge(int maxMonths) {
List<Workout> result = new ArrayList<>();
for (Workout w : workouts) {
if (w.monthAge() < maxMonths) {
result.add(w);
}
}
Collections.sort(result, new Comparator<Workout>() {
@Override
public int compare(Workout o1, Workout o2) {
return o2.monthAge() - o1.monthAge();
}
});
!
return result;
}
32.
33. Scratching the surface of Scala syntax
class Cat(name: String) {
initLitterBox()
def meow(volume: Int = 5) = {
println(s"$name meows " +
(if (volume <= 5) "quietly" else "loudly"))
volume <= 5
}
}
Class body is the constructor
identifier: type notation
Functions with def keyword
Arguments can have default values
Return keyword optional
No semicolons needed
34. Burn the boilerplate - Workout.java
!
!
!
public void setDuration(int duration) {
this.duration = duration;
}
!
public double getAvgHR() {
return avgHR;
}
!
public void setAvgHR(double avgHR) {
this.avgHR = avgHR;
}
!
public double getMaxHR() {
return maxHR;
}
!
public void setMaxHR(double maxHR) {
this.maxHR = maxHR;
}
!
public int getCalories() {
return calories;
}
!
public void setCalories(int calories) {
this.calories = calories;
}
!
public String getComment() {
return comment;
}
!
public void setComment(String comment) {
this.comment = comment;
}
}
public class Workout {
private String activity;
private Date date;
private int duration, calories;
private double avgHR, maxHR;
private String comment;
!
public Workout(String activity, Date date, int time, double avgHR,
double maxHR, int kcal, String comment) {
this.activity = activity;
this.date = date;
this.duration = time;
this.avgHR = avgHR;
this.maxHR = maxHR;
this.calories = kcal;
this.comment = comment;
}
!
public int monthAge() {
return (int) Period.between(date, LocalDate.now()).toTotalMonths();
}
!
public String getActivity() {
return activity;
}
!
public void setActivity(String activity) {
this.activity = activity;
}
!
public Date getDate() {
return date;
}
!
public void setDate(Date date) {
this.date = date;
}
!
public int getDuration() {
return duration;
}
37. An example
// Scaladin
val layout = new VerticalLayout {
margin = true
!
add(Label("Hello, OSCON!"),
alignment = Alignment.TopCenter)
add(Button("Click me”, handleButtonClick))
}
// Java 7
VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
Label label = new Label(“Hello, OSCON!”);
layout.addComponent(title);
layout.setComponentAlignment(label,
Alignment.TOP_CENTER);
!
Button button = new Button(“Click me", new
Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
handleButtonClick();
}
});
layout.addComponent(button);
38. Input validation, Java 8 & Scala
// Scaladin version of the editor gives us the components as a Scala Set
// which supports functional operations.
private def areInputsValid = !editor.components.exists(fieldNotValidating)
// Java 8 version with anyMatch and a method reference
private boolean areInputsValid() {
return !StreamSupport.stream(editor.spliterator(), true)
.anyMatch(this::fieldNotValidating);
}