Combo inside grid

I want to know how to add a ComboBox in a row inside a Grid, Part already solvent, and by means of a listener in the grid, change the values in that cell completely.

Can you explain in more detail what is your goal? I don’t understand what you mean except that you want a Grid column with a ComboBox inside.

What kind of listener do you mean (on the grid or on the comboBox? listening to what event?), and what should change exactly? the options of the comboBox? or an attribute of the bean?

hey thank you very much for the prompt response, well yes, that, I already have the combo in the first column, and the listener, whichever works,

I think about selecting an item from the combo, with that specific item changing the values ​​of the whole cell, that is to say replacing the previous item by means of what is selected in the combo.

I have only one bean that I use for the whole cell, only one.

In the combo I intend to double click to obtain a list of items, and then through an itemcaptionGenerator where I only show the name of the item I get it and change the whole cell.

What do you mean change the whole cell? I thought you had the ComboBox in that cell.

Ah, I believe I get what you’re trying to say. Let me paint the picture of your idea, and you tell me if I’m right okay?

You have a Grid with items of Type Foo (example class). And a Foo item has a list of other items, of Type Bar (example class too).
And in your Grid<Foo> you add a column to show details of a single Bar item but since each Foo can have multiple Bars the user will have to choose which Bar should be displayed, using a ComboBox that is also in the same column.

Kaspar Scherrer:
What do you mean change the whole cell? I thought you had the ComboBox in that cell.

Ah, I believe I get what you’re trying to say. Let me paint the picture of your idea, and you tell me if I’m right okay?

You have a Grid with items of Type Foo (example class). And a Foo item has a list of other items, of Type Bar (example class too).
And in your Grid<Foo> you add a column to show details of a single Bar item but since each Foo can have multiple Bars the user will have to choose which Bar should be displayed, using a ComboBox that is also in the same column.

yeah that’s correct.

In general, Grid rows are not made to display collections of items. You would usually use another grid for that, as Grid is the perfect Component to show collections of items.
However, there are ways how to display this information anyway. Your approach is one of them but I would choose a more intuitive and user-freindly approach.

