diff options
author | ericflock <40864945+ericflock@users.noreply.github.com> | 2018-11-06 11:47:31 +0100 |
---|---|---|
committer | Olli Tietäväinen <ollit@vaadin.com> | 2018-11-06 12:47:31 +0200 |
commit | eafd44672650e076fc4a43362e11b47ffb0dbff1 (patch) | |
tree | 1cf048d4a661bf2fbcaa8e7a7a6d9c9ebdad3abe | |
parent | ad8c6181fddab9e397dcc0112c1d976779c5f3c4 (diff) | |
download | vaadin-framework-eafd44672650e076fc4a43362e11b47ffb0dbff1.tar.gz vaadin-framework-eafd44672650e076fc4a43362e11b47ffb0dbff1.zip |
Add columns at once in a batched way to increase performance (#11261)
* provide possibility to add columns in a batched way
This is the basis to increase the performance for further changes.
* add the columns at once to the grid to increase performance
* combined performance fixes
* respect the column order
* Fixed formatting
-rw-r--r-- | client/src/main/java/com/vaadin/client/connectors/GridConnector.java | 83 | ||||
-rwxr-xr-x | client/src/main/java/com/vaadin/client/widgets/Grid.java | 154 |
2 files changed, 150 insertions, 87 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/GridConnector.java b/client/src/main/java/com/vaadin/client/connectors/GridConnector.java index 6b9e925497..cecfb726dc 100644 --- a/client/src/main/java/com/vaadin/client/connectors/GridConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/GridConnector.java @@ -179,6 +179,28 @@ public class GridConnector extends AbstractHasComponentsConnector } /** + * Creates and initializes a custom grid column with attributes of given state. + * + * @param state with attributes to initialize the column. + */ + @SuppressWarnings("unchecked") + private CustomGridColumn(GridColumnState state) { + this(state.id, (AbstractRendererConnector<Object>) state.rendererConnector); + this.hidingToggleCaption = state.hidingToggleCaption; + this.hidden = state.hidden; + this.hidable = state.hidable; + this.resizable = state.resizable; + this.sortable = state.sortable; + this.headerCaption = state.headerCaption == null ? "" : state.headerCaption; + this.widthUser = state.width; + this.minimumWidthPx = state.minWidth; + this.maximumWidthPx = state.maxWidth; + this.expandRatio = state.expandRatio; + this.editable = state.editable; + setEditorConnector((AbstractComponentConnector) state.editorConnector); + } + + /** * Sets a new renderer for this column object * * @param rendererConnector @@ -909,7 +931,7 @@ public class GridConnector extends AbstractHasComponentsConnector super.onStateChanged(stateChangeEvent); initialChange = stateChangeEvent.isInitialStateChange(); - + if (initialChange) { Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override @@ -931,15 +953,10 @@ public class GridConnector extends AbstractHasComponentsConnector // Remove old columns purgeRemovedColumns(); - // Add new columns - for (GridColumnState state : getState().columns) { - if (!columnIdToColumn.containsKey(state.id)) { - addColumnFromStateChangeEvent(state); - } - updateColumnFromStateChangeEvent(state); - } + // Update all columns + updateColumnsFromState(); } - + if (stateChangeEvent.hasPropertyChanged("columnOrder")) { if (orderNeedsUpdate(getState().columnOrder)) { updateColumnOrderFromState(getState().columnOrder); @@ -1138,37 +1155,33 @@ public class GridConnector extends AbstractHasComponentsConnector cell.setStyleName(cellState.styleName); } - /** - * Updates a column from a state change event. - * - * @param columnIndex - * The index of the column to update - */ - private void updateColumnFromStateChangeEvent(GridColumnState columnState) { - CustomGridColumn column = columnIdToColumn.get(columnState.id); - - columnsUpdatedFromState = true; - updateColumnFromState(column, columnState); - columnsUpdatedFromState = false; - } /** - * Adds a new column to the grid widget from a state change event + * Update columns from the current state. * - * @param columnIndex - * The index of the column, according to how it */ - private void addColumnFromStateChangeEvent(GridColumnState state) { + private void updateColumnsFromState() { + this.columnsUpdatedFromState = true; + final List<Column<?, JsonObject>> columns = new ArrayList<Column<?, JsonObject>>(getState().columns.size()); + for (String columnId : getState().columnOrder) { + for (GridColumnState state : getState().columns) { + if (state.id.equals(columnId)) { + CustomGridColumn column = this.columnIdToColumn.get(state.id); + if (column == null) { + column = new CustomGridColumn(state); + this.columnIdToColumn.put(state.id, column); + this.columnOrder.add(state.id); + columns.add(column); + } else { + updateColumnFromState(column, state); + } + } + } + } @SuppressWarnings("unchecked") - CustomGridColumn column = new CustomGridColumn(state.id, - ((AbstractRendererConnector<Object>) state.rendererConnector)); - columnIdToColumn.put(state.id, column); - - /* - * Add column to grid. Reordering is handled as a separate problem. - */ - getWidget().addColumn(column); - columnOrder.add(state.id); + final Column<?, JsonObject>[] columnArray = columns.toArray(new Column[0]); + getWidget().addColumns(columnArray); + this.columnsUpdatedFromState = 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 b0bb391050..4f0b012a00 100755 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -4772,33 +4772,65 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private Grid<T> grid; /** - * Width of column in pixels as {@link #setWidth(double)} has been - * called + * Width of column in pixels as {@link #setWidth(double)} has been called. */ - private double widthUser = GridConstants.DEFAULT_COLUMN_WIDTH_PX; + protected double widthUser = GridConstants.DEFAULT_COLUMN_WIDTH_PX; /** * Renderer for rendering a value into the cell */ private Renderer<? super C> bodyRenderer; - private boolean sortable = false; + /** + * The sortable state of this column. + */ + protected boolean sortable = false; - private boolean editable = true; + /** + * The editable state of this column. + */ + protected boolean editable = true; + + /** + * The resizable state of this column. + */ + protected boolean resizable = true; + + /** + * The hidden state of this column. + */ + protected boolean hidden = false; + + /** + * The hidable state of this column. + */ + protected boolean hidable = false; - private boolean resizable = true; + /** + * The header-caption of this column. + */ + protected String headerCaption = ""; - private boolean hidden = false; + /** + * The hiding-toggle-caption of this column. + */ + protected String hidingToggleCaption = null; - private boolean hidable = false; + /** + * The minimum width in pixels of this column. + */ + protected double minimumWidthPx = GridConstants.DEFAULT_MIN_WIDTH; - private String headerCaption = ""; + /** + * The maximum width in pixels of this column. + */ + protected double maximumWidthPx = GridConstants.DEFAULT_MAX_WIDTH; - private String hidingToggleCaption = null; + /** + * The expand ratio of this column. + */ + protected int expandRatio = GridConstants.DEFAULT_EXPAND_RATIO; - private double minimumWidthPx = GridConstants.DEFAULT_MIN_WIDTH; - private double maximumWidthPx = GridConstants.DEFAULT_MAX_WIDTH; - private int expandRatio = GridConstants.DEFAULT_EXPAND_RATIO; /** * Constructs a new column with a simple TextRenderer. @@ -6419,9 +6451,24 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * the columns to add */ public void addColumns(Column<?, T>... columns) { - int count = getColumnCount(); + final int count = getColumnCount(); for (Column<?, T> column : columns) { - addColumn(column, count++); + checkColumnIsValidToAdd(column, count); + } + addColumnsSkipSelectionColumnCheck(Arrays.asList(columns), count); + } + + + /** + * Checks the given column is valid to add at the given index. + */ + private void checkColumnIsValidToAdd(Column<?, T> column, int index) { + if (column == this.selectionColumn) { + throw new IllegalArgumentException( + "The selection column many " + "not be added manually"); + } else if (this.selectionColumn != null && index == 0) { + throw new IllegalStateException("A column cannot be inserted " + + "before the selection column"); } } @@ -6451,53 +6498,56 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * and {@code index} is 0. */ public <C extends Column<?, T>> C addColumn(C column, int index) { - if (column == selectionColumn) { - throw new IllegalArgumentException( - "The selection column many " + "not be added manually"); - } else if (selectionColumn != null && index == 0) { - throw new IllegalStateException("A column cannot be inserted " - + "before the selection column"); - } - - addColumnSkipSelectionColumnCheck(column, index); + checkColumnIsValidToAdd(column, index); + addColumnsSkipSelectionColumnCheck(Collections.singleton(column), index); return column; } - private void addColumnSkipSelectionColumnCheck(Column<?, T> column, - int index) { - // Register column with grid - columns.add(index, column); - header.addColumn(column); - footer.addColumn(column); + private <C extends Column<?, T>> void addColumnsSkipSelectionColumnCheck(Collection<C> columnCollection, int index) { + int visibleNewColumns = 0; + int currentIndex = index; - // Register this grid instance with the column - ((Column<?, T>) column).setGrid(this); + //prevent updates of hiding toggles. + //it will be updated finally all at once. + this.columnHider.hidingColumn = true; - // Grid knows about hidden columns, Escalator only knows about what is - // visible so column indexes do not match - if (!column.isHidden()) { - int escalatorIndex = index; - for (int existingColumn = 0; existingColumn < index; existingColumn++) { - if (getColumn(existingColumn).isHidden()) { - escalatorIndex--; - } + for (final Column<?, T> column : columnCollection) { + // Register column with grid + this.columns.add(currentIndex++, column); + this.footer.addColumn(column); + this.header.addColumn(column); + + // Register this grid instance with the column + column.setGrid(this); + + if (!column.isHidden()) { + visibleNewColumns++; } - escalator.getColumnConfiguration().insertColumns(escalatorIndex, 1); + } + if (visibleNewColumns > 0) { + final ColumnConfiguration columnConfiguration = this.escalator.getColumnConfiguration(); + columnConfiguration.insertColumns(index, visibleNewColumns); } - // Reapply column width - column.reapplyWidth(); - - // Sink all renderer events - Set<String> events = new HashSet<String>(); - events.addAll(getConsumedEventsForRenderer(column.getRenderer())); + for (final Column<?, T> column : columnCollection) { + // Reapply column width + column.reapplyWidth(); + // Sink all renderer events + final Set<String> events = new HashSet<String>(); + events.addAll(getConsumedEventsForRenderer(column.getRenderer())); - if (column.isHidable()) { - columnHider.updateColumnHidable(column); + if (column.isHidable()) { + this.columnHider.updateColumnHidable(column); + } + sinkEvents(events); } - - sinkEvents(events); + //now we do the update of the hiding toggles. + this.columnHider.hidingColumn = false; + this.columnHider.updateTogglesOrder(); + refreshHeader(); + this.header.updateColSpans(); + this.footer.updateColSpans(); } private void sinkEvents(Collection<String> events) { @@ -7891,7 +7941,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, cellFocusHandler.offsetRangeBy(1); selectionColumn = new SelectionColumn(selectColumnRenderer); - addColumnSkipSelectionColumnCheck(selectionColumn, 0); + addColumnsSkipSelectionColumnCheck(Collections.singleton(selectionColumn), 0); selectionColumn.setEnabled(isEnabled()); selectionColumn.initDone(); |