Botão Editar / Atualizar - Vaadin

Bom dia a todos.

Estou começando agora a trabalhar com Vaadin/Java, então me perdoem se estiver falando algo que para muito de vcs é bem simples.

Tenho um sistema de cadastro de produtos, feito todo com Vaadin.

Este sistema é bem simples, ele tem 5 atributos:

  • ID (que é fornecido pelo sistema) - neste momento ainda não estou trabalhando com Banco de Dados

  • Nome do Produto

  • Marca / Fabricante do Produto

  • Modelo do Produto

  • Valor do Produto

Este últimos 4 atributos são fornecidos pelo usuário

Após o usuário salvar o produto, este produto é lançado em uma lista e gerado um uma grade.

Até aqui tudo está funcionando perfeitamente.

Agora o que quero fazer é criar um botão para atualizar, quando necessário este produto, alterar nome, ou valor, alterar marca…qualquer alteração

O comportamento deste botão deve ser da seguinte forma:

  • O botão editar deve ficar desabilitado enquanto o usuário não seleciona o produto na grade.
  • O botão editar só será habilitado após o clique sobre o produto que será alterado.
  • A edição pode ser feita diretamente na grade ou abrindo uma janela com todas as informações atuais do produto, ou mesmo com duplo clique

Vou postar agora como estão as minhas classes deste sistema:

Classe Produto

package br.com.fjsistemas.backend;

public class Produto {

	private Long id;
	private String nome;
	private String marca;
	private String modelo;
	private Double valor;

	public Produto() {

	}

	public Produto(Long id, String nome, String marca, String modelo, Double valor) {

		this.id = id;
		this.nome = nome;
		this.marca = marca;
		this.modelo = modelo;
		this.valor = valor;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getMarca() {
		return marca;
	}

	public void setMarca(String marca) {
		this.marca = marca;
	}

	public String getModelo() {
		return modelo;
	}

	public void setModelo(String modelo) {
		this.modelo = modelo;
	}

	public Double getValor() {
		return valor;
	}

	public void setValor(Double valor) {
		this.valor = valor;
	}

}

Classe GridProduto

package br.com.fjsistemas.grid;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.data.renderer.NumberRenderer;

import br.com.fjsistemas.backend.Produto;

public class GridProduto extends Div {

	private static final long serialVersionUID = 1L;

	private List<Produto> lista;
	private Grid<Produto> grid;

	public GridProduto() {

		lista = new ArrayList<>();
		grid = new Grid<>();

		grid.setItems(lista);
		
		grid.setHeight("835px");

		grid.addColumn(Produto::getId).setHeader("ID:").setAutoWidth(true);
		grid.addColumn(Produto::getNome).setHeader("Produto:").setAutoWidth(true);
		grid.addColumn(Produto::getMarca).setHeader("Marca:").setAutoWidth(true);
		grid.addColumn(Produto::getModelo).setHeader("Modelo:").setAutoWidth(true);
		grid.addColumn(new NumberRenderer<>(Produto::getValor, "R$ %(,.2f",
		        Locale.getDefault(), "R$ 0.00")).setHeader("Valor Unitário:");
		
		grid.addThemeVariants(GridVariant.LUMO_COMPACT, GridVariant.LUMO_COLUMN_BORDERS);

		add(grid);

	}

	public Grid<Produto> getGrid() {
		return grid;
	}

	public List<Produto> getLista() {
		return lista;
	}

}

Classe CadastroProduto

package br.com.fjsistemas.views;

import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.data.converter.StringToDoubleConverter;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteAlias;

import br.com.fjsistemas.backend.Produto;
import br.com.fjsistemas.grid.GridProduto;
import br.com.fjsistemas.main.MainView;

@Route(value = "cadastroprodutos", layout = MainView.class)
@PageTitle("Cadastro de Produtos")
@RouteAlias(value = "Cadastro Produtos", layout = MainView.class)

public class CadastroProduto extends Div {

	private static final long serialVersionUID = 1L;

