From cdb8996e925784c908b8b7607b1650c09811f293 Mon Sep 17 00:00:00 2001 From: Henrik Paul Date: Fri, 6 Feb 2015 16:35:16 +0200 Subject: [PATCH] Fixes subpixel allocation accuracy and speed (#16614, #16750) This reverts workarounds used in subpixel quick fix commit 6133b2cffd0c0b0e0e360ae30330a8adbe7662f4. New logic uses Escalator's more optimised multiple column width setting method. Change-Id: I0863f9774e6efc26f01ebdb736b4847e4ef5354c --- .../client/widget/escalator/FlyweightRow.java | 1 - .../com/vaadin/client/widgets/Escalator.java | 192 ++++++++++++++++-- .../src/com/vaadin/client/widgets/Grid.java | 178 ++++++++-------- .../grid/GridWidthIncreaseTest.java | 34 +++- .../GridClientColumnPropertiesTest.java | 10 +- 5 files changed, 280 insertions(+), 135 deletions(-) diff --git a/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java b/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java index 6e25e82235..8628adb05f 100644 --- a/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java +++ b/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java @@ -21,7 +21,6 @@ import java.util.Iterator; import java.util.List; import com.google.gwt.dom.client.TableRowElement; -import com.vaadin.client.widgets.Escalator; /** * An internal implementation of the {@link Row} interface. diff --git a/client/src/com/vaadin/client/widgets/Escalator.java b/client/src/com/vaadin/client/widgets/Escalator.java index 0e34d98466..5f69be9142 100644 --- a/client/src/com/vaadin/client/widgets/Escalator.java +++ b/client/src/com/vaadin/client/widgets/Escalator.java @@ -819,18 +819,23 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker double tableWrapperWidth = widthOfEscalator; boolean verticalScrollNeeded = scrollContentHeight > tableWrapperHeight - - header.heightOfSection - footer.heightOfSection; - boolean horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth; + + WidgetUtil.PIXEL_EPSILON + - header.heightOfSection + - footer.heightOfSection; + boolean horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth + + WidgetUtil.PIXEL_EPSILON; // One dimension got scrollbars, but not the other. Recheck time! if (verticalScrollNeeded != horizontalScrollNeeded) { if (!verticalScrollNeeded && horizontalScrollNeeded) { verticalScrollNeeded = scrollContentHeight > tableWrapperHeight + + WidgetUtil.PIXEL_EPSILON - header.heightOfSection - footer.heightOfSection - horizontalScrollbar.getScrollbarThickness(); } else { horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth + + WidgetUtil.PIXEL_EPSILON - verticalScrollbar.getScrollbarThickness(); } } @@ -1810,12 +1815,13 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker */ protected void reapplyRowWidths() { double rowWidth = columnConfiguration.calculateRowWidth(); + if (rowWidth < 0) { + return; + } - com.google.gwt.dom.client.Element row = root.getFirstChildElement(); + Element row = root.getFirstChildElement(); while (row != null) { - if (rowWidth >= 0) { - row.getStyle().setWidth(rowWidth, Unit.PX); - } + row.getStyle().setWidth(rowWidth, Unit.PX); row = row.getNextSiblingElement(); } } @@ -2035,22 +2041,17 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker cellClone.getStyle().clearWidth(); rowElement.insertBefore(cellClone, cellOriginal); - - /* - * [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: not - * using the double-version is a workaround for a bug. It'll be - * converted to use the double version at a later time - */ double requiredWidth = WidgetUtil - .getRequiredWidthBoundingClientRect(cellClone); + .getRequiredWidthBoundingClientRectDouble(cellClone); - if (BrowserInfo.get().isIE9()) { + if (BrowserInfo.get().isIE()) { /* - * IE9 does not support subpixels. Usually it is rounded - * down which leads to content not shown. Increase the - * counted required size by one just to be on the safe side. + * IE browsers have some issues with subpixels. Occasionally + * content is overflown even if not necessary. Increase the + * counted required size by 0.01 just to be on the safe + * side. */ - requiredWidth += 1; + requiredWidth += 0.01; } maxCellWidth = Math.max(requiredWidth, maxCellWidth); @@ -3792,7 +3793,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker } else { /* * the column's width is calculated at Escalator.onLoad - * via measureIfNeeded! + * via measureAndSetWidthIfNeeded! */ measuringRequested = true; } @@ -3818,7 +3819,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker * widths yet. * * This is fixed during Escalator.onLoad, by the call to - * "measureIfNeeded", which fixes "everything". + * "measureAndSetWidthIfNeeded", which fixes "everything". */ if (!measuringRequested) { return calculatedWidth; @@ -3833,7 +3834,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker * Called by {@link Escalator#onLoad()}. */ public boolean measureAndSetWidthIfNeeded() { - assert isAttached() : "Column.measureIfNeeded() was called even though Escalator was not attached!"; + assert isAttached() : "Column.measureAndSetWidthIfNeeded() was called even though Escalator was not attached!"; if (measuringRequested) { measuringRequested = false; @@ -3851,6 +3852,11 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker private final List columns = new ArrayList(); private int frozenColumns = 0; + /* + * TODO: this is a bit of a duplicate functionality with the + * Column.calculatedWidth caching. Probably should use one or the other, + * not both + */ /** * A cached array of all the calculated column widths. * @@ -3995,6 +4001,8 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker */ @Override public void insertColumns(final int index, final int numberOfColumns) { + subpixelBrowserBugDetector.invalidateFix(); + // Validate if (index < 0 || index > getColumnCount()) { throw new IndexOutOfBoundsException("The given index(" + index @@ -4146,14 +4154,23 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker for (Entry entry : indexWidthMap.entrySet()) { int index = entry.getKey().intValue(); double width = entry.getValue().doubleValue(); + + if (index == getColumnCount() - 1) { + subpixelBrowserBugDetector.invalidateFix(); + } + checkValidColumnIndex(index); columns.get(index).setWidth(width); + } widthsArray = null; header.reapplyColumnWidths(); body.reapplyColumnWidths(); footer.reapplyColumnWidths(); + + subpixelBrowserBugDetector.checkAndFix(); + recalculateElementSizes(); } @@ -4248,6 +4265,137 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker } } + private class SubpixelBrowserBugDetector { + private static final double SUBPIXEL_ADJUSTMENT = .1; + private boolean hasAlreadyBeenFixed = false; + + /** + * This is a fix essentially for Firefox and how it handles subpixels. + *

+ * Even if an element has {@code style="width: 1000.12px"}, the bounding + * box's width in Firefox is usually nothing of that sort. It's actually + * 1000.11669921875 (in version 35.0.1). That's not even close, when + * talking about floating point precision. Other browsers handle the + * subpixels way better + *

+ * In any case, we need to fix that. And that's fixed by simply checking + * if the sum of the width of all the cells is larger than the width of + * the row. If it is, we hack the last column + * {@value #SUBPIXEL_ADJUSTMENT}px narrower. + */ + public void checkAndFix() { + if (!hasAlreadyBeenFixed && hasSubpixelBrowserBug()) { + fixSubpixelBrowserBug(); + hasAlreadyBeenFixed = true; + } + } + + public void invalidateFix() { + adjustBookkeepingPixels(SUBPIXEL_ADJUSTMENT); + hasAlreadyBeenFixed = false; + } + + private boolean hasSubpixelBrowserBug() { + final RowContainer rowContainer; + if (header.getRowCount() > 0) { + rowContainer = header; + } else if (body.getRowCount() > 0) { + rowContainer = body; + } else if (footer.getRowCount() > 0) { + rowContainer = footer; + } else { + return false; + } + + double sumOfCellWidths = 0; + TableRowElement tr = rowContainer.getElement().getRows().getItem(0); + + if (tr == null) { + /* + * for some weird reason, the row might be null at this point in + * (some?) webkit browsers. + */ + return false; + } + + NodeList cells = tr.getCells(); + assert cells != null : "cells was null, why is it null?"; + + for (int i = 0; i < cells.getLength(); i++) { + TableCellElement cell = cells.getItem(i); + if (!cell.getStyle().getDisplay() + .equals(Display.NONE.getCssName())) { + sumOfCellWidths += WidgetUtil.getBoundingClientRect(cell) + .getWidth(); + } + } + + double rowWidth = WidgetUtil.getBoundingClientRect(tr).getWidth(); + return sumOfCellWidths >= rowWidth; + } + + private void fixSubpixelBrowserBug() { + assert columnConfiguration.getColumnCount() > 0 : "Why are we running this code if there are no columns?"; + + adjustBookkeepingPixels(-SUBPIXEL_ADJUSTMENT); + + fixSubpixelBrowserBugFor(header); + fixSubpixelBrowserBugFor(body); + fixSubpixelBrowserBugFor(footer); + } + + private void adjustBookkeepingPixels(double adjustment) { + int lastColumnIndex = columnConfiguration.columns.size() - 1; + if (lastColumnIndex < 0) { + return; + } + + columnConfiguration.columns.get(lastColumnIndex).calculatedWidth += adjustment; + if (columnConfiguration.widthsArray != null) { + columnConfiguration.widthsArray[lastColumnIndex] += adjustment; + } + } + + /** + * Adjust the last non-spanned cell by {@link #SUBPIXEL_ADJUSTMENT} ( + * {@value #SUBPIXEL_ADJUSTMENT}px). + *

+ * We'll do this brute-force, by individually measuring and shrinking + * the last non-spanned cell. Brute-force, since each row might be + * spanned differently - we can't simply pick one index and one width, + * and mass-apply that to everything :( + */ + private void fixSubpixelBrowserBugFor(RowContainer rowContainer) { + if (rowContainer.getRowCount() == 0) { + return; + } + + NodeList rows = rowContainer.getElement() + .getRows(); + for (int i = 0; i < rows.getLength(); i++) { + + NodeList cells = rows.getItem(i).getCells(); + TableCellElement lastNonspannedCell = null; + for (int j = cells.getLength() - 1; j >= 0; j--) { + TableCellElement cell = cells.getItem(j); + if (!cell.getStyle().getDisplay() + .equals(Display.NONE.getCssName())) { + lastNonspannedCell = cell; + break; + } + } + + assert lastNonspannedCell != null : "all cells were \"display: none\" on row " + + i + " in " + rowContainer.getElement().getTagName(); + + double cellWidth = WidgetUtil.getBoundingClientRect( + lastNonspannedCell).getWidth(); + double newWidth = cellWidth - SUBPIXEL_ADJUSTMENT; + lastNonspannedCell.getStyle().setWidth(newWidth, Unit.PX); + } + } + } + // abs(atan(y/x))*(180/PI) = n deg, x = 1, solve y /** * The solution to @@ -4344,6 +4492,8 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker } }; + private final SubpixelBrowserBugDetector subpixelBrowserBugDetector = new SubpixelBrowserBugDetector(); + /** * Creates a new Escalator widget instance. */ diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index 3c2d070fa0..9e0cb0f4f8 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -60,6 +60,7 @@ import com.google.gwt.user.client.ui.HasEnabled; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.ResizeComposite; import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.BrowserInfo; import com.vaadin.client.DeferredWorker; import com.vaadin.client.WidgetUtil; import com.vaadin.client.data.DataChangeHandler; @@ -2447,29 +2448,6 @@ public class Grid extends ResizeComposite implements applyColumnWidths(); } else { applyColumnWidthsWithExpansion(); - - /* - * [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: just - * dump all the remaining pixels into the last column and - * whistle loudly - */ - boolean dumpIntoLastColumn = false; - double escalatorWidth = escalator.getInnerWidth(); - double occupiedWidth = 0; - for (Column column : getColumns()) { - occupiedWidth += column.getWidthActual(); - if (column.getWidth() < 0 && column.getExpandRatio() != 0) { - dumpIntoLastColumn = true; - } - } - - if (dumpIntoLastColumn) { - Column lastColumn = getColumn(getColumnCount() - 1); - double width = Math.floor(lastColumn.getWidthActual() - + (escalatorWidth - occupiedWidth)); - escalator.getColumnConfiguration().setColumnWidth( - getColumnCount() - 1, width); - } } } @@ -2526,10 +2504,12 @@ public class Grid extends ResizeComposite implements } private void applyColumnWidthsWithExpansion() { - boolean someColumnExpands = false; + boolean defaultExpandRatios = true; int totalRatios = 0; double reservedPixels = 0; - final Set> columnsToExpand = new HashSet>(); + final Set> columnsToExpand = new HashSet>(); + List> nonFixedColumns = new ArrayList>(); + Map columnSizes = new HashMap(); /* * Set all fixed widths and also calculate the size-to-fit widths @@ -2538,49 +2518,37 @@ public class Grid extends ResizeComposite implements * This way we know with how many pixels we have left to expand the * rest. */ - for (Column column : getColumns()) { + for (Column column : getColumns()) { final double widthAsIs = column.getWidth(); final boolean isFixedWidth = widthAsIs >= 0; final double widthFixed = Math.max(widthAsIs, column.getMinimumWidth()); - final int expandRatio = column.getExpandRatio(); + defaultExpandRatios = defaultExpandRatios + && column.getExpandRatio() == -1; if (isFixedWidth) { - column.doSetWidth(widthFixed); + columnSizes.put(indexOfColumn(column), widthFixed); + reservedPixels += widthFixed; } else { - column.doSetWidth(-1); - final double newWidth = column.getWidthActual(); - final double maxWidth = getMaxWidth(column); - boolean shouldExpand = newWidth < maxWidth - && expandRatio > 0; - if (shouldExpand) { - totalRatios += expandRatio; - columnsToExpand.add(column); - someColumnExpands = true; - } + nonFixedColumns.add(column); + columnSizes.put(indexOfColumn(column), -1.0d); } - reservedPixels += column.getWidthActual(); } - /* - * If no column has a positive expand ratio, all columns with a - * negative expand ratio has an expand ratio. Columns with 0 expand - * ratio are excluded. - * - * This means that if we only define one column to have 0 expand, it - * will be the only one not to expand, while all the others expand. - */ - if (!someColumnExpands) { - assert totalRatios == 0 : "totalRatios should've been 0"; - assert columnsToExpand.isEmpty() : "columnsToExpand should've been empty"; - for (Column column : getColumns()) { - final double width = column.getWidth(); - final int expandRatio = column.getExpandRatio(); - if (width < 0 && expandRatio < 0) { - totalRatios++; - columnsToExpand.add(column); - } + setColumnSizes(columnSizes); + + for (Column column : nonFixedColumns) { + final int expandRatio = (defaultExpandRatios ? 1 : column + .getExpandRatio()); + final double newWidth = column.getWidthActual(); + final double maxWidth = getMaxWidth(column); + boolean shouldExpand = newWidth < maxWidth && expandRatio > 0; + if (shouldExpand) { + totalRatios += expandRatio; + columnsToExpand.add(column); } + reservedPixels += newWidth; + columnSizes.put(indexOfColumn(column), newWidth); } /* @@ -2588,8 +2556,7 @@ public class Grid extends ResizeComposite implements * can distribute the remaining pixels to all columns according to * their expand ratios. */ - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: ceil - double pixelsToDistribute = Math.ceil(escalator.getInnerWidth()) + double pixelsToDistribute = escalator.getInnerWidth() - reservedPixels; if (pixelsToDistribute <= 0 || totalRatios <= 0) { return; @@ -2603,30 +2570,30 @@ public class Grid extends ResizeComposite implements boolean aColumnHasMaxedOut; do { aColumnHasMaxedOut = false; - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME floor - final double widthPerRatio = Math.floor(pixelsToDistribute - / totalRatios); - final Iterator> i = columnsToExpand.iterator(); + final double widthPerRatio = pixelsToDistribute / totalRatios; + final Iterator> i = columnsToExpand.iterator(); while (i.hasNext()) { - final Column column = i.next(); + final Column column = i.next(); final int expandRatio = getExpandRatio(column, - someColumnExpands); - final double autoWidth = column.getWidthActual(); + defaultExpandRatios); + final double autoWidth = columnSizes + .get(indexOfColumn(column)); final double maxWidth = getMaxWidth(column); - final double widthCandidate = autoWidth + widthPerRatio + double expandedWidth = autoWidth + widthPerRatio * expandRatio; - if (maxWidth <= widthCandidate) { - column.doSetWidth(maxWidth); - totalRatios -= expandRatio; - pixelsToDistribute -= maxWidth - autoWidth; + if (maxWidth <= expandedWidth) { i.remove(); + totalRatios -= expandRatio; aColumnHasMaxedOut = true; + pixelsToDistribute -= maxWidth - autoWidth; + columnSizes.put(indexOfColumn(column), maxWidth); } } } while (aColumnHasMaxedOut); if (totalRatios <= 0 && columnsToExpand.isEmpty()) { + setColumnSizes(columnSizes); return; } assert pixelsToDistribute > 0 : "We've run out of pixels to distribute (" @@ -2641,16 +2608,28 @@ public class Grid extends ResizeComposite implements * If we still have anything left, distribute the remaining pixels * to the remaining columns. */ - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: floor - final double widthPerRatio = Math.floor(pixelsToDistribute - / totalRatios); - for (Column column : columnsToExpand) { + final double widthPerRatio; + int leftOver = 0; + if (BrowserInfo.get().isIE8() || BrowserInfo.get().isIE9() + || BrowserInfo.getBrowserString().contains("PhantomJS")) { + // These browsers report subpixels as integers. this usually + // results into issues.. + widthPerRatio = (int) (pixelsToDistribute / totalRatios); + leftOver = (int) (pixelsToDistribute - widthPerRatio + * totalRatios); + } else { + widthPerRatio = pixelsToDistribute / totalRatios; + } + for (Column column : columnsToExpand) { final int expandRatio = getExpandRatio(column, - someColumnExpands); - final double autoWidth = column.getWidthActual(); - final double totalWidth = autoWidth + widthPerRatio - * expandRatio; - column.doSetWidth(totalWidth); + defaultExpandRatios); + final double autoWidth = columnSizes.get(indexOfColumn(column)); + double totalWidth = autoWidth + widthPerRatio * expandRatio; + if (leftOver > 0) { + totalWidth += 1; + leftOver--; + } + columnSizes.put(indexOfColumn(column), totalWidth); totalRatios -= expandRatio; } @@ -2679,12 +2658,12 @@ public class Grid extends ResizeComposite implements * wouldn't show up in that set. */ - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME ceil - double minWidth = Math.ceil(getMinWidth(column)); - double currentWidth = column.getWidthActual(); + double minWidth = getMinWidth(column); + double currentWidth = columnSizes + .get(indexOfColumn(column)); boolean hasAutoWidth = column.getWidth() < 0; if (hasAutoWidth && currentWidth < minWidth) { - column.doSetWidth(minWidth); + columnSizes.put(indexOfColumn(column), minWidth); pixelsToRemoveFromOtherColumns += (minWidth - currentWidth); minWidthsCausedReflows = true; @@ -2703,27 +2682,36 @@ public class Grid extends ResizeComposite implements */ totalRatios = 0; for (Column column : columnsToExpand) { - totalRatios += getExpandRatio(column, someColumnExpands); + totalRatios += getExpandRatio(column, defaultExpandRatios); } - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: ceil - final double pixelsToRemovePerRatio = Math - .ceil(pixelsToRemoveFromOtherColumns / totalRatios); - for (Column column : columnsToExpand) { + final double pixelsToRemovePerRatio = pixelsToRemoveFromOtherColumns + / totalRatios; + for (Column column : columnsToExpand) { final double pixelsToRemove = pixelsToRemovePerRatio - * getExpandRatio(column, someColumnExpands); - column.doSetWidth(column.getWidthActual() - pixelsToRemove); + * getExpandRatio(column, defaultExpandRatios); + int colIndex = indexOfColumn(column); + columnSizes.put(colIndex, columnSizes.get(colIndex) + - pixelsToRemove); } } while (minWidthsCausedReflows); + + // Finally set all the column sizes. + setColumnSizes(columnSizes); + } + + private void setColumnSizes(Map columnSizes) { + // Set all widths at once + escalator.getColumnConfiguration().setColumnWidths(columnSizes); } private int getExpandRatio(Column column, - boolean someColumnExpands) { + boolean defaultExpandRatios) { int expandRatio = column.getExpandRatio(); if (expandRatio > 0) { return expandRatio; } else if (expandRatio < 0) { - assert !someColumnExpands : "No columns should've expanded"; + assert defaultExpandRatios : "No columns should've expanded"; return 1; } else { assert false : "this method should've not been called at all if expandRatio is 0"; @@ -6192,9 +6180,7 @@ public class Grid extends ResizeComposite implements @Override public void execute() { - if (!autoColumnWidthsRecalculator.isScheduled()) { - autoColumnWidthsRecalculator.schedule(); - } + recalculateColumnWidths(); } }); } diff --git a/uitest/src/com/vaadin/tests/components/grid/GridWidthIncreaseTest.java b/uitest/src/com/vaadin/tests/components/grid/GridWidthIncreaseTest.java index bf9110b01d..96b1a56fba 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridWidthIncreaseTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridWidthIncreaseTest.java @@ -16,12 +16,15 @@ package com.vaadin.tests.components.grid; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; + +import java.io.IOException; import org.junit.Test; +import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; public class GridWidthIncreaseTest extends MultiBrowserTest { @@ -29,28 +32,37 @@ public class GridWidthIncreaseTest extends MultiBrowserTest { private static int INCREASE_COUNT = 3; @Test - public void testColumnsExpandWithGrid() { + public void testColumnsExpandWithGrid() throws IOException { openTestURL(); GridElement grid = $(GridElement.class).first(); - int[] widths = new int[GridWidthIncrease.COLUMN_COUNT]; + double accuracy = 1.0d; + DesiredCapabilities cap = getDesiredCapabilities(); + if (BrowserUtil.isIE(cap, 8) || BrowserUtil.isIE(cap, 9) + || BrowserUtil.isPhantomJS(cap)) { + accuracy = 2.0d; + } + for (int i = 0; i < INCREASE_COUNT; ++i) { - int totalWidth = 0; $(ButtonElement.class).first().click(); + int prevWidth = 0; for (int c = 0; c < GridWidthIncrease.COLUMN_COUNT; ++c) { int width = grid.getCell(0, c).getSize().getWidth(); - totalWidth += width; - widths[c] = width; if (c > 0) { // check that columns are roughly the same width. - assertEquals("Difference in column widths", widths[c], - widths[c - 1], 1.0d); + assertEquals("Difference in column widths", prevWidth, + width, accuracy); } + prevWidth = width; } - // Column widths should be the same as table wrapper size - assertTrue(totalWidth == grid.getTableWrapper().getSize() - .getWidth()); + /* + * Column widths should be the same as table wrapper size. Since + * Selenium doesn't support subpixels correctly, we use a rough + * estimation. + */ + assertEquals(grid.getRow(0).getSize().getWidth(), grid + .getTableWrapper().getSize().getWidth(), accuracy); } } } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java index 2ba1dbc311..9e7256e0d3 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java @@ -145,14 +145,12 @@ public class GridClientColumnPropertiesTest extends GridBasicClientFeaturesTest gridElement = getGridElement(); headerCells = gridElement.getHeaderCells(0); final int size = headerCells.size(); - // skip last column since there is a bug in the width of the last column - for (int i = 0; i < size - 1; i++) { + for (int i = 0; i < size; i++) { + // Avoid issues with inaccuracies regarding subpixels. assertEquals( "Column widths don't match after reset, index after flip " - + i, - columnWidths.get(i), - Integer.valueOf(headerCells.get(size - 1 - i).getSize() - .getWidth())); + + i, columnWidths.get(i), + headerCells.get(size - 1 - i).getSize().getWidth(), 1.0d); } } -- 2.39.5