Ad

Vaadin Grid Column Setting Generics Arguments

- 1 answer

I want to remove the warnings in my code. I tried the following two changes:

    grid = new MyGrid<>(KPIBusinessDisplay.class);

    grid.setColumns();
    grid.addColumn("frequency");    
    Grid.Column<KPIBusinessDisplay, FREQUENCYUNITTYPES> frequencyUnitColumn = grid.addColumn("frequencyUnit");

    frequencyUnitColumn.setRenderer(new ValueProvider<FREQUENCYUNITTYPES, String>()
    {
        private static final long serialVersionUID = 6833675800012389627L;

        @Override
        public String apply(FREQUENCYUNITTYPES source) {
            return messageByLocaleService.getMessage(source.name());
        }}, new TextRenderer()
    );

For this case, I get an error when assigning grid.addColumn return value:

Type mismatch: cannot convert from Grid.Column<KPIBusinessDisplay,capture#13-of ?> to Grid.Column<KPIBusinessDisplay,CalendarConstants.FREQUENCYUNITTYPES>

If I try it differently:

Grid.Column<KPIBusinessDisplay, ?> frequencyUnitColumn = grid.addColumn("frequencyUnit");

        frequencyUnitColumn.setRenderer(new ValueProvider<FREQUENCYUNITTYPES, String>()
        {
            private static final long serialVersionUID = 6833675800012389627L;

            @Override
            public String apply(FREQUENCYUNITTYPES source) {
                return messageByLocaleService.getMessage(source.name());
            }}, new TextRenderer()
        );

I get the error at setRenderer:

The method setRenderer(ValueProvider<capture#14-of ?,P>, Renderer<? super P>) in the type Grid.Column<KPIBusinessDisplay,capture#14-of ?> is not applicable for the arguments (new ValueProvider<CalendarConstants.FREQUENCYUNITTYPES,String>(){}, TextRenderer)

If I use it like this:

Grid.Column frequencyUnitColumn = grid.addColumn("frequencyUnit");

        frequencyUnitColumn.setRenderer(new ValueProvider<FREQUENCYUNITTYPES, String>()
        {
            private static final long serialVersionUID = 6833675800012389627L;

            @Override
            public String apply(FREQUENCYUNITTYPES source) {
                return messageByLocaleService.getMessage(source.name());
            }}, new TextRenderer()
        );

then I get a warning:

Type safety: The method setRenderer(ValueProvider, Renderer) belongs to the raw type Grid.Column. References to generic type Grid.Column<T,V> should be parameterized

How can I fix the warning without provoking an error?

Ad

Answer

The compiler warning happens because the compiler doesn't have enough type information to "guarantee" that the code won't cause ClassCastException at runtime. The reason for this is that you're using a "magic" string for identifying bean properties. The compiler cannot "know" that "frequencyUnit" refers to the method getFrequencyUnit() in KPIBusinessDisplay, and it can therefore also not know that the renderer you're setting will be compatible.

The compiler warning basically means that the compiler cannot warn you if the return type of getFrequencyUnit() would be changed to return values of a type that the renderer cannot handle.

If you don't want to suppress those warnings, your can instead create the column in a way that makes the compiler aware of the relationship between types: Grid.Column<KPIBusinessDisplay, FREQUENCYUNITTYPES> frequencyUnitColumn = grid.addColumn(KPIBusinessDisplay::getFrequencyUnit);.

This is slightly longer to type, but it has the benefit that the compiler can detect problems immediately for you if you change the return type of getFrequencyUnit. Also, if using the refactor functionality in your IDE to change the name of getFrequencyUnit, then the IDE will also automatically update the code in addColumn. This would not be the case if a string would be used.

Ad
source: stackoverflow.com
Ad