Sfoglia il codice sorgente

Merge of (#6160) and (#10470) to Vaadin 7.

Cache handling update.

Change-Id: I81ba74d457eb484f6f2c350629534ab284ead7b7
tags/7.0.1
Johannes Dahlström 11 anni fa
parent
commit
7a111fc541

+ 162
- 54
client/src/com/vaadin/client/ui/VScrollTable.java Vedi File

@@ -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);
}
}


+ 7
- 0
client/src/com/vaadin/client/ui/table/TableConnector.java Vedi File

@@ -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

+ 145
- 62
server/src/com/vaadin/ui/Table.java Vedi File

@@ -1645,6 +1645,9 @@ public class Table extends AbstractSelect implements Action.Container,
if (rows > 0) {
pageBufferFirstIndex = firstIndex;
}
if (getPageLength() != 0) {
removeUnnecessaryRows();
}

setRowCacheInvalidated(true);
markAsDirty();
@@ -1710,6 +1713,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.
*
@@ -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);

+ 275
- 0
uitest/src/com/vaadin/tests/components/table/EmptyRowsWhenScrolling.java Vedi File

@@ -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;
}
}

}

+ 52
- 0
uitest/src/com/vaadin/tests/components/treetable/EmptyingTreeTableTest.html Vedi File

@@ -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>

+ 50
- 50
uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html Vedi File

@@ -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>

+ 30
- 16
uitest/src/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java Vedi File

@@ -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);
}

+ 61
- 0
uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.html Vedi File

@@ -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>

+ 82
- 0
uitest/src/com/vaadin/tests/components/treetable/TreeTableInternalError.java Vedi File

@@ -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;
}

}

}

Loading…
Annulla
Salva