Framework: Provide an API to set a Grid column Renderer after column creation

Created on 16 Jan 2017  路  10Comments  路  Source: vaadin/framework

In Vaadin 8.0.0.beta1 there's no way to set a Renderer to a Grid column that has been already created. This makes it harder to separate creation and configuration logic which is required in some designs.

Most helpful comment

I also vote for allowing to set the renderer. Currently, when the grid is created using the one-arg Class constructor, the only way to change the renderer is to delete the column and create it anew.

All 10 comments

Could you provide an example of some case where it would be useful to change the renderer after the column has been created?

Yes. The Crud UI add-on allows developers to generate a CRUD interface for a domain class. It works by building a Grid (among other components) that includes the required columns. The add-on uses default configurations (captions, renderers, ...) and clients can adjust if needed. For example, clients may want to use a DateRenderer for a certain column (after the column is internally created by the add-on). Moreover, developers may want the end user to be able to adjust the date format at runtime.

The generic types of Column might cause some problems for that kind of design, since e.g. DateRenderer is only valid for a Column<ItemType, Date> but not for a Column<ItemType, String>. This means that you'd still need some way of getting something that is typed as a Date column without falling back to unsafe casts.

There's a slight dev UX downside I just discovered: I added a new column like this:

Grid.Column<Bean, Date> dateColumn = grid.addColumn(Bean::getDate);

Then I was trying to figure out how to add a Renderer to this new column; there's no way to do that. Of course once I learned that there can be a second parameter in addColumn it's simple, but before I got a hint, I don't know how I should have guessed that.

I also vote for allowing to set the renderer. Currently, when the grid is created using the one-arg Class constructor, the only way to change the renderer is to delete the column and create it anew.

Is also needed for my vaadin-grid-util
Why have you changed the api that much - futhermore the documentation is lacking a lot in all these changes. Nearly it's impossible to get my often used addon working anymore...

an other example from my addon why render changes afterwards are needed:

Grid grid = new Grid(Inhabitants.class);
grid.addColumn(Inhabitants::getId,
    new EditDeleteButtonValueRenderer<Inhabitants>(edit -> {
        Notification.show(edit.getItem()
                .toString() + " want's to get edited", Type.HUMANIZED_MESSAGE);
    }, delete -> {
        Notification.show(delete.getItem()
                .toString() + " want's to get deleted", Type.WARNING_MESSAGE);
    }))
    .setWidth(160);

Explanation: Normally you initialize the grid with the given bean and afterwards you would like to change the renderer in order to inject edit delete buttons within this cell by a rendere.

Same for your provided ButtonRender or how would you use this in my example?
Initialize all columns by hand and don't provide the class within the constructor in the grid?

As the author of the ClickableTextRenderer Add-on I can only agree with melistik and others on this topic. I'll put a hold on the upgrade efforts of this add-on for now, but I'll be happy to review my decision once this has been resolved.

Fix should also be picked to 8.0 branch (without the 8.1 specific TreeGrid related parts).

The same problem exists in Vaadin Flow, but the method Column::setRenderer does not exist here. Is it done in a different way now, or was this feature just overlooked?

The Grid for Vaadin 10+ has a slightly different relationship between the value provider and the renderer which means that this fix can most likely not be used as-is but would instead require a separate implementation.

In Vaadin 8, there is always a value provider and its output is then passed to the renderer. In Vaadin 10+, there is only a renderer which receives the whole row item and then most renderer implementations are internally using a value provider callback for extracting the right value from the item.

Was this page helpful?
0 / 5 - 0 ratings