Vaadin 指南 - 如何正确添加它们

Vaadin guides - how to add them correctly

大家下午好

我正在创建一个到目前为止看起来像这样的销售系统。

它显示我的网格没有任何销售,因为我仍在实施系统,我们还可以看到 3 个按钮(新建、更改、删​​除)的存在。到目前为止一切顺利。

当我单击“新建”按钮时,window 打开

如附件 2 所示打开 window,我们有 3 个选项卡(销售、交付和财务)。

每个选项卡必须有自己的表单,每个表单必须有自己的组件(ComboBox、TextField、DatePicker ...等)

到这里我的问题数不胜数,都是我编程经验不足造成的,毕竟才几个月才开始学

我的第一个问题:

使用当前代码,如果我单击三个选项卡中的任何一个,将显示具有相同组件的相同表单(见附件 3 和附件 4)。

如何确保每个指南都有其形式并且每个形式都有其组成部分?

查看我的代码:

package br.com.fjsistemas.cadastros.view;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.textfieldformatter.CustomStringBlockFormatter;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
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.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.PropertyId;
import com.vaadin.flow.data.renderer.NumberRenderer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;

import br.com.fjsistemas.backend.Venda;
import br.com.fjsistemas.main.MainView;
import br.com.fjsistemas.service.VendaService;

@Route(value = "venda-view", layout = MainView.class)
@PageTitle("Lançamento de Vendas")
public class VendaView extends VerticalLayout {

    private static final long serialVersionUID = 1L;

    private HorizontalLayout hltVenda = new HorizontalLayout();
    Grid<Venda> grdVenda = new Grid<>(Venda.class, false);

    private HorizontalLayout hltBarraBotoes = new HorizontalLayout();
    Button btnNovo = new Button("Novo");
    Button btnAlterar = new Button("Alterar");
    Button btnExcluir = new Button("Excluir");

    private Dialog dlgJanela = new Dialog();

    private FormLayout fltCamposVenda = new FormLayout();

    HorizontalLayout layoutGuiaVenda = new HorizontalLayout();
    HorizontalLayout layoutGuiaVenda2 = new HorizontalLayout();
    HorizontalLayout layoutGuiaVenda3 = new HorizontalLayout();
    HorizontalLayout layoutGuiaVenda4 = new HorizontalLayout();
    VerticalLayout layoutSeparar = new VerticalLayout();
    VerticalLayout layoutSeparar2 = new VerticalLayout();
    VerticalLayout layoutSeparar3 = new VerticalLayout();

    @PropertyId("data")
    private DatePicker txtDataVenda = new DatePicker("Data Venda");

    @PropertyId("nomeCliente")
    private TextField txtNomeCliente = new TextField("Nome Cliente");

    @PropertyId("telefone")
    private TextField txtTelefone = new TextField("Telefone");

    @PropertyId("celular")
    private TextField txtCelular = new TextField("Celular");

    @PropertyId("produtos")
    private ComboBox<String> txtProdutos = new ComboBox<>("Produtos");

    @PropertyId("quantidade")
    private NumberField txtQuantidade = new NumberField("Quantidade");

    @PropertyId("unitario")
    private TextField txtValorUnitario = new TextField("Valor Unitário");

    @PropertyId("valorTotalVenda")
    private NumberField txtValorTotalItem = new NumberField("Valor Total Item");

    private HorizontalLayout htlDlgBarraBotoes = new HorizontalLayout();
    private Button btnSalvar = new Button("Salvar");
    private Button btnFechar = new Button("Fechar");
    private Button btnAdicionarItem = new Button("Adicionar Item");

    @Autowired
    VendaService vendaService;

    private List<Venda> listaVendas;
    private Venda venda;

    Binder<Venda> binderVenda = new Binder<>(Venda.class);

    public VendaView() {

    }

    @PostConstruct
    public void init() {
        configuraTela();

    }

