It seems simple enough, and used to work as follows:
private List<Person> list = Arrays.asList(new Person("Jim"), new Person("Jack"));
private ListDataModel<Person> dataModel = new ListDataModel<>(list);
This had some shortcomings when for example the user decided to select a different department, executing this code:private ListDataModel<Person> dataModel = new ListDataModel<>(list);
list = findPersonsByDepartment(department);
This seems to work just fine. A person selects a different department, and the employees data model updates itself. Or so one would think.What happens is that the ListDataModel retains the old list. So, the frontend is never updated.
Reusing the same list
Because of this little problem, our code retains a lot of the following statements, to make sure the same list is used over and over again:list.clear();
list.addAll(findPersonsByDepartment(department));
It seems a slightly convoluted way to doing things.list.addAll(findPersonsByDepartment(department));
Anonymous inner classes
We soon found out that anonymous inner classes would solve this problem better, and in fact there are more anonymous inner classes than there are named DataModels in our current code base.It looks like the following:
private ListDataModel<Person> dataModel = new ListDataModel<Person>()
{
@Override
public List<Person> getList()
{
return findPersonsByDepartment(department);
}
};
There now, any time the contents of the ListDataModel is requested in the frontend, a new and accurate List containing the department employees is returned.{
@Override
public List<Person> getList()
{
return findPersonsByDepartment(department);
}
};
Passing code
Instead of creating an entire new anonymous inner subclass of a ListDataModel, it might be more elegant to create an interface especially for this purpose, call it the ListProvider interface.As follows:
public interface ListProvider<T>
{
List<T> getList();
}
private ListDataModel<Person> dataModel = new ListDataModel<Person>(new ListProvider<>()
{
@Override
public List<Person> getList()
{
return findPersonsByDepartment(department);
}
});
{
List<T> getList();
}
private ListDataModel<Person> dataModel = new ListDataModel<Person>(new ListProvider<>()
{
@Override
public List<Person> getList()
{
return findPersonsByDepartment(department);
}
});
Using lambdas
The good part is that now with Java 8 we can start using Lambdas.
And in this case, we have an interface containing just one method. This is in essence the definition of a lambda.
So now the proper way to write this would be the following:
public interface ListProvider<T>
{
List<T> getList();
}
private ListDataModel<Person> dataModel =
new ListDataModel<Person>(() -> findPersonsByDepartment(department));
Convenient, isn't it?{
List<T> getList();
}
private ListDataModel<Person> dataModel =
new ListDataModel<Person>(() -> findPersonsByDepartment(department));
In this case, the lambda is called a Supplier2 .
References
- [1] Welcome to the SlickGrid! (outdated sadly)
- https://github.com/mleibman/SlickGrid/wiki
- [2] Supplier (Java Platform SE 8)
- https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html