I have already [answered a similar question on stackoverflow]
(https://stackoverflow.com/a/55393201/3441504), where I describe these other approaches. In short, I recommend one of the following approaches (sorted by my own preference):

  • Make a Layout to show some attributes of the selected Foo item. In this separate Layout, you can add for example a Grid<Bar> with all Bar items of the selected Foo. Whenever the user selects a different Foo in the main grid, the other layout will update to use the currently selected foo. You could also show this layout in a Dialog that appears when a row is clicked, or in a separate View.

  • Similar to the above, you can define an itemDetailsRenderer directly on the grid, where you set a Layout to show up below the row when a grid row is clicked. The main difference to the approach above is that the layout is shown within the grid - so the details layout should not be too big. Also, showing another grid within a grid-details does not look very great and intuitive.

  • (Your Approach) add a ComboBox next to some details of a single Bar item. Using the ComboBox, the user can choose which bar should be used to display some details. (I did not think of your approach to this when I wrote that answer, but yours is surely possible. If you really want it that way, then I shall help you figure it out.)

  • find the most important information you want to show from each Bar and concatenate them for all Bars of the foo item, so they can be shown within a single column. I must say that I really don’t like this approach in general as it is usually not clear enough. In some cases, this could be enough though.

Hi Kaspar Scherrer,

This is the grid, thanks for the detailed explanation, but I think it explains badly

Bean Alimento

/**
 *
 *
 * @author _0x52e
 *
 */
public final class Alimento {

    private String nombre;
    private double proteinas;
    private double grasas;
    private double carbohidratos;
    private double cantidad;
    private double kiloCalorias;
    private Identificador identificador;

    public Alimento(final Alimento.Builder builder) {
        this.nombre = builder.nombre;
        this.proteinas = builder.proteinas;
        this.carbohidratos = builder.carbohidratos;
        this.grasas = builder.grasas;
        this.cantidad = builder.cantidadDeGramosDeAlimento;
        this.kiloCalorias = builder.kiloCalorias;
        this.identificador = builder.identificador;
    }

    public void setNombre(final String nombre){this.nombre = nombre;}

    public String getNombre() {
        return nombre;
    }

    public double getProteinas() {
        return proteinas;
    }

    public double getGrasas() {
        return grasas;
    }

    public double getCarbohidratos() {
        return carbohidratos;
    }

    public double getCantidadGramosDeAlimento() {
        return cantidad;
    }

    public double getKiloCalorias() {
        return kiloCalorias;
    }

    public Identificador getIdentificador() {
        return identificador;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Alimento)) return false;
        Alimento alimento = (Alimento) o;
        return Double.compare(alimento.proteinas, proteinas) == 0 &&
                Double.compare(alimento.grasas, grasas) == 0 &&
                Double.compare(alimento.carbohidratos, carbohidratos) == 0 &&
                Double.compare(alimento.cantidad, cantidad) == 0 &&
                Double.compare(alimento.kiloCalorias, kiloCalorias) == 0 &&
                Objects.equals(nombre, alimento.nombre) &&
                identificador == alimento.identificador;
    }

    @Override
    public int hashCode() {
        return Objects.hash(nombre, proteinas, grasas, carbohidratos, cantidad, kiloCalorias, identificador);
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("\nAlimento ");
        sb.append(nombre).append("\n");
        sb.append("proteinas=").append(proteinas);
        sb.append("gr, carbohidratos=").append(carbohidratos);
        sb.append("gr, grasas=").append(grasas);
        sb.append("gr, cantidad a consumir=").append(cantidad);
        sb.append("gr, kiloCalorias=").append(kiloCalorias);
        sb.append(", identificador=").append(identificador);
        sb.append("]");
        return sb.toString();
    }

    /**
     * Builder
     */
    public static class Builder implements IBuilder<Alimento> {

        private String nombre;
        private double proteinas;
        private double grasas;
        private double carbohidratos;
        private double cantidadDeGramosDeAlimento;
        private double kiloCalorias;
        public Identificador identificador;

        public Builder con(final Consumer<Builder> consumer) {
            consumer.accept(this);
            return this;
        }

        public Builder conNombre(final String nombre) {
            this.nombre = nombre;
            return this;
        }

        public Builder conProteina(final double proteinas) {
            this.proteinas = proteinas;
            return this;
        }

        public Builder conGrasas(final double grasa) {
            this.grasas = grasa;
            return this;
        }

        public Builder conCarbohidratos(final double carbos) {
            this.carbohidratos = carbos;
            return this;
        }

        public Builder conKiloCalorias(final double kiloCalorias) {
            this.kiloCalorias = kiloCalorias;
            return this;
        }

        public Builder conCantidadDeGramosDeAlimento(final double cantidad) {
            this.cantidadDeGramosDeAlimento = cantidad;
            return this;
        }

        @Override
        public Alimento make() {
            return new Alimento(this);
        }
    }
}

This is how I create the grid with its combobox rendering in the first column