    private void configuraTela() {

        setMargin(false);
        setPadding(false);

        configuraHltVenda();
        configuraFltBarraBotoes();
        configuraDlgJanela();
        populaGrdVenda();
        configuraBinder();

        add(hltVenda, hltBarraBotoes);
    }

    private void configuraFltBarraBotoes() {

        btnNovo.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        btnNovo.addClickListener(e -> {
            novoClick();
        });

        btnAlterar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        btnAlterar.addClickListener(e -> {
            alterarClick();
        });

        btnExcluir.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        btnExcluir.addClickListener(e -> {
            excluirClick();
        });

        hltBarraBotoes.add(btnNovo, btnAlterar, btnExcluir);
    }

    private void excluirClick() {

        if (venda != null) {
            listaVendas.remove(venda);
            vendaService.delete(venda);
            atualizaGrdVenda();
        }
    }

    private void configuraHltVenda() {
        hltVenda.setWidthFull();
        configuraGrdVenda();
        hltVenda.add(grdVenda);
    }

    private void configuraGrdVenda() {
        grdVenda.setHeight("820px");
        grdVenda.setWidthFull();

        grdVenda.addColumn(Venda::getId).setHeader("ID:").setAutoWidth(true);

        grdVenda.addColumn(Venda::getDataVenda).setHeader("Data Venda:").setAutoWidth(true).setKey("dataVenda");

        grdVenda.addColumn(Venda::getCliente).setHeader("Cliente:").setAutoWidth(true).setKey("cliente");

        grdVenda.addColumn(new NumberRenderer<>(Venda::getValorTotalVenda, "R$ %(,.2f", Locale.getDefault(), "R$ 0.00"))
                .setHeader("Valor Total:").setAutoWidth(true).setKey("valorTotalVenda");

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

        grdVenda.getColumns().forEach(col -> col.setAutoWidth(true).setSortable(true).setResizable(true));

        grdVenda.addItemClickListener(e -> {
            venda = e.getItem();
        });

    }

    private void configuraDlgJanela() {

        dlgJanela.setHeight("800px");
        dlgJanela.setWidth("860px");

        Tab vender = new Tab("Vendas");
        Div venderDiv = new Div();
        Tab entregar = new Tab("Entregas");
        Div entregarDiv = new Div();
        entregarDiv.setVisible(false);
        Tab financeiro = new Tab("Financeiro");
        Div financeiroDiv = new Div();
        financeiroDiv.setVisible(false);

        LocalDate now = LocalDate.now();
        txtDataVenda.setValue(now);
        
        txtNomeCliente.setWidth("380px");

        new CustomStringBlockFormatter.Builder().blocks(0, 2, 4, 4).delimiters("(", ")", "-").numeric().build()
                .extend(txtTelefone);

        new CustomStringBlockFormatter.Builder().blocks(0, 2, 5, 4).delimiters("(", ")", "-").numeric().build()
                .extend(txtCelular);

        txtQuantidade.setHasControls(true);

        Label valorTotalCompra = new Label("VALOR TOTAL DA COMPRA R$:");
        valorTotalCompra.getStyle().set("margin-top", "112px");

        TextField campoValorTotal = new TextField("Valor Total da Compra");
        campoValorTotal.getStyle().set("margin-top", "100px");

        layoutGuiaVenda.add(txtDataVenda);
        layoutGuiaVenda2.add(txtNomeCliente, txtTelefone, txtCelular);
        layoutGuiaVenda3.add(txtProdutos, txtQuantidade, txtValorUnitario, txtValorTotalItem);
        layoutGuiaVenda4.add(valorTotalCompra, campoValorTotal);
        fltCamposVenda.add(layoutGuiaVenda, layoutSeparar, layoutGuiaVenda2, layoutSeparar2, layoutGuiaVenda3,
                layoutSeparar3, layoutGuiaVenda4);
        
        vender.add(fltCamposVenda);

        Map<Tab, Component> tabsToPages = new HashMap<>();
        tabsToPages.put(vender, venderDiv);
        tabsToPages.put(entregar, entregarDiv);
        tabsToPages.put(financeiro, financeiroDiv);
        Tabs tabs = new Tabs(vender, entregar, financeiro);
        Div pages = new Div(venderDiv, entregarDiv, financeiroDiv);

        tabs.addSelectedChangeListener(event -> {
            tabsToPages.values().forEach(page -> page.setVisible(false));
            Component selectedPage = tabsToPages.get(tabs.getSelectedTab());
            selectedPage.setVisible(true);
        });

        dlgJanela.add(tabs, pages);

        btnSalvar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        btnSalvar.getStyle().set("margin-top", "180px");
        btnSalvar.getStyle().set("margin-left", "0px");
        btnSalvar.addClickListener(e -> {
            salvarClick();
        });

        btnFechar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        btnFechar.getStyle().set("margin-top", "180px");
        btnFechar.addClickListener(e -> {
            dlgJanela.close();
        });

        btnAdicionarItem.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        btnAdicionarItem.getStyle().set("margin-top", "180px");
        btnAdicionarItem.addClickListener(e -> {

        });

        htlDlgBarraBotoes.add(btnSalvar, btnFechar, btnAdicionarItem);

        dlgJanela.add(fltCamposVenda, htlDlgBarraBotoes);
    }

