summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Paul <henrik@vaadin.com>2014-10-22 14:42:16 +0300
committerTeemu Suo-Anttila <teemusa@vaadin.com>2014-11-05 09:23:31 +0000
commit9d83b55e3ed2f72bc76b778d95de972c4a5c0e89 (patch)
tree8bcd7b3e032a96f56e027b04ed60e2563929abe4
parent070caa2a23623b78fdb08a931c6350465275a259 (diff)
downloadvaadin-framework-9d83b55e3ed2f72bc76b778d95de972c4a5c0e89.tar.gz
vaadin-framework-9d83b55e3ed2f72bc76b778d95de972c4a5c0e89.zip
Column remove/insertion doesn't refresh the entire row (#13334)
Change-Id: Id224b7225e570b3fb593de1b27a026ae161bf526
-rw-r--r--client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java35
-rw-r--r--client/src/com/vaadin/client/ui/grid/Escalator.java119
-rw-r--r--client/src/com/vaadin/client/ui/grid/RowContainer.java2
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java7
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java6
5 files changed, 134 insertions, 35 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java b/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java
index f523fdbbd4..d1baf5ba99 100644
--- a/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java
+++ b/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java
@@ -30,6 +30,11 @@ public interface ColumnConfiguration {
* <p>
* If any of the removed columns were frozen, the number of frozen columns
* will be reduced by the number of the removed columns that were frozen.
+ * <p>
+ * <em>Note:</em> This method simply removes the given columns, and does not
+ * do much of anything else. Especially if you have column spans, you
+ * probably need to run {@link #refreshColumns(int, int)} or
+ * {@link RowContainer#refreshRows(int, int)}
*
* @param index
* the index of the first column to be removed
@@ -61,8 +66,9 @@ public interface ColumnConfiguration {
* <p>
* <em>Note:</em> Only the contents of the inserted columns will be
* rendered. If inserting new columns affects the contents of existing
- * columns, {@link RowContainer#refreshRows(int, int)} needs to be called as
- * appropriate.
+ * columns (e.g. you have column spans),
+ * {@link RowContainer#refreshRows(int, int)} or
+ * {@link #refreshColumns(int, int)} needs to be called as appropriate.
*
* @param index
* the index of the column before which new columns are inserted,
@@ -142,4 +148,29 @@ public interface ColumnConfiguration {
* if <code>index</code> is not a valid column index
*/
public int getColumnWidthActual(int index) throws IllegalArgumentException;
+
+ /**
+ * Refreshes a range of rows in the current row containers in each Escalator
+ * section.
+ * <p>
+ * The data for the refreshed columns is queried from the current cell
+ * renderer.
+ *
+ * @param index
+ * the index of the first row that will be updated
+ * @param numberOfRows
+ * the number of rows to update, starting from the index
+ * @throws IndexOutOfBoundsException
+ * if any integer number in the range
+ * <code>[index..(index+numberOfColumns)]</code> is not an
+ * existing column index.
+ * @throws IllegalArgumentException
+ * if {@code numberOfColumns} is less than 1.
+ * @see RowContainer#setEscalatorUpdater(EscalatorUpdater)
+ * @see Escalator#getHeader()
+ * @see Escalator#getBody()
+ * @see Escalator#getFooter()
+ */
+ public void refreshColumns(int index, int numberOfColumns)
+ throws IndexOutOfBoundsException, IllegalArgumentException;
} \ No newline at end of file
diff --git a/client/src/com/vaadin/client/ui/grid/Escalator.java b/client/src/com/vaadin/client/ui/grid/Escalator.java
index 2ca90fe802..3aaa1f6c06 100644
--- a/client/src/com/vaadin/client/ui/grid/Escalator.java
+++ b/client/src/com/vaadin/client/ui/grid/Escalator.java
@@ -1415,12 +1415,28 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
*/
@Override
// overridden because of JavaDoc
- public abstract void refreshRows(final int index, final int numberOfRows);
+ public void refreshRows(final int index, final int numberOfRows) {
+ Range rowRange = Range.withLength(index, numberOfRows);
+ Range colRange = Range.withLength(0, getColumnConfiguration()
+ .getColumnCount());
+ refreshCells(rowRange, colRange);
+ }
+
+ protected abstract void refreshCells(Range logicalRowRange,
+ Range colRange);
- void refreshRow(final TableRowElement tr, final int logicalRowIndex) {
+ void refreshRow(TableRowElement tr, int logicalRowIndex) {
+ refreshRow(tr, logicalRowIndex, Range.withLength(0,
+ getColumnConfiguration().getColumnCount()));
+ }
+
+ void refreshRow(final TableRowElement tr, final int logicalRowIndex,
+ Range colRange) {
flyweightRow.setup(tr, logicalRowIndex,
columnConfiguration.getCalculatedColumnWidths());
- updater.update(flyweightRow, flyweightRow.getCells());
+ Iterable<FlyweightCell> cellsToUpdate = flyweightRow.getCells(
+ colRange.getStart(), colRange.length());
+ updater.update(flyweightRow, cellsToUpdate);
/*
* the "assert" guarantees that this code is run only during
@@ -1503,16 +1519,6 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
setColumnFrozen(col, true);
}
}
-
- /*
- * Because we might insert columns where affected by colspans, it's
- * easiest to simply redraw everything when columns are modified.
- *
- * Yes, this is a TODO [[optimize]].
- */
- if (getRowCount() > 0) {
- refreshRows(0, getRowCount());
- }
}
/**
@@ -1569,6 +1575,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
}
getEscalatorUpdater().postAttach(flyweightRow, cells);
+ getEscalatorUpdater().update(flyweightRow, cells);
assert flyweightRow.teardown();
}
@@ -1861,6 +1868,14 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
return new Cell(domRowIndex, domColumnIndex, cellElement);
}
+
+ void refreshColumns(int index, int numberOfColumns) {
+ if (getRowCount() > 0) {
+ Range rowRange = Range.withLength(0, getRowCount());
+ Range colRange = Range.withLength(index, numberOfColumns);
+ refreshCells(rowRange, colRange);
+ }
+ }
}
private abstract class AbstractStaticRowContainer extends
@@ -1954,10 +1969,11 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
protected abstract void sectionHeightCalculated();
@Override
- public void refreshRows(final int index, final int numberOfRows) {
+ protected void refreshCells(Range logicalRowRange, Range colRange) {
Profiler.enter("Escalator.AbstractStaticRowContainer.refreshRows");
- assertArgumentsAreValidAndWithinRange(index, numberOfRows);
+ assertArgumentsAreValidAndWithinRange(logicalRowRange.getStart(),
+ logicalRowRange.length());
if (!isAttached()) {
return;
@@ -1975,9 +1991,10 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
* TODO [[rowheight]]: nudge rows down with
* refreshRowPositions() as needed
*/
- for (int row = index; row < index + numberOfRows; row++) {
+ for (int row = logicalRowRange.getStart(); row < logicalRowRange
+ .getEnd(); row++) {
final TableRowElement tr = getTrByVisualIndex(row);
- refreshRow(tr, row);
+ refreshRow(tr, row, colRange);
}
}
@@ -3112,11 +3129,10 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
}
@Override
- public void refreshRows(final int index, final int numberOfRows) {
+ protected void refreshCells(Range logicalRowRange, Range colRange) {
Profiler.enter("Escalator.BodyRowContainer.refreshRows");
- final Range visualRange = convertToVisual(Range.withLength(index,
- numberOfRows));
+ final Range visualRange = convertToVisual(logicalRowRange);
if (!visualRange.isEmpty()) {
final int firstLogicalRowIndex = getLogicalRowIndex(visualRowOrder
@@ -3124,7 +3140,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
for (int rowNumber = visualRange.getStart(); rowNumber < visualRange
.getEnd(); rowNumber++) {
refreshRow(visualRowOrder.get(rowNumber),
- firstLogicalRowIndex + rowNumber);
+ firstLogicalRowIndex + rowNumber, colRange);
}
}
@@ -3576,22 +3592,27 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
body.verifyEscalatorCount();
if (getColumnConfiguration().getColumnCount() > 0) {
- readjustRows(header);
- readjustRows(body);
- readjustRows(footer);
+ reapplyRowWidths(header);
+ reapplyRowWidths(body);
+ reapplyRowWidths(footer);
}
+
+ /*
+ * Colspans make any kind of automatic clever content re-rendering
+ * impossible: As soon as anything has colspans, removing one might
+ * reveal further colspans, modifying the DOM structure once again,
+ * ending in a cascade of updates. Because we don't know how the
+ * data is updated.
+ *
+ * So, instead, we don't do anything. The client code is responsible
+ * for re-rendering the content (if so desired). Everything Just
+ * Works (TM) if colspans aren't used.
+ */
}
- private void readjustRows(AbstractRowContainer container) {
+ private void reapplyRowWidths(AbstractRowContainer container) {
if (container.getRowCount() > 0) {
container.reapplyRowWidths();
-
- /*
- * FIXME: Because we might remove columns where affected by
- * colspans, it's easiest to simply redraw everything when
- * columns are modified.
- */
- container.refreshRows(0, container.getRowCount());
}
}
@@ -3710,6 +3731,18 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
horizontalScrollbar.setScrollPos(scroller.lastScrollLeft
+ insertedColumnsWidth);
}
+
+ /*
+ * Colspans make any kind of automatic clever content re-rendering
+ * impossible: As soon as anything has colspans, adding one might
+ * affect surrounding colspans, modifying the DOM structure once
+ * again, ending in a cascade of updates. Because we don't know how
+ * the data is updated.
+ *
+ * So, instead, we don't do anything. The client code is responsible
+ * for re-rendering the content (if so desired). Everything Just
+ * Works (TM) if colspans aren't used.
+ */
}
@Override
@@ -3840,6 +3873,28 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
}
return widthsArray;
}
+
+ @Override
+ public void refreshColumns(int index, int numberOfColumns)
+ throws IndexOutOfBoundsException, IllegalArgumentException {
+ if (numberOfColumns < 1) {
+ throw new IllegalArgumentException(
+ "Number of columns must be 1 or greater (was "
+ + numberOfColumns + ")");
+ }
+
+ if (index < 0 || index + numberOfColumns > getColumnCount()) {
+ throw new IndexOutOfBoundsException("The given "
+ + "column range (" + index + ".."
+ + (index + numberOfColumns)
+ + ") was outside of the current number of columns ("
+ + getColumnCount() + ")");
+ }
+
+ header.refreshColumns(index, numberOfColumns);
+ body.refreshColumns(index, numberOfColumns);
+ footer.refreshColumns(index, numberOfColumns);
+ }
}
// abs(atan(y/x))*(180/PI) = n deg, x = 1, solve y
diff --git a/client/src/com/vaadin/client/ui/grid/RowContainer.java b/client/src/com/vaadin/client/ui/grid/RowContainer.java
index 8b03ef3c36..f969f90fc9 100644
--- a/client/src/com/vaadin/client/ui/grid/RowContainer.java
+++ b/client/src/com/vaadin/client/ui/grid/RowContainer.java
@@ -109,7 +109,7 @@ public interface RowContainer {
/**
* Refreshes a range of rows in the current row container.
* <p>
- * The data for the refreshed rows are queried from the current cell
+ * The data for the refreshed rows is queried from the current cell
* renderer.
*
* @param index
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java
index 60b9d5cc7d..08dc1d2eae 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java
@@ -456,6 +456,13 @@ public class EscalatorBasicClientFeaturesWidget extends
.getColumnCount() - 1, 1);
}
}, menupath);
+
+ addMenuCommand("Refresh first column", new ScheduledCommand() {
+ @Override
+ public void execute() {
+ escalator.getColumnConfiguration().refreshColumns(0, 1);
+ }
+ }, menupath);
}
private void createHeaderRowsMenu() {
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
index 866fdbd5c2..f1d64a50e7 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
@@ -80,6 +80,12 @@ public class EscalatorProxy extends Escalator {
throws IllegalArgumentException {
return columnConfiguration.getColumnWidthActual(index);
}
+
+ @Override
+ public void refreshColumns(int index, int numberOfColumns)
+ throws IndexOutOfBoundsException, IllegalArgumentException {
+ columnConfiguration.refreshColumns(index, numberOfColumns);
+ }
}
private class RowContainerProxy implements RowContainer {