How do I apply a custom comparator on a column in a Grid?

So for example my grid is composed of People (in fact People is a subclass of the items in the Grid) so that I have:

    public class People
    {
        int id;
        String name;
    }

My grid is such that I have:

grid.addColumn(People::getName).setId("Name");

Now I know I can do:

    grid.sort("Name", SortDirection.ASCENDING);

The problem is what if I have two people with the same name, say John. In this case I want to first sort by name and then by id. The id is not a column in the grid, it’s just a property of the People class.

Although this example is oversimplified I do include additional information so it’s important that I’m able to sort by the actual person and not just the name. In my case the grid is a report and the person’s name is just one of many fields.

That’s fine if the the only property I need to compare is name, but what if it’s also say city in other cases. Basically People is one property of many but there are more than one column about People (name, address, city, etc.).

In other words I want to be able to define how to sort a specific column (set a comparator). This way I can say use this value first but if that fails (they are equal) then fall back to this value. In other words

Comparator.comparing(People::getName, Comparator.nullsFirst(Comparator.naturalOrder()))
    .thenComparing(People::getId, Comparator.nullsFirst(Comparator.naturalOrder()));

So that if I have another column, say city, I can then do:

Comparator.comparing(People::getFirstname, Comparator.nullsFirst(Comparator.naturalOrder()))
    .thenComparing(People::getId, Comparator.nullsFirst(Comparator.naturalOrder()));

Basically so that it’s possible to revert to a second comparator if the values are the same so that the same person is grouped together rather than being mixed randomly.

IIRC it’s enough to let People implement Comparable .

This is where I get a little confused. Ok so let’s say I have a grid of Cars. The Car object is such that:

public class Car
{
    private String name;
    private People owner;
}

The for my Grid I have:

Grid<Car> cars = new Grid<Car>();
grid.addColumn(Car::getName).setId("Name");
grid.addColumn(Car::getOwner).setId("Owner").setComparator(new CarComparator());

In this case the Compartor has to be on Car and can’t be on the People class. It’s not the end of the world but it’s just seems weird. Am I doing this correctly?

Also is it possible to create the Grid compartor with a lambda? The only way I could find was by implementing the interface?

On a side now do you know how I can create a custom renderer for the car so that I don’t have to rely on the toString()? There are a lot of examples online but none that seem to map a simple POJO to a String with a lambda…

Check grid.getColumn(…).setComparator(…)


https://vaadin.com/download/release/8.3/8.3.1/docs/api/com/vaadin/ui/Grid.Column.html#setComparator-com.vaadin.server.SerializableComparator-