public Grid<Alimento> createGridDieta(String fase, final Button buttonDeleteGrid) {
        final Grid<Alimento> gridDieta = new Grid<>();
        gridDieta.setWidthFull();
        gridDieta.setHeightByRows(Boolean.TRUE);
        gridDieta.addThemeVariants(GridVariant.LUMO_COLUMN_BORDERS, GridVariant.LUMO_ROW_STRIPES);

        final Grid.Column<Alimento> columnNombre = gridDieta.addColumn(Alimento::getNombre)
                .setHeader("Alimento").setKey(N).setWidth("200px");

        final Grid.Column<Alimento> cantidadGr = gridDieta.addColumn(Alimento::getCantidadGramosDeAlimento)
                .setHeader("Porción gr")
                .setKey(CANTIDAD);

        final Grid.Column<Alimento> columnProtes = gridDieta.addColumn(Alimento::getProteinas)
                .setHeader(PROTEINAS)
                .setKey(P);

        final Grid.Column<Alimento> columnCarbos = gridDieta.addColumn(Alimento::getCarbohidratos)
                .setHeader(CARBOS)
                .setKey(C);

        final Grid.Column<Alimento> columnGrasa = gridDieta.addColumn(Alimento::getGrasas)
                .setHeader(GRASAS)
                .setKey(G);

        final Grid.Column<Alimento> columnKCals = gridDieta.addColumn(Alimento::getKiloCalorias)
                .setHeader(KILO_CALORIAS)
                .setKey(KCALS);

        gridDieta.getColumns().forEach(e -> e.setComparator(Comparator.comparing(Objects::toString)));
        gridDieta.getColumns().forEach(e -> e.setResizable(Boolean.TRUE));

        final HeaderRow headerRow = gridDieta.prependHeaderRow();

        final Div div = new Div();
        div.getStyle().set(TEXT_ALIGN, CENTER);
        div.setSizeFull();

        final StringBuilder sb = new StringBuilder();

        if (fase.equals(DEFINICION)) {

            sb.append(PROTEINAS_2)
                    .append(porcentajeProteina)
                    .append("% ")
                    .append(CARBOS_2)
                    .append(porcentajeCarbos)
                    .append("% ")
                    .append(GRASAS_2)
                    .append(porcentajeGrasas)
                    .append("% ");

            final List<Alimento> comidaDiariaDefinicion = alimentoRepository.getComidaDiariaDefinicion();
            final ListDataProvider<Alimento> listDataProviderComida = new ListDataProvider<>(comidaDiariaDefinicion);
            gridDieta.setDataProvider(listDataProviderComida);
            gridDieta.getDataProvider().refreshAll();

            /*
             * Footers
             */
            gridDieta.getColumnByKey(N).setFooter("Total");

            gridDieta.getColumnByKey(CANTIDAD).setFooter("-");
            final double protesPorComida = comidaDiariaDefinicion.get(0).getProteinas();
            final double sumaProtes = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getProteinas).sum());
            if (sumaProtes > protesPorComida + 5) {
                final Label labelProtes = new Label(String.valueOf(sumaProtes));
                labelProtes.getStyle().set(COLOR, COLOR_ERROR);
                gridDieta.getColumnByKey(P).setFooter(labelProtes);
            } else {
                gridDieta.getColumnByKey(P).setFooter(String.valueOf(sumaProtes));
            }

            final double sumaCarbos = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getCarbohidratos).sum());
            gridDieta.getColumnByKey(C).setFooter(String.valueOf(sumaCarbos));

            final double sumaGrasas = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getGrasas).sum());
            gridDieta.getColumnByKey(G).setFooter(String.valueOf(sumaGrasas));

            final double sumaCalorias = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getKiloCalorias).sum());
            gridDieta.getColumnByKey(KCALS).setFooter(String.valueOf(sumaCalorias));

        } else if (fase.equals(MANTENIMIENTO)) {

            sb.append(PROTEINAS_2)
                    .append(porcentajeProteina)
                    .append("% ")
                    .append(CARBOS_2)
                    .append(porcentajeCarbos)
                    .append("% ")
                    .append(GRASAS_2)
                    .append(porcentajeGrasas)
                    .append("% ");

            final List<Alimento> comidaDiariaMantenimiento = alimentoRepository.getComidaDiariaMantenimiento();
            final ListDataProvider<Alimento> listDataProviderComida = new ListDataProvider<>(comidaDiariaMantenimiento);
            gridDieta.setDataProvider(listDataProviderComida);
            gridDieta.getDataProvider().refreshAll();

            /*
             * Footers
             */
            gridDieta.getColumnByKey(N).setFooter("Total");

            gridDieta.getColumnByKey(CANTIDAD).setFooter("-");
            final double protesPorComida = comidaDiariaMantenimiento.get(0).getProteinas();
            final double sumaProtes = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getProteinas).sum());
            if (sumaProtes > protesPorComida + 5) {
                final Label labelProtes = new Label(String.valueOf(sumaProtes));
                labelProtes.getStyle().set(COLOR, COLOR_ERROR);
                gridDieta.getColumnByKey(P).setFooter(labelProtes);
            } else {
                gridDieta.getColumnByKey(P).setFooter(String.valueOf(sumaProtes));
            }

            final double sumaCarbos = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getCarbohidratos).sum());
            gridDieta.getColumnByKey(C).setFooter(String.valueOf(sumaCarbos));

            final double sumaGrasas = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getGrasas).sum());
            gridDieta.getColumnByKey(G).setFooter(String.valueOf(sumaGrasas));

            final double sumaCalorias = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getKiloCalorias).sum());
            gridDieta.getColumnByKey(KCALS).setFooter(String.valueOf(sumaCalorias));

        } else {

            sb.append(PROTEINAS_2)
                    .append(porcentajeProteina)
                    .append("% ")
                    .append(CARBOS_2)
                    .append(porcentajeCarbos)
                    .append("% ")
                    .append(GRASAS_2)
                    .append(porcentajeGrasas)
                    .append("% ");


            final List<Alimento> comidaDiariaVolumen = alimentoRepository.getComidaDiariaVolumen();
            final ListDataProvider<Alimento> listDataProviderComida = new ListDataProvider<>(comidaDiariaVolumen);
            gridDieta.setDataProvider(listDataProviderComida);
            gridDieta.getDataProvider().refreshAll();

            /*
             * Footers
             */
            gridDieta.getColumnByKey(N).setFooter("Total");

            gridDieta.getColumnByKey(CANTIDAD).setFooter("-");
            final double protesPorComida = comidaDiariaVolumen.get(0).getProteinas();
            final double sumaProtes = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getProteinas).sum());
            if (sumaProtes > protesPorComida + 5) {
                final Label labelProtes = new Label(String.valueOf(sumaProtes));
                labelProtes.getStyle().set(COLOR, COLOR_ERROR);
                gridDieta.getColumnByKey(P).setFooter(labelProtes);
            } else {
                gridDieta.getColumnByKey(P).setFooter(String.valueOf(sumaProtes));
            }

            final double sumaCarbos = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getCarbohidratos).sum());
            gridDieta.getColumnByKey(C).setFooter(String.valueOf(sumaCarbos));

            final double sumaGrasas = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getGrasas).sum());
            gridDieta.getColumnByKey(G).setFooter(String.valueOf(sumaGrasas));

            final double sumaCalorias = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getKiloCalorias).sum());
            gridDieta.getColumnByKey(KCALS).setFooter(String.valueOf(sumaCalorias));
        }

        final Label label = new Label("Comida numero " + sb.toString());
        final HorizontalLayout row = new HorizontalLayout(buttonDeleteGrid, label);
        row.setWidthFull();
        row.setSpacing(Boolean.TRUE);
        row.setVerticalComponentAlignment(FlexComponent.Alignment.CENTER, label);

        headerRow.join(columnNombre, cantidadGr, columnProtes, columnCarbos, columnGrasa, columnKCals).setComponent(row);

        final Binder<Alimento> binder = new Binder<>(Alimento.class);
        gridDieta.getEditor().setBinder(binder);

        final ComboBox<String> comboBox = new ComboBox<>();
        comboBox.setWidthFull();
        comboBox.setPreventInvalidInput(Boolean.TRUE);

        final List<String> listaAlimentosCombo = new ArrayList<>(alimentoRepository.findAllProtes()
                .stream()
                .map(Alimento::getNombre)
                .collect(Collectors.toList()));

        final ListDataProvider<String> listDataNewAlimentosCombo = new ListDataProvider<>(listaAlimentosCombo);
        comboBox.setDataProvider(listDataNewAlimentosCombo);
        //comboBox.setItemLabelGenerator(Alimento::getNombre);
        //comboBox.setValue(Alimento::getNombre);
        binder.bind(comboBox, N);
        columnNombre.setEditorComponent(comboBox);

        //FIXME
        // Close the editor in case of forward navigation between components
        comboBox.getElement().addEventListener("keydown", event -> {
            if ("Sardina".equals(comboBox.getValue())) {
                gridDieta.getEditor().cancel();
            }
        }).setFilter("event.key === 'Tab' && !event.shiftKey");

        gridDieta.addItemDoubleClickListener(event -> {
            gridDieta.getEditor().editItem(event.getItem());
            comboBox.focus();
        });

        // Re-validates the editors every time something changes on the Binder.
        // This is needed for the email column to turn into nothing when the
        // checkbox is deselected, for example.
        binder.addValueChangeListener(event -> {
            gridDieta.getEditor().refresh();
        });

        gridDieta.getEditor().addCloseListener(event -> {
            if (binder.getBean() != null) {
                NotificationBuilder.newBuilder()
                        .conDuracion(3000)
                        .conTexto(binder.getBean().getNombre() + ", " + binder.getBean().getProteinas() + ", "
                                + binder.getBean().getCarbohidratos()
                                + binder.getBean().getGrasas())
                        .conIcono(VaadinIcon.INFO)
                        .conPosicion(Notification.Position.BOTTOM_END)
                        .make();
            }
        });

        return gridDieta;
    }