    private void salvarClick() {

        venda = binderVenda.getBean();

        boolean adicionarLista = venda.getId() == null ? true : false;

        vendaService.create(venda);

        if (adicionarLista) {
            listaVendas.add(venda);
        }
        atualizaGrdVenda();
        novaVenda();
        txtNomeCliente.focus();

        binderVenda.setBean(venda);

        if (adicionarLista) {
            dlgJanela.close();
        }
    }

    private void populaGrdVenda() {

        listaVendas = vendaService.read();
        atualizaGrdVenda();
    }

    private void atualizaGrdVenda() {
        grdVenda.setItems(listaVendas);
    }

    private void configuraBinder() {

        binderVenda.bindInstanceFields(this);

    }

    private void novoClick() {

        novaVenda();
        binderVenda.setBean(venda);

        dlgJanela.open();
        txtNomeCliente.focus();
    }

    private void alterarClick() {

        if (venda != null) {
            binderVenda.setBean(venda);

            dlgJanela.open();

        }
    }

    private void novaVenda() {
        venda = new Venda();
        venda.setCliente(" ");
        dlgJanela.close();

    }
}

欢迎来到编程世界。你当然还有很多东西要学,但你正在跳入新事物并接受挑战是非常好的!

正在查看您的标签代码。选项卡和内容似乎没问题。单击选项卡时,您会隐藏所有内容,然后找到与单击的选项卡匹配的内容,然后打开该内容的可见性。

如果我没看错,vender 是顶部的选项卡按钮,您将(以某种方式)所有表单内容放入此选项卡 header 和 vender.add(fltCamposVenda); .我认为那一行应该是`venderDiv.add(fltCamposVenda);.

现在选项卡似乎在 venderDiventregarDivfinanceiroDiv 之间切换内容,但它们都是三个空的 div,因此当您切换它们的可见性时屏幕上没有任何变化!

我可以给你两条建议吗?

1:考虑用英文编码。即使它不是您的母语,获得帮助也会变得更加容易,并且您不会混用两种语言,例如 Venda 和 VerticalLayout。

2:考虑将您的视图拆分为更小的 classes。现在您有一个视图、一个网格、一个对话框、一个标签表、多个表单,可能还有更多,所有这些都混合在同一个 class 中。其中的任何部分都可以访问所有其他部分并导致意外错误,并且理解代码变得更加困难。例如。您可以在 JanelaDialog.java 中执行 public class JanelaDialog extends Dialog {,然后用 JanelaDialog dlgJanela = new JanelaDialog() 初始化它,而不是 private Dialog dlgJanela = new Dialog();。这样一来,网格视图在一个 class 中,对话框组件在另一个中,代码变得更易于管理。

祝你好运:)