vaadin:textfield在点击网格编辑按钮后消失

k7fdbhmy  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(429)

我的代码如下所示,它代表了一个具有两个主要功能的视图:
添加新对象的简单窗体
表示数据库中对象的网格
我最近添加了网格编辑功能,然后发生了一些奇怪的事情。单击“编辑”按钮后,表单部分中的一些文本字段将消失。
我注意到这些字段使用binder对象来设置一些验证或转换(那些不可见的)。我怎样才能解决这个问题?

package com.jg.marketing.web;

import com.jg.marketing.DAO.Receiver;
import com.jg.marketing.repository.ReceiverRepo;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.dependency.StyleSheet;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.editor.Editor;
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.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.converter.StringToIntegerConverter;
import com.vaadin.flow.data.validator.IntegerRangeValidator;
import com.vaadin.flow.data.validator.StringLengthValidator;
import com.vaadin.flow.router.Route;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.Collections;
import java.util.WeakHashMap;

@Route("receivers")
@StyleSheet("/css/style.css")
public class ReceiverGui extends VerticalLayout {

    private ReceiverRepo receiverRepo;

    @Autowired
    public ReceiverGui(ReceiverRepo receiverRepo) {
        this.receiverRepo = receiverRepo;

        // Receivers grid
        Grid<Receiver> grid = new Grid<>(Receiver.class);
        grid.setItems(receiverRepo.findAll());
        grid.setColumns("id", "sapNumber", "score", "city", "postCode", "street", "streetNumber", "phoneNumber", "materials");
        grid.getColumnByKey("id").setWidth("30px");
        grid.getColumnByKey("score").setWidth("55px");
        grid.getColumnByKey("city").setAutoWidth(true);
        grid.getColumnByKey("postCode").setWidth("50px");
        grid.getColumnByKey("street").setAutoWidth(true);
        grid.getColumnByKey("streetNumber").setAutoWidth(true);
        grid.getColumnByKey("phoneNumber").setAutoWidth(true);

        // Grid editor
        Binder<Receiver> binder = new Binder<>(Receiver.class);
        Editor<Receiver> editor = grid.getEditor();
        editor.setBinder(binder);
        editor.setBuffered(true);

        // Editor status message
        Div validationStatus = new Div();
        validationStatus.setId("validation");

        // Add new Receiver horizontal layout
        TextField textFieldSapNumber = new TextField("SAP", "wpisz numer");
        binder.forField(textFieldSapNumber)
                .withConverter(new StringToIntegerConverter("Niepoprawny numer"))
                .withValidator(new IntegerRangeValidator("Niepoprawny zakres numeru SAP! 70000000 - 79999999", 70000000, 79999999))
                .withStatusLabel(validationStatus)
                .bind("sapNumber");
        grid.getColumnByKey("sapNumber").setEditorComponent(textFieldSapNumber);

        TextField textFieldScore = new TextField("Realizacja %", "np.: 99.99 ");
        textFieldScore.setWidth("100px");

        TextField textFieldCity = new TextField("Miasto", "wpisz miasto");
        binder.forField(textFieldCity)
                .withValidator(new StringLengthValidator("Wprowadź nazwe miasta o długości od 2 do 25 znaków", 2, 25))
                .withStatusLabel(validationStatus)
                .bind("city");
        grid.getColumnByKey("city").setEditorComponent(textFieldCity);

        TextField textFieldPostCode = new TextField("Kod pocztowy", "np.: 12-345");
        textFieldPostCode.setWidth("120px");
        binder.forField(textFieldPostCode)
                .withValidator(new StringLengthValidator("Wprowadź kod rozdzielony myślnikiem wg. wzoru: 12-345", 6, 6))
                .bind("postCode");
        grid.getColumnByKey("postCode").setEditorComponent(textFieldPostCode);
        // TODO PostCode validation

        TextField textFieldStreet = new TextField("Ulica", "wpisz ulicę");
        TextField textFieldStreetNumber = new TextField("Nr budynku", "np.: 125 B");
        textFieldStreetNumber.setWidth("120px");
        TextField textFieldPhoneNumber = new TextField("Nr kontaktowy", "podaj nr telefonu");
        HorizontalLayout addNewReceiverSection = new HorizontalLayout(textFieldSapNumber, textFieldScore, textFieldCity, textFieldPostCode, textFieldStreet, textFieldStreetNumber, textFieldPhoneNumber);

        // Add edit buttons column
        Collection<Button> editButtons = Collections
                .newSetFromMap(new WeakHashMap<>());

        Grid.Column<Receiver> editorColumn = grid.addComponentColumn(receiver -> {
            Button edit = new Button("Edytuj");
            edit.addClassName("edit");
            edit.addClickListener(e -> {
                editor.editItem(receiver);
                textFieldSapNumber.focus();
            });
            edit.setEnabled(!editor.isOpen());
            editButtons.add(edit);
            return edit;
        });

        editor.addOpenListener(e -> editButtons.stream()
                .forEach(button -> button.setEnabled(!editor.isOpen()))
        );
        editor.addCloseListener(e -> editButtons.stream()
                .forEach(button -> button.setEnabled(!editor.isOpen()))
        );

        Button save = new Button("Save", e -> editor.save());
        save.addClassName("save");

        Button cancel = new Button("Cancel", e -> editor.cancel());
        cancel.addClassName("cancel");

        // Add a keypress listener that listens for an escape key up event.
        // Note! some browsers return key as Escape and some as Esc
        grid.getElement().addEventListener("keyup", event -> editor.cancel())
                .setFilter("event.key === 'Escape' || event.key === 'Esc'");

        Div buttons = new Div(save, cancel);
        editorColumn.setEditorComponent(buttons);

        editor.addSaveListener(
                event -> validationStatus.setText("Poprawnie zaktualizowano wpis"));
        add(validationStatus, grid);

        // Submit new receiver button
        Button buttonAddReceiver = new Button("Dodaj", new Icon(VaadinIcon.PLUS));
        buttonAddReceiver.addClickListener(buttonClickEvent -> {
            final Receiver receiverToAdd
                    = new Receiver(Integer.parseInt(textFieldSapNumber.getValue()),
                    Double.parseDouble(textFieldScore.getValue()),
                    textFieldCity.getValue(),
                    textFieldPostCode.getValue(),
                    textFieldStreet.getValue(),
                    textFieldStreetNumber.getValue(),
                    textFieldPhoneNumber.getValue()
            );
            receiverRepo.save(receiverToAdd);

            // Refresh grid data
            grid.setItems(receiverRepo.findAll());

            // Open notification
            Notification notification = new Notification("Dodano nowego odbiorcę!", 3000);
            notification.open();
        });

        add(addNewReceiverSection);
        add(buttonAddReceiver);
        add(grid);
    }

}
hzbexzde

hzbexzde1#

HorizontalLayout addNewReceiverSection = new HorizontalLayout(
    textFieldSapNumber, textFieldScore, textFieldCity, textFieldPostCode, 
    textFieldStreet, textFieldStreetNumber, textFieldPhoneNumber
);

这条线就是问题所在。网格编辑器的实现非常好,但是您忘记了一个事实,即任何vaadin组件都不能同时两次添加到任何ui!
决不能重复使用这样的组件。如果您想两次显示“相同”组件,请始终创建一个新示例。这意味着您应该为编辑器和newreceiversection使用单独的输入字段示例。

相关问题