java.lang.NullPointerException: null

Bom dia a todos, criei um sistema de cadastro de produtos, o usuário deve fornecer ao sistema Nome do Produto, Marca, Modelo e Valor Unitário.

O sistema através do banco, fornece o ID…usuário salva as informações que são salvas no banco de dados…bem simples pois estou começando.

Estou fazendo o front em Vaadin, uso Spring Boot e MySQL

Segue minhas classes até aqui:

CLASSE APPLICATION

package br.com.fjsistemas;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

CLASSE PRODUTO

package br.com.fjsistemas.backend;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Produto  {
	

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;
	private String nome;
	private String marca;
	private String modelo;
	private Double valor;

}

INTERFACE PRODUTOREPOSITORY

package br.com.fjsistemas.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import br.com.fjsistemas.backend.Produto;

public interface ProdutoRepository extends JpaRepository<Produto, Integer> {

	
}

CLASSE PRODUTOSERVICE

package br.com.fjsistemas.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import br.com.fjsistemas.backend.Produto;
import br.com.fjsistemas.repository.ProdutoRepository;

@Service
public class ProdutoService {

	@Autowired

	private ProdutoRepository produtoRepository;

	public List<Produto> buscar() {
		List<Produto> produtos = produtoRepository.findAll();
		return produtos;

	}

}

CLASSE CADASTROPRODUTO

package br.com.fjsistemas.view;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
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.notification.Notification;
import com.vaadin.flow.component.notification.Notification.Position;
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.converter.StringToDoubleConverter;
import com.vaadin.flow.data.renderer.NumberRenderer;
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.main.MainView;
import br.com.fjsistemas.service.ProdutoService;

@Route(value = "cadastroproduto", layout = MainView.class)
@PageTitle("Cadastro de Produtos")
@RouteAlias(value = "Cadastro Produtos", layout = MainView.class)
@Component
public class CadastroProduto extends Div {

	private static final long serialVersionUID = 1L;

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

	@Autowired
	private ProdutoService produtoService;


	private final Button remover;
	private final Button adicionar;
	private final Button edit;

	private Produto produtoAtual;

	private final Binder<Produto> janelaBinder = new Binder<>(Produto.class);
	private final Binder<Produto> gridBinder = new Binder<>(Produto.class);

	private final TextField gridTxtNome = new TextField();
	private final TextField gridTxtMarca = new TextField();
	private final TextField gridTxtModelo = new TextField();
	private final TextField gridTxtValor = new TextField();

	public CadastroProduto() {
		addGrid();

		Dialog janela = getEditDialog();

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

		remover = new Button(new Icon(VaadinIcon.MINUS_CIRCLE_O));
		remover.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		remover.addClickListener(event -> {
			if (produtoAtual != null) {
				lista.remove(produtoAtual);
				grid.setItems(lista);
				produtoAtual = null;
				enableEditingButtons(false);
			}
		});

		edit = new Button(new Icon(VaadinIcon.EDIT));
		edit.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		edit.addClickListener(e -> {
			grid.getEditor().editItem(produtoAtual);
			gridTxtNome.focus();
			gridTxtMarca.focus();
			gridTxtModelo.focus();
			gridTxtValor.focus();

		});

		enableEditingButtons(false);
		HorizontalLayout layoutInterno2 = new HorizontalLayout();
		layoutInterno2.add(adicionar, remover, edit);
		add(layoutInterno2);
	}

