user12106967
user12106967

Reputation:

Vaadin addComponentColumn only works in last row

    this.grid = new Grid<>(Person.class);
    this.grid.setItems(personList);
    this.grid.setSelectionMode(SelectionMode.MULTI);
    this.grid.removeAllColumns();
    this.grid.setColumns("firstname");
    this.editButton = new Button(null, ImageIcons.EDIT.create());
    this.editButton.getStyle().set("color", "#000000");
    this.grid.addComponentColumn(person -> this.editButton);
    this.deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create());
    this.deleteButton.getStyle().set("color", "#000000");
    this.grid.addComponentColumn(person -> this.deleteButton);
    this.addComponentAsFirst(this.grid);

I have a personList with several entries. The grid shows all these entries with their first name. But it only shows the buttons in the last row. What is the problem?

Upvotes: 0

Views: 794

Answers (1)

kscherrer
kscherrer

Reputation: 5766

You use the very same Button instance for each row. You should create a new Button within the componentRenderer, so each row will have its own Button.

Try it like this:

this.grid = new Grid<>(Person.class, false);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.setColumns("firstname");

this.grid.addComponentColumn(person -> {
    // edit: added click listener for inline-editing of the person. Editor must be configured for this to work. See https://vaadin.com/components/vaadin-grid/java-examples/grid-editor
    // You don't have to use inline-editing if you don't want. you can also edit the item in a separate Layout with Input fields and a Binder.    
    Button editButton = new Button(ImageIcons.EDIT.create(), click -> {
        this.grid.getEditor().editItem(person);
    });
    editButton.getStyle().set("color", "#000000");
    return editButton;
});

this.grid.addComponentColumn(person -> {
    // edit: added click listener for person removal
    Button deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create(), click -> {
        this.personDao.remove(person);
        // TODO: when using an in-memory dataprovider, fetch all items again from service/dao and set them with grid.setItems(this.personDao.findAll());
        // but that is not necessary when using a callback dataprovider, which I belive OP is using
        this.grid.getDataProvider().refresh();
    });
    deleteButton.getStyle().set("color", "#000000");
    return deleteButton;
}
this.addComponentAsFirst(this.grid);

Edit: a minor thing but I still wanted to mention it - You do some unnecessary creation of columns, only to remove them all again later. Instead of this you could tell the grid not to create these columns in the first place, by passing false as second parameter of the Grid constructor.

this.grid = new Grid(Person.class, false);

// instead of

this.grid = new Grid(Person.class);
this.grid.removeAllColumns();

Upvotes: 5

Related Questions