Skip to content

Commit

Permalink
vaadin spring
Browse files Browse the repository at this point in the history
  • Loading branch information
rockoder committed Jul 23, 2018
1 parent 717bd1d commit dacf049
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 0 deletions.
63 changes: 63 additions & 0 deletions vaadin-spring/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<groupId>com.baeldung</groupId>
<artifactId>vaadin-spring</artifactId>
<version>0.1.0</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>10.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
29 changes: 29 additions & 0 deletions vaadin-spring/src/main/java/com/baeldung/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.baeldung;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {

private static final Logger log = LoggerFactory.getLogger(Application.class);

public static void main(String[] args) {
SpringApplication.run(Application.class);
}

@Bean
public CommandLineRunner loadData(EmployeeRepository repository) {
return (args) -> {
repository.save(new Employee("Bill", "Gates"));
repository.save(new Employee("Mark", "Zuckerberg"));
repository.save(new Employee("Sundar", "Pichai"));
repository.save(new Employee("Jeff", "Bezos"));
};
}
}
51 changes: 51 additions & 0 deletions vaadin-spring/src/main/java/com/baeldung/Employee.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.baeldung;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Employee {

@Id
@GeneratedValue
private Long id;

private String firstName;

private String lastName;

protected Employee() {
}

public Employee(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

public Long getId() {
return id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

@Override
public String toString() {
return String.format("Employee[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
}

}
117 changes: 117 additions & 0 deletions vaadin-spring/src/main/java/com/baeldung/EmployeeEditor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.baeldung;

import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.KeyNotifier;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.spring.annotation.SpringComponent;
import com.vaadin.flow.spring.annotation.UIScope;
import org.springframework.beans.factory.annotation.Autowired;

/**
* A simple example to introduce building forms. As your real application is probably much
* more complicated than this example, you could re-use this form in multiple places. This
* example component is only used in MainView.
* <p>
* In a real world application you'll most likely using a common super class for all your
* forms - less code, better UX.
*/
@SpringComponent
@UIScope
public class EmployeeEditor extends VerticalLayout implements KeyNotifier {

private final EmployeeRepository repository;

/**
* The currently edited employee
*/
private Employee employee;

/* Fields to edit properties in Employee entity */
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");

/* Action buttons */
// TODO why more code?
Button save = new Button("Save", VaadinIcon.CHECK.create());
Button cancel = new Button("Cancel");
Button delete = new Button("Delete", VaadinIcon.TRASH.create());
HorizontalLayout actions = new HorizontalLayout(save, cancel, delete);

Binder<Employee> binder = new Binder<>(Employee.class);
private ChangeHandler changeHandler;

@Autowired
public EmployeeEditor(EmployeeRepository repository) {
this.repository = repository;

add(firstName, lastName, actions);

// bind using naming convention
binder.bindInstanceFields(this);

// Configure and style components
setSpacing(true);

save.getElement().getThemeList().add("primary");
delete.getElement().getThemeList().add("error");

addKeyPressListener(Key.ENTER, e -> save());

// wire action buttons to save, delete and reset
save.addClickListener(e -> save());
delete.addClickListener(e -> delete());
cancel.addClickListener(e -> editEmployee(employee));
setVisible(false);
}

void delete() {
repository.delete(employee);
changeHandler.onChange();
}

void save() {
repository.save(employee);
changeHandler.onChange();
}

public interface ChangeHandler {
void onChange();
}

public final void editEmployee(Employee c) {
if (c == null) {
setVisible(false);
return;
}
final boolean persisted = c.getId() != null;
if (persisted) {
// Find fresh entity for editing
employee = repository.findById(c.getId()).get();
} else {
employee = c;
}
cancel.setVisible(persisted);

// Bind employee properties to similarly named fields
// Could also use annotation or "manual binding" or programmatically
// moving values from fields to entities before saving
binder.setBean(employee);

setVisible(true);

// Focus first name initially
firstName.focus();
}

public void setChangeHandler(ChangeHandler h) {
// ChangeHandler is notified when either save or delete
// is clicked
changeHandler = h;
}

}
10 changes: 10 additions & 0 deletions vaadin-spring/src/main/java/com/baeldung/EmployeeRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.baeldung;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface EmployeeRepository extends JpaRepository<Employee, Long> {

List<Employee> findByLastNameStartsWithIgnoreCase(String lastName);
}
78 changes: 78 additions & 0 deletions vaadin-spring/src/main/java/com/baeldung/MainView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.baeldung;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.UIScope;
import org.springframework.util.StringUtils;

@Route
public class MainView extends VerticalLayout {

private final EmployeeRepository employeeRepository;

private final EmployeeEditor editor;

final Grid<Employee> grid;

final TextField filter;

private final Button addNewBtn;

public MainView(EmployeeRepository repo, EmployeeEditor editor) {
this.employeeRepository = repo;
this.editor = editor;
this.grid = new Grid<>(Employee.class);
this.filter = new TextField();
this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create());

// build layout
HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn);
add(actions, grid, editor);

grid.setHeight("200px");
grid.setColumns("id", "firstName", "lastName");
grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0);

filter.setPlaceholder("Filter by last name");

// Hook logic to components

// Replace listing with filtered content when user changes filter
filter.setValueChangeMode(ValueChangeMode.EAGER);
filter.addValueChangeListener(e -> listEmployees(e.getValue()));

// Connect selected Employee to editor or hide if none is selected
grid.asSingleSelect().addValueChangeListener(e -> {
editor.editEmployee(e.getValue());
});

// Instantiate and edit new Employee the new button is clicked
addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", "")));

// Listen changes made by the editor, refresh data from backend
editor.setChangeHandler(() -> {
editor.setVisible(false);
listEmployees(filter.getValue());
});

// Initialize listing
listEmployees(null);
}

// tag::listEmployees[]
void listEmployees(String filterText) {
if (StringUtils.isEmpty(filterText)) {
grid.setItems(employeeRepository.findAll());
} else {
grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText));
}
}
// end::listEmployees[]

}

0 comments on commit dacf049

Please sign in to comment.