Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.vaadin.flow.component.grid.demo;
import static com.vaadin.flow.component.grid.demo.data.CountryData.UNITED_STATES;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.ColumnTextAlign;
import com.vaadin.flow.component.grid.FooterRow;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.Grid.Column;
import com.vaadin.flow.component.grid.Grid.SelectionMode;
import com.vaadin.flow.component.grid.GridMultiSelectionModel;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.grid.HeaderRow;
import com.vaadin.flow.component.grid.HeaderRow.HeaderCell;
import com.vaadin.flow.component.grid.contextmenu.GridContextMenu;
import com.vaadin.flow.component.grid.contextmenu.GridMenuItem;
import com.vaadin.flow.component.grid.dataview.GridLazyDataView;
import com.vaadin.flow.component.grid.dataview.GridListDataView;
import com.vaadin.flow.component.grid.demo.data.CountryData;
import com.vaadin.flow.component.grid.demo.data.CustomerData;
import com.vaadin.flow.component.grid.demo.data.StatesData;
import com.vaadin.flow.component.grid.demo.data.TaskData;
import com.vaadin.flow.component.grid.demo.entity.Customer;
import com.vaadin.flow.component.grid.demo.entity.Task;
import com.vaadin.flow.component.grid.dnd.GridDragEndEvent;
import com.vaadin.flow.component.grid.dnd.GridDragStartEvent;
import com.vaadin.flow.component.grid.dnd.GridDropEvent;
import com.vaadin.flow.component.grid.dnd.GridDropLocation;
import com.vaadin.flow.component.grid.dnd.GridDropMode;
import com.vaadin.flow.component.grid.editor.Editor;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Hr;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.html.NativeButton;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.radiobutton.RadioButtonGroup;
import com.vaadin.flow.component.select.Select;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.treegrid.TreeGrid;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.converter.StringToIntegerConverter;
import com.vaadin.flow.data.provider.ListDataProvider;
import com.vaadin.flow.data.provider.hierarchy.TreeData;
import com.vaadin.flow.data.provider.hierarchy.TreeDataProvider;
import com.vaadin.flow.data.renderer.LocalDateRenderer;
import com.vaadin.flow.data.renderer.LocalDateTimeRenderer;
import com.vaadin.flow.data.renderer.NativeButtonRenderer;
import com.vaadin.flow.data.renderer.NumberRenderer;
import com.vaadin.flow.data.renderer.TemplateRenderer;
import com.vaadin.flow.data.validator.StringLengthValidator;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.demo.DemoView;
import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.router.Route;
@Route("vaadin-grid")
@JsModule("@vaadin/flow-frontend/grid-demo-styles.js")
@SuppressWarnings("squid:S1192")
public class GridDemo extends DemoView {
// begin-source-example
// source-example-heading: Grid example model
/**
* Example object.
*/
public static class Person implements Cloneable {
private int id;
private String firstName;
private String lastName;
private int age;
private Address address;
private String phoneNumber;
private MaritalStatus maritalStatus;
private LocalDate birthDate;
private boolean isSubscriber;
private String email;
public Person() {
}
public Person(int id, String firstName, String lastName, int age,
Address address, String phoneNumber) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.address = address;
this.phoneNumber = phoneNumber;
}
public Person(int id, String firstName, String lastName, int age,
Address address, String phoneNumber,
MaritalStatus maritalStatus, LocalDate birthDate) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.address = address;
this.phoneNumber = phoneNumber;
this.maritalStatus = maritalStatus;
this.birthDate = birthDate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = 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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public MaritalStatus getMaritalStatus() {
return maritalStatus;
}
public void setMaritalStatus(MaritalStatus maritalStatus) {
this.maritalStatus = maritalStatus;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
public String getImage() {
return "https://randomuser.me/api/portraits/men/" + getId()
+ ".jpg";
}
public boolean isSubscriber() {
return isSubscriber;
}
public void setSubscriber(boolean isSubscriber) {
this.isSubscriber = isSubscriber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof Person)) {
return false;
}
Person other = (Person) obj;
return id == other.id;
}
@Override
public String toString() {
return String.format("%s, %s", firstName, lastName);
}
@Override
public Person clone() { // NOSONAR
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(
"The Person object could not be cloned.", e);
}
}
}
public static class Address {
private String street;
private int number;
private String postalCode;
private String city;
public Address() {
}
public Address(String postalCode, String city) {
this.postalCode = postalCode;
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return String.format("%s %s", postalCode, city);
}
}
public enum MaritalStatus {
MARRIED, SINGLE;
}
// end-source-example
public class PersonService {
private PersonData personData = new PersonData();
public List fetch(int offset, int limit) {
int end = offset + limit;
int size = personData.getPersons().size();
if (size <= end) {
end = size;
}
return personData.getPersons().subList(offset, end);
}
public Stream fetchPage(int page, int pageSize) {
return personData.getPersons().stream().skip(page * pageSize)
.limit(pageSize);
}
public int count() {
return personData.getPersons().size();
}
public List fetchAll() {
return personData.getPersons();
}
}
// begin-source-example
// source-example-heading: Using Components in Grid
/**
* Component used for the cell rendering.
*/
public static class PersonComponent extends Div {
private String text;
/**
* Creates a new component with the given item.
*
* @param person
* the person to set
*/
public PersonComponent(Person person) {
setPerson(person);
}
/**
* Sets the person for the component.
*
* @param person
* the person to be inside inside the cell
*/
public void setPerson(Person person) {
text = "Hi, i'm the component for " + person.getFirstName() + "!";
setText(text);
}
}
/**
* Component used for the details row.
*/
public static class PersonCard extends Div {
/**
* Constructor that takes a Person as parameter.
*
* @param person
* the person to be used inside the card
*/
public PersonCard(Person person) {
addClassName("custom-details");
setId("person-card-" + person.getId());
VerticalLayout layout1 = new VerticalLayout();
layout1.add(new Label("Name: " + person.getFirstName()));
layout1.add(new Label("Id: " + person.getId()));
layout1.add(new Label("Age: " + person.getAge()));
VerticalLayout layout2 = new VerticalLayout();
layout2.add(
new Label("Street: " + person.getAddress().getStreet()));
layout2.add(new Label(
"Address number: " + person.getAddress().getNumber()));
layout2.add(new Label(
"Postal Code: " + person.getAddress().getPostalCode()));
HorizontalLayout hlayout = new HorizontalLayout(layout1, layout2);
hlayout.getStyle().set("border", "1px solid gray")
.set("padding", "10px").set("boxSizing", "border-box")
.set("width", "100%");
add(hlayout);
}
}
// end-source-example
public static class Item {
private String name;
private double price;
private LocalDateTime purchaseDate;
private LocalDate EstimatedDeliveryDate;
public Item() {
}
public Item(String name, double price, LocalDateTime purchaseDate,
LocalDate estimatedDeliveryDate) {
this.name = name;
this.price = price;
this.purchaseDate = purchaseDate;
EstimatedDeliveryDate = estimatedDeliveryDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public LocalDateTime getPurchaseDate() {
return purchaseDate;
}
public void setPurchaseDate(LocalDateTime purchaseDate) {
this.purchaseDate = purchaseDate;
}
public LocalDate getEstimatedDeliveryDate() {
return EstimatedDeliveryDate;
}
public void setEstimatedDeliveryDate(LocalDate estimatedDeliveryDate) {
EstimatedDeliveryDate = estimatedDeliveryDate;
}
@Override
public String toString() {
return getName();
}
}
public static class Order {
private String name;
private int numberOfOrder;
private float price;
private LocalDateTime purchaseDate;
private LocalDate estimatedDeliveryDate;
private String personName;
private Address address;
public Order(String name, int numberOfOrder, float price,
LocalDateTime purchaseDate, LocalDate estimatedDeliveryDate,
String personName, Address address) {
this.name = name;
this.numberOfOrder = numberOfOrder;
this.price = price;
this.purchaseDate = purchaseDate;
this.estimatedDeliveryDate = estimatedDeliveryDate;
this.personName = personName;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public LocalDateTime getPurchaseDate() {
return purchaseDate;
}
public void setPurchaseDate(LocalDateTime purchaseDate) {
this.purchaseDate = purchaseDate;
}
public LocalDate getEstimatedDeliveryDate() {
return estimatedDeliveryDate;
}
public void setEstimatedDeliveryDate(LocalDate estimatedDeliveryDate) {
this.estimatedDeliveryDate = estimatedDeliveryDate;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public int getNumberOfOrder() {
return numberOfOrder;
}
public void setNumberOfOrder(int numberOfOrder) {
this.numberOfOrder = numberOfOrder;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
public static class Benefit {
private int year;
private int quarter1;
private int quarter2;
private int quarter3;
private int quarter4;
public Benefit(int year, int quarter1, int quarter2, int quarter3,
int quarter4) {
this.year = year;
this.quarter1 = quarter1;
this.quarter2 = quarter2;
this.quarter3 = quarter3;
this.quarter4 = quarter4;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getQuarter1() {
return quarter1;
}
public void setQuarter1(int quarter1) {
this.quarter1 = quarter1;
}
public int getQuarter2() {
return quarter2;
}
public void setQuarter2(int quarter2) {
this.quarter2 = quarter2;
}
public int getQuarter3() {
return quarter3;
}
public void setQuarter3(int quarter3) {
this.quarter3 = quarter3;
}
public int getQuarter4() {
return quarter4;
}
public void setQuarter4(int quarter4) {
this.quarter4 = quarter4;
}
}
@Override
protected void initView() {
createBasicUsage();// Basic Grid
addVariantFeature();
createGridWithLazyLoading(); // Lazy Loading
createGridWithCustomItemCountEstimate();
createGridWithExactItemCount();
createGridWithPagedRepository();
createSingleSelect(); // Selection
createMultiSelect();
createProgrammaticSelect();
createGridWithSortableColumns();// Sorting
createGridWithTextFieldFilters();// Filtering
createGridWithDataTypeSpecificFilters();
createConfiguringColumns();// Configuring Columns
createManuallyDefiningColumns();
createAutoWidthColumns();
createFrozenColumns();
createColumnAlignment();
columnReorder();
createHeaderAndFooter();// Header and footer
createColumnGrouping();
createHeaderAndFooterUsingComponents();
createFormattingText();// Formatting contents
createHtmlTemplateRenderer();
createGridUsingComponent();// Using components
createGridUsingComponentFilters();
createGridWithItemDetails();
createItemDetailsOpenedProgrammatically();
createContextMenu();// Context Menu
createContextSubMenu();// Context Sub Menu
createDynamicContextMenu(); // Dynamic Context Menu
createClickListener();// Click Listener
createDoubleClickListener();
createBufferedEditor();// Grid Editor
createNotBufferedEditor();
createBufferedDynamicEditor();
createNotBufferedDynamicEditor();
createRowReordering();
createDragRowsBetweenGrids();
createDropLocations();
createDragData();
createDragDropFilters();
createExternalDataNavigation();
createDynamicHeight();
addCard("Grid example model",
new Label("These objects are used in the examples above"));
addCard("Using Components", "Using Components in Grid",
new Label("These objects are used in the examples above"));
}
// Grid Basics begin
private void createBasicUsage() {
// begin-source-example
// source-example-heading: Grid Basics
List personList = new ArrayList<>();
personList.add(new Person(100, "Lucas", "Kane", 68,
new Address("12080", "Washington"), "127-942-237"));
personList.add(new Person(101, "Peter", "Buchanan", 38,
new Address("93849", "New York"), "201-793-488"));
personList.add(new Person(102, "Samuel", "Lee", 53,
new Address("86829", "New York"), "043-713-538"));
personList.add(new Person(103, "Anton", "Ross", 37,
new Address("63521", "New York"), "150-813-6462"));
personList.add(new Person(104, "Aaron", "Atkinson", 18,
new Address("25415", "Washington"), "321-679-8544"));
personList.add(new Person(105, "Jack", "Woodward", 28,
new Address("95632", "New York"), "187-338-588"));
Grid grid = new Grid<>(Person.class);
grid.setItems(personList);
grid.removeColumnByKey("id");
// The Grid<>(Person.class) sorts the properties and in order to
// reorder the properties we use the 'setColumns' method.
grid.setColumns("firstName", "lastName", "age", "address",
"phoneNumber");
// end-source-example
grid.setId("basic-usage");
addCard("Grid Basics", grid);
}
private void addVariantFeature() {
// begin-source-example
// source-example-heading: Theme variants usage
List personList = getItems();
Grid grid = new Grid<>();
grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getAge).setHeader("Age");
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER,
GridVariant.LUMO_NO_ROW_BORDERS, GridVariant.LUMO_ROW_STRIPES);
// end-source-example
addVariantsDemo(() -> grid, Grid::addThemeVariants,
Grid::removeThemeVariants, GridVariant::getVariantName,
GridVariant.LUMO_NO_BORDER, GridVariant.LUMO_NO_ROW_BORDERS,
GridVariant.LUMO_ROW_STRIPES);
}
// Lazy Loading Begin
private void createGridWithLazyLoading() {
// begin-source-example
// source-example-heading: Grid with lazy loading
Grid grid = new Grid<>();
PersonService personService = new PersonService();
/*
* When provided a callback, the grid doesn't load all items from
* backend to server memory right away. It will request only the data
* that is shown in its current view "window". The data is provided
* based on offset and limit.
*
* When the user scrolls to the end grid will automatically extend and
* fetch more items until the backend runs out of items.
*/
grid.setItems(query -> personService
.fetch(query.getOffset(), query.getLimit()).stream());
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getLastName).setHeader("Last Name");
grid.addColumn(Person::getAge).setHeader("Age");
// end-source-example
grid.setId("lazy-loading");
addCard("Lazy Loading", "Grid with lazy loading", grid);
}
private void createGridWithCustomItemCountEstimate() {
// begin-source-example
// source-example-heading: Fast Scroll with Custom Item Count Estimate
// The backend will have 12345 items
final ItemGenerator fakeBackend = new ItemGenerator(12345);
Grid grid = new Grid<>();
GridLazyDataView lazyDataView = grid.setItems(query -> fakeBackend
.generateItems(query.getOffset(), query.getLimit()));
/*
* By default the grid will initially adjust the scrollbar to 200 items
* and as the user scrolls down it automatically increases the size by
* 200 until the backend runs out of items.
*
* Both the estimated item count and its increase can be customized to
* allow the user to scroll down faster when the backend will have a lot
* of items.
*/
lazyDataView.setItemCountEstimate(1000);
lazyDataView.setItemCountEstimateIncrease(1000);
// Showing the item count for demo purposes
Div countText = new Div();
lazyDataView.addItemCountChangeListener(event -> {
if (event.isItemCountEstimated()) {
countText.setText(
"Item Count Estimate: " + event.getItemCount());
} else {
countText.setText("Exact Item Count: " + event.getItemCount());
}
});
VerticalLayout layout = new VerticalLayout(grid, countText);
grid.addColumn(Item::getName).setHeader("Name").setWidth("20px");
grid.addColumn(new NumberRenderer<>(Item::getPrice, "$ %(,.2f",
Locale.US, "$ 0.00")).setHeader("Price");
grid.addColumn(new LocalDateTimeRenderer<>(Item::getPurchaseDate,
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT,
FormatStyle.MEDIUM)))
.setHeader("Purchase Date and Time").setFlexGrow(2);
grid.addColumn(new LocalDateRenderer<>(Item::getEstimatedDeliveryDate,
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))
.setHeader("Estimated Delivery Date");
// end-source-example
grid.setId("custom-item-count-estimate");
addCard("Lazy Loading", "Fast Scroll with Custom Item Count Estimate",
layout);
}
private void createGridWithExactItemCount() {
// begin-source-example
// source-example-heading: Exact item count
Grid grid = new Grid<>();
PersonService personService = new PersonService();
/*
* In case it is desired to show to the user the exact number of items
* in the backend, that can be done providing another callback that
* fetches the item count from the backend.
*/
GridLazyDataView lazyDataView = grid.setItems(
query -> personService
.fetch(query.getOffset(), query.getLimit()).stream(),
query -> personService.count());
// The grid can be on switched back to unknown item count through the
// API in the lazy data view:
// lazyDataView.setItemCountUnknown();
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getLastName).setHeader("Last Name");
grid.addColumn(Person::getAge).setHeader("Age");
// end-source-example
grid.setId("count-callback");
addCard("Lazy Loading", "Exact item count", grid);
}
private void createGridWithPagedRepository() {
//@formatter:off
// begin-source-example
// source-example-heading: Loading from a paged repository
Grid grid = new Grid<>();
PersonService service = new PersonService();
/*
* For backends which provide data in pages, like Spring Data
* repositories, it is possible to get the page number and size from the
* Query API.
* For more instructions on how to work with Spring Data,
* see the documentation in https://vaadin.com/docs and the tutorials in
* https://vaadin.com/learn/tutorials/.
*/
grid.setItems(query -> service.fetchPage(query.getPage(),
query.getPageSize())
);
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getLastName).setHeader("Last Name");
grid.addColumn(Person::getAge).setHeader("Age");
// end-source-example
//@formatter:on
grid.setId("paged-grid");
addCard("Lazy Loading", "Loading from a paged repository", grid);
}
// Assigning Data Begin
private void createArrayData() {
// begin-source-example
// source-example-heading: Assigning Array Data
List personList = getItems();
// Providing a bean-type generates columns for all of it's properties
Grid grid = new Grid<>();
grid.setItems(personList);
Grid.Column firstNameColumn = grid
.addColumn(Person::getFirstName).setHeader("First Name");
Grid.Column lastNameColumn = grid.addColumn(Person::getLastName)
.setHeader("Last Name");
grid.addColumn(Person::getAge).setHeader("Age");
Button addButton = new Button("Add Item", event -> {
personList.add(new Person(10000, "X", "Y", 16,
new Address("95632", "New York"), "187-338-588"));
// The dataProvider knows which List it is based on, so when you
// edit the list
// you edit the dataprovider.
grid.getDataProvider().refreshAll();
});
Button removeButton = new Button("Remove last", event -> {
personList.remove(personList.size() - 1);
// The dataProvider knows which List it is based on, so when you
// edit the list
// you edit the dataprovider.
grid.getDataProvider().refreshAll();
});
FooterRow footerRow = grid.appendFooterRow();
footerRow.getCell(firstNameColumn).setComponent(addButton);
footerRow.getCell(lastNameColumn).setComponent(removeButton);
// end-source-example
grid.setId("assigning-array-data");
addButton.setId("assigning-array-data-add");
removeButton.setId("assigning-array-data-remove");
addCard("Assigning Data", "Assigning Array Data", grid, addButton,
removeButton);
}
private void createDynamicHeight() {
// begin-source-example
// source-example-heading: Dynamic Height
List personList = getItems();
// Providing a bean-type generates columns for all of it's properties
Grid grid = new Grid<>();
// When using allRowsVisible, all items are fetched and
// Grid uses all the space needed to render everything.
//
// Note: allRowsVisible disables the grid's virtual scrolling so that
// all the rows are rendered in the DOM at once.
// If the grid has a large number of items, using the feature is
// discouraged to avoid performance issues.
grid.setAllRowsVisible(true);
final GridListDataView dataView = grid.setItems(personList);
Grid.Column firstNameColumn = grid
.addColumn(Person::getFirstName).setHeader("First Name");
Grid.Column lastNameColumn = grid.addColumn(Person::getLastName)
.setHeader("Last Name");
Grid.Column ageColumn = grid.addColumn(Person::getAge)
.setHeader("Age");
Button addButton = new Button("Add Item",
event -> dataView.addItem(new Person(106, "X", "Y", 16,
new Address("95632", "New York"), "187-338-588")));
Button removeButton = new Button("Remove last", event -> dataView
.removeItem(dataView.getItem(dataView.getItemCount() - 1)));
FooterRow footerRow = grid.appendFooterRow();
footerRow.getCell(firstNameColumn).setComponent(addButton);
footerRow.getCell(lastNameColumn).setComponent(removeButton);
// end-source-example
grid.setId("dynamic-height");
addButton.setId("dynamic-height-add");
removeButton.setId("dynamic-height-remove");
addCard("Dynamic Height", "Dynamic Height", grid, addButton,
removeButton);
}
// Selection Begin
private void createSingleSelect() {
Div messageDiv = new Div();
// begin-source-example
// source-example-heading: Grid Single Selection
List personList = getItems();
Grid grid = new Grid<>();
grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getAge).setHeader("Age");
grid.asSingleSelect().addValueChangeListener(event -> {
String message = String.format("Selection changed from %s to %s",
event.getOldValue(), event.getValue());
messageDiv.setText(message);
});
// end-source-example
grid.setId("single-selection");
messageDiv.setId("single-selection-message");
addCard("Selection", "Grid Single Selection", grid, messageDiv);
}
private void createMultiSelect() {
Div messageDiv = new Div();
// begin-source-example
// source-example-heading: Grid Multi Selection
List personList = getItems();
Grid grid = new Grid<>();
grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getAge).setHeader("Age");
grid.setSelectionMode(SelectionMode.MULTI);
grid.asMultiSelect().addValueChangeListener(event -> {
String message = String.format("Selection changed from %s to %s",
event.getOldValue(), event.getValue());
messageDiv.setText(message);
});
// You can pre-select items
grid.asMultiSelect().select(personList.get(0), personList.get(1));
// end-source-example
grid.setId("multi-selection");
messageDiv.setId("multi-selection-message");
addCard("Selection", "Grid Multi Selection", grid, messageDiv);
}
private void createProgrammaticSelect() {
// begin-source-example
// source-example-heading: Grid with Programmatic Selection
PersonService personService = new PersonService();
List personList = personService.fetchAll();
H3 firstHeader = new H3("Grid with single select");
Grid firstGrid = new Grid<>();
firstGrid.setItems(personList);
H3 secondHeader = new H3("Grid with multi select");
Grid secondGrid = new Grid<>();
secondGrid.setItems(personList);
secondGrid.setSelectionMode(SelectionMode.MULTI);
TextField filterField = new TextField();
filterField.setValueChangeMode(ValueChangeMode.EAGER);
filterField.addValueChangeListener(event -> {
Optional foundPerson = personList.stream()
.filter(person -> person.getFirstName().toLowerCase()
.startsWith(event.getValue().toLowerCase()))
.findFirst();
firstGrid.asSingleSelect().setValue(foundPerson.orElse(null));
secondGrid.getSelectionModel().deselectAll();
Set foundpersons = personList.stream()
.filter(person -> person.getFirstName().toLowerCase()
.startsWith(event.getValue().toLowerCase()))
.collect(Collectors.toSet());
secondGrid.asMultiSelect().setValue(foundpersons);
});
firstGrid.addColumn(Person::getFirstName).setHeader("First Name");
firstGrid.addColumn(Person::getAge).setHeader("Age");
secondGrid.addColumn(Person::getFirstName).setHeader("First Name");
secondGrid.addColumn(Person::getAge).setHeader("Age");
NativeButton deselectBtn = new NativeButton("Deselect all");
deselectBtn.addClickListener(
event -> secondGrid.asMultiSelect().deselectAll());
NativeButton selectAllBtn = new NativeButton("Select all");
selectAllBtn.addClickListener(
event -> ((GridMultiSelectionModel) secondGrid
.getSelectionModel()).selectAll());
// end-source-example
filterField.setId("programmatic-select-filter");
firstHeader.setId("programmatic-select-first-header");
firstGrid.setId("programmatic-select");
secondHeader.setId("programmatic-select-second-header");
secondGrid.setId("programmatic-select-second-filter");
selectAllBtn.setId("programmatic-select-select-all");
deselectBtn.setId("programmatic-select-deselect");
addCard("Selection", "Grid with Programmatic Selection", filterField,
firstHeader, firstGrid, secondHeader, secondGrid, selectAllBtn,
deselectBtn);
}
// Sorting Begin
private void createGridWithSortableColumns() {
Div messageDiv = new Div();
// begin-source-example
// source-example-heading: Grid with sortable columns
List personList = getItems();
Grid grid = new Grid<>();
grid.setItems(personList);
grid.setSelectionMode(SelectionMode.NONE);
grid.addColumn(Person::getFirstName, "First Name")
.setHeader("First Name");
grid.addColumn(Person::getLastName, "Last Name").setHeader("Last Name");
grid.addColumn(Person::getAge, "age").setHeader("Age");
// addColumn is not Comparable so it uses toString method to sort the
// column.
grid.addColumn(TemplateRenderer. of(
"
[[item.city]] [[item.postalCode]]
")
.withProperty("city", person -> person.getAddress().getCity())
.withProperty("postalCode",
person -> person.getAddress().getPostalCode()),
"city", "postalCode").setHeader("Address");
Checkbox multiSort = new Checkbox("Multiple column sorting enabled");
multiSort.addValueChangeListener(
event -> grid.setMultiSort(event.getValue()));
// you can set the sort order from server-side with the grid.sort method
NativeButton invertAllSortings = new NativeButton(
"Invert all sort directions", event -> {
List> newList = grid.getSortOrder()
.stream()
.map(order -> new GridSortOrder<>(order.getSorted(),
order.getDirection().getOpposite()))
.collect(Collectors.toList());
grid.sort(newList);
});
NativeButton resetAllSortings = new NativeButton("Reset all sortings",
event -> grid.sort(null));
// end-source-example
grid.setId("grid-sortable-columns");
multiSort.setId("grid-multi-sort-toggle");
invertAllSortings.setId("grid-sortable-columns-invert-sorting");
resetAllSortings.setId("grid-sortable-columns-reset-sorting");
messageDiv.setId("grid-sortable-columns-message");
addCard("Sorting", "Grid with sortable columns", grid, multiSort,
messageDiv, invertAllSortings, resetAllSortings);
}
// Filtering
private void createGridWithTextFieldFilters() {
// begin-source-example
// source-example-heading: Using text fields for filtering items
List personList = getItems();
Grid grid = new Grid<>();
final GridListDataView dataView = grid.setItems(personList);
Grid.Column firstNameColumn = grid
.addColumn(Person::getFirstName).setHeader("Name");
Grid.Column ageColumn = grid.addColumn(Person::getAge)
.setHeader("Age");
Grid.Column cityColumn = grid
.addColumn(person -> person.getAddress().getCity())
.setHeader("City");
Grid.Column postalCodeColumn = grid
.addColumn(person -> person.getAddress().getPostalCode())
.setHeader("Postal Code");
HeaderRow filterRow = grid.appendHeaderRow();
// First filter
TextField firstNameField = new TextField();
firstNameField.addValueChangeListener(event -> dataView.addFilter(
person -> StringUtils.containsIgnoreCase(person.getFirstName(),
firstNameField.getValue())));
firstNameField.setValueChangeMode(ValueChangeMode.EAGER);
filterRow.getCell(firstNameColumn).setComponent(firstNameField);
firstNameField.setSizeFull();
firstNameField.setPlaceholder("Filter");
// Second filter
TextField ageField = new TextField();
ageField.addValueChangeListener(event -> dataView
.addFilter(person -> StringUtils.containsIgnoreCase(
String.valueOf(person.getAge()), ageField.getValue())));
ageField.setValueChangeMode(ValueChangeMode.EAGER);
filterRow.getCell(ageColumn).setComponent(ageField);
ageField.setSizeFull();
ageField.setPlaceholder("Filter");
// Third filter
TextField cityField = new TextField();
cityField.addValueChangeListener(event -> dataView
.addFilter(person -> StringUtils.containsIgnoreCase(
person.getAddress().getCity(), cityField.getValue())));
cityField.setValueChangeMode(ValueChangeMode.EAGER);
filterRow.getCell(cityColumn).setComponent(cityField);
cityField.setSizeFull();
cityField.setPlaceholder("Filter");
// Fourth filter
TextField postalCodeField = new TextField();
postalCodeField.addValueChangeListener(
event -> dataView.addFilter(person -> StringUtils
.containsIgnoreCase(person.getAddress().getPostalCode(),
postalCodeField.getValue())));
postalCodeField.setValueChangeMode(ValueChangeMode.EAGER);
filterRow.getCell(postalCodeColumn).setComponent(postalCodeField);
postalCodeField.setSizeFull();
postalCodeField.setPlaceholder("Filter");
// end-source-example
grid.setId("grid-with-filters");
addCard("Filtering", "Using text fields for filtering items", grid);
}
// begin-source-example
// source-example-heading: Using data type specific filtering
private ComboBox maritalStatus;
private DatePicker birthDateField;
private VerticalLayout createGridWithFilters() {
VerticalLayout layout = new VerticalLayout();
PersonService personService = new PersonService();
List personList = personService.fetchAll();
Grid grid = new Grid<>();
final GridListDataView dataView = grid.setItems(personList);
final Column nameColumn = grid.addColumn(Person::getFirstName)
.setHeader("Name");
grid.addColumn(Person::getAge).setHeader("Age");
grid.addColumn(Person::getBirthDate).setHeader("Birth Date");
grid.addColumn(person -> person.getAddress().getPostalCode())
.setHeader("Postal Code");
maritalStatus = new ComboBox<>("Filter by marital status: ");
maritalStatus.setItems(MaritalStatus.values());
maritalStatus.setClearButtonVisible(true);
birthDateField = new DatePicker("Filter by birth date: ");
maritalStatus.addValueChangeListener(event -> applyFilter(dataView));
birthDateField.addValueChangeListener(event -> applyFilter(dataView));
final Label sizeLabel = new Label();
grid.appendFooterRow().getCell(nameColumn).setComponent(sizeLabel);
// Show total amount of matching items
dataView.addItemCountChangeListener(
event -> sizeLabel.setText("Total: " + event.getItemCount()));
layout.add(maritalStatus, birthDateField, grid);
return layout;
}
private void applyFilter(GridListDataView dataView) {
dataView.removeFilters();
if (birthDateField.getValue() != null) {
dataView.addFilter(person -> Objects
.equals(birthDateField.getValue(), person.getBirthDate()));
}
if (maritalStatus.getValue() != null) {
dataView.addFilter(person -> maritalStatus.getValue() == person
.getMaritalStatus());
}
}
// end-source-example
private void createGridWithDataTypeSpecificFilters() {
VerticalLayout layout = createGridWithFilters();
layout.setId("layout-with-filters");
addCard("Filtering", "Using data type specific filtering", layout);
}
// Configuring Columns Begin
private void createConfiguringColumns() {
// begin-source-example
// source-example-heading: Configuring columns
List personList = getItems();
// Providing a bean-type generates columns for all of it's properties
Grid grid = new Grid<>(Person.class);
// Property-names are automatically set as keys
// You can remove undesired columns by using the key
grid.removeColumnByKey("id");
// It could be used to specify columns order
grid.setColumns("firstName", "lastName", "age", "address",
"phoneNumber");
grid.setItems(personList);
// Columns for sub-properties can be added easily
grid.addColumn("address.postalCode");
// end-source-example
grid.setId("configuring-columns");
addCard("Configuring columns", "Configuring columns", grid);
}
private void createManuallyDefiningColumns() {
// begin-source-example
// source-example-heading: Manually defining columns
List personList = getItems();
Grid grid = new Grid<>();
grid.setSelectionMode(Grid.SelectionMode.MULTI);
grid.setItems(personList);
Grid.Column idColumn = grid.addColumn(Person::getId)
.setHeader("ID").setFlexGrow(0).setWidth("75px");
// Combination of properties
grid.addColumn(
Person -> Person.getFirstName() + " " + Person.getLastName())
.setHeader("Full Name").setResizable(true);
// Setting a column-key allows fetching the column later
grid.addColumn(Person::getAge).setHeader("Age").setKey("age");
grid.getColumnByKey("age").setResizable(true);
Checkbox idColumnVisibility = new Checkbox(
"Toggle visibility of the ID column");
idColumnVisibility.addValueChangeListener(
event -> idColumn.setVisible(!idColumn.isVisible()));
Checkbox userReordering = new Checkbox(
"Toggle user reordering of columns");
userReordering.addValueChangeListener(event -> grid
.setColumnReorderingAllowed(!grid.isColumnReorderingAllowed()));
// end-source-example
grid.setId("column-api-example");
idColumnVisibility.setId("toggle-id-column-visibility");
userReordering.setId("toggle-user-reordering");
addCard("Configuring columns", "Manually defining columns", grid,
new VerticalLayout(grid, idColumnVisibility, userReordering));
}
private void createAutoWidthColumns() {
// begin-source-example
// source-example-heading: Columns with automatic width
List personList = getItems();
Grid grid = new Grid<>(Person.class);
grid.setItems(personList);
grid.setColumns("firstName", "lastName", "age", "birthDate", "address",
"phoneNumber");
grid.getColumns()
.forEach(personColumn -> personColumn.setAutoWidth(true));
Button recalculateWidthsButton = new Button(
"Recalculate column widths");
recalculateWidthsButton.addClickListener(
buttonClickEvent -> grid.recalculateColumnWidths());
// end-source-example
grid.setId("column-auto-width-grid");
recalculateWidthsButton.setId("column-auto-width-button");
addCard("Configuring columns", "Columns with automatic width", grid,
recalculateWidthsButton);
}
private void createFrozenColumns() {
// begin-source-example
// source-example-heading: Frozen column example
List personList = getItems();
H3 firstHeader = new H3("Freezing the selection column");
Grid firstGrid = new Grid<>();
firstGrid.setItems(personList);
firstGrid.addColumn(Person::getId).setHeader("ID").setWidth("75px");
firstGrid.addColumn(Person::getFirstName).setHeader("First Name");
firstGrid.addColumn(Person::getLastName).setHeader("Last Name");
firstGrid.addColumn(Person::getPhoneNumber).setHeader("Phone Number")
.setWidth("200px");
firstGrid.addColumn(Person::getAddress).setHeader("Adress")
.setWidth("200px");
firstGrid.addColumn(Person::getMaritalStatus)
.setHeader("Marital status").setWidth("200px");
firstGrid.addColumn(Person::getBirthDate).setHeader("Birth Date")
.setWidth("200px");
firstGrid.setColumnReorderingAllowed(true);
((GridMultiSelectionModel>) firstGrid
.setSelectionMode(Grid.SelectionMode.MULTI))
// Freezing the selection column only
.setSelectionColumnFrozen(true);
H3 secondHeader = new H3("Freezing the data columns");
Grid secondGrid = new Grid<>();
secondGrid.setItems(personList);
// Freezing any column
secondGrid.addColumn(Person::getId).setHeader("ID").setWidth("75px")
.setFrozen(true);
secondGrid.addColumn(Person::getFirstName).setHeader("First Name")
.setFrozen(true);
secondGrid.addColumn(Person::getLastName).setHeader("Last Name")
.setFrozen(true);
secondGrid.addColumn(Person::getPhoneNumber).setHeader("Phone Number")
.setWidth("200px");
secondGrid.addColumn(Person::getAddress).setHeader("Adress")
.setWidth("200px");
secondGrid.addColumn(Person::getMaritalStatus)
.setHeader("Marital status").setWidth("200px");
secondGrid.addColumn(Person::getBirthDate).setHeader("Birth Date")
.setWidth("200px");
// end-source-example
firstGrid.setId("frozen-column-first-grid");
secondGrid.setId("frozen-column-first-grid");
addCard("Configuring columns", "Frozen column example", firstHeader,
firstGrid, secondHeader, secondGrid);
}
private void createColumnAlignment() {
// begin-source-example
// source-example-heading: Column alignment example
List personList = getItems();
Grid grid = new Grid<>();
grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name");
// Setting a column-key allows fetching the column later
grid.addColumn(Person::getAge).setHeader("Age").setKey("age");
grid.getColumnByKey("age");
RadioButtonGroup alignments = new RadioButtonGroup<>();
alignments.setItems(ColumnTextAlign.values());
alignments.setLabel("Text alignment for the Age column");
// ColumnTextAlign is a grid feature enum that is used to configure text
// alignment inside columns.
alignments.setValue(ColumnTextAlign.START);
alignments.addValueChangeListener(event -> grid.getColumnByKey("age")
.setTextAlign(event.getValue()));
// end-source-example
grid.setId("column-alignment-example");
alignments.setId("column-alignment-example-alignments");
addCard("Configuring columns", "Column alignment example", grid,
alignments);
}
private void columnReorder() {
// begin-source-example
// source-example-heading: Column reorder example
List personList = getItems();
Grid grid = new Grid<>();
grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name")
.setKey("firstName");
grid.addColumn(Person::getLastName).setHeader("Last Name")
.setKey("lastName");
grid.addColumn(Person::getAge).setHeader("Age").setKey("age");
grid.addColumn(Person::getEmail).setHeader("Email").setKey("email");
grid.addColumn(Person::getPhoneNumber).setHeader("Phone Number")
.setKey("phoneNo");
grid.addColumn(Person::getBirthDate).setHeader("Birth Date")
.setKey("birthDate");
Span columnOrder = new Span();
grid.setColumnReorderingAllowed(true);
grid.addColumnReorderListener(event -> columnOrder
.setText(event.getColumns().stream().map(Column::getKey)
.collect(Collectors.joining(", "))));
// end-source-example
grid.setId("column-reorder-example");
addCard("Configuring columns", "Column reorder example", grid,
columnOrder);
}
// Header and footer begin
private void createHeaderAndFooter() {
// begin-source-example
// source-example-heading: Header and footer texts
List personList = getItems();
Grid grid = new Grid<>();
final GridListDataView dataView = grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name")
.setFooter("Total: " + dataView.getItemCount() + " people");
long averageOfAge = Math.round(personList.stream()
.mapToInt(Person::getAge).average().orElse(0));
grid.addColumn(Person::getAge).setHeader("Age")
.setFooter("Average: " + averageOfAge);
// end-source-example
grid.setId("header-and-footer");
addCard("Header and footer", "Header and footer texts", grid);
}
private void createColumnGrouping() {
// begin-source-example
// source-example-heading: Column Grouping
int sum = 200;
List benefitList = new ArrayList<>();
benefitList.add(new Benefit(2017, sum, sum, sum, sum));
benefitList.add(new Benefit(2018, sum += 10, sum, sum, sum));
benefitList.add(new Benefit(2019, sum += 10, sum, sum, sum));
benefitList.add(new Benefit(2020, sum += 10, sum, sum, sum));
benefitList.add(new Benefit(2021, sum += 10, sum, sum, sum));
Grid grid = new Grid<>();
grid.setItems(benefitList);
grid.addColumn(Benefit::getYear).setHeader("Year");
// Setting the alignment of columns
Grid.Column quarter1 = grid.addColumn(Benefit::getQuarter1, "")
.setHeader("Quarter 1").setTextAlign(ColumnTextAlign.END);
Grid.Column quarter2 = grid.addColumn(Benefit::getQuarter2, "")
.setHeader("Quarter 2").setTextAlign(ColumnTextAlign.END);
Grid.Column quarter3 = grid.addColumn(Benefit::getQuarter3, "")
.setHeader("Quarter 3").setTextAlign(ColumnTextAlign.END);
Grid.Column quarter4 = grid.addColumn(Benefit::getQuarter4, "")
.setHeader("Quarter 4").setTextAlign(ColumnTextAlign.END);
HeaderRow halfheaderRow = grid.prependHeaderRow();
// Setting the alignment of only the header
Div half1Header = new Div(new Span("Half 1"));
half1Header.getStyle().set("text-align", "right");
half1Header.setSizeFull();
halfheaderRow.join(quarter1, quarter2).setComponent(half1Header);
// Setting the alignment of only the header
Div half2Header = new Div(new Span("Half 2"));
half2Header.getStyle().set("text-align", "right");
half2Header.setSizeFull();
halfheaderRow.join(quarter3, quarter4).setComponent(half2Header);
// Footers can be set with a similar API
// end-source-example
grid.setId("grid-with-header-and-footer");
addCard("Header and footer", "Column Grouping", grid);
}
private void createHeaderAndFooterUsingComponents() {
// begin-source-example
// source-example-heading: Using components
Grid grid = new Grid<>();
final GridListDataView dataView = grid.setItems(getItems());
Grid.Column nameColumn = grid.addColumn(Person::getFirstName)
.setHeader(new Label("Name")).setComparator((p1, p2) -> p1
.getFirstName().compareToIgnoreCase(p2.getFirstName()));
Column ageColumn = grid.addColumn(Person::getAge, "age")
.setHeader(new Label("Age"));
Column streetColumn = grid
.addColumn(person -> person.getAddress().getCity())
.setHeader(new Label("City"));
Column postalCodeColumn = grid
.addColumn(person -> person.getAddress().getPostalCode())
.setHeader(new Label("Postal Code"));
// Create and combine the header
HeaderRow topRow = grid.prependHeaderRow();
HeaderCell buttonsCell = topRow.join(nameColumn, ageColumn,
streetColumn, postalCodeColumn);
// Create and add buttons
Button lessThanTwentyYearsold = new Button("-20 years old",
event -> dataView.setFilter(person -> person.getAge() < 20));
Button twentyToForty = new Button("Between 20-40 years old",
event -> dataView.setFilter(person -> (person.getAge() >= 20
&& person.getAge() <= 40)));
Button overForty = new Button("+40 years old",
event -> dataView.setFilter(person -> person.getAge() > 40));
HorizontalLayout filter = new HorizontalLayout(lessThanTwentyYearsold,
twentyToForty, overForty);
buttonsCell.setComponent(filter);
final Label sizeLabel = new Label();
grid.appendFooterRow().getCell(nameColumn).setComponent(sizeLabel);
// Set the total amount of people when the size changes due to filters
dataView.addItemCountChangeListener(event -> sizeLabel
.setText("Total: " + event.getItemCount() + " people"));
// end-source-example
grid.setId("using-components");
addCard("Header and footer", "Using components", grid);
}
// Formatting contents
private void createFormattingText() {
// begin-source-example
// source-example-heading: Formatting text
List itemList = new ArrayList<>();
String str = "2016-03-04 11:30:40";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
LocalDate localDate = LocalDate.parse(str, formatter);
itemList.add(new Item("Car", 250, dateTime, localDate));
itemList.add(new Item("Flower", 10, dateTime, localDate));
itemList.add(new Item("Book", 210, dateTime, localDate));
itemList.add(new Item("Games", 250, dateTime, localDate));
Grid grid = new Grid<>();
grid.setItems(itemList);
grid.addColumn(Item::getName).setHeader("Name").setWidth("20px");
// NumberRenderer to render numbers in general
grid.addColumn(new NumberRenderer<>(Item::getPrice, "$ %(,.2f",
Locale.US, "$ 0.00")).setHeader("Price");
// LocalDateTimeRenderer for date and time
grid.addColumn(new LocalDateTimeRenderer<>(Item::getPurchaseDate,
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT,
FormatStyle.MEDIUM)))
.setHeader("Purchase Date and Time").setFlexGrow(2);
// LocalDateRenderer for dates
grid.addColumn(new LocalDateRenderer<>(Item::getEstimatedDeliveryDate,
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))
.setHeader("Estimated Delivery Date");
// end-source-example
grid.setId("grid-formatting-contents");
addCard("Formatting contents", "Formatting text", grid);
}
private void createHtmlTemplateRenderer() {
// begin-source-example
// source-example-heading: Grid with HTML template renderer
List orderList = new ArrayList<>();
String str = "2016-03-04 11:30:40";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
LocalDate localDate = LocalDate.parse(str, formatter);
orderList.add(new Order("T-shirt", 2, 20, dateTime, localDate,
"Mickael", new Address("12080", "Washington")));
orderList.add(new Order("Pant", 2, 70, dateTime, localDate, "Peter",
new Address("93849", "New York")));
orderList.add(new Order("Bag", 1, 60, dateTime, localDate, "Samuel",
new Address("86829", "New York")));
Grid grid = new Grid<>();
grid.setItems(orderList);
grid.addColumn(Order::getName).setHeader("Buyer").setFlexGrow(1);
NumberFormat moneyFormat = NumberFormat.getCurrencyInstance(Locale.US);
// You can also set complex objects directly. Internal properties of the
// bean are accessible in the template.
grid.addColumn(TemplateRenderer. of(
"
[[item.name]],[[item.price]] purchased on: [[item.purchasedate]]
")
.withProperty("name", Order::getName)
// NumberRenderer to render numbers in general
.withProperty("price",
order -> moneyFormat.format(order.getPrice()))
.withProperty("purchasedate",
order -> formatter.format(order.getPurchaseDate())))
.setHeader("Purchase").setFlexGrow(6);
grid.addColumn(TemplateRenderer. of(
"
Estimated delivery date: [[item.estimatedDeliveryDate]] to: [[item.address.city]],[[item.address.postalCode]]
")
.withProperty("estimatedDeliveryDate",
order -> formatter.format(order.getPurchaseDate()))
.withProperty("address", order -> order.getAddress()))
.setHeader("Delivery").setFlexGrow(6);
// end-source-example
grid.setId("template-renderer");
addCard("Formatting Contents", "Grid with HTML template renderer",
grid);
}
// Using components begin
private Grid createGridUsingComponent() {
// begin-source-example
// source-example-heading: Using Components
List personList = getItems();
Grid grid = new Grid<>();
final GridListDataView dataView = grid.setItems(personList);
// Use the component constructor that accepts an item ->
// new PersonComponent(Person person)
grid.addComponentColumn(PersonComponent::new).setHeader("Person");
// Or you can use an ordinary function to setup the component
grid.addComponentColumn(item -> createRemoveButton(dataView, item))
.setHeader("Actions");
grid.setSelectionMode(Grid.SelectionMode.NONE);
return grid;
}
private Button createRemoveButton(GridListDataView dataView,
Person item) {
Button button = new Button("Remove",
clickEvent -> dataView.removeItem(item));
return button;
}
// end-source-example
private void createGridUsingComponentFilters() {
Grid grid = createGridUsingComponent();
grid.setId("using-components");
addCard("Using Components", "Using Components", grid);
}
// Item details
private void createGridWithItemDetails() {
// begin-source-example
// source-example-heading: Grid with item details
List personList = getItems();
H3 header = new H3("Clicking on a row will show more details");
Grid grid = new Grid<>();
grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getAge).setHeader("Age");
grid.setSelectionMode(Grid.SelectionMode.NONE);
// You can use any renderer for the item details. By default, the
// details are opened and closed by clicking the rows.
grid.setItemDetailsRenderer(TemplateRenderer. of(
"
"
+ "
Hi! My name is [[item.firstName]]!
"
+ ""
+ "
")
.withProperty("firstName", Person::getFirstName)
.withProperty("lastname", Person::getLastName)
.withProperty("address", Person::getAddress)
.withProperty("image", Person::getImage)
.withEventHandler("handleClick",
person -> grid.getListDataView().refreshItem(person)));
// end-source-example
grid.setId("item-details");
header.setId("item-details-header");
addCard("Item details", "Grid with item details", header, grid);
}
private void createItemDetailsOpenedProgrammatically() {
// begin-source-example
// source-example-heading: Open details programmatically
// Disable the default way of opening item details:
List personList = getItems();
H3 header = new H3("Clicking on buttons will show more details");
Grid grid = new Grid<>();
grid.setItems(personList);
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getAge).setHeader("Age");
grid.setSelectionMode(Grid.SelectionMode.NONE);
// You can use any renderer for the item details. By default, the
// details are opened and closed by clicking the rows.
grid.setItemDetailsRenderer(TemplateRenderer. of(
"
"
+ "
Hi! My name is [[item.firstName]]!
"
+ "
")
.withProperty("firstName", Person::getFirstName)
// This is now how we open the details
.withEventHandler("handleClick",
person -> grid.getListDataView().refreshItem(person)));
// Disable the default way of opening item details:
grid.setDetailsVisibleOnClick(false);
grid.addColumn(new NativeButtonRenderer<>("Details", item -> grid
.setDetailsVisible(item, !grid.isDetailsVisible(item))));
// end-source-example
grid.setId("open-details-programmatically");
header.setId("open-details-programmatically-header");
addCard("Item details", "Open details programmatically", header, grid);
}
// begin-source-example
// source-example-heading: Navigating grid items externally
// Clicking on item in grid opens dialog for item navigation
private Grid createExternalDataNavigationGrid() {
Grid grid = new Grid<>(Person.class);
final GridListDataView dataView = grid
.setItems(new PersonService().fetchAll());
grid.removeColumnByKey("id");
// The Grid<>(Person.class) sorts the properties and in order to
// reorder the properties we use the 'setColumns' method.
grid.setColumns("firstName", "lastName", "age", "address",
"phoneNumber");
grid.addItemClickListener(
event -> new DataDialog(dataView, event.getItem()).open());
return grid;
}
private class DataDialog extends Dialog {
private Button next;
private Button previous;
private Person currentItem;
private final GridListDataView dataView;
private Span data = new Span();
public DataDialog(GridListDataView dataView, Person item) {
this.dataView = dataView;
next = new Button("Next",
event -> setItem(dataView.getNextItem(currentItem).get()));
previous = new Button("Previous", event -> setItem(
dataView.getPreviousItem(currentItem).get()));
setItem(item);
setModal(true);
HorizontalLayout layout = new HorizontalLayout(previous, data,
next);
layout.expand(data);
layout.setAlignItems(FlexComponent.Alignment.CENTER);
layout.setWidth("400px");
add(new VerticalLayout(new Span("Click outside to close"), layout));
}
private void setItem(Person item) {
currentItem = item;
data.setText(String.format("%s %s", item.getFirstName(),
item.getLastName()));
next.setEnabled(dataView.getNextItem(currentItem).isPresent());
previous.setEnabled(
dataView.getPreviousItem(currentItem).isPresent());
}
}
// end-source-example
private void createExternalDataNavigation() {
Grid grid = createExternalDataNavigationGrid();
grid.setId("external-item-navigation");
addCard("Item details", "Navigating grid items externally", grid);
}
// Context Menu begin
private void createContextMenu() {
TextArea message = new TextArea("");
message.setHeight("100px");
message.setReadOnly(true);
TaskData taskData = new TaskData();
List taskList = taskData.getTasks();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
// begin-source-example
// source-example-heading: Using ContextMenu With Grid
Grid grid = new Grid<>();
List tasks = taskData.getTasks();
GridListDataView dataView = grid.setItems(tasks);
grid.addColumn(Task::getName).setHeader("Task Name");
grid.addColumn(Task::getDueDate).setHeader("Due Date");
GridContextMenu contextMenu = new GridContextMenu<>(grid);
GridMenuItem insert = contextMenu.addItem("Insert");
insert.getSubMenu().addItem("Add a task before", event -> event
.getItem()
.ifPresent(item -> dataView.addItemBefore(
new Task(100, "New Task",
LocalDate.parse("02/01/2019", formatter)),
item)));
insert.getSubMenu().add(new Hr());
insert.getSubMenu().addItem("Add a task after", event -> event.getItem()
.ifPresent(item -> dataView.addItemAfter(
new Task(100, "New Task",
LocalDate.parse("02/01/2019", formatter)),
item)));
contextMenu.addItem("Remove",
event -> event.getItem().ifPresent(dataView::removeItem));
contextMenu.addGridContextMenuOpenedListener(event -> message.setValue(
String.format("Menu opened on\n Row: '%s'\n Column: '%s'",
event.getItem().map(Task::toString).orElse("-no item-"),
event.getColumnId().orElse("-no column-"))));
// end-source-example
grid.setId("context-menu-grid");
addCard("Context Menu", "Using ContextMenu With Grid", grid,
contextMenu, message);
}
// Context sub Menu begin
private void createContextSubMenu() {
// begin-source-example
// source-example-heading: Using Context Sub Menu With Grid
Grid grid = new Grid<>();
final GridListDataView dataView = grid
.setItems(new PersonService().fetchAll());
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getAge).setHeader("Age");
GridContextMenu contextMenu = new GridContextMenu<>(grid);
GridMenuItem insert = contextMenu.addItem("Insert");
insert.getSubMenu().addItem("Insert a row above", event -> {
Optional item = event.getItem();
if (!item.isPresent()) {
// no selected row
return;
}
dataView.addItemBefore(item.get(), createItems(1).get(0));
});
insert.getSubMenu().add(new Hr());
insert.getSubMenu().addItem("Insert a row below", event -> {
Optional item = event.getItem();
if (!item.isPresent()) {
// no selected row
return;
}
dataView.addItemAfter(item.get(), createItems(1).get(0));
});
// end-source-example
grid.setId("context-sub-menu-grid");
addCard("Context Menu", "Using Context Sub Menu With Grid", grid,
contextMenu);
}
// Dynamic Context Menu begin
private void createDynamicContextMenu() {
TaskData taskData = new TaskData();
// begin-source-example
// source-example-heading: Dynamic Context Menu
Grid grid = new Grid<>();
grid.setItems(taskData.getTasks());
grid.addColumn(Task::getName).setHeader("Task Name");
grid.addColumn(Task::getDueDate).setHeader("Due Date");
GridContextMenu contextMenu = new GridContextMenu<>(grid);
contextMenu.setDynamicContentHandler(task -> {
if (task == null) {
// do not show the context menu when a row is not clicked
return false;
}
contextMenu.removeAll();
contextMenu.addItem("Name: " + task.getName());
contextMenu.addItem("Due date: " + task.getDueDate());
return true; // show the context menu
});
// end-source-example
grid.setId("dynamic-context-menu-grid");
addCard("Context Menu", "Dynamic Context Menu", grid, contextMenu);
}
// Click Listener Begin
private void createClickListener() {
FormLayout formLayout = new FormLayout();
Label name = new Label();
Label age = new Label();
Label column = new Label();
// begin-source-example
// source-example-heading: Item Click Listener
Grid grid = new Grid<>();
grid.setItems(getItems());
grid.addColumn(Person::getFirstName).setHeader("First Name")
.setKey("First Name");
grid.addColumn(Person::getAge).setHeader("Age").setKey("Age");
// Disable selection: will receive only click events instead
grid.setSelectionMode(Grid.SelectionMode.NONE);
formLayout.add(name, age);
formLayout.addFormItem(name, "Name");
formLayout.addFormItem(age, "Age");
formLayout.addFormItem(column, "Column");
grid.addItemClickListener(event -> {
name.setText(event.getItem().getFirstName());
age.setText(String.valueOf(event.getItem().getAge()));
column.setText(event.getColumn().getKey());
});
// end-source-example
grid.setId("item-click-listener");
addCard("Click Listeners", "Item Click Listener", grid, formLayout);
}
private void createDoubleClickListener() {
Div message = new Div();
message.setId("doubleclicked-item");
FormLayout formLayout = new FormLayout();
Label name = new Label();
Label age = new Label();
// begin-source-example
// source-example-heading: Item Double Click Listener
Grid grid = new Grid<>();
grid.setItems(getItems());
grid.addColumn(Person::getFirstName).setHeader("First Name");
grid.addColumn(Person::getAge).setHeader("Age");
formLayout.add(name, age);
formLayout.addFormItem(name, "Name");
formLayout.addFormItem(age, "Age");
grid.addItemDoubleClickListener(event -> {
name.setText(event.getItem().getFirstName());
age.setText(String.valueOf(event.getItem().getAge()));
});
// end-source-example
grid.setId("item-doubleclick-listener");
message.addClickListener(event -> message.setText(""));
addCard("Click Listeners", "Item Double Click Listener", grid,
formLayout);
}
// Grid Editor
private void createBufferedEditor() {
PersonService personService = new PersonService();
List personList = personService.fetchAll();
Div message = new Div();
message.setId("buffered-editor-msg");
// begin-source-example
// source-example-heading: Editor in Buffered Mode
Grid grid = new Grid<>();
List persons = getItems();
grid.setItems(persons);
Grid.Column firstNameColumn = grid
.addColumn(Person::getFirstName).setHeader("First Name");
Grid.Column ageColumn = grid.addColumn(Person::getAge)
.setHeader("Age");
Binder binder = new Binder<>(Person.class);
Editor editor = grid.getEditor();
editor.setBinder(binder);
editor.setBuffered(true);
Div validationStatus = new Div();
validationStatus.setId("validation");
TextField firstNameField = new TextField();
binder.forField(firstNameField)
.withValidator(new StringLengthValidator(
"First name length must be between 3 and 50.", 3, 50))
.withStatusLabel(validationStatus).bind("firstName");
firstNameColumn.setEditorComponent(firstNameField);
TextField ageField = new TextField();
binder.forField(ageField)
.withConverter(
new StringToIntegerConverter("Age must be a number."))
.withStatusLabel(validationStatus).bind("age");
ageColumn.setEditorComponent(ageField);
Collection