我的代码如下所示,它代表了一个具有两个主要功能的视图:
添加新对象的简单窗体
表示数据库中对象的网格
我最近添加了网格编辑功能,然后发生了一些奇怪的事情。单击“编辑”按钮后,表单部分中的一些文本字段将消失。
我注意到这些字段使用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);
}
}
1条答案
按热度按时间hzbexzde1#
这条线就是问题所在。网格编辑器的实现非常好,但是您忘记了一个事实,即任何vaadin组件都不能同时两次添加到任何ui!
决不能重复使用这样的组件。如果您想两次显示“相同”组件,请始终创建一个新示例。这意味着您应该为编辑器和newreceiversection使用单独的输入字段示例。