From b5fb9c61ee7710558bdedda2ccf4c5e2f9481bff Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Mon, 18 Jan 2016 13:52:14 +0200 Subject: [PATCH] Fix NPE on column width detection in TreeTable and RowGenerator (#19437) Change-Id: I7ed03d34124dda839bddc2507274a63b1e22f05f --- .../com/vaadin/client/ui/VScrollTable.java | 10 ++- .../treetable/TreeTableRowGenerator.java | 65 +++++++++++++++++++ .../treetable/TreeTableRowGeneratorTest.java | 31 +++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGenerator.java create mode 100644 uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGeneratorTest.java diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 74966d6b26..5e5ae8a259 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -5307,9 +5307,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets, for (Widget row : renderedRows) { if (!(row instanceof VScrollTableGeneratedRow)) { TableRowElement tr = row.getElement().cast(); - Element wrapperdiv = tr.getCells().getItem(columnIndex) - .getFirstChildElement().cast(); - return wrapperdiv.getOffsetWidth(); + // Spanned rows might cause an NPE. + if (columnIndex < tr.getChildCount()) { + Element wrapperdiv = tr.getCells() + .getItem(columnIndex) + .getFirstChildElement().cast(); + return wrapperdiv.getOffsetWidth(); + } } } return 0; diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGenerator.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGenerator.java new file mode 100644 index 0000000000..e8da4abbec --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGenerator.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.treetable; + +import com.vaadin.data.Item; +import com.vaadin.data.util.HierarchicalContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Table; +import com.vaadin.ui.TreeTable; + +public class TreeTableRowGenerator extends AbstractTestUI { + public static final String COLUMN_A = "first"; + public static final String COLUMN_B = "second"; + + @Override + protected void setup(VaadinRequest request) { + TreeTable treeTable = new TreeTable(); + + final HierarchicalContainer hierarchicalContainer = new HierarchicalContainer(); + hierarchicalContainer.addContainerProperty(COLUMN_A, String.class, ""); + hierarchicalContainer.addContainerProperty(COLUMN_B, String.class, ""); + + Item it = hierarchicalContainer.addItem(0); + it.getItemProperty(COLUMN_A).setValue("row 1 column a"); + it.getItemProperty(COLUMN_B).setValue("row 1 column b"); + hierarchicalContainer.setChildrenAllowed(0, true); + + Item it2 = hierarchicalContainer.addItem(1); + it2.getItemProperty(COLUMN_A).setValue("row 2 column a"); + it2.getItemProperty(COLUMN_B).setValue("row 2 column b"); + hierarchicalContainer.setChildrenAllowed(1, false); + + hierarchicalContainer.setParent(1, 0); + + treeTable.setRowGenerator(new Table.RowGenerator() { + @Override + public Table.GeneratedRow generateRow(Table table, Object itemId) { + if (table instanceof TreeTable + && ((TreeTable) table).areChildrenAllowed(itemId)) { + return new Table.GeneratedRow("Spanned Row"); + } else { + return null; + } + } + }); + + treeTable.setContainerDataSource(hierarchicalContainer); + treeTable.setSizeFull(); + addComponent(treeTable); + } +} diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGeneratorTest.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGeneratorTest.java new file mode 100644 index 0000000000..84a2f7bbb3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableRowGeneratorTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.treetable; + +import org.junit.Test; + +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class TreeTableRowGeneratorTest extends SingleBrowserTest { + + @Test + public void testNoExceptionOnRender() { + setDebug(true); + openTestURL(); + + assertNoErrorNotifications(); + } +} -- 2.39.5