	@SuppressWarnings("deprecation")
	private Long identity = new Long(0);

	public CadastroProduto() throws ValidationException {

		HorizontalLayout layoutInterno1 = new HorizontalLayout();

		GridProduto grid = new GridProduto();

		add(grid);

		HorizontalLayout layoutInterno2 = new HorizontalLayout();

		Dialog janela = new Dialog();

		janela.setCloseOnEsc(false);
		janela.setCloseOnOutsideClick(false);
		janela.setWidth("700px");
		janela.setHeight("360px");

		Button adicionar = new Button(new Icon(VaadinIcon.PLUS_CIRCLE_O));
		adicionar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		adicionar.addClickListener(event -> janela.open());

		Button remover = new Button(new Icon(VaadinIcon.MINUS_CIRCLE_O));
		remover.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		remover.addClickListener(event -> {
			grid.getLista().remove(grid.getLista().size() - 1);
			grid.getGrid().getDataProvider().refreshAll();
		});

		Button atualizar = new Button(new Icon(VaadinIcon.REFRESH));
		atualizar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		atualizar.setEnabled(false);		

		Binder<Produto> binder = new Binder<>(Produto.class);

		HorizontalLayout layoutJanelaInterno1 = new HorizontalLayout();

		Text titulo = new Text("Novo Produto");

		HorizontalLayout layoutJanelaInterno2 = new HorizontalLayout();

		TextField produto = new TextField("Produto:");
		produto.setMinWidth("50%");

		TextField marca = new TextField("Marca:");
		marca.setWidth("50%");

		HorizontalLayout layoutJanelaInterno3 = new HorizontalLayout();

		TextField modelo = new TextField("Modelo:");
		modelo.setWidth("50%");

		TextField valorUnitario = new TextField("Valor Unitário R$:");
		valorUnitario.setWidth("50%");

		layoutJanelaInterno1.add(titulo);
		layoutJanelaInterno1.setMargin(isVisible());
		layoutJanelaInterno2.add(produto, marca);
		layoutJanelaInterno2.setMargin(isVisible());
		layoutJanelaInterno3.add(modelo, valorUnitario);
		layoutJanelaInterno3.setMargin(isVisible());

		binder.forField(produto).withConverter(String::toUpperCase, String::valueOf).bind(Produto::getNome,
				Produto::setNome);
		binder.forField(marca).withConverter(String::toUpperCase, String::valueOf).bind(Produto::getMarca,
				Produto::setMarca);
		binder.forField(modelo).withConverter(String::toUpperCase, String::valueOf).bind(Produto::getModelo,
				Produto::setModelo);
		binder.forField(valorUnitario).withConverter(new StringToDoubleConverter(0.0, "Valor Inválido"))
				.withNullRepresentation(0.0).bind(Produto::getValor, Produto::setValor);

		HorizontalLayout layoutBotoes = new HorizontalLayout();

		Button salvar = new Button("Salvar");
		salvar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		salvar.getStyle().set("margin-top", "25px");
		salvar.addClickListener(event -> {
			Produto produtoNovo = new Produto();
			produtoNovo.setId(++identity);

			grid.getLista().add(produtoNovo);
			grid.getGrid().getDataProvider().refreshAll();
			binder.writeBeanIfValid(produtoNovo);
			binder.readBean(new Produto(null, " ", " ", " ", null));
			binder.getFields().forEach(f -> f.clear());

		});

		Button fechar = new Button("Fechar");
		fechar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		fechar.getStyle().set("margin-top", "25px");
		fechar.addClickListener(event -> {
			janela.close();
		});

		janela.add(layoutJanelaInterno1);
		janela.add(layoutJanelaInterno2);
		janela.add(layoutJanelaInterno3);
		janela.add(layoutBotoes);

		layoutBotoes.add(salvar, fechar);

		layoutInterno2.add(adicionar, remover, atualizar);

		add(layoutInterno1, layoutInterno2);

	}

}