If the filter does not have any text there is no NullPointerException.
I am calling addRow() after resultsGrid.getContainerDataSource().removeAllItems(); is called. I am repopulating the grid from the database to reflect new changes.
If the filter does not have any text there is no NullPointerException.
I am calling addRow() after resultsGrid.getContainerDataSource().removeAllItems(); is called. I am repopulating the grid from the database to reflect new changes.
Hi,
I was unable to reproduce this bug. Can you show a piece of code that triggers the NPE? What container you are using? What kind of Filter?
From a quick go-through of the related methods I did not spot any location which should cause the problem.
//Teemu
Below is a component with full code that will reproduce the error. (null pointer is created at line 5604 in the Grid.class)
The same code is attached as a file too.
package com.widgets;
import com.vaadin.data.util.GeneratedPropertyContainer;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.filter.SimpleStringFilter;
import com.vaadin.server.Responsive;
import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.HeaderCell;
import com.vaadin.ui.Grid.HeaderRow;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
public class GridFilterNull extends VerticalLayout {
private static final long serialVersionUID = -8367212819731798521L;
CssLayout panelWrap = new CssLayout();
Panel resultsPanel = new Panel("Search Results");
VerticalLayout resultsPanelLayout = new VerticalLayout();
Panel personPanel = new Panel("Person");
VerticalLayout personPanelLayout = new VerticalLayout();
HorizontalLayout person_ctrl = new HorizontalLayout();
Label label_name = new Label("<h3><em>Please select row above...</em></h3>", ContentMode.HTML);
Button view_apps = new Button("Applications");
Button view_event_roles = new Button("Event Roles");
Button view_visits = new Button("Visits");
Label html_hr = new Label("<hr />", ContentMode.HTML);
HorizontalLayout updatePerson = new HorizontalLayout();
IndexedContainer container = new IndexedContainer();
GeneratedPropertyContainer gpcontainer = new GeneratedPropertyContainer(container);
Grid resultsGrid = new Grid();
Button refreshPopGrid = new Button("Refresh Pop Grid", e -> populateGrid());
public GridFilterNull() {
//Grid Container
container.addContainerProperty("person_id", String.class, null);
container.addContainerProperty("firstname", String.class, null);
container.addContainerProperty("lastname", String.class, null);
container.addContainerProperty("email", String.class, null);
container.addContainerProperty("role", String.class, null);
gpcontainer = new GeneratedPropertyContainer(container);
resultsGrid.setContainerDataSource(gpcontainer);
resultsGrid.setSelectionMode(Grid.SelectionMode.SINGLE);
//Gets designated column value from row selection
resultsGrid.addItemClickListener(e -> personSelect((String) e.getItem().getItemProperty("person_id").getValue(),
(String) e.getItem().getItemProperty("firstname").getValue() + " " + (String) e.getItem().getItemProperty("lastname").getValue()));
//Set Column header names
resultsGrid.getColumn("person_id").setHeaderCaption("Person ID").setWidth(100);
resultsGrid.getColumn("firstname").setHeaderCaption("First Name");
resultsGrid.getColumn("lastname").setHeaderCaption("Last Name");
resultsGrid.getColumn("email").setHeaderCaption("Email");
resultsGrid.getColumn("role").setHeaderCaption("System Role").setWidth(200);
///////////////////////////////////////////////////////////////////////////////
setSpacing(false);
setMargin(false);
// panel & panelLayout
this.addComponent(panelWrap);
panelWrap.setWidth("100%");
panelWrap.addStyleName("panelWrap");
Responsive.makeResponsive(panelWrap);
panelWrap.addStyleName("panel-padding");
//results panel from search
panelWrap.addComponent(resultsPanel);
resultsPanel.setWidth("100%");
resultsPanel.setContent(resultsPanelLayout);
resultsPanelLayout.setMargin(true);
resultsPanelLayout.setSpacing(true);
resultsPanelLayout.addComponent(resultsGrid);
resultsGrid.setWidth("100%");
resultsGrid.setHeightMode(HeightMode.ROW);
resultsGrid.setHeightByRows(8);
panelWrap.addComponent(personPanel);
personPanel.setWidth("100%");
personPanel.setContent(personPanelLayout);
personPanelLayout.setSpacing(false);
Responsive.makeResponsive(personPanelLayout);
HorizontalLayout buttons = new HorizontalLayout();
buttons.setMargin(false);
buttons.setSpacing(true);
buttons.addComponents(refreshPopGrid);
Responsive.makeResponsive(buttons);
HorizontalLayout person_sel = new HorizontalLayout();
person_sel.setMargin(false);
person_sel.setSpacing(true);
person_sel.setWidth("80%");
person_sel.addComponents(label_name);
person_ctrl.setWidth("100%");
person_ctrl.setMargin(true);
person_ctrl.addComponents(person_sel, buttons);
person_ctrl.setComponentAlignment(person_sel, Alignment.TOP_LEFT);
person_ctrl.setComponentAlignment(buttons, Alignment.TOP_RIGHT);
Responsive.makeResponsive(person_ctrl);
personPanelLayout.addComponent(person_ctrl);
//adds filters to grid
addFilters();
//populate grid
populateGrid();
}
public void personSelect(String person_id, String name) {
label_name.setValue("<h3><em>" + name + "</em></h3>");
}
public void addFilters() {
// Create a header row to hold column filters
HeaderRow filterRow = resultsGrid.appendHeaderRow();
// Set up a filter for all columns
for (Object pid: resultsGrid.getContainerDataSource().getContainerPropertyIds()) {
HeaderCell cell = filterRow.getCell(pid);
TextField filterField = new TextField();
filterField.setInputPrompt("Filter");
filterField.addStyleName(ValoTheme.TEXTFIELD_TINY);
// Update filter When the filter input is changed
filterField.addTextChangeListener(change -> {
// Can't modify filters so need to replace
container.removeContainerFilters(pid);
// (Re)create the filter if necessary
if (! change.getText().isEmpty())
container.addContainerFilter(new SimpleStringFilter(pid,change.getText(), true, false));
});
cell.setComponent(filterField);
}
}
public void populateGrid() {
//clears grid data from grid datasource
resultsGrid.getContainerDataSource().removeAllItems();
//normally there is MySQLfunction that pulls a massive list of people
resultsGrid.addRow("1", "John", "Smith", "js@grid.com", "User");
resultsGrid.addRow("2", "Sam", "Tarley", "st@grid.com", "User");
resultsGrid.addRow("3", "Tina", "Sousa", "ts@grid.com", "Admin");
resultsGrid.addRow("4", "Murphy", "Watson", "mw@grid.com", "Admin");
resultsGrid.addRow("5", "Finn", "Brien", "fb@grid.com", "User");
resultsGrid.addRow("6", "Alison", "Wallace", "aw@grid.com", "User");
resultsGrid.addRow("7", "James", "Reynolds", "jr@grid.com", "Admin");
resultsGrid.addRow("8", "Don", "Williams", "dw@grid.com", "User");
}
}
21067.java (6.49 KB)
Hello,
The issue is not related to Grid specifically but a faulty behaviour in GeneratedPropertyContainer. The underlying container returns null on adding the item and thus leads into a null pointer exception when the item is attempted to access. I posted a ticket for this at https://dev.vaadin.com/ticket/18685 . Thank you for noticing!
//Teemu
Thanks Teemu! I have been trying to find ways to modify the filters for a temporary workaround. No success yet. Will try to work with the container as well.