summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Dahlström <johannesd@vaadin.com>2013-02-14 13:15:34 +0000
committerVaadin Code Review <review@vaadin.com>2013-02-14 13:15:34 +0000
commit655a44cadffb2fc0f4d94327582c6611126be8ad (patch)
tree9726648f7a025454bcd6259ed01f7ff72906784e
parent35571f0f3e11595e0306cfbe158682f0c370ca4c (diff)
parent7a111fc541dcc507032cdad6799b477df6d4833f (diff)
downloadvaadin-framework-655a44cadffb2fc0f4d94327582c6611126be8ad.tar.gz
vaadin-framework-655a44cadffb2fc0f4d94327582c6611126be8ad.zip
Merge "Merge of (#6160) and (#10470) to Vaadin 7." into 7.0
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java216
-rw-r--r--client/src/com/vaadin/client/ui/table/TableConnector.java7
-rw-r--r--server/src/com/vaadin/data/util/IndexedContainer.java3
-rw-r--r--server/src/com/vaadin/server/VaadinPortletService.java7
-rw-r--r--server/src/com/vaadin/server/VaadinServletService.java7
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java24
-rw-r--r--server/src/com/vaadin/ui/Label.java17
-rw-r--r--server/src/com/vaadin/ui/Table.java207
-rw-r--r--server/tests/src/com/vaadin/data/util/TestIndexedContainer.java8
-rw-r--r--uitest/src/com/vaadin/tests/components/table/EmptyRowsWhenScrolling.java275
-rw-r--r--uitest/src/com/vaadin/tests/components/treetable/EmptyingTreeTableTest.html52
-rw-r--r--uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html100
-rw-r--r--uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java46
-rw-r--r--uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.html61
-rw-r--r--uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.java82
15 files changed, 886 insertions, 226 deletions
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index 8553398718..75f5550790 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -539,6 +539,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
public int serverCacheFirst = -1;
public int serverCacheLast = -1;
+ /**
+ * In several cases TreeTable depends on the scrollBody.lastRendered being
+ * 'out of sync' while the update is being done. In those cases the sanity
+ * check must be performed afterwards.
+ */
+ public boolean postponeSanityCheckForLastRendered;
+
/** For internal use only. May be removed or replaced in the future. */
public boolean sizeNeedsInit = true;
@@ -1375,9 +1382,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (uidl == null || reqRows < 1) {
// container is empty, remove possibly existing rows
if (firstRow <= 0) {
- while (scrollBody.getLastRendered() > scrollBody.firstRendered) {
+ postponeSanityCheckForLastRendered = true;
+ while (scrollBody.getLastRendered() > scrollBody
+ .getFirstRendered()) {
scrollBody.unlinkRow(false);
}
+ postponeSanityCheckForLastRendered = false;
scrollBody.unlinkRow(false);
}
return;
@@ -1408,6 +1418,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* cache_rate);
int lastRowToKeep = (int) (firstRowInViewPort + pageLength + pageLength
* cache_rate);
+ // sanity checks:
+ if (firstRowToKeep < 0) {
+ firstRowToKeep = 0;
+ }
+ if (lastRowToKeep > totalRows) {
+ lastRowToKeep = totalRows - 1;
+ }
debug("Client side calculated cache rows to keep: " + firstRowToKeep
+ "-" + lastRowToKeep);
@@ -1999,15 +2016,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (totalRows - 1 > scrollBody.getLastRendered()) {
// fetch cache rows
int firstInNewSet = scrollBody.getLastRendered() + 1;
- rowRequestHandler.setReqFirstRow(firstInNewSet);
int lastInNewSet = (int) (firstRowInViewPort + pageLength + cache_rate
* pageLength);
if (lastInNewSet > totalRows - 1) {
lastInNewSet = totalRows - 1;
}
- rowRequestHandler.setReqRows(lastInNewSet - firstInNewSet
- + 1);
- rowRequestHandler.deferRowFetch(1);
+ rowRequestHandler.triggerRowFetch(firstInNewSet,
+ lastInNewSet - firstInNewSet + 1, 1);
}
}
}
@@ -2093,6 +2108,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private int reqRows = 0;
private boolean isRunning = false;
+ public void triggerRowFetch(int first, int rows) {
+ setReqFirstRow(first);
+ setReqRows(rows);
+ deferRowFetch();
+ }
+
+ public void triggerRowFetch(int first, int rows, int delay) {
+ setReqFirstRow(first);
+ setReqRows(rows);
+ deferRowFetch(delay);
+ }
+
public void deferRowFetch() {
deferRowFetch(250);
}
@@ -2119,17 +2146,28 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
+ public int getReqFirstRow() {
+ return reqFirstRow;
+ }
+
public void setReqFirstRow(int reqFirstRow) {
if (reqFirstRow < 0) {
- reqFirstRow = 0;
+ this.reqFirstRow = 0;
} else if (reqFirstRow >= totalRows) {
- reqFirstRow = totalRows - 1;
+ this.reqFirstRow = totalRows - 1;
+ } else {
+ this.reqFirstRow = reqFirstRow;
}
- this.reqFirstRow = reqFirstRow;
}
public void setReqRows(int reqRows) {
- this.reqRows = reqRows;
+ if (reqRows < 0) {
+ this.reqRows = 0;
+ } else if (reqFirstRow + reqRows > totalRows) {
+ this.reqRows = totalRows - reqFirstRow;
+ } else {
+ this.reqRows = reqRows;
+ }
}
@Override
@@ -2140,7 +2178,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
schedule(250);
} else {
- int firstToBeRendered = scrollBody.firstRendered;
+ int firstRendered = scrollBody.getFirstRendered();
+ int lastRendered = scrollBody.getLastRendered();
+ if (lastRendered > totalRows) {
+ lastRendered = totalRows - 1;
+ }
+ boolean rendered = firstRendered >= 0 && lastRendered >= 0;
+
+ int firstToBeRendered = firstRendered;
+
if (reqFirstRow < firstToBeRendered) {
firstToBeRendered = reqFirstRow;
} else if (firstRowInViewPort - (int) (cache_rate * pageLength) > firstToBeRendered) {
@@ -2149,12 +2195,24 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (firstToBeRendered < 0) {
firstToBeRendered = 0;
}
+ } else if (rendered && firstRendered + 1 < reqFirstRow
+ && lastRendered + 1 < reqFirstRow) {
+ // requested rows must fall within the requested rendering
+ // area
+ firstToBeRendered = reqFirstRow;
+ }
+ if (firstToBeRendered + reqRows < firstRendered) {
+ // must increase the required row count accordingly,
+ // otherwise may leave a gap and the rows beyond will get
+ // removed
+ setReqRows(firstRendered - firstToBeRendered);
}
- int lastToBeRendered = scrollBody.lastRendered;
+ int lastToBeRendered = lastRendered;
+ int lastReqRow = reqFirstRow + reqRows - 1;
- if (reqFirstRow + reqRows - 1 > lastToBeRendered) {
- lastToBeRendered = reqFirstRow + reqRows - 1;
+ if (lastReqRow > lastToBeRendered) {
+ lastToBeRendered = lastReqRow;
} else if (firstRowInViewPort + pageLength + pageLength
* cache_rate < lastToBeRendered) {
lastToBeRendered = (firstRowInViewPort + pageLength + (int) (pageLength * cache_rate));
@@ -2163,14 +2221,36 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
// due Safari 3.1 bug (see #2607), verify reqrows, original
// problem unknown, but this should catch the issue
- if (reqFirstRow + reqRows - 1 > lastToBeRendered) {
- reqRows = lastToBeRendered - reqFirstRow;
+ if (lastReqRow > lastToBeRendered) {
+ setReqRows(lastToBeRendered - reqFirstRow);
}
+ } else if (rendered && lastRendered - 1 > lastReqRow
+ && firstRendered - 1 > lastReqRow) {
+ // requested rows must fall within the requested rendering
+ // area
+ lastToBeRendered = lastReqRow;
+ }
+
+ if (lastToBeRendered > totalRows) {
+ lastToBeRendered = totalRows - 1;
+ }
+ if (reqFirstRow < firstToBeRendered
+ || (reqFirstRow > firstToBeRendered && (reqFirstRow < firstRendered || reqFirstRow > lastRendered + 1))) {
+ setReqFirstRow(firstToBeRendered);
+ }
+ if (lastRendered < lastToBeRendered
+ && lastRendered + reqRows < lastToBeRendered) {
+ // must increase the required row count accordingly,
+ // otherwise may leave a gap and the rows after will get
+ // removed
+ setReqRows(lastToBeRendered - lastRendered);
+ } else if (lastToBeRendered >= firstRendered
+ && reqFirstRow + reqRows < firstRendered) {
+ setReqRows(lastToBeRendered - lastRendered);
}
client.updateVariable(paintableId, "firstToBeRendered",
firstToBeRendered, false);
-
client.updateVariable(paintableId, "lastToBeRendered",
lastToBeRendered, false);
// remember which firstvisible we requested, in case the server
@@ -2191,10 +2271,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
- public int getReqFirstRow() {
- return reqFirstRow;
- }
-
/**
* Sends request to refresh content at this position.
*/
@@ -3991,6 +4067,24 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
setElement(container);
}
+ public void setLastRendered(int lastRendered) {
+ if (totalRows >= 0 && lastRendered > totalRows) {
+ VConsole.log("setLastRendered: " + this.lastRendered + " -> "
+ + lastRendered);
+ this.lastRendered = totalRows - 1;
+ } else {
+ this.lastRendered = lastRendered;
+ }
+ }
+
+ public int getLastRendered() {
+ return lastRendered;
+ }
+
+ public int getFirstRendered() {
+ return firstRendered;
+ }
+
public VScrollTableRow getRowByRowIndex(int indexInTable) {
int internalIndex = indexInTable - firstRendered;
if (internalIndex >= 0 && internalIndex < renderedRows.size()) {
@@ -4045,7 +4139,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
public void renderInitialRows(UIDL rowData, int firstIndex, int rows) {
firstRendered = firstIndex;
- lastRendered = firstIndex + rows - 1;
+ setLastRendered(firstIndex + rows - 1);
final Iterator<?> it = rowData.getChildIterator();
aligns = tHead.getColumnAlignments();
while (it.hasNext()) {
@@ -4065,7 +4159,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
while (it.hasNext()) {
final VScrollTableRow row = prepareRow((UIDL) it.next());
addRow(row);
- lastRendered++;
+ setLastRendered(lastRendered + 1);
}
fixSpacers();
} else if (firstIndex + rows == firstRendered) {
@@ -4081,19 +4175,27 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
} else {
// completely new set of rows
+
+ // there can't be sanity checks for last rendered within this
+ // while loop regardless of what has been set previously, so
+ // change it temporarily to true and then return the original
+ // value
+ boolean temp = postponeSanityCheckForLastRendered;
+ postponeSanityCheckForLastRendered = true;
while (lastRendered + 1 > firstRendered) {
unlinkRow(false);
}
- final VScrollTableRow row = prepareRow((UIDL) it.next());
+ postponeSanityCheckForLastRendered = temp;
+ VScrollTableRow row = prepareRow((UIDL) it.next());
firstRendered = firstIndex;
- lastRendered = firstIndex - 1;
+ setLastRendered(firstIndex - 1);
addRow(row);
- lastRendered++;
+ setLastRendered(lastRendered + 1);
setContainerHeight();
fixSpacers();
while (it.hasNext()) {
addRow(prepareRow((UIDL) it.next()));
- lastRendered++;
+ setLastRendered(lastRendered + 1);
}
fixSpacers();
}
@@ -4129,14 +4231,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* not waste time rendering a set of rows that will never be
* visible...
*/
- rowRequestHandler.setReqFirstRow(reactFirstRow);
- rowRequestHandler.setReqRows(reactLastRow - reactFirstRow + 1);
- rowRequestHandler.deferRowFetch(1);
+ rowRequestHandler.triggerRowFetch(reactFirstRow, reactLastRow
+ - reactFirstRow + 1, 1);
} else if (lastRendered < reactLastRow) {
// get some cache rows below visible area
- rowRequestHandler.setReqFirstRow(lastRendered + 1);
- rowRequestHandler.setReqRows(reactLastRow - lastRendered);
- rowRequestHandler.deferRowFetch(1);
+ rowRequestHandler.triggerRowFetch(lastRendered + 1,
+ reactLastRow - lastRendered, 1);
} else if (firstRendered > reactFirstRow) {
/*
* Branch for fetching cache above visible area.
@@ -4146,9 +4246,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* some rare situations the table may make two cache visits to
* server.
*/
- rowRequestHandler.setReqFirstRow(reactFirstRow);
- rowRequestHandler.setReqRows(firstRendered - reactFirstRow);
- rowRequestHandler.deferRowFetch(1);
+ rowRequestHandler.triggerRowFetch(reactFirstRow, firstRendered
+ - reactFirstRow, 1);
}
}
@@ -4172,7 +4271,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
final VScrollTableRow row = prepareRow((UIDL) it.next());
addRow(row);
insertedRows.add(row);
- lastRendered++;
+ if (postponeSanityCheckForLastRendered) {
+ lastRendered++;
+ } else {
+ setLastRendered(lastRendered + 1);
+ }
}
fixSpacers();
} else if (firstIndex + rows == firstRendered) {
@@ -4194,7 +4297,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
VScrollTableRow row = prepareRow((UIDL) it.next());
insertRowAt(row, ix);
insertedRows.add(row);
- lastRendered++;
+ if (postponeSanityCheckForLastRendered) {
+ lastRendered++;
+ } else {
+ setLastRendered(lastRendered + 1);
+ }
ix++;
}
fixSpacers();
@@ -4307,7 +4414,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
firstRendered++;
} else {
actualIx = renderedRows.size() - 1;
- lastRendered--;
+ if (postponeSanityCheckForLastRendered) {
+ --lastRendered;
+ } else {
+ setLastRendered(lastRendered - 1);
+ }
}
if (actualIx >= 0) {
unlinkRowAtActualIndex(actualIx);
@@ -4323,6 +4434,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
if (firstRendered > firstIndex
&& firstRendered < firstIndex + count) {
+ count = count - (firstRendered - firstIndex);
firstIndex = firstRendered;
}
int lastIndex = firstIndex + count - 1;
@@ -4331,7 +4443,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
for (int ix = lastIndex; ix >= firstIndex; ix--) {
unlinkRowAtActualIndex(actualIndex(ix));
- lastRendered--;
+ if (postponeSanityCheckForLastRendered) {
+ // partialUpdate handles sanity check later
+ lastRendered--;
+ } else {
+ setLastRendered(lastRendered - 1);
+ }
}
fixSpacers();
}
@@ -4352,7 +4469,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
for (int ix = renderedRows.size() - 1; ix >= index; ix--) {
unlinkRowAtActualIndex(actualIndex(ix));
- lastRendered--;
+ setLastRendered(lastRendered - 1);
}
fixSpacers();
}
@@ -4538,14 +4655,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
- public int getLastRendered() {
- return lastRendered;
- }
-
- public int getFirstRendered() {
- return firstRendered;
- }
-
public void moveCol(int oldIndex, int newIndex) {
// loop all rows and move given index to its new place
@@ -5911,8 +6020,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
client.updateVariable(paintableId, "pagelength", pageLength, false);
if (!rendering) {
- int currentlyVisible = scrollBody.lastRendered
- - scrollBody.firstRendered;
+ int currentlyVisible = scrollBody.getLastRendered()
+ - scrollBody.getFirstRendered();
if (currentlyVisible < pageLength
&& currentlyVisible < totalRows) {
// shake scrollpanel to fill empty space
@@ -6397,10 +6506,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
if (postLimit > lastRendered) {
// need some rows to the end of the rendered area
- rowRequestHandler.setReqFirstRow(lastRendered + 1);
- rowRequestHandler.setReqRows((int) ((firstRowInViewPort
- + pageLength + pageLength * cache_rate) - lastRendered));
- rowRequestHandler.deferRowFetch();
+ int reqRows = (int) ((firstRowInViewPort + pageLength + pageLength
+ * cache_rate) - lastRendered);
+ rowRequestHandler.triggerRowFetch(lastRendered + 1, reqRows);
}
}
diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java
index dedcab84fa..c967642059 100644
--- a/client/src/com/vaadin/client/ui/table/TableConnector.java
+++ b/client/src/com/vaadin/client/ui/table/TableConnector.java
@@ -165,12 +165,19 @@ public class TableConnector extends AbstractHasComponentsConnector implements
UIDL partialRowAdditions = uidl.getChildByTagName("prows");
UIDL partialRowUpdates = uidl.getChildByTagName("urows");
if (partialRowUpdates != null || partialRowAdditions != null) {
+ getWidget().postponeSanityCheckForLastRendered = true;
// we may have pending cache row fetch, cancel it. See #2136
getWidget().rowRequestHandler.cancel();
getWidget().updateRowsInBody(partialRowUpdates);
getWidget().addAndRemoveRows(partialRowAdditions);
+
+ // sanity check (in case the value has slipped beyond the total
+ // amount of rows)
+ getWidget().scrollBody.setLastRendered(getWidget().scrollBody
+ .getLastRendered());
} else {
+ getWidget().postponeSanityCheckForLastRendered = false;
UIDL rowData = uidl.getChildByTagName("rows");
if (rowData != null) {
// we may have pending cache row fetch, cancel it. See #2136
diff --git a/server/src/com/vaadin/data/util/IndexedContainer.java b/server/src/com/vaadin/data/util/IndexedContainer.java
index 1705365f60..306f9cf23b 100644
--- a/server/src/com/vaadin/data/util/IndexedContainer.java
+++ b/server/src/com/vaadin/data/util/IndexedContainer.java
@@ -166,7 +166,8 @@ public class IndexedContainer extends
public Property getContainerProperty(Object itemId, Object propertyId) {
// map lookup more efficient than propertyIds if there are many
// properties
- if (!containsId(itemId) || !types.containsKey(propertyId)) {
+ if (!containsId(itemId) || propertyId == null
+ || !types.containsKey(propertyId)) {
return null;
}
diff --git a/server/src/com/vaadin/server/VaadinPortletService.java b/server/src/com/vaadin/server/VaadinPortletService.java
index e59ea7fd5e..8c1e7af0fa 100644
--- a/server/src/com/vaadin/server/VaadinPortletService.java
+++ b/server/src/com/vaadin/server/VaadinPortletService.java
@@ -46,7 +46,12 @@ public class VaadinPortletService extends VaadinService {
}
}
- protected VaadinPortlet getPortlet() {
+ /**
+ * Retrieves a reference to the portlet associated with this service.
+ *
+ * @return A reference to the VaadinPortlet this service is using
+ */
+ public VaadinPortlet getPortlet() {
return portlet;
}
diff --git a/server/src/com/vaadin/server/VaadinServletService.java b/server/src/com/vaadin/server/VaadinServletService.java
index 71f47ea217..7120e3a5c5 100644
--- a/server/src/com/vaadin/server/VaadinServletService.java
+++ b/server/src/com/vaadin/server/VaadinServletService.java
@@ -44,7 +44,12 @@ public class VaadinServletService extends VaadinService {
}
}
- protected VaadinServlet getServlet() {
+ /**
+ * Retrieves a reference to the servlet associated with this service.
+ *
+ * @return A reference to the VaadinServlet this service is using
+ */
+ public VaadinServlet getServlet() {
return servlet;
}
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index 422e0a1796..619d717d97 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -373,30 +373,6 @@ public abstract class AbstractField<T> extends AbstractComponent implements
/* Property interface implementation */
/**
- * Returns the (field) value converted to a String using toString().
- *
- * @see java.lang.Object#toString()
- * @deprecated As of 7.0, use {@link #getValue()} to get the value of the
- * field, {@link #getConvertedValue()} to get the field value
- * converted to the data model type or
- * {@link #getPropertyDataSource()} .getValue() to get the value
- * of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- logger.warning("You are using AbstractField.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This will not be supported starting from Vaadin 7.1 "
- + "(your debugger might call toString() and cause this message to appear).");
- final Object value = getFieldValue();
- if (value == null) {
- return null;
- }
- return value.toString();
- }
-
- /**
* Gets the current value of the field.
*
* <p>
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java
index f49a1403cf..f413ea47f2 100644
--- a/server/src/com/vaadin/ui/Label.java
+++ b/server/src/com/vaadin/ui/Label.java
@@ -203,23 +203,6 @@ public class Label extends AbstractComponent implements Property<String>,
}
/**
- * Returns the value displayed by this label.
- *
- * @see java.lang.Object#toString()
- * @deprecated As of 7.0, use {@link #getValue()} to get the value of the
- * label or {@link #getPropertyDataSource()} .getValue() to get
- * the value of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- logger.warning("You are using Label.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This will not be supported starting from Vaadin 7.1 (your debugger might call toString() and cause this message to appear).");
- return getValue();
- }
-
- /**
* Gets the type of the Property.
*
* @see com.vaadin.data.Property#getType()
diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java
index a9632da038..641c0ff1f6 100644
--- a/server/src/com/vaadin/ui/Table.java
+++ b/server/src/com/vaadin/ui/Table.java
@@ -1645,6 +1645,9 @@ public class Table extends AbstractSelect implements Action.Container,
if (rows > 0) {
pageBufferFirstIndex = firstIndex;
}
+ if (getPageLength() != 0) {
+ removeUnnecessaryRows();
+ }
setRowCacheInvalidated(true);
markAsDirty();
@@ -1711,6 +1714,47 @@ public class Table extends AbstractSelect implements Action.Container,
}
/**
+ * Removes rows that fall outside the required cache.
+ */
+ private void removeUnnecessaryRows() {
+ int minPageBufferIndex = getMinPageBufferIndex();
+ int maxPageBufferIndex = getMaxPageBufferIndex();
+
+ int maxBufferSize = maxPageBufferIndex - minPageBufferIndex + 1;
+
+ /*
+ * Number of rows that were previously cached. This is not necessarily
+ * the same as pageLength if we do not have enough rows in the
+ * container.
+ */
+ int currentlyCachedRowCount = pageBuffer[CELL_ITEMID].length;
+
+ if (currentlyCachedRowCount <= maxBufferSize) {
+ // removal unnecessary
+ return;
+ }
+
+ /* Figure out which rows to get rid of. */
+ int firstCacheRowToRemoveInPageBuffer = -1;
+ if (minPageBufferIndex > pageBufferFirstIndex) {
+ firstCacheRowToRemoveInPageBuffer = pageBufferFirstIndex;
+ } else if (maxPageBufferIndex < pageBufferFirstIndex
+ + currentlyCachedRowCount) {
+ firstCacheRowToRemoveInPageBuffer = maxPageBufferIndex + 1;
+ }
+
+ if (firstCacheRowToRemoveInPageBuffer - pageBufferFirstIndex < currentlyCachedRowCount) {
+ /*
+ * Unregister all components that fall beyond the cache limits after
+ * inserting the new rows.
+ */
+ unregisterComponentsAndPropertiesInRows(
+ firstCacheRowToRemoveInPageBuffer, currentlyCachedRowCount
+ - firstCacheRowToRemoveInPageBuffer);
+ }
+ }
+
+ /**
* Requests that the Table should be repainted as soon as possible.
*
* Note that a {@code Table} does not necessarily repaint its contents when
@@ -1856,41 +1900,24 @@ public class Table extends AbstractSelect implements Action.Container,
"Insert {0} rows at index {1} to existing page buffer requested",
new Object[] { rows, firstIndex });
- // Page buffer must not become larger than pageLength*cacheRate before
- // or after the current page
- int minPageBufferIndex = getCurrentPageFirstItemIndex()
- - (int) (getPageLength() * getCacheRate());
- if (minPageBufferIndex < 0) {
- minPageBufferIndex = 0;
- }
+ int minPageBufferIndex = getMinPageBufferIndex();
+ int maxPageBufferIndex = getMaxPageBufferIndex();
- int maxPageBufferIndex = getCurrentPageFirstItemIndex()
- + (int) (getPageLength() * (1 + getCacheRate()));
- int maxBufferSize = maxPageBufferIndex - minPageBufferIndex;
+ int maxBufferSize = maxPageBufferIndex - minPageBufferIndex + 1;
if (getPageLength() == 0) {
// If pageLength == 0 then all rows should be rendered
- maxBufferSize = pageBuffer[0].length + rows;
+ maxBufferSize = pageBuffer[CELL_ITEMID].length + rows;
}
/*
* Number of rows that were previously cached. This is not necessarily
- * the same as pageLength if we do not have enough rows in the
- * container.
+ * the same as maxBufferSize.
*/
int currentlyCachedRowCount = pageBuffer[CELL_ITEMID].length;
- /*
- * firstIndexInPageBuffer is the offset in pageBuffer where the new rows
- * will be inserted (firstIndex is the index in the whole table).
- *
- * E.g. scrolled down to row 1000: firstIndex==1010,
- * pageBufferFirstIndex==1000 -> cacheIx==10
- */
- int firstIndexInPageBuffer = firstIndex - pageBufferFirstIndex;
-
/* If rows > size available in page buffer */
- if (firstIndexInPageBuffer + rows > maxBufferSize) {
- rows = maxBufferSize - firstIndexInPageBuffer;
+ if (firstIndex + rows - 1 > maxPageBufferIndex) {
+ rows = maxPageBufferIndex - firstIndex + 1;
}
/*
@@ -1899,38 +1926,59 @@ public class Table extends AbstractSelect implements Action.Container,
* the cache.
*/
- /* All rows until the insertion point remain, always. */
- int firstCacheRowToRemoveInPageBuffer = firstIndexInPageBuffer;
+ /*
+ * if there are rows before the new pageBuffer limits they must be
+ * removed
+ */
+ int lastCacheRowToRemove = minPageBufferIndex - 1;
+ int rowsFromBeginning = lastCacheRowToRemove - pageBufferFirstIndex + 1;
+ if (lastCacheRowToRemove >= pageBufferFirstIndex) {
+ unregisterComponentsAndPropertiesInRows(pageBufferFirstIndex,
+ rowsFromBeginning);
+ } else {
+ rowsFromBeginning = 0;
+ }
/*
+ * the rows that fall outside of the new pageBuffer limits after the new
+ * rows are inserted must also be removed
+ */
+ int firstCacheRowToRemove = firstIndex;
+ /*
* IF there is space remaining in the buffer after the rows have been
* inserted, we can keep more rows.
*/
- int numberOfOldRowsAfterInsertedRows = maxBufferSize
- - firstIndexInPageBuffer - rows;
+ int numberOfOldRowsAfterInsertedRows = Math.min(pageBufferFirstIndex
+ + currentlyCachedRowCount + rows, maxPageBufferIndex + 1)
+ - (firstIndex + rows - 1);
if (numberOfOldRowsAfterInsertedRows > 0) {
- firstCacheRowToRemoveInPageBuffer += numberOfOldRowsAfterInsertedRows;
+ firstCacheRowToRemove += numberOfOldRowsAfterInsertedRows;
}
+ int rowsFromAfter = currentlyCachedRowCount
+ - (firstCacheRowToRemove - pageBufferFirstIndex);
- if (firstCacheRowToRemoveInPageBuffer <= currentlyCachedRowCount) {
+ if (rowsFromAfter > 0) {
/*
* Unregister all components that fall beyond the cache limits after
* inserting the new rows.
*/
- unregisterComponentsAndPropertiesInRows(
- firstCacheRowToRemoveInPageBuffer + pageBufferFirstIndex,
- currentlyCachedRowCount - firstCacheRowToRemoveInPageBuffer
- + pageBufferFirstIndex);
+ unregisterComponentsAndPropertiesInRows(firstCacheRowToRemove,
+ rowsFromAfter);
}
// Calculate the new cache size
- int newCachedRowCount = currentlyCachedRowCount;
- if (maxBufferSize == 0 || currentlyCachedRowCount < maxBufferSize) {
- newCachedRowCount = currentlyCachedRowCount + rows;
- if (maxBufferSize > 0 && newCachedRowCount > maxBufferSize) {
- newCachedRowCount = maxBufferSize;
- }
- }
+ int newCachedRowCount = maxBufferSize;
+ if (pageBufferFirstIndex + currentlyCachedRowCount + rows - 1 < maxPageBufferIndex) {
+ // there aren't enough rows to fill the whole potential -> use what
+ // there is
+ newCachedRowCount -= maxPageBufferIndex
+ - (pageBufferFirstIndex + currentlyCachedRowCount + rows - 1);
+ } else if (minPageBufferIndex < pageBufferFirstIndex) {
+ newCachedRowCount -= pageBufferFirstIndex - minPageBufferIndex;
+ }
+ /* calculate the internal location of the new rows within the new cache */
+ int firstIndexInNewPageBuffer = firstIndex - pageBufferFirstIndex
+ - rowsFromBeginning;
/* Paint the new rows into a separate buffer */
Object[][] cells = getVisibleCellsNoCache(firstIndex, rows, false);
@@ -1942,21 +1990,25 @@ public class Table extends AbstractSelect implements Action.Container,
Object[][] newPageBuffer = new Object[pageBuffer.length][newCachedRowCount];
for (int i = 0; i < pageBuffer.length; i++) {
- for (int row = 0; row < firstIndexInPageBuffer; row++) {
+ for (int row = 0; row < firstIndexInNewPageBuffer; row++) {
// Copy the first rows
- newPageBuffer[i][row] = pageBuffer[i][row];
+ newPageBuffer[i][row] = pageBuffer[i][rowsFromBeginning + row];
}
- for (int row = firstIndexInPageBuffer; row < firstIndexInPageBuffer
+ for (int row = firstIndexInNewPageBuffer; row < firstIndexInNewPageBuffer
+ rows; row++) {
// Copy the newly created rows
- newPageBuffer[i][row] = cells[i][row - firstIndexInPageBuffer];
+ newPageBuffer[i][row] = cells[i][row
+ - firstIndexInNewPageBuffer];
}
- for (int row = firstIndexInPageBuffer + rows; row < newCachedRowCount; row++) {
+ for (int row = firstIndexInNewPageBuffer + rows; row < newCachedRowCount; row++) {
// Move the old rows down below the newly inserted rows
- newPageBuffer[i][row] = pageBuffer[i][row - rows];
+ newPageBuffer[i][row] = pageBuffer[i][rowsFromBeginning + row
+ - rows];
}
}
pageBuffer = newPageBuffer;
+ pageBufferFirstIndex = Math.max(pageBufferFirstIndex
+ + rowsFromBeginning, minPageBufferIndex);
if (getLogger().isLoggable(Level.FINEST)) {
getLogger().log(
Level.FINEST,
@@ -1970,6 +2022,40 @@ public class Table extends AbstractSelect implements Action.Container,
return cells;
}
+ private int getMaxPageBufferIndex() {
+ int total = size();
+ if (getPageLength() == 0) {
+ // everything is shown at once, no caching
+ return total - 1;
+ }
+ // Page buffer must not become larger than pageLength*cacheRate after
+ // the current page
+ int maxPageBufferIndex = getCurrentPageFirstItemIndex()
+ + (int) (getPageLength() * (1 + getCacheRate()));
+ if (shouldHideNullSelectionItem()) {
+ --total;
+ }
+ if (maxPageBufferIndex >= total) {
+ maxPageBufferIndex = total - 1;
+ }
+ return maxPageBufferIndex;
+ }
+
+ private int getMinPageBufferIndex() {
+ if (getPageLength() == 0) {
+ // everything is shown at once, no caching
+ return 0;
+ }
+ // Page buffer must not become larger than pageLength*cacheRate before
+ // the current page
+ int minPageBufferIndex = getCurrentPageFirstItemIndex()
+ - (int) (getPageLength() * getCacheRate());
+ if (minPageBufferIndex < 0) {
+ minPageBufferIndex = 0;
+ }
+ return minPageBufferIndex;
+ }
+
/**
* Render rows with index "firstIndex" to "firstIndex+rows-1" to a new
* buffer.
@@ -3076,26 +3162,23 @@ public class Table extends AbstractSelect implements Action.Container,
// Rows
if (isPartialRowUpdate() && painted && !target.isFullRepaint()) {
paintPartialRowUpdate(target, actionSet);
- /*
- * Send the page buffer indexes to ensure that the client side stays
- * in sync. Otherwise we _might_ have the situation where the client
- * side discards too few or too many rows, causing out of sync
- * issues.
- *
- * This could probably be done for full repaints also to simplify
- * the client side.
- */
- int pageBufferLastIndex = pageBufferFirstIndex
- + pageBuffer[CELL_ITEMID].length - 1;
- target.addAttribute(TableConstants.ATTRIBUTE_PAGEBUFFER_FIRST,
- pageBufferFirstIndex);
- target.addAttribute(TableConstants.ATTRIBUTE_PAGEBUFFER_LAST,
- pageBufferLastIndex);
} else if (target.isFullRepaint() || isRowCacheInvalidated()) {
paintRows(target, cells, actionSet);
setRowCacheInvalidated(false);
}
+ /*
+ * Send the page buffer indexes to ensure that the client side stays in
+ * sync. Otherwise we _might_ have the situation where the client side
+ * discards too few or too many rows, causing out of sync issues.
+ */
+ int pageBufferLastIndex = pageBufferFirstIndex
+ + pageBuffer[CELL_ITEMID].length - 1;
+ target.addAttribute(TableConstants.ATTRIBUTE_PAGEBUFFER_FIRST,
+ pageBufferFirstIndex);
+ target.addAttribute(TableConstants.ATTRIBUTE_PAGEBUFFER_LAST,
+ pageBufferLastIndex);
+
paintSorting(target);
resetVariablesAndPageBuffer(target);
diff --git a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
index 971cdb5f62..09e5a26c15 100644
--- a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
+++ b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
@@ -384,4 +384,12 @@ public class TestIndexedContainer extends AbstractInMemoryContainerTest {
assertNull(ic.getContainerProperty(object1, "xyz"));
}
+ // test getting null property id (#10445)
+ public void testNullPropertyId() {
+ IndexedContainer ic = new IndexedContainer();
+ String object1 = new String("Obj1");
+ ic.addItem(object1);
+ assertNull(ic.getContainerProperty(object1, null));
+ }
+
}
diff --git a/uitest/src/com/vaadin/tests/components/table/EmptyRowsWhenScrolling.java b/uitest/src/com/vaadin/tests/components/table/EmptyRowsWhenScrolling.java
new file mode 100644
index 0000000000..c1ae9b4118
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/EmptyRowsWhenScrolling.java
@@ -0,0 +1,275 @@
+package com.vaadin.tests.components.table;
+
+import java.util.Random;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.util.BeanContainer;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.server.ClassResource;
+import com.vaadin.server.Resource;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.ColumnGenerator;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * This test cannot be automated. http://dev.vaadin.com/ticket/6160, base code
+ * by user radosdesign.
+ *
+ * The test fails if even occasionally empty rows appear in the table. A
+ * relatively good way to get them (before the fix) is to wait for the page to
+ * load, move the scrollbar down, press 'R' before the rows have time to be
+ * rendered, and then move the scrollbar up when no rows have been rendered yet.
+ * After this, when you scroll down slowly there may be empty rows. This doesn't
+ * happen always, and you may need to force the threads slower to get it to
+ * happen at all. On a slow 32-bit Windows 7 with Chrome version 22.0.1229.94 m
+ * (no GWT dev mode) this test has managed to reproduce the problem maybe nine
+ * times out of ten.
+ *
+ * @author Anna Koskinen / Vaadin Oy
+ *
+ */
+public class EmptyRowsWhenScrolling extends UI {
+
+ @Override
+ public void init(VaadinRequest request) {
+ getPage().setTitle("Simpletable Application");
+ AppView appView = new AppView(this);
+ setContent(appView);
+ addAction(new Button.ClickShortcut(appView.getBtnRefreshTable(),
+ KeyCode.R));
+ }
+
+ private class AppView extends CustomComponent {
+
+ @AutoGenerated
+ private AbsoluteLayout mainLayout;
+ @AutoGenerated
+ private VerticalLayout verticalLayout_1;
+ @AutoGenerated
+ private Table table;
+ @AutoGenerated
+ private HorizontalLayout horizontalLayout_1;
+ @AutoGenerated
+ private Button btnRefreshTable;
+
+ /*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+ /*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+ /**
+ * The constructor should first build the main layout, set the
+ * composition root and then do any custom initialization.
+ *
+ * The constructor will not be automatically regenerated by the visual
+ * editor.
+ */
+ public AppView(final UI application) {
+ buildMainLayout();
+ setCompositionRoot(mainLayout);
+
+ // Container with sample data
+ BeanContainer<Integer, SimpleBean> container = new BeanContainer<Integer, SimpleBean>(
+ SimpleBean.class);
+ container.setBeanIdProperty("id");
+ for (int i = 1; i <= 50; ++i) {
+ container.addBean(new SimpleBean(i, "image",
+ "Column1 row " + i, "Column2 row " + i, "Column3 row "
+ + i, "Column4 row " + i));
+ }
+ table.setContainerDataSource(container);
+ table.setEditable(true);
+ table.setColumnReorderingAllowed(true);
+ table.setVisibleColumns(new String[] { "image", "id", "col1",
+ "col2", "col3", "col4" });
+ table.addGeneratedColumn("image", new ColumnGenerator() {
+ public Object generateCell(Table source, Object itemId,
+ Object columnId) {
+ int imgNum = new Random().nextInt(5) + 1;
+ try {
+ // Simulate background work
+ System.out
+ .println("Generated column for image /com/example/simpletable/img/px50-"
+ + imgNum + ".jpg");
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ Resource resource = new ClassResource(
+ "/com/example/simpletable/img/px50-" + imgNum
+ + ".jpg");
+ Embedded image = new Embedded("", resource);
+ image.setWidth("50px");
+ image.setHeight("50px");
+ image.addClickListener(new com.vaadin.event.MouseEvents.ClickListener() {
+ public void click(
+ com.vaadin.event.MouseEvents.ClickEvent event) {
+ Notification.show("Image clicked!");
+ }
+ });
+ return image;
+ }
+ });
+
+ // Refresh table button
+ getBtnRefreshTable().addClickListener(new ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ table.refreshRowCache();
+ }
+ });
+ }
+
+ @AutoGenerated
+ private AbsoluteLayout buildMainLayout() {
+ // common part: create layout
+ mainLayout = new AbsoluteLayout();
+ mainLayout.setImmediate(false);
+ mainLayout.setWidth("100%");
+ mainLayout.setHeight("100%");
+
+ // top-level component properties
+ setWidth("100.0%");
+ setHeight("100.0%");
+
+ // verticalLayout_1
+ verticalLayout_1 = buildVerticalLayout_1();
+ mainLayout.addComponent(verticalLayout_1, "top:0.0px;left:0.0px;");
+
+ return mainLayout;
+ }
+
+ @AutoGenerated
+ private VerticalLayout buildVerticalLayout_1() {
+ // common part: create layout
+ verticalLayout_1 = new VerticalLayout();
+ verticalLayout_1.setImmediate(false);
+ verticalLayout_1.setWidth("100.0%");
+ verticalLayout_1.setHeight("100.0%");
+ verticalLayout_1.setMargin(false);
+
+ // horizontalLayout_1
+ horizontalLayout_1 = buildHorizontalLayout_1();
+ verticalLayout_1.addComponent(horizontalLayout_1);
+
+ // table_1
+ table = new Table();
+ table.setImmediate(false);
+ table.setWidth("100.0%");
+ table.setHeight("100.0%");
+ verticalLayout_1.addComponent(table);
+ verticalLayout_1.setExpandRatio(table, 1.0f);
+
+ return verticalLayout_1;
+ }
+
+ @AutoGenerated
+ private HorizontalLayout buildHorizontalLayout_1() {
+ // common part: create layout
+ horizontalLayout_1 = new HorizontalLayout();
+ horizontalLayout_1.setImmediate(false);
+ horizontalLayout_1.setWidth("100.0%");
+ horizontalLayout_1.setHeight("-1px");
+ horizontalLayout_1.setMargin(false);
+
+ // btnRefreshTable
+ setBtnRefreshTable(new Button());
+ getBtnRefreshTable().setCaption("Reload table row cache");
+ getBtnRefreshTable().setImmediate(false);
+ getBtnRefreshTable().setWidth("-1px");
+ getBtnRefreshTable().setHeight("-1px");
+ horizontalLayout_1.addComponent(getBtnRefreshTable());
+ horizontalLayout_1.setComponentAlignment(getBtnRefreshTable(),
+ new Alignment(33));
+
+ return horizontalLayout_1;
+ }
+
+ public Button getBtnRefreshTable() {
+ return btnRefreshTable;
+ }
+
+ public void setBtnRefreshTable(Button btnRefreshTable) {
+ this.btnRefreshTable = btnRefreshTable;
+ }
+
+ }
+
+ protected class SimpleBean {
+ private int id;
+ private String image;
+ private String col1;
+ private String col2;
+ private String col3;
+ private String col4;
+
+ public SimpleBean(int id, String image, String col1, String col2,
+ String col3, String col4) {
+ super();
+ this.id = id;
+ this.image = image;
+ this.col1 = col1;
+ this.col2 = col2;
+ this.col3 = col3;
+ this.col4 = col4;
+ }
+
+ public String getImage() {
+ return image;
+ }
+
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+ public String getCol1() {
+ return col1;
+ }
+
+ public void setCol1(String col1) {
+ this.col1 = col1;
+ }
+
+ public String getCol2() {
+ return col2;
+ }
+
+ public void setCol2(String col2) {
+ this.col2 = col2;
+ }
+
+ public String getCol3() {
+ return col3;
+ }
+
+ public void setCol3(String col3) {
+ this.col3 = col3;
+ }
+
+ public String getCol4() {
+ return col4;
+ }
+
+ public void setCol4(String col4) {
+ this.col4 = col4;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/treetable/EmptyingTreeTableTest.html b/uitest/src/com/vaadin/tests/components/treetable/EmptyingTreeTableTest.html
new file mode 100644
index 0000000000..0c43d41aca
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/treetable/EmptyingTreeTableTest.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/run/com.vaadin.tests.components.treetable.TreeTableTest?restartApplication" />
+<title>EmptyingTreeTableTest</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">EmptyingTreeTableTest</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.treetable.TreeTableTest?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>initial</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_Smenu#item0</td>
+ <td>46,6</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[0]/VMenuBar[0]#item5</td>
+ <td>12,7</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[1]/VMenuBar[0]#item1</td>
+ <td>84,9</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[2]/VMenuBar[0]#item0</td>
+ <td>16,10</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>itemsRemoved</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html b/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html
index d9366385ce..df1656dd23 100644
--- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html
+++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html
@@ -4,12 +4,12 @@
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
-<title>New Test</title>
+<title>TreeTableCacheOnPartialUpdates</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
+<tr><td rowspan="1" colspan="3">TreeTableCacheOnPartialUpdates</td></tr>
</thead><tbody>
<tr>
<td>open</td>
@@ -18,17 +18,17 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
+ <td>cacheTestButton-1 (children)-A</td>
<td>47,5</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VNativeButton[0]</td>
+ <td>cacheTestButton-2-B</td>
<td>46,7</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[6]/VNativeButton[0]</td>
+ <td>cacheTestButton-7 (children)-G</td>
<td>54,12</td>
</tr>
<tr>
@@ -48,7 +48,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>cacheTestButtonToggle-1 (children)-A</td>
<td>10,7</td>
</tr>
<tr>
@@ -58,27 +58,27 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
+ <td>cacheTestButton-1 (children)-A</td>
<td>81,6</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VNativeButton[0]</td>
+ <td>cacheTestButton-1.1-A.A</td>
<td>73,8</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
+ <td>cacheTestButton-1 (children)-A</td>
<td>86,7</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[5]/VNativeButton[0]</td>
+ <td>cacheTestButton-1.5-A.E</td>
<td>72,2</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[6]/VNativeButton[0]</td>
+ <td>cacheTestButton-2-B</td>
<td>73,7</td>
</tr>
<tr>
@@ -108,7 +108,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>cacheTestButtonToggle-1 (children)-A</td>
<td>11,2</td>
</tr>
<tr>
@@ -118,22 +118,22 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
+ <td>cacheTestButton-1 (children)-A</td>
<td>76,5</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[2]/VNativeButton[0]</td>
+ <td>cacheTestButton-3 (children)-C</td>
<td>58,7</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VNativeButton[0]</td>
+ <td>cacheTestButton-2-B</td>
<td>69,10</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
+ <td>cacheTestButton-1 (children)-A</td>
<td>78,7</td>
</tr>
<tr>
@@ -173,22 +173,22 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[41]/VNativeButton[0]</td>
+ <td>cacheTestButton-100-CV</td>
<td>53,-2462</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
+ <td>cacheTestButton-93-CO</td>
<td>91,-2452</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[28]/VNativeButton[0]</td>
+ <td>cacheTestButton-87-CI</td>
<td>84,-2461</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[41]/VNativeButton[0]</td>
+ <td>cacheTestButton-100-CV</td>
<td>102,-2452</td>
</tr>
<tr>
@@ -234,7 +234,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[34]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>cacheTestButtonToggle-40 (children)-AN</td>
<td>9,-995</td>
</tr>
<tr>
@@ -249,7 +249,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
+ <td>cacheTestButton-40 (children)-AN</td>
<td>93,-991</td>
</tr>
<tr>
@@ -259,7 +259,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[35]/VNativeButton[0]</td>
+ <td>cacheTestButton-40.1-AN.A</td>
<td>123,-991</td>
</tr>
<tr>
@@ -269,7 +269,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[40]/VNativeButton[0]</td>
+ <td>cacheTestButton-40.6-AN.F</td>
<td>114,-1000</td>
</tr>
<tr>
@@ -279,7 +279,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
+ <td>cacheTestButton-40 (children)-AN</td>
<td>118,-993</td>
</tr>
<tr>
@@ -289,7 +289,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[34]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>cacheTestButtonToggle-40 (children)-AN</td>
<td>9,-998</td>
</tr>
<tr>
@@ -304,7 +304,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
+ <td>cacheTestButton-40 (children)-AN</td>
<td>42,-990</td>
</tr>
<tr>
@@ -314,7 +314,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[29]/VNativeButton[0]</td>
+ <td>cacheTestButton-35-AI</td>
<td>84,-990</td>
</tr>
<tr>
@@ -324,12 +324,12 @@
</tr>
<tr>
<td>waitForElementPresent</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
+ <td>cacheTestButton-48-AV</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
+ <td>cacheTestButton-48-AV</td>
<td>98,-998</td>
</tr>
<tr>
@@ -339,7 +339,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[35]/VNativeButton[0]</td>
+ <td>cacheTestButton-41-AO</td>
<td>101,-994</td>
</tr>
<tr>
@@ -359,22 +359,22 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[30]/VNativeButton[0]</td>
+ <td>cacheTestButton-86-CH</td>
<td>136,-2447</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
+ <td>cacheTestButton-98-CT</td>
<td>131,-2462</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
+ <td>cacheTestButton-99 (children)-CU</td>
<td>134,-2459</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
+ <td>cacheTestButton-100-CV</td>
<td>144,-2454</td>
</tr>
<tr>
@@ -399,17 +399,17 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[43]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>cacheTestButtonToggle-99 (children)-CU</td>
<td>10,-2461</td>
</tr>
<tr>
<td>waitForElementPresent</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
+ <td>cacheTestButton-99 (children)-CU</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
+ <td>cacheTestButton-99 (children)-CU</td>
<td>65,-2456</td>
</tr>
<tr>
@@ -424,7 +424,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[30]/VNativeButton[0]</td>
+ <td>cacheTestButton-86-CH</td>
<td>109,-2455</td>
</tr>
<tr>
@@ -434,7 +434,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
+ <td>cacheTestButton-99.1-CU.A</td>
<td>82,-2457</td>
</tr>
<tr>
@@ -454,22 +454,22 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
+ <td>cacheTestButton-99 (children)-CU</td>
<td>85,-2792</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
+ <td>cacheTestButton-98-CT</td>
<td>101,-2788</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
+ <td>cacheTestButton-99.1-CU.A</td>
<td>111,-2794</td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[56]/VNativeButton[0]</td>
+ <td>cacheTestButton-99.13-CU.M</td>
<td>113,-2794</td>
</tr>
<tr>
@@ -495,7 +495,7 @@
<!--collapse 99-->
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[43]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>cacheTestButtonToggle-99 (children)-CU</td>
<td>11,-2792</td>
</tr>
<tr>
@@ -505,12 +505,12 @@
</tr>
<tr>
<td>waitForElementPresent</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[40]/VNativeButton[0]</td>
+ <td>cacheTestButton-99 (children)-CU</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[40]/VNativeButton[0]</td>
+ <td>cacheTestButton-99 (children)-CU</td>
<td>71,-2465</td>
</tr>
<tr>
@@ -520,7 +520,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[41]/VNativeButton[0]</td>
+ <td>cacheTestButton-100-CV</td>
<td>81,-2459</td>
</tr>
<tr>
@@ -530,7 +530,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[39]/VNativeButton[0]</td>
+ <td>cacheTestButton-98-CT</td>
<td>80,-2458</td>
</tr>
<tr>
@@ -540,7 +540,7 @@
</tr>
<tr>
<td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[28]/VNativeButton[0]</td>
+ <td>cacheTestButton-87-CI</td>
<td>86,-2462</td>
</tr>
<tr>
diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java
index c2bd3da860..f792a32f8f 100644
--- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java
+++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java
@@ -72,13 +72,11 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
public Component generateCell(final com.vaadin.ui.Table source,
final Object itemId, Object columnId) {
TestBean tb = (TestBean) itemId;
- // if (!tb.getCol1().contains("children")) {
- // return null;
- // }
String identifier = "Item " + itemId + "/" + columnId;
- System.out.println("Generating new Button for " + identifier);
Button btnCol3 = new NativeButton(identifier);
- btnCol3.addListener(new Button.ClickListener() {
+ btnCol3.setId("cacheTestButton-" + tb.getCol1() + "-"
+ + tb.getCol2());
+ btnCol3.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
log.log("Button " + event.getButton().getCaption()
@@ -91,6 +89,25 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
}
+ public class Col4ColumnGenerator implements ColumnGenerator {
+ public Component generateCell(final com.vaadin.ui.Table source,
+ final Object itemId, Object columnId) {
+ TestBean tb = (TestBean) itemId;
+ String identifier = "Expand/Collapse";
+ Button btnCol4 = new NativeButton(identifier);
+ btnCol4.setId("cacheTestButtonToggle-" + tb.getCol1() + "-"
+ + tb.getCol2());
+ btnCol4.addClickListener(new Button.ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ treeTable.setCollapsed(itemId,
+ !treeTable.isCollapsed(itemId));
+ }
+ });
+ return btnCol4;
+ }
+
+ }
+
protected int indexOfId(Table source, Object itemId) {
Container.Ordered c = (Ordered) source.getContainerDataSource();
if (c instanceof Container.Indexed) {
@@ -105,19 +122,17 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
private TreeTable treeTable;
private BeanItemContainer<TestBean> testBeanContainer;
private static String[] columnHeaders = new String[] { "Col1", "Col2",
- "Col3" };
+ "Col3", "Col4" };
private static Object[] visibleColumns = new Object[] { "col1", "col2",
- "col3" };
+ "col3", "col4" };
@Override
public void setup() {
- setTheme("reindeer-tests");
-
// Force row height to be the same in all browsers so scrolling based on
// pixels works as expected
Button b = new Button("Show first");
addComponent(b);
- b.addListener(new ClickListener() {
+ b.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
@@ -132,7 +147,7 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
cacheRateSelect.addItem(new Integer(1));
cacheRateSelect.addItem(new Integer(2));
cacheRateSelect.setValue(2);
- cacheRateSelect.addListener(new ValueChangeListener() {
+ cacheRateSelect.addValueChangeListener(new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
@@ -143,7 +158,6 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
addComponent(cacheRateSelect);
treeTable = new TreeTable();
treeTable.addStyleName("table-equal-rowheight");
- // treeTable.setPageLength(0);
testBeanContainer = new BeanItemContainer<TestBean>(TestBean.class);
Map<String, Integer> hasChildren = new HashMap<String, Integer>();
@@ -156,7 +170,8 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
hasChildren.put("99", 20);
treeTable.setContainerDataSource(createContainer(100, hasChildren));
treeTable.addGeneratedColumn("col3", new Col3ColumnGenerator());
- treeTable.addListener(new ExpandListener() {
+ treeTable.addGeneratedColumn("col4", new Col4ColumnGenerator());
+ treeTable.addExpandListener(new ExpandListener() {
@Override
public void nodeExpand(ExpandEvent event) {
@@ -164,7 +179,7 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
}
});
- treeTable.addListener(new CollapseListener() {
+ treeTable.addCollapseListener(new CollapseListener() {
@Override
public void nodeCollapse(CollapseEvent event) {
@@ -172,12 +187,11 @@ public class TreeTableCacheOnPartialUpdates extends TestBase {
}
});
- treeTable.setColumnHeaders(columnHeaders);
treeTable.setVisibleColumns(visibleColumns);
+ treeTable.setColumnHeaders(columnHeaders);
treeTable.setColumnWidth("col1", 150);
treeTable.setColumnWidth("col2", 50);
treeTable.setHeight("430px");
- // treeTable.setColumnWidth("col3", 150);
addComponent(log);
addComponent(treeTable);
}
diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.html b/uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.html
new file mode 100644
index 0000000000..1aa952d77e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>TreeTableInternalError</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">TreeTableInternalError</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.treetable.TreeTableInternalError?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>scroll</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableInternalError::PID_Streetable/domChild[1]</td>
+ <td>1320</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>cacheTestButtonToggle-57</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>resize</td>
+ <td></td>
+</tr>
+<tr>
+ <td>scroll</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableInternalError::PID_Streetable/domChild[1]</td>
+ <td>1500</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>cacheTestButtonToggle-55</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>cacheTestButtonToggle-55</td>
+ <td>-402,-1632</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>cacheTestButtonToggle-58</td>
+ <td>-402,-1660</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.java
new file mode 100644
index 0000000000..f6d7f11eb7
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.java
@@ -0,0 +1,82 @@
+package com.vaadin.tests.components.treetable;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.Table.ColumnGenerator;
+import com.vaadin.ui.TreeTable;
+import com.vaadin.ui.VerticalLayout;
+
+public class TreeTableInternalError extends TestBase {
+ private TreeTable t;
+
+ @Override
+ protected void setup() {
+ VerticalLayout content = getLayout();
+ content.setSizeFull();
+
+ t = new TreeTable() {
+ {
+ setSizeFull();
+ fillTreeTable(this);
+ }
+ };
+ t.setId("treetable");
+ content.addComponent(t);
+ content.setExpandRatio(t, 1);
+
+ Button button = new Button("Resize") {
+ {
+ addClickListener(new Button.ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ t.setHeight("300px");
+ }
+ });
+ }
+ };
+ button.setId("resize");
+ content.addComponent(button);
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Internal Error when scrolling down enough that more rows are loaded (cache updated), then scrolling down just a few rows and expanding rows";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 10057;
+ }
+
+ private void fillTreeTable(TreeTable t) {
+ t.addContainerProperty("name", String.class, null);
+ t.addGeneratedColumn("toggle", new ButtonColumnGenerator());
+ for (int i = 0; i < 1000; i++) {
+ t.addItem(i);
+ t.getContainerProperty(i, "name").setValue("Item-" + i);
+ t.addItem(i + "c");
+ t.getContainerProperty(i + "c", "name").setValue("Child-" + i);
+ t.setParent(i + "c", i);
+ t.setChildrenAllowed(i + "c", false);
+ }
+ }
+
+ public class ButtonColumnGenerator implements ColumnGenerator {
+ public Component generateCell(final com.vaadin.ui.Table source,
+ final Object itemId, Object columnId) {
+ String identifier = "Expand/Collapse";
+ Button btnCol = new NativeButton(identifier);
+ btnCol.setId("cacheTestButtonToggle-" + itemId);
+ btnCol.addClickListener(new Button.ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ t.setCollapsed(itemId, !t.isCollapsed(itemId));
+ }
+ });
+ return btnCol;
+ }
+
+ }
+
+}