	private Dialog getEditDialog() {
		Dialog janela = new Dialog();

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

		HorizontalLayout layoutJanelaInterno1 = new HorizontalLayout();

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

		HorizontalLayout layoutJanelaInterno2 = new HorizontalLayout();

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

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

		HorizontalLayout layoutJanelaInterno3 = new HorizontalLayout();

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

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

		layoutJanelaInterno1.add(titulo);
		layoutJanelaInterno1.setMargin(isVisible());
		layoutJanelaInterno2.add(nome, marca);
		layoutJanelaInterno2.setMargin(isVisible());
		layoutJanelaInterno3.add(modelo, valor);
		layoutJanelaInterno3.setMargin(isVisible());

		janelaBinder.forField(nome).withConverter(String::toUpperCase, String::valueOf, " ").bind(Produto::getNome,
				Produto::setNome);

		janelaBinder.forField(marca).withConverter(String::toUpperCase, String::valueOf, " ").bind(Produto::getMarca,
				Produto::setMarca);

		janelaBinder.forField(modelo).withConverter(String::toUpperCase, String::valueOf, " ").bind(Produto::getModelo,
				Produto::setModelo);

		janelaBinder.forField(valor).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();

			lista.add(produtoNovo);

			grid.setItems(lista);

			janelaBinder.writeBeanIfValid(produtoNovo);
			janelaBinder.readBean(new Produto(null, " ", " ", " ", null));
			janelaBinder.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);
		return janela;
	}

	private void enableEditingButtons(boolean enable) {
		remover.setEnabled(enable);
		edit.setEnabled(enable);
	}

	
	private void addGrid() {

		lista = produtoService.buscar();
		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).setKey("nome");

		grid.addColumn(Produto::getMarca).setHeader("Marca:").setAutoWidth(true).setKey("marca");

		grid.addColumn(Produto::getModelo).setHeader("Modelo:").setAutoWidth(true).setKey("modelo");

		grid.addColumn(new NumberRenderer<>(Produto::getValor, "R$ %(,.2f", Locale.getDefault(), "R$ 0.00"))
				.setHeader("Valor Unitário:").setAutoWidth(true).setKey("valor");

		grid.addThemeVariants(GridVariant.LUMO_COMPACT, GridVariant.LUMO_COLUMN_BORDERS);

		grid.asSingleSelect().addValueChangeListener(e -> {
			produtoAtual = e.getValue();
			enableEditingButtons(e.getValue() != null);
		});

		grid.getEditor().setBinder(gridBinder);

		gridTxtNome.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridTxtMarca.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridTxtModelo.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridTxtValor.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridBinder.forField(gridTxtNome).withConverter(String::toUpperCase, String::valueOf, " ").bind("nome");
		grid.getColumnByKey("nome").setEditorComponent(gridTxtNome);

		gridBinder.forField(gridTxtMarca).withConverter(String::toUpperCase, String::valueOf, " ").bind("marca");
		grid.getColumnByKey("marca").setEditorComponent(gridTxtMarca);

		gridBinder.forField(gridTxtModelo).withConverter(String::toUpperCase, String::valueOf, " ").bind("modelo");
		grid.getColumnByKey("modelo").setEditorComponent(gridTxtModelo);

		gridBinder.forField(gridTxtValor).withConverter(new StringToDoubleConverter("Número Inválido")).bind("valor");
		grid.getColumnByKey("valor").setEditorComponent(gridTxtValor);

		grid.getEditor().addCloseListener(event -> {
			if (gridBinder.getBean() != null) {
				Notification.show("Texto Alterado!", 1000, Position.TOP_END);

			}
		});
		add(grid);
	}
}

O ERRO:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-02-22 08:56:34.593 ERROR 8176 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cadastroProduto' defined in file [C:\Users\fjd2320\eclipse-workspace\fjsistemas\target\classes\br\com\fjsistemas\view\CadastroProduto.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [br.com.fjsistemas.view.CadastroProduto]: Constructor threw exception; nested exception is java.lang.NullPointerException
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1318) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1216) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:571) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:923) ~[spring-context-5.3.3.jar:5.3.3]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.3.jar:5.3.3]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.4.2.jar:2.4.2]
	at br.com.fjsistemas.Application.main(Application.java:11) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.4.2.jar:2.4.2]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [br.com.fjsistemas.view.CadastroProduto]: Constructor threw exception; nested exception is java.lang.NullPointerException
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:225) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1310) ~[spring-beans-5.3.3.jar:5.3.3]
	... 23 common frames omitted
Caused by: java.lang.NullPointerException: null
	at br.com.fjsistemas.view.CadastroProduto.addGrid(CadastroProduto.java:188) ~[classes/:na]
	at br.com.fjsistemas.view.CadastroProduto.<init>(CadastroProduto.java:63) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[na:na]
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) ~[na:na]
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:212) ~[spring-beans-5.3.3.jar:5.3.3]
	... 25 common frames omitted

SEI QUE O ERRO ESTÁ NA LINHA 188 DA CLASSE CADASTROPRODUTO

LINHA 188: lista = produtoService.buscar();