When selecting the yogurt(example) item, it should obtain the corresponding values ​​to fill the entire row, but I don’t know how to do it.


17912121.gif

I believe you mixed some things up. It seems you use the comboBox not in the way I was guessing. It looks you want to change the complete grid item upon selecting something in the ComboBox. This is usually done outside of the grid with an add button or a more dedicated form to add new items, and a remove button as a separate component column.

what you want should still be possible if you want to do it this way. I may not fully understand how this will effectively be used and operated by its users, but programmatically its possible.

What you need to do is to add a value change listener to the comboBox that removes the current item from the grid, and adds the selected item to the grid. then refresh the grids dataprovider to show the changes.

columnNombre.setEditorComponent(item -> {
	ComboBox<Alimento> comboBox = new ComboBox();
	comboBox.setItemLabelGenerator(Alimento::getNombre);
	comboBox.setItems(alimentoRepository.findAllProtes());
	comboBox.addValueChangeListener(event -> {
		Collection<Alimento> gridItems = ((ListDataProvider) gridDieta.getDataProvider()).getItems();
		// remove current item from list
		gridItems.remove(item);
		// add selected item to list
		gridItems.add(event.getValue());
		// not sure if this is necessary. 
		gridDieta.setItems(gridItems);
		// refresh grid
		gridDieta.getDataProvider().refreshAll();
	});
});

	

