diff options
author | Anna Koskinen <Ansku@users.noreply.github.com> | 2020-04-24 12:01:32 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-24 12:01:32 +0300 |
commit | 616f24764b2659380c4f4c6ce1057c0056513199 (patch) | |
tree | 30605364c45672aa662845e0f919d0b26592acd6 /client | |
parent | 5947875fd3ad16e815bb551604bc26bbe44872de (diff) | |
download | vaadin-framework-616f24764b2659380c4f4c6ce1057c0056513199.tar.gz vaadin-framework-616f24764b2659380c4f4c6ce1057c0056513199.zip |
Ensure recalculateColumnWidths works with refreshAll. (#11934) (#11959)
Column widths shouldn't be calculated between the clearing of cache and
re-populating it, but be delayed until the cache has some content again.
The calculations should only be triggered immediately if no rows are
expected.
Fixes #9996
Diffstat (limited to 'client')
-rw-r--r-- | client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java | 51 | ||||
-rwxr-xr-x | client/src/main/java/com/vaadin/client/widgets/Grid.java | 42 |
2 files changed, 77 insertions, 16 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java index 93d2c9189a..ef240e8ba4 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java @@ -43,10 +43,13 @@ import com.vaadin.client.annotations.OnStateChange; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.connectors.AbstractListingConnector; import com.vaadin.client.connectors.grid.ColumnConnector.CustomColumn; +import com.vaadin.client.data.AbstractRemoteDataSource; import com.vaadin.client.data.DataSource; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.client.widget.escalator.RowContainer; import com.vaadin.client.widget.grid.CellReference; +import com.vaadin.client.widget.grid.DataAvailableEvent; +import com.vaadin.client.widget.grid.DataAvailableHandler; import com.vaadin.client.widget.grid.EventCellReference; import com.vaadin.client.widget.grid.events.BodyClickHandler; import com.vaadin.client.widget.grid.events.BodyDoubleClickHandler; @@ -100,6 +103,8 @@ public class GridConnector extends AbstractListingConnector */ private class GridConnectorClientRpc implements GridClientRpc { private final Grid<JsonObject> grid; + private HandlerRegistration dataAvailableHandlerRegistration = null; + private boolean recalculateScheduled = false; private GridConnectorClientRpc(Grid<JsonObject> grid) { this.grid = grid; @@ -138,7 +143,51 @@ public class GridConnector extends AbstractListingConnector @Override public void recalculateColumnWidths() { - grid.recalculateColumnWidths(); + if (recalculateScheduled) { + return; + } + + // Must be scheduled so that possible refreshAll has time to clear + // the cache. + recalculateScheduled = true; + Scheduler.get().scheduleFinally(() -> { + // If cache has been cleared, wait for data to become available. + // Don't trigger another attempt if there is already a handler + // waiting, that one will trigger the call when calculations are + // possible and clear out the registration afterwards. + if (((AbstractRemoteDataSource<JsonObject>) getDataSource()) + .getCachedRange().length() == 0 + && getDataSource().size() > 0) { + if (dataAvailableHandlerRegistration == null) { + dataAvailableHandlerRegistration = grid + .addDataAvailableHandler( + new DataAvailableHandler() { + + @Override + public void onDataAvailable( + DataAvailableEvent event) { + if (event.getAvailableRows() + .length() == 0 + && getDataSource() + .size() > 0) { + // Cache not populated yet, + // wait for next call. + return; + } + grid.recalculateColumnWidths(); + if (dataAvailableHandlerRegistration != null) { + dataAvailableHandlerRegistration + .removeHandler(); + dataAvailableHandlerRegistration = null; + } + } + }); + } + } else if (dataAvailableHandlerRegistration == null) { + grid.recalculateColumnWidths(); + } + recalculateScheduled = false; + }); } } diff --git a/client/src/main/java/com/vaadin/client/widgets/Grid.java b/client/src/main/java/com/vaadin/client/widgets/Grid.java index 4f13d0ae42..908446dfee 100755 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -3393,7 +3393,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, Scheduler.get().scheduleDeferred(this); } } else if (currentDataAvailable.isEmpty() - && dataSource.isWaitingForData()) { + && (dataSource.isWaitingForData() + || escalator.getBody().getRowCount() > 0)) { Scheduler.get().scheduleDeferred(this); } else { calculate(); @@ -3406,20 +3407,16 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, /** * Calculates and applies column widths, taking into account fixed - * widths and column expand rules + * widths and column expand rules. * - * @param immediately - * <code>true</code> if the widths should be executed - * immediately (ignoring lazy loading completely), or - * <code>false</code> if the command should be run after a - * while (duplicate non-immediately invocations are ignored). * @see Column#setWidth(double) * @see Column#setExpandRatio(int) * @see Column#setMinimumWidth(double) * @see Column#setMaximumWidth(double) */ public void schedule() { - if (!isScheduled && isAttached()) { + if (!isScheduled && isAttached() && !(currentDataAvailable.isEmpty() + && escalator.getBody().getRowCount() > 0)) { isScheduled = true; Scheduler.get().scheduleFinally(calculateCommand); } @@ -3434,8 +3431,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, // Make SelectAllCheckbox visible getSelectionColumn().ifPresent(col -> { - if (getDefaultHeaderRow() == null) + if (getDefaultHeaderRow() == null) { return; + } HeaderCell headerCell = getDefaultHeaderRow().getCell(col); if (headerCell.getType().equals(GridStaticCellType.WIDGET)) { // SelectAllCheckbox is present already @@ -7248,6 +7246,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, this.dataSource = dataSource; changeHandler = dataSource .addDataChangeHandler(new DataChangeHandler() { + private boolean recalculateColumnWidthsNeeded = false; + @Override public void dataUpdated(int firstIndex, int numberOfItems) { escalator.getBody().refreshRows(firstIndex, @@ -7280,11 +7280,23 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, int numberOfItems) { currentDataAvailable = Range.withLength(firstIndex, numberOfItems); + if (recalculateColumnWidthsNeeded) { + // Ensure that cache has actually been populated or + // all rows removed, otherwise wait for next call. + if (numberOfItems > 0 + || getDataSource().size() == 0) { + recalculateColumnWidths(); + recalculateColumnWidthsNeeded = false; + } + } fireEvent(new DataAvailableEvent(currentDataAvailable)); } @Override public void resetDataAndSize(int newSize) { + // It might take a while for new data to arrive, + // clear the record of cached rows. + currentDataAvailable = Range.emptyRange(); RowContainer body = escalator.getBody(); int oldSize = body.getRowCount(); @@ -7300,8 +7312,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, // Need to recalculate column widths when the // first row is added to a non-header grid, // otherwise the checkbox will be aligned in a - // wrong place. - recalculateColumnWidths(); + // wrong place. Wait until the cache has been + // populated before making the call. + recalculateColumnWidthsNeeded = true; } body.insertRows(oldSize, newSize - oldSize); cellFocusHandler.rowsAddedToBody(Range @@ -7320,8 +7333,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, visibleRowRange.length()); } else { // We won't expect any data more data updates, so - // just make - // the bookkeeping happy + // just make the bookkeeping happy. dataAvailable(0, 0); } @@ -9307,11 +9319,11 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, }, 50); } } - + private void doRefreshOnResize() { if (escalator .getInnerWidth() != autoColumnWidthsRecalculator.lastCalculatedInnerWidth) { - recalculateColumnWidths(); + recalculateColumnWidths(); } // Vertical resizing could make editor positioning invalid so it |