MAS NÃO SEI O QUE ESTÁ ERRADO, JA TENTEI DE TUDO…SE ALGUEM PUDER ME AJUDAR, FICAREI MUITO AGRADECIDO…OBG A TODOS

Você está tentando usar o produtoService enquanto o Spring Boot ainda está instanciando o seu CadastroProduto, ou seja, ainda está executando o construtor.
Provavelmente vai funcionar se você tirar o @Autowired do atributo e pôr no construtor, dessa forma:

private ProdutoService produtoService;

@Autowired
public CadastroProduto(ProdutoService produtoService) {
    this.produtoService = produtoService;
}
1 curtida

staroski…muito obrigado, realmente era este o problema…agora cai em outro problema, mas vou dar uma pesquisada antes de postar aqui…mas muito obrigado por sua ajuda!!!

java.lang.IllegalStateException: Can't move a node from one state tree to another. If this is intentional, first remove the node from its current state tree by calling removeFromTree
	at com.vaadin.flow.internal.StateNode.doSetTree(StateNode.java:717) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.internal.StateNode.lambda$setTree$3(StateNode.java:370) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.internal.StateNode.visitNodeTree(StateNode.java:670) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.internal.StateNode.setTree(StateNode.java:370) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.internal.StateNode.setParent(StateNode.java:270) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.internal.nodefeature.NodeFeature.attachPotentialChild(NodeFeature.java:78) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.internal.nodefeature.StateNodeNodeList.add(StateNodeNodeList.java:53) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.internal.nodefeature.ElementChildrenList.add(ElementChildrenList.java:42) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.dom.impl.AbstractNodeStateProvider.insertChild(AbstractNodeStateProvider.java:102) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.dom.Node.insertChild(Node.java:294) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.dom.Node.appendChild(Node.java:141) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.component.internal.UIInternals.showRouteTarget(UIInternals.java:733) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.handle(AbstractNavigationStateRenderer.java:255) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.router.Router.handleNavigation(Router.java:249) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.router.Router.navigate(Router.java:220) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.router.Router.navigate(Router.java:186) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.router.Router.initializeUI(Router.java:93) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.server.BootstrapHandler.createAndInitUI(BootstrapHandler.java:1526) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.server.BootstrapHandler.synchronizedHandleRequest(BootstrapHandler.java:475) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1547) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:247) ~[flow-server-2.4.6.jar:2.4.6]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:111) ~[vaadin-spring-12.3.2.jar:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.3.jar:5.3.3]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.3.jar:5.3.3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.3.jar:5.3.3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.3.jar:5.3.3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
	at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]
package br.com.fjsistemas.view;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
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.notification.Notification;
import com.vaadin.flow.component.notification.Notification.Position;
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.converter.StringToDoubleConverter;
import com.vaadin.flow.data.renderer.NumberRenderer;
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.main.MainView;
import br.com.fjsistemas.service.ProdutoService;

@Route(value = "cadastroproduto", layout = MainView.class)
@PageTitle("Cadastro de Produtos")
@RouteAlias(value = "Cadastro Produtos", layout = MainView.class)
@Component
public class CadastroProduto extends Div {

	private static final long serialVersionUID = 1L;

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

	private ProdutoService produtoService;

	private final Button remover;
	private final Button adicionar;
	private final Button edit;

	private Produto produtoAtual;

	private final Binder<Produto> janelaBinder = new Binder<>(Produto.class);
	private final Binder<Produto> gridBinder = new Binder<>(Produto.class);

	private final TextField gridTxtNome = new TextField();
	private final TextField gridTxtMarca = new TextField();
	private final TextField gridTxtModelo = new TextField();
	private final TextField gridTxtValor = new TextField();

	@Autowired
	public CadastroProduto(ProdutoService produtoService) {
		this.produtoService = produtoService;
		addGrid();

		Dialog janela = getEditDialog();

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

		remover = new Button(new Icon(VaadinIcon.MINUS_CIRCLE_O));
		remover.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		remover.addClickListener(event -> {
			if (produtoAtual != null) {
				lista.remove(produtoAtual);
				grid.setItems(lista);
				produtoAtual = null;
				enableEditingButtons(false);
			}
		});

		edit = new Button(new Icon(VaadinIcon.EDIT));
		edit.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		edit.addClickListener(e -> {
			grid.getEditor().editItem(produtoAtual);
			gridTxtNome.focus();
			gridTxtMarca.focus();
			gridTxtModelo.focus();
			gridTxtValor.focus();

		});

		enableEditingButtons(false);
		HorizontalLayout layoutInterno2 = new HorizontalLayout();
		layoutInterno2.add(adicionar, remover, edit);
		add(layoutInterno2);
	}