Kaspar Scherrer:
I believe you mixed some things up. It seems you use the comboBox not in the way I was guessing. It looks you want to change the complete grid item upon selecting something in the ComboBox. This is usually done outside of the grid with an add button or a more dedicated form to add new items, and a remove button as a separate component column.

what you want should still be possible if you want to do it this way. I may not fully understand how this will effectively be used and operated by its users, but programmatically its possible.

What you need to do is to add a value change listener to the comboBox that removes the current item from the grid, and adds the selected item to the grid. then refresh the grids dataprovider to show the changes.

columnNombre.setEditorComponent(item -> {
	ComboBox<Alimento> comboBox = new ComboBox();
	comboBox.setItemLabelGenerator(Alimento::getNombre);
	comboBox.setItems(alimentoRepository.findAllProtes());
	comboBox.addValueChangeListener(event -> {
		Collection<Alimento> gridItems = ((ListDataProvider) gridDieta.getDataProvider()).getItems();
		// remove current item from list
		gridItems.remove(item);
		// add selected item to list
		gridItems.add(event.getValue());
		// not sure if this is necessary. 
		gridDieta.setItems(gridItems);
		// refresh grid
		gridDieta.getDataProvider().refreshAll();
	});
});

	

Hi, I’m sorry it still doesn’t work, I’m testing it.

