javavaadinnested-generics

Using nested generics in java


In Vaadin 8.5.1 we have a Grid component which has this method to add new columns to the grid.

<V> Grid.​Column<​T​,V>     addColumn(​ValueProvider<​T​,V> valueProvider)

A full examples looks like this:

// Have some data
List<Person> people = Arrays.asList(
    new Person("Nicolaus Copernicus", 1543),
    new Person("Galileo Galilei", 1564),
    new Person("Johannes Kepler", 1571));

// Create a grid bound to the list
Grid<Person> grid = new Grid<>();
grid.setItems(people);
grid.addColumn(Person::getName).setCaption("Name");
grid.addColumn(Person::getBirthYear).setCaption("Year of birth");

layout.addComponent(grid);

and this works fine. But what I'm now trying to implement is, when the Person class extends another class which is common to most objects.

For example:

public class NamedClass
{
    ...
    public String getName()
    {
        return name;
    }
}

public class Person extends NamedClass
{
    ...
    public int getBirthYear()
    {
         return birthYear;
    }
}

Now I wish to make a grid helper class, which does the

grid.addColumn(NamedClass::getName).setCaption("Name");

for all descendent class, als the other properties are handled my a extension of this.

I tried with:

public class ANamedGridHelper<T extends NamedClass> {

    public Column<T, ?> mapProperties(Grid grid) {
       return grid.addColumn(NamedClass::getName).setId("name");
    }
}

and

 public class PersonGridHellper<Person>
 {
     ----
 }

but it won't compile the ANamedGridHelper class

org/aarboard/gridtest1/ANamedGridHelper.java:[19,19] no suitable method found for addColumn(NamedClass::getName)
    method com.vaadin.ui.Grid.addColumn(java.lang.String) is not applicable
      (argument mismatch; java.lang.String is not a functional interface)
    method com.vaadin.ui.Grid.addColumn(com.vaadin.data.ValueProvider) is not applicable
      (argument mismatch; invalid method reference
          method getName in class org.aarboard.gridtest1.NamedClass cannot be applied to given types
            required: no arguments
            found: java.lang.Object
            reason: actual and formal argument lists differ in length)
org/aarboard/gridtest1/ANamedGridHelper.java:[19,30] invalid method reference
  non-static method getName() cannot be referenced from a static context

Solution

  • There is unknown for compiler type of T. Since the method getName comes from NamedClass, you have to do the same either in the method `ANamedGridHelper::mapProperties:

    public class ANamedGridHelper<T extends NamedClass> {
        public Column<T, ?> mapProperties(Grid<T> grid, T bo) {
           return grid.addColumn(NamedClass::getName).setId("name");
        }
    }
    

    Few notes:

    I had to also add the to the Grid parameter of the method, now it works as expected.