Skip to content

Commit 503fa50

Browse files
committed
Updated to use Vaadin 8
1 parent 7a76111 commit 503fa50

File tree

3 files changed

+106
-100
lines changed

3 files changed

+106
-100
lines changed

pom.xml

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@
22
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
33
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
44
<modelVersion>4.0.0</modelVersion>
5-
<parent>
6-
<groupId>org.springframework.boot</groupId>
7-
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>1.4.2.RELEASE</version>
9-
</parent>
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>1.5.2.RELEASE</version>
9+
</parent>
1010

11-
<groupId>com.example</groupId>
11+
<groupId>com.example</groupId>
1212
<artifactId>spring-data-vaadin-crud</artifactId>
1313
<version>0.0.1-SNAPSHOT</version>
1414
<description>Simple CRUD with Vaadin and Spring Data backend</description>
1515

1616
<properties>
1717
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1818
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
19-
<version.vaadin>7.7.3</version.vaadin>
20-
<version.vaadin-spring>1.1.0</version.vaadin-spring>
19+
<version.vaadin>8.0.4</version.vaadin>
2120
<start-class>crud.Application</start-class>
2221
</properties>
2322

@@ -40,7 +39,7 @@
4039
<artifactId>flyway-core</artifactId>
4140
</dependency>
4241

43-
<!-- vaadin4spring https://github.com/peholmst/vaadin4spring
42+
<!-- vaadin4spring https://github.com/peholmst/vaadin4spring
4443
contains lots of handy helpers for serious Spring + Vaadin
4544
applications. This example uses event bus to decouple the editor
4645
form from the MainUI class.
@@ -90,47 +89,37 @@
9089
</dependency>
9190
</dependencies>
9291

93-
<dependencyManagement>
94-
<dependencies>
95-
<dependency>
96-
<groupId>com.vaadin</groupId>
97-
<artifactId>vaadin-bom</artifactId>
98-
<version>${version.vaadin}</version>
99-
<type>pom</type>
100-
<scope>import</scope>
101-
</dependency>
92+
<dependencyManagement>
93+
<dependencies>
10294
<dependency>
10395
<groupId>com.vaadin</groupId>
104-
<artifactId>vaadin-spring</artifactId>
105-
<version>${version.vaadin-spring}</version>
96+
<artifactId>vaadin-bom</artifactId>
97+
<version>${version.vaadin}</version>
98+
<type>pom</type>
99+
<scope>import</scope>
100+
</dependency>
101+
<dependency>
102+
<groupId>org.vaadin.spring.extensions</groupId>
103+
<artifactId>vaadin-spring-ext-boot</artifactId>
104+
<version>2.0.0.RELEASE</version>
105+
</dependency>
106+
<dependency>
107+
<groupId>org.vaadin.spring.addons</groupId>
108+
<artifactId>vaadin-spring-addon-eventbus</artifactId>
109+
<version>2.0.0.RELEASE</version>
110+
</dependency>
111+
<dependency>
112+
<groupId>org.vaadin</groupId>
113+
<artifactId>viritin</artifactId>
114+
<version>2.0.beta1</version>
115+
</dependency>
116+
<dependency>
117+
<groupId>org.vaadin.teemu</groupId>
118+
<artifactId>switch</artifactId>
119+
<version>3.0.0</version>
106120
</dependency>
107-
<dependency>
108-
<groupId>com.vaadin</groupId>
109-
<artifactId>vaadin-spring-boot-starter</artifactId>
110-
<version>${version.vaadin-spring}</version>
111-
</dependency>
112-
<dependency>
113-
<groupId>org.vaadin.spring.extensions</groupId>
114-
<artifactId>vaadin-spring-ext-boot</artifactId>
115-
<version>0.0.7.RELEASE</version>
116-
</dependency>
117-
<dependency>
118-
<groupId>org.vaadin.spring.addons</groupId>
119-
<artifactId>vaadin-spring-addon-eventbus</artifactId>
120-
<version>0.0.7.RELEASE</version>
121-
</dependency>
122-
<dependency>
123-
<groupId>org.vaadin</groupId>
124-
<artifactId>viritin</artifactId>
125-
<version>1.57</version>
126-
</dependency>
127-
<dependency>
128-
<groupId>org.vaadin.teemu</groupId>
129-
<artifactId>switch</artifactId>
130-
<version>2.0.2</version>
131-
</dependency>
132-
</dependencies>
133-
</dependencyManagement>
121+
</dependencies>
122+
</dependencyManagement>
134123

135124
<build>
136125
<plugins>

src/main/java/crud/vaadin/MainUI.java

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22

