summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorAnna Koskinen <Ansku@users.noreply.github.com>2020-04-24 12:01:32 +0300
committerGitHub <noreply@github.com>2020-04-24 12:01:32 +0300
commit616f24764b2659380c4f4c6ce1057c0056513199 (patch)
tree30605364c45672aa662845e0f919d0b26592acd6 /client
parent5947875fd3ad16e815bb551604bc26bbe44872de (diff)
downloadvaadin-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.java51
-rwxr-xr-xclient/src/main/java/com/vaadin/client/widgets/Grid.java42
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