
public class Person {
private String name;
private String lastName;
private Integer age;
public Person(String name, String lastName, Integer age) {
super();
this.name = name;
this.lastName = lastName;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
List<Person> persons = getPersonService().fetchPersons();
Grid<Person> personsGrid = new Grid<>(Person.class);
personsGrid.setItems(persons);</code></pre>
Lazy Loading
DataProvider<Person, Void> dataProvider = DataProvider.fromCallbacks(
// First callback fetches items based on a query
query -> {
// The index of the first item to load
int offset = query.getOffset();
// The number of items to load
int limit = query.getLimit();
List<Person> persons = getPersonService()
.fetchPersons(offset, limit);
return persons.stream();
},
// Second callback fetches the number of items for a query
query -> getPersonService().getPersonCount());
);
Grid<Person> grid = new Grid<>();
grid.setDataProvider(dataProvider);
Now we added two new different methods to our service class.
But let’s continue with another relevant requirement.
Filtering
public class PersonFilter {
private String nameFilter = null;
private String lastNameFilter = null;
public PersonFilter() {
}
public PersonFilter(String nameFilter, String lastNameFilter) {
this.setNameFilter(nameFilter);
this.setLastNameFilter(lastNameFilter);
}
public String getNameFilter() {
return nameFilter;
}
public String getLastNameFilter() {
return lastNameFilter;
}
public void setNameFilter(String nameFilter) {
this.nameFilter = nameFilter;
}
public void setLastNameFilter(String lastNameFilter) {
this.lastNameFilter = lastNameFilter;
}
}
DataProvider<Person, PersonFilter> dataProvider =
DataProvider.fromFilteringCallbacks(
query -> {
Optional<PersonFilter> filter = query.getFilter();
return getPersonService().fetchPersons(
query.getOffset(),
query.getLimit(),
filter.map(f -> f.getNameFilter()).orElse(null),
filter.map(f -> f.getLastNameFilter()).orElse(null)
);
},
query -> {
Optional<PersonFilter> filter = query.getFilter();
return getPersonService().getPersonCount(
filter.map(f -> f.getNameFilter()).orElse(null),
filter.map(f -> f.getLastNameFilter()).orElse(null)
);
}
);</code></pre>
PersonFilter gridFilter = new PersonFilter();
ConfigurableFilterDataProvider<Person,Void,PersonFilter> dp = dataProvider.withConfigurableFilter();
dp.setFilter(gridFilter);</code></pre>
HeaderRow hr = personsGrid.prependHeaderRow();
TextField nameFilterTF = new TextField();
nameFilterTF.addValueChangeListener(ev->{
gridFilter.setNameFilter(ev.getValue());
dp.refreshAll();
});
hr.getCell(personsGrid.getColumnByKey("name")).setComponent(nameFilterTF);
TextField lastNameFilterTF = new TextField();
lastNameFilterTF.addValueChangeListener(ev->{
gridFilter.setLastNameFilter(ev.getValue());
dp.refreshAll();
});
hr.getCell(personsGrid.getColumnByKey("lastName")).setComponent(lastNameFilterTF);</code></pre>
Sorting
Similarly to our filtering case, we need a class to store each sorting information that we need:
public class PersonSort {
private String propertyName;
private boolean descending;
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public boolean isDescending() {
return descending;
}
public void setDescending(boolean descending) {
this.descending = descending;
}
}
DataProvider<Person, PersonFilter> dataProvider =
DataProvider.fromFilteringCallbacks(
query -> {
Optional<PersonFilter> filter = query.getFilter();
List<PersonSort> sortOrders = query.getSortOrders().stream().map(sortOrder->new PersonSort(sortOrder.getSorted(),sortOrder.getDirection().equals(SortDirection.ASCENDING))).collect(Collectors.toList());
return getPersonService().fetchPersons(
query.getOffset(),
query.getLimit(),
filter.map(f -> f.getNameFilter()).orElse(null),
filter.map(f -> f.getLastNameFilter()).orElse(null),
sortOrders
);
},
query -> {
Optional<PersonFilter> filter = query.getFilter();
return getPersonService().getPersonCount(
filter.map(f -> f.getNameFilter()).orElse(null),
filter.map(f -> f.getLastNameFilter()).orElse(null)
);
}
);</code></pre>
- Lazy loading information: offset and limit
- Filtering information: name and last name filters
- Sorting information: list of PersonSort
SELECT *
FROM PERSONS P
WHERE P.NAME LIKE %FILTERNAME% AND P.LASTNAME LIKE %LASTNAME%
ORDER BY P.NAME DESC, P.LASTNAME ASC
LIMIT OFFSET,LIMIT
Here’s a small animation showing our grid in action:
You can play around with this example, by checking this GitHub project with the sources.
Have fun!






Join the conversation!