Browse Source

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
tags/7.7.16
ericflock 5 years ago
parent
commit
eafd446726

+ 48
- 35
client/src/main/java/com/vaadin/client/connectors/GridConnector.java View File

@@ -178,6 +178,28 @@ public class GridConnector extends AbstractHasComponentsConnector
this.id = id;
}

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

/**

+ 102
- 52
client/src/main/java/com/vaadin/client/widgets/Grid.java View File

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

Loading…
Cancel
Save