Hi Kaspar Scherrer,

This is the grid, thanks for the detailed explanation, but I think it explains badly

This is how I create the grid with its combobox rendering in the first column

public Grid<Alimento> createGridDieta(String fase, final Button buttonDeleteGrid) {
        final Grid<Alimento> gridDieta = new Grid<>();
        gridDieta.setWidthFull();
        gridDieta.setHeightByRows(Boolean.TRUE);
        gridDieta.addThemeVariants(GridVariant.LUMO_COLUMN_BORDERS, GridVariant.LUMO_ROW_STRIPES);

        final Grid.Column<Alimento> columnNombre = gridDieta.addColumn(Alimento::getNombre)
                .setHeader("Alimento").setKey(N).setWidth("200px");

        final Grid.Column<Alimento> cantidadGr = gridDieta.addColumn(Alimento::getCantidadGramosDeAlimento)
                .setHeader("Porción gr")
                .setKey(CANTIDAD);

        final Grid.Column<Alimento> columnProtes = gridDieta.addColumn(Alimento::getProteinas)
                .setHeader(PROTEINAS)
                .setKey(P);

        final Grid.Column<Alimento> columnCarbos = gridDieta.addColumn(Alimento::getCarbohidratos)
                .setHeader(CARBOS)
                .setKey(C);

        final Grid.Column<Alimento> columnGrasa = gridDieta.addColumn(Alimento::getGrasas)
                .setHeader(GRASAS)
                .setKey(G);

        final Grid.Column<Alimento> columnKCals = gridDieta.addColumn(Alimento::getKiloCalorias)
                .setHeader(KILO_CALORIAS)
                .setKey(KCALS);

        gridDieta.getColumns().forEach(e -> e.setComparator(Comparator.comparing(Objects::toString)));
        gridDieta.getColumns().forEach(e -> e.setResizable(Boolean.TRUE));

        final HeaderRow headerRow = gridDieta.prependHeaderRow();

        final Div div = new Div();
        div.getStyle().set(TEXT_ALIGN, CENTER);
        div.setSizeFull();

        final StringBuilder sb = new StringBuilder();

        if (fase.equals(DEFINICION)) {

            sb.append(PROTEINAS_2)
                    .append(porcentajeProteina)
                    .append("% ")
                    .append(CARBOS_2)
                    .append(porcentajeCarbos)
                    .append("% ")
                    .append(GRASAS_2)
                    .append(porcentajeGrasas)
                    .append("% ");

            final List<Alimento> comidaDiariaDefinicion = alimentoRepository.getComidaDiariaDefinicion();
            final ListDataProvider<Alimento> listDataProviderComida = new ListDataProvider<>(comidaDiariaDefinicion);
            gridDieta.setDataProvider(listDataProviderComida);
            gridDieta.getDataProvider().refreshAll();

            /*
             * Footers
             */
            gridDieta.getColumnByKey(N).setFooter("Total");

            gridDieta.getColumnByKey(CANTIDAD).setFooter("-");
            final double protesPorComida = comidaDiariaDefinicion.get(0).getProteinas();
            final double sumaProtes = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getProteinas).sum());
            if (sumaProtes > protesPorComida + 5) {
                final Label labelProtes = new Label(String.valueOf(sumaProtes));
                labelProtes.getStyle().set(COLOR, COLOR_ERROR);
                gridDieta.getColumnByKey(P).setFooter(labelProtes);
            } else {
                gridDieta.getColumnByKey(P).setFooter(String.valueOf(sumaProtes));
            }

            final double sumaCarbos = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getCarbohidratos).sum());
            gridDieta.getColumnByKey(C).setFooter(String.valueOf(sumaCarbos));

            final double sumaGrasas = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getGrasas).sum());
            gridDieta.getColumnByKey(G).setFooter(String.valueOf(sumaGrasas));

            final double sumaCalorias = format(comidaDiariaDefinicion.stream().mapToDouble(Alimento::getKiloCalorias).sum());
            gridDieta.getColumnByKey(KCALS).setFooter(String.valueOf(sumaCalorias));

        } else if (fase.equals(MANTENIMIENTO)) {

            sb.append(PROTEINAS_2)
                    .append(porcentajeProteina)
                    .append("% ")
                    .append(CARBOS_2)
                    .append(porcentajeCarbos)
                    .append("% ")
                    .append(GRASAS_2)
                    .append(porcentajeGrasas)
                    .append("% ");

            final List<Alimento> comidaDiariaMantenimiento = alimentoRepository.getComidaDiariaMantenimiento();
            final ListDataProvider<Alimento> listDataProviderComida = new ListDataProvider<>(comidaDiariaMantenimiento);
            gridDieta.setDataProvider(listDataProviderComida);
            gridDieta.getDataProvider().refreshAll();

            /*
             * Footers
             */
            gridDieta.getColumnByKey(N).setFooter("Total");

            gridDieta.getColumnByKey(CANTIDAD).setFooter("-");
            final double protesPorComida = comidaDiariaMantenimiento.get(0).getProteinas();
            final double sumaProtes = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getProteinas).sum());
            if (sumaProtes > protesPorComida + 5) {
                final Label labelProtes = new Label(String.valueOf(sumaProtes));
                labelProtes.getStyle().set(COLOR, COLOR_ERROR);
                gridDieta.getColumnByKey(P).setFooter(labelProtes);
            } else {
                gridDieta.getColumnByKey(P).setFooter(String.valueOf(sumaProtes));
            }

            final double sumaCarbos = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getCarbohidratos).sum());
            gridDieta.getColumnByKey(C).setFooter(String.valueOf(sumaCarbos));

            final double sumaGrasas = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getGrasas).sum());
            gridDieta.getColumnByKey(G).setFooter(String.valueOf(sumaGrasas));

            final double sumaCalorias = format(comidaDiariaMantenimiento.stream().mapToDouble(Alimento::getKiloCalorias).sum());
            gridDieta.getColumnByKey(KCALS).setFooter(String.valueOf(sumaCalorias));

        } else {

            sb.append(PROTEINAS_2)
                    .append(porcentajeProteina)
                    .append("% ")
                    .append(CARBOS_2)
                    .append(porcentajeCarbos)
                    .append("% ")
                    .append(GRASAS_2)
                    .append(porcentajeGrasas)
                    .append("% ");


            final List<Alimento> comidaDiariaVolumen = alimentoRepository.getComidaDiariaVolumen();
            final ListDataProvider<Alimento> listDataProviderComida = new ListDataProvider<>(comidaDiariaVolumen);
            gridDieta.setDataProvider(listDataProviderComida);
            gridDieta.getDataProvider().refreshAll();

            /*
             * Footers
             */
            gridDieta.getColumnByKey(N).setFooter("Total");

            gridDieta.getColumnByKey(CANTIDAD).setFooter("-");
            final double protesPorComida = comidaDiariaVolumen.get(0).getProteinas();
            final double sumaProtes = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getProteinas).sum());
            if (sumaProtes > protesPorComida + 5) {
                final Label labelProtes = new Label(String.valueOf(sumaProtes));
                labelProtes.getStyle().set(COLOR, COLOR_ERROR);
                gridDieta.getColumnByKey(P).setFooter(labelProtes);
            } else {
                gridDieta.getColumnByKey(P).setFooter(String.valueOf(sumaProtes));
            }

            final double sumaCarbos = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getCarbohidratos).sum());
            gridDieta.getColumnByKey(C).setFooter(String.valueOf(sumaCarbos));

            final double sumaGrasas = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getGrasas).sum());
            gridDieta.getColumnByKey(G).setFooter(String.valueOf(sumaGrasas));

            final double sumaCalorias = format(comidaDiariaVolumen.stream().mapToDouble(Alimento::getKiloCalorias).sum());
            gridDieta.getColumnByKey(KCALS).setFooter(String.valueOf(sumaCalorias));
        }

        final Label label = new Label("Comida numero " + sb.toString());
        final HorizontalLayout row = new HorizontalLayout(buttonDeleteGrid, label);
        row.setWidthFull();
        row.setSpacing(Boolean.TRUE);
        row.setVerticalComponentAlignment(FlexComponent.Alignment.CENTER, label);

        headerRow.join(columnNombre, cantidadGr, columnProtes, columnCarbos, columnGrasa, columnKCals).setComponent(row);

        final Binder<Alimento> binder = new Binder<>(Alimento.class);
        gridDieta.getEditor().setBinder(binder);

        final ComboBox<String> comboBox = new ComboBox<>();
        comboBox.setWidthFull();
        comboBox.setPreventInvalidInput(Boolean.TRUE);

        final List<String> listaAlimentosCombo = new ArrayList<>(alimentoRepository.findAllProtes()
                .stream()
                .map(Alimento::getNombre)
                .collect(Collectors.toList()));

        final ListDataProvider<String> listDataNewAlimentosCombo = new ListDataProvider<>(listaAlimentosCombo);
        comboBox.setDataProvider(listDataNewAlimentosCombo);
        //comboBox.setItemLabelGenerator(Alimento::getNombre);
        //comboBox.setValue(Alimento::getNombre);
        binder.bind(comboBox, N);
        columnNombre.setEditorComponent(comboBox);

        //FIXME
        // Close the editor in case of forward navigation between components
        comboBox.getElement().addEventListener("keydown", event -> {
            if ("Sardina".equals(comboBox.getValue())) {
                gridDieta.getEditor().cancel();
            }
        }).setFilter("event.key === 'Tab' && !event.shiftKey");

        gridDieta.addItemDoubleClickListener(event -> {
            gridDieta.getEditor().editItem(event.getItem());
            comboBox.focus();
        });

        // Re-validates the editors every time something changes on the Binder.
        // This is needed for the email column to turn into nothing when the
        // checkbox is deselected, for example.
        binder.addValueChangeListener(event -> {
            gridDieta.getEditor().refresh();
        });

        gridDieta.getEditor().addCloseListener(event -> {
            if (binder.getBean() != null) {
                NotificationBuilder.newBuilder()
                        .conDuracion(3000)
                        .conTexto(binder.getBean().getNombre() + ", " + binder.getBean().getProteinas() + ", "
                                + binder.getBean().getCarbohidratos()
                                + binder.getBean().getGrasas())
                        .conIcono(VaadinIcon.INFO)
                        .conPosicion(Notification.Position.BOTTOM_END)
                        .make();
            }
        });

        return gridDieta;
    }

When selecting the yogurt(example) item, it should obtain the corresponding values ​​to fill the entire row, but I don’t know how to do it.

Solved with thanks a lot.

final Grid.Column<Alimento> columnNombre = gridDieta.addColumn(new ComponentRenderer<>(item -> {
            if(fase.equals(DEFINICION)) {
                return createComboBoxAlimentos(gridDieta, item, fase);
            } else if (fase.equals(MANTENIMIENTO)) {
                return createComboBoxAlimentos(gridDieta, item, fase);
            } else {
                return createComboBoxAlimentos(gridDieta, item, fase);
            }
        })).setHeader("Alimento");
        columnNombre.setKey(N).setWidth("250px");

17923808.gif