33
import com.vaadin.annotations.Theme;
44
import com.vaadin.annotations.Title;
5-
import com.vaadin.server.FontAwesome;
5+
import com.vaadin.data.provider.GridSortOrder;
6+
import com.vaadin.data.provider.QuerySortOrder;
7+
import com.vaadin.event.SortEvent;
8+
import com.vaadin.icons.VaadinIcons;
69
import com.vaadin.server.VaadinRequest;
10+
import com.vaadin.shared.data.sort.SortDirection;
711
import com.vaadin.spring.annotation.SpringUI;
812
import com.vaadin.ui.Button;
913
import com.vaadin.ui.Button.ClickEvent;
10-
import com.vaadin.ui.TextField;
1114
import com.vaadin.ui.UI;
1215
import crud.backend.Person;
1316
import crud.backend.PersonRepository;
14-
import org.springframework.beans.factory.annotation.Autowired;
17+
import java.util.List;
1518
import org.springframework.data.domain.PageRequest;
1619
import org.springframework.data.domain.Sort;
1720
import org.vaadin.spring.events.EventBus;
@@ -20,8 +23,8 @@
2023
import org.vaadin.viritin.button.ConfirmButton;
2124
import org.vaadin.viritin.button.MButton;
2225
import org.vaadin.viritin.components.DisclosurePanel;
23-
import org.vaadin.viritin.fields.MTable;
2426
import org.vaadin.viritin.fields.MTextField;
27+
import org.vaadin.viritin.grid.MGrid;
2528
import org.vaadin.viritin.label.RichText;
2629
import org.vaadin.viritin.layouts.MHorizontalLayout;
2730
import org.vaadin.viritin.layouts.MVerticalLayout;
@@ -32,30 +35,31 @@
3235
public class MainUI extends UI {
3336

3437
private static final long serialVersionUID = 1L;
35-
38+
3639
PersonRepository repo;
3740
PersonForm personForm;
3841
EventBus.UIEventBus eventBus;
39-
40-
private MTable<Person> list = new MTable<>(Person.class)
42+
43+
private MGrid<Person> list = new MGrid<>(Person.class)
4144
.withProperties("id", "name", "email")
4245
.withColumnHeaders("id", "Name", "Email")
43-
.setSortableProperties("name", "email")
46+
// not yet supported by V8
47+
//.setSortableProperties("name", "email")
4448
.withFullWidth();
45-
46-
private TextField filterByName = new MTextField()
47-
.withInputPrompt("Filter by name");
48-
private Button addNew = new MButton(FontAwesome.PLUS, this::add);
49-
private Button edit = new MButton(FontAwesome.PENCIL_SQUARE_O, this::edit);
50-
private Button delete = new ConfirmButton(FontAwesome.TRASH_O,
49+
50+
private MTextField filterByName = new MTextField()
51+
.withPlaceholder("Filter by name");
52+
private Button addNew = new MButton(VaadinIcons.PLUS, this::add);
53+
private Button edit = new MButton(VaadinIcons.PENCIL, this::edit);
54+
private Button delete = new ConfirmButton(VaadinIcons.TRASH,
5155
"Are you sure you want to delete the entry?", this::remove);
5256

5357
public MainUI(PersonRepository r, PersonForm f, EventBus.UIEventBus b) {
5458
this.repo = r;
5559
this.personForm = f;
5660
this.eventBus = b;
5761
}
58-
62+
5963
@Override
6064
protected void init(VaadinRequest request) {
6165
DisclosurePanel aboutBox = new DisclosurePanel("Spring Boot JPA CRUD example with Vaadin UI", new RichText().withMarkDownResource("/welcome.md"));
@@ -67,32 +71,32 @@ protected void init(VaadinRequest request) {
6771
).expand(list)
6872
);
6973
listEntities();
70-
71-
list.addMValueChangeListener(e -> adjustActionButtonState());
72-
filterByName.addTextChangeListener(e -> {
73-
listEntities(e.getText());
74+
75+
list.asSingleSelect().addValueChangeListener(e -> adjustActionButtonState());
76+
filterByName.addValueChangeListener(e -> {
77+
listEntities(e.getValue());
7478
});
7579

7680
// Listen to change events emitted by PersonForm see onEvent method
7781
eventBus.subscribe(this);
7882
}
79-
83+
8084
protected void adjustActionButtonState() {
81-
boolean hasSelection = list.getValue() != null;
85+
boolean hasSelection = !list.getSelectedItems().isEmpty();
8286
edit.setEnabled(hasSelection);
8387
delete.setEnabled(hasSelection);
8488
}
85-
86-
static final int PAGESIZE = 45;
87-
89+
8890
private void listEntities() {
8991
listEntities(filterByName.getValue());
9092
}
91-
93+
94+
final int PAGESIZE = 45;
95+
9296
private void listEntities(String nameFilter) {
9397
// A dead simple in memory listing would be:
9498
// list.setRows(repo.findAll());
95-
99+
96100
// But we want to support filtering, first add the % marks for SQL name query
97101
String likeFilter = "%" + nameFilter + "%";
98102
list.setRows(repo.findByNameLikeIgnoreCase(likeFilter));
@@ -101,40 +105,41 @@ private void listEntities(String nameFilter) {
101105
// Spring Repository. This approach uses less memory and database
102106
// resources. Use this approach if you expect you'll have lots of data
103107
// in your table. There are simpler APIs if you don't need sorting.
104-
// list.lazyLoadFrom(
105-
// // entity fetching strategy
106-
// (firstRow, asc, sortProperty) -> repo.findByNameLikeIgnoreCase(
107-
// likeFilter,
108-
// new PageRequest(
109-
// firstRow / PAGESIZE,
110-
// PAGESIZE,
111-
// asc ? Sort.Direction.ASC : Sort.Direction.DESC,
112-
// // fall back to id as "natural order"
113-
// sortProperty == null ? "id" : sortProperty
114-
// )
115-
// ),
116-
// // count fetching strategy
117-
// () -> (int) repo.countByNameLike(likeFilter),
118-
// PAGESIZE
119-
// );
108+
list.setDataProvider(
109+
// entity fetching strategy
110+
(sortOrder, offset, limit) -> {
111+
final List<Person> page = repo.findByNameLikeIgnoreCase(likeFilter,
112+
new PageRequest(
113+
offset / limit,
114+
limit,
115+
sortOrder.isEmpty() || sortOrder.get(0).getDirection() == SortDirection.ASCENDING ? Sort.Direction.ASC : Sort.Direction.DESC,
116+
// fall back to id as "natural order"
117+
sortOrder.isEmpty() ? "id" : sortOrder.get(0).getSorted()
118+
)
119+
);
120+
return page.subList(offset % limit, page.size()).stream();
121+
},
122+
// count fetching strategy
123+
() -> (int) repo.countByNameLike(likeFilter)
124+
);
120125
adjustActionButtonState();
121-
126+
122127
}
123-
128+
124129
public void add(ClickEvent clickEvent) {
125130
edit(new Person());
126131
}
127-
132+
128133
public void edit(ClickEvent e) {
129-
edit(list.getValue());
134+
edit(list.asSingleSelect().getValue());
130135
}
131-
132-
public void remove(ClickEvent e) {
133-
repo.delete(list.getValue());
134-
list.setValue(null);
136+
137+
public void remove() {
138+
repo.delete(list.asSingleSelect().getValue());
139+
list.deselectAll();
135140
listEntities();
136141
}
137-
142+
138143
protected void edit(final Person phoneBookEntry) {
139144
personForm.setEntity(phoneBookEntry);
140145
personForm.openInModalPopup();
@@ -145,5 +150,5 @@ public void onPersonModified(PersonModifiedEvent event) {
145150
listEntities();
146151
personForm.closePopup();
147152
}
148-
153+
149154
}

src/main/java/crud/vaadin/PersonForm.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package crud.vaadin;
22

3+
import com.vaadin.data.converter.LocalDateToDateConverter;
34
import com.vaadin.spring.annotation.SpringComponent;
45
import com.vaadin.spring.annotation.UIScope;
56
import com.vaadin.ui.Component;
67
import com.vaadin.ui.DateField;
78
import com.vaadin.ui.TextField;
89
import crud.backend.Person;
910
import crud.backend.PersonRepository;
10-
import org.springframework.beans.factory.annotation.Autowired;
1111
import org.vaadin.spring.events.EventBus;
1212
import org.vaadin.teemu.switchui.Switch;
1313
import org.vaadin.viritin.fields.MTextField;
@@ -31,6 +31,7 @@ public class PersonForm extends AbstractForm<Person> {
3131
Switch colleague = new Switch("Colleague");
3232

3333
PersonForm(PersonRepository r, EventBus.UIEventBus b) {
34+
super(Person.class);
3435
this.repo = r;
3536
this.eventBus = b;
3637

@@ -46,6 +47,17 @@ public class PersonForm extends AbstractForm<Person> {
4647
setSizeUndefined();
4748
}
4849

50+
@Override
51+
protected void bind() {
52+
// DateField in Vaadin 8 uses LocalDate by default, the backend
53+
// uses plain old java.util.Date, thus we need a converter, using
54+
// built in helper here
55+
getBinder()
56+
.forMemberField(birthDay)
57+
.withConverter(new LocalDateToDateConverter());
58+
super.bind();
59+
}
60+
4961
@Override
5062
protected Component createContent() {
5163
return new MVerticalLayout(

0 commit comments

Comments
 (0)