	private Dialog getEditDialog() {
		Dialog janela = new Dialog();

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

		HorizontalLayout layoutJanelaInterno1 = new HorizontalLayout();

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

		HorizontalLayout layoutJanelaInterno2 = new HorizontalLayout();

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

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

		HorizontalLayout layoutJanelaInterno3 = new HorizontalLayout();

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

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

		layoutJanelaInterno1.add(titulo);
		layoutJanelaInterno1.setMargin(isVisible());
		layoutJanelaInterno2.add(nome, marca);
		layoutJanelaInterno2.setMargin(isVisible());
		layoutJanelaInterno3.add(modelo, valor);
		layoutJanelaInterno3.setMargin(isVisible());

		janelaBinder.forField(nome).withConverter(String::toUpperCase, String::valueOf, " ").bind(Produto::getNome,
				Produto::setNome);

		janelaBinder.forField(marca).withConverter(String::toUpperCase, String::valueOf, " ").bind(Produto::getMarca,
				Produto::setMarca);

		janelaBinder.forField(modelo).withConverter(String::toUpperCase, String::valueOf, " ").bind(Produto::getModelo,
				Produto::setModelo);

		janelaBinder.forField(valor).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();

			lista.add(produtoNovo);

			grid.setItems(lista);

			janelaBinder.writeBeanIfValid(produtoNovo);
			janelaBinder.readBean(new Produto(null, " ", " ", " ", null));
			janelaBinder.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);
		return janela;
	}

	private void enableEditingButtons(boolean enable) {
		remover.setEnabled(enable);
		edit.setEnabled(enable);
	}

	
	private void addGrid() {

		lista = produtoService.buscar();
		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).setKey("nome");

		grid.addColumn(Produto::getMarca).setHeader("Marca:").setAutoWidth(true).setKey("marca");

		grid.addColumn(Produto::getModelo).setHeader("Modelo:").setAutoWidth(true).setKey("modelo");

		grid.addColumn(new NumberRenderer<>(Produto::getValor, "R$ %(,.2f", Locale.getDefault(), "R$ 0.00"))
				.setHeader("Valor Unitário:").setAutoWidth(true).setKey("valor");

		grid.addThemeVariants(GridVariant.LUMO_COMPACT, GridVariant.LUMO_COLUMN_BORDERS);

		grid.asSingleSelect().addValueChangeListener(e -> {
			produtoAtual = e.getValue();
			enableEditingButtons(e.getValue() != null);
		});

		grid.getEditor().setBinder(gridBinder);

		gridTxtNome.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridTxtMarca.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridTxtModelo.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridTxtValor.getElement().addEventListener("keydown", event -> grid.getEditor().cancel())
				.setFilter("event.key === 'Enter'");

		gridBinder.forField(gridTxtNome).withConverter(String::toUpperCase, String::valueOf, " ").bind("nome");
		grid.getColumnByKey("nome").setEditorComponent(gridTxtNome);

		gridBinder.forField(gridTxtMarca).withConverter(String::toUpperCase, String::valueOf, " ").bind("marca");
		grid.getColumnByKey("marca").setEditorComponent(gridTxtMarca);

		gridBinder.forField(gridTxtModelo).withConverter(String::toUpperCase, String::valueOf, " ").bind("modelo");
		grid.getColumnByKey("modelo").setEditorComponent(gridTxtModelo);

		gridBinder.forField(gridTxtValor).withConverter(new StringToDoubleConverter("Número Inválido")).bind("valor");
		grid.getColumnByKey("valor").setEditorComponent(gridTxtValor);

		grid.getEditor().addCloseListener(event -> {
			if (gridBinder.getBean() != null) {
				Notification.show("Texto Alterado!", 1000, Position.TOP_END);

			}
		});
		add(grid);
	}
}