我有一个奇怪的浮动虫,Vaadin网格不时出现。第一件事是网格有行重复,前提是数据不重复。第二个是当我点击dublicated行click事件可能包含相应行或相邻行的值。行似乎相互重叠。
解释
在上图(图№1)中,我们可以看到网格。我们考虑三行:AHTO-18,AHTO-22,AHTO-29(第一列的值)。如果我点击第一个AHTO-18预期的行为是窗口,应该打开AHTO-18的详细信息。但是打开的窗口包含另一行的详细信息(AHELAID而不是AHTO-18)。它可以在下面的图片中看到(图№2)。
然后我向下滚动网格,第二次找到这三行(AHTO-18,AHTO-22,AHTO-29)。如下图所示(图№3)。
如果点击AHTO-18,最后会发现第二个时间窗口,其中包含正确行的详细信息。
代码:
protected DataProvider<EstonianShipDTO, Void> createDataProvider() {
return DataProvider.fromCallbacks(
query -> {
final FindEstonianShipsRequestDTO request = FindEstonianShipsRequestDTO.builder()
.criteria(getSearchFormCriteria())
.build();
final List<SortDTO.OrderDTO> orders = query.getSortOrders().stream()
.map(queryOrder -> SortDTO.OrderDTO.builder()
.property(queryOrder.getSorted())
.direction(queryOrder.getDirection() == SortDirection.DESCENDING ? DirectionEnum.DESC : DirectionEnum.ASC)
.build()
)
.collect(toList());
if (orders.isEmpty()) {
orders.add(SortDTO.OrderDTO.builder()
.property("shipName")
.direction(DirectionEnum.ASC)
.build());
}
request.setSort(SortDTO.builder().orders(orders).build());
return estonianShipService.findAll(request, query.getOffset(), query.getLimit()).getContent().stream();
},
query -> (int) estonianShipService.count(FindEstonianShipsRequestDTO.builder()
.criteria(getSearchFormCriteria())
.build())
);
}
private Grid<EstonianShipDTO> createSearchResultsGrid() {
final Grid<EstonianShipDTO> grid = new Grid<>();
grid.setId("ships-area-grid");
grid.setHeightByRows(DEFAULT_PAGE_SIZE);
grid.setDataProvider(createDataProvider());
grid.setSizeFull();
grid.setSelectionMode(Grid.SelectionMode.SINGLE);
if (ALL_SHIPS.equals(getSearchFormCriteria().getShipState())) {
grid.setStyleGenerator((StyleGenerator<EstonianShipDTO>) item -> {
if (NOT_REGISTERED_SHIPS.equals(item.getShipState())) {
return "yellow_row";
} else if (REDEEMED_SHIPS.equals(item.getShipState())) {
return "grey_row";
} else {
return "white_row";
}
});
}
// Grid Columns
final Grid.Column shipNameColumn = grid.addColumn(EstonianShipDTO::getShipName)
.setId(COLUMN_SHIP_NAME)
.setCaption(messageSource.getMessage("views.ships.results.form.name.caption", null, VaadinSession.getCurrent().getLocale()))
.setExpandRatio(1)
.setDescriptionGenerator(item -> "Laeva ID: " + item.getId() + ofNullable(item.getRegistrationDate()).map(regDate -> "\n" + "Registreerimise kuup\u00e4ev: " + regDate.format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT))).orElse(""));
final Grid.Column regNumberColumn = grid.addColumn(EstonianShipDTO::getRegistrationNumber)
.setId(COLUMN_REG_NUMBER)
.setCaption(messageSource.getMessage("views.ships.results.form.regNumber.caption", null, VaadinSession.getCurrent().getLocale()))
.setExpandRatio(1);
final Grid.Column callSignColumn = grid.addColumn(EstonianShipDTO::getCallSign)
.setId(COLUMN_CALL_SIGN)
.setCaption(messageSource.getMessage("views.ships.results.form.callSign.caption", null, VaadinSession.getCurrent().getLocale()))
.setExpandRatio(1);
final Grid.Column mmsiNumberColumn = grid.addColumn(EstonianShipDTO::getMmsiNumber)
.setId(COLUMN_MMSI_NUMBER)
.setCaption(messageSource.getMessage("views.ships.results.form.mmsiNumber.caption", null, VaadinSession.getCurrent().getLocale()))
.setExpandRatio(1);
final Grid.Column imoNumberColumn = grid.addColumn(EstonianShipDTO::getImoNumber)
.setId(COLUMN_IMO_NUMBER)
.setCaption(messageSource.getMessage("views.ships.results.form.imoNumber.caption", null, VaadinSession.getCurrent().getLocale()))
.setExpandRatio(1);
final Grid.Column regDateColumn = grid.addColumn(EstonianShipDTO::getRegistrationDate, new LocalDateRenderer(Constants.DATE_FORMAT))
.setId(COLUMN_REG_DATE)
.setCaption(messageSource.getMessage("views.ships.results.form.regDate.caption", null, VaadinSession.getCurrent().getLocale()))
.setExpandRatio(1);
final Grid.Column shipTypeColumn = grid.addColumn(EstonianShipDTO::getSailType)
.setId(COLUMN_SHIP_TYPE)
.setCaption(messageSource.getMessage("views.ships.results.form.sailType.caption", null, VaadinSession.getCurrent().getLocale()))
.setExpandRatio(1);
grid.addSelectionListener(event -> OptionalConsumer.of(event.getFirstSelectedItem())
.ifPresent(item -> deleteButton.setEnabled(true))
.ifNotPresent(() -> deleteButton.setEnabled(false))
);
grid.addComponentColumn(item -> {
final MButton editButton = new MButton()
.withCaption(messageSource.getMessage(isEditEnabled ? "views.common.buttons.open.caption" : "views.common.buttons.view.caption", null, VaadinSession.getCurrent().getLocale()))
.withStyleName(ValoTheme.BUTTON_TINY);
editButton.addClickListener(click -> {
// add item ID to the location
final String itemId = getId(item);
final String uriFragment = UI.getCurrent().getPage().getUriFragment();
final String newUriFragment;
if (StringUtils.contains(uriFragment, "/id/")) {
newUriFragment = substringBeforeLast(uriFragment, "/id/") + "/id/" + itemId;
} else {
newUriFragment = uriFragment + "/id/" + itemId;
}
UI.getCurrent().getPage().setUriFragment(newUriFragment, false);
// show popup window
openItemDetailsWindow(getId(item));
});
return new MHorizontalLayout()
.withStyleName("rowButtons")
.withSpacing(true)
.with(editButton);
})
.setStyleGenerator(person -> "buttonsColumn")
.setExpandRatio(-1);
updateGridHeight(grid);
return grid;
}
private void updateGridHeight(Grid<EstonianShipDTO> grid) {
final long count = estonianShipService.count(FindEstonianShipsRequestDTO.builder()
.criteria(getSearchFormCriteria())
.build());
totalResultAmount.setCaption(
messageSource.getMessage("views.ships.search.total.caption", new Long[]{count}, VaadinSession.getCurrent().getLocale())
);
if (count <= DEFAULT_PAGE_SIZE) {
grid.setHeightByRows(count < 1 ? 1 : count);
} else {
grid.setHeightByRows(DEFAULT_PAGE_SIZE);
}
}
EstonianShipDTO
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = "id")
public class EstonianShipDTO {
@Min(0)
private Double boardHeight;
@Length(max = 7)
private String boardNumber;
private ShipBodyMaterialDTO bodyMaterial;
@Min(0)
private Double brt;
@Length(max = 10)
private String callSign;
@Min(0)
private Double carryingCapacity;
private LocalDate certificateValidFrom;
private LocalDate certificateValidUntil;
private Long chartererId;
private AgencyDTO classificationAgency;
@Length(max = 10)
private String classificationCertificateNumber;
@Length(max = 150)
private String classificationNote;
@Length(max = 255)
private String constructionNote;
private ConstructionSiteDTO constructionSite;
@Min(Constants.YEAR_MIN_VALUE)
@Max(Constants.YEAR_MAX_VALUE)
private Integer constructionYear;
private LocalDate dateOnTheKeel;
@Min(0)
private Integer deckCount;
@Min(0)
private Double diveDepth;
@Min(0)
private Double fullLength;
@Min(0)
private Integer grossTonnage;
@Length(max = 15)
private String hinCin;
@Length(max = 70)
private String hydroParameters;
private IceClassDTO iceClass;
private Long id;
@Min(Constants.IMO_MIN_VALUE)
@Max(Constants.IMO_MAX_VALUE)
private Integer imoNumber;
private Boolean isSmallVessel;
@Min(0)
private Double length;
@Min(Constants.MMSI_MIN_VALUE)
@Max(Constants.MMSI_MAX_VALUE)
private Integer mmsiNumber;
@Min(0)
private Integer netCapacity;
@Min(0)
private Integer netTonnage;
@Min(0)
private Double nrt;
private Long ownerId;
@Min(0)
private Integer passengerAmount;
@Min(0)
private Integer peopleAmount;
private PortDTO port;
@Min(0)
private Double power;
private ShipBodyMaterialDTO reconstructionBodyMaterial;
@Length(max = 255)
private String reconstructionNote;
private ConstructionSiteDTO reconstructionSite;
@Min(Constants.YEAR_MIN_VALUE)
@Max(Constants.YEAR_MAX_VALUE)
private Integer reconstructionYear;
private LocalDate redeemedDate;
private RegistryDTO register;
private LocalDate registrationDate;
@NotEmpty
@Length(max = 10)
private String registrationNumber;
private RegistryChapterDTO registryChapter;
private Long registryChapterId;
private SailTypeEnum sailType;
@Length(max = 30)
private String shipName;
private ShipSearchTypeEnum shipState;
private ShipTypeDTO shipType;
private AgencyDTO supervisoryDepartment;
@Min(0)
private Integer tonnageFrom;
@Min(0)
private Integer tonnageTo;
private TradeZoneDTO tradeZone;
private LocalDate underSupervisionFrom;
private LocalDate underSupervisionUntil;
private LocalDateTime updateDate;
private UserDTO updateUser;
@Min(0)
private Double width;
}