Browse Source

GridColumns can resize-to-fit. (#13334)

SelectionColumns do that now automatically.
Colspanned cells get ignored

Change-Id: Ie427ba8df43ad84786c381def8cec216297feb06
tags/7.4.0.beta1
Henrik Paul 9 years ago
parent
commit
1997cc53a5
20 changed files with 676 additions and 135 deletions
  1. 0
    13
      client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java
  2. 161
    78
      client/src/com/vaadin/client/ui/grid/Escalator.java
  3. 132
    17
      client/src/com/vaadin/client/ui/grid/Grid.java
  4. 0
    1
      client/src/com/vaadin/client/ui/grid/GridColumn.java
  5. 5
    2
      shared/src/com/vaadin/shared/ui/grid/GridColumnState.java
  6. 94
    0
      uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java
  7. 62
    0
      uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidth.java
  8. 35
    0
      uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClient.java
  9. 27
    0
      uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java
  10. 27
    0
      uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java
  11. 1
    0
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java
  12. 6
    3
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java
  13. 6
    5
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java
  14. 3
    2
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java
  15. 4
    0
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java
  16. 3
    2
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java
  17. 8
    1
      uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java
  18. 0
    11
      uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
  19. 31
    0
      uitest/src/com/vaadin/tests/widgetset/client/grid/GridColumnAutoWidthClientConnector.java
  20. 71
    0
      uitest/src/com/vaadin/tests/widgetset/client/grid/GridColumnAutoWidthClientWidget.java

+ 0
- 13
client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java View File

public void setColumnWidth(int index, int px) public void setColumnWidth(int index, int px)
throws IllegalArgumentException; throws IllegalArgumentException;


/**
* Sets the column width to as wide as the widest currently visible content
* in that column.
*
* @param index
* the index of the column for which to calculate the width.
* @throws IllegalArgumentException
* if {@code index} is not a valid column index, or if any cell
* in the given column is a part of a colspan range
*/
public void setColumnWidthToContent(int index)
throws IllegalArgumentException;

/** /**
* Returns the user-defined width of a column. * Returns the user-defined width of a column.
* *

+ 161
- 78
client/src/com/vaadin/client/ui/grid/Escalator.java View File

} }
} }


protected abstract class AbstractRowContainer implements RowContainer {
private class ColumnAutoWidthAssignScheduler {
private boolean isScheduled = false;
private final ScheduledCommand widthCommand = new ScheduledCommand() {
@Override
public void execute() {
if (!isScheduled) {
return;
}

isScheduled = false;

ColumnConfigurationImpl cc = columnConfiguration;
for (int col = 0; col < cc.getColumnCount(); col++) {
ColumnConfigurationImpl.Column column = cc.columns.get(col);
if (!column.isWidthFinalized()) {
cc.setColumnWidth(col, -1);
column.widthIsFinalized();
}
}
}
};


/**
* Calculates the widths of all uncalculated cells once the javascript
* execution is done.
* <p>
* This method makes sure that any duplicate requests in the same cycle
* are ignored.
*/
public void reschedule() {
if (!isScheduled) {
isScheduled = true;
Scheduler.get().scheduleFinally(widthCommand);
}
}

public void cancel() {
isScheduled = false;
}
}

protected abstract class AbstractRowContainer implements RowContainer {
private EscalatorUpdater updater = EscalatorUpdater.NULL; private EscalatorUpdater updater = EscalatorUpdater.NULL;


private int rows; private int rows;
*/ */
if (isAttached()) { if (isAttached()) {
paintInsertRows(index, numberOfRows); paintInsertRows(index, numberOfRows);

if (rows == numberOfRows) {
/*
* We are inserting the first rows in this container. We
* potentially need to autocalculate the widths for the
* cells for the first time.
*
* To make sure that can take the entire dataset into
* account, we'll do this deferredly, so that each container
* section gets populated before we start calculating.
*/
columnAutoWidthAssignScheduler.reschedule();
}
} }
} }


int getMaxCellWidth(int colIndex) throws IllegalArgumentException { int getMaxCellWidth(int colIndex) throws IllegalArgumentException {
int maxCellWidth = -1; int maxCellWidth = -1;


assert isAttached() : "Can't measure max width of cell, since Escalator is not attached to the DOM.";

NodeList<TableRowElement> rows = root.getRows(); NodeList<TableRowElement> rows = root.getRows();
for (int row = 0; row < rows.getLength(); row++) { for (int row = 0; row < rows.getLength(); row++) {
TableRowElement rowElement = rows.getItem(row); TableRowElement rowElement = rows.getItem(row);
colIndex); colIndex);


if (cellIsPartOfSpan(cellOriginal)) { if (cellIsPartOfSpan(cellOriginal)) {
throw new IllegalArgumentException("Encountered a column "
+ "spanned cell in column " + colIndex + ".");
continue;
} }


/* /*


private int definedWidth = -1; private int definedWidth = -1;
private int calculatedWidth = DEFAULT_COLUMN_WIDTH_PX; private int calculatedWidth = DEFAULT_COLUMN_WIDTH_PX;
private boolean measuringRequested = false;

/**
* If a column has been created (either via insertRow or
* insertColumn), it will be given an arbitrary width, and only then
* a width will be defined.
*/
private boolean widthHasBeenFinalized = false;


public void setWidth(int px) { public void setWidth(int px) {
definedWidth = px; definedWidth = px;
calculatedWidth = (px >= 0) ? px : DEFAULT_COLUMN_WIDTH_PX;

if (px < 0) {
if (isAttached()) {
calculateWidth();
} else {
/*
* the column's width is calculated at Escalator.onLoad
* via measureIfNeeded!
*/
measuringRequested = true;
}
} else {
calculatedWidth = px;
}
} }


public int getDefinedWidth() { public int getDefinedWidth() {
return definedWidth; return definedWidth;
} }


/**
* Returns the actual width in the DOM.
*
* @return the width in pixels in the DOM. Returns -1 if the column
* needs measuring, but has not been yet measured
*/
public int getCalculatedWidth() { public int getCalculatedWidth() {
return calculatedWidth;
/*
* This might return an untrue value (e.g. during init/onload),
* since we haven't had a proper chance to actually calculate
* widths yet.
*
* This is fixed during Escalator.onLoad, by the call to
* "measureIfNeeded", which fixes "everything".
*/
if (!measuringRequested) {
return calculatedWidth;
} else {
return -1;
}
}

/**
* Checks if the column needs measuring, and then measures it.
* <p>
* Called by {@link Escalator#onLoad()}.
*/
public boolean measureAndSetWidthIfNeeded() {
assert isAttached() : "Column.measureIfNeeded() was called even though Escalator was not attached!";

if (measuringRequested) {
measuringRequested = false;
setWidth(definedWidth);
return true;
}
return false;
}

private void calculateWidth() {
calculatedWidth = getMaxCellWidth(columns.indexOf(this));
}

public void widthIsFinalized() {
columnAutoWidthAssignScheduler.cancel();
widthHasBeenFinalized = true;
}

public boolean isWidthFinalized() {
return widthHasBeenFinalized;
} }
} }


body.paintInsertColumns(index, numberOfColumns, frozen); body.paintInsertColumns(index, numberOfColumns, frozen);
footer.paintInsertColumns(index, numberOfColumns, frozen); footer.paintInsertColumns(index, numberOfColumns, frozen);


// fix autowidth
if (header.getRowCount() > 0 || body.getRowCount() > 0
|| footer.getRowCount() > 0) {
for (int col = index; col < index + numberOfColumns; col++) {
getColumnConfiguration().setColumnWidth(col, -1);
columnConfiguration.columns.get(col).widthIsFinalized();
}
}

// Adjust scrollbar // Adjust scrollbar
int pixelsToInsertedColumn = columnConfiguration int pixelsToInsertedColumn = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(0, index)); .getCalculatedColumnsWidth(Range.withLength(0, index));
checkValidColumnIndex(index); checkValidColumnIndex(index);


columns.get(index).setWidth(px); columns.get(index).setWidth(px);
columns.get(index).widthIsFinalized();
widthsArray = null; widthsArray = null;


/* /*
return columns.get(index).getCalculatedWidth(); return columns.get(index).getCalculatedWidth();
} }


@Override
public void setColumnWidthToContent(int index)
throws IllegalArgumentException {

if (index < 0 || index >= getColumnCount()) {
throw new IllegalArgumentException(index
+ " is not a valid index for a column");
}

int maxWidth = getMaxCellWidth(index);

if (maxWidth == -1) {
return;
}

setCalculatedColumnWidth(index, maxWidth);
header.reapplyColumnWidths();
footer.reapplyColumnWidths();
body.reapplyColumnWidths();
}

private int getMaxCellWidth(int colIndex) private int getMaxCellWidth(int colIndex)
throws IllegalArgumentException { throws IllegalArgumentException {
int headerWidth = header.getMaxCellWidth(colIndex); int headerWidth = header.getMaxCellWidth(colIndex);
int bodyWidth = body.getMaxCellWidth(colIndex); int bodyWidth = body.getMaxCellWidth(colIndex);
int footerWidth = footer.getMaxCellWidth(colIndex); int footerWidth = footer.getMaxCellWidth(colIndex);
return Math.max(headerWidth, Math.max(bodyWidth, footerWidth));

int maxWidth = Math.max(headerWidth,
Math.max(bodyWidth, footerWidth));
assert maxWidth > 0 : "Got a negative max width for a column, which should be impossible.";
return maxWidth;
} }


/** /**


int sum = 0; int sum = 0;
for (int i = columns.getStart(); i < columns.getEnd(); i++) { for (int i = columns.getStart(); i < columns.getEnd(); i++) {
sum += getColumnWidthActual(i);
int columnWidthActual = getColumnWidthActual(i);
sum += columnWidthActual;
} }
return sum; return sum;
} }


void setCalculatedColumnWidth(int index, int width) {
columns.get(index).calculatedWidth = width;
widthsArray = null;
}

int[] getCalculatedColumnWidths() { int[] getCalculatedColumnWidths() {
if (widthsArray == null || widthsArray.length != getColumnCount()) { if (widthsArray == null || widthsArray.length != getColumnCount()) {
widthsArray = new int[getColumnCount()]; widthsArray = new int[getColumnCount()];
} }
}; };


private final ColumnAutoWidthAssignScheduler columnAutoWidthAssignScheduler = new ColumnAutoWidthAssignScheduler();

private static native double getPreciseWidth(Element element) private static native double getPreciseWidth(Element element)
/*-{ /*-{
if (element.getBoundingClientRect) { if (element.getBoundingClientRect) {
* rows. * rows.
*/ */


boolean columnsChanged = false;
for (ColumnConfigurationImpl.Column column : columnConfiguration.columns) {
boolean columnChanged = column.measureAndSetWidthIfNeeded();
if (columnChanged) {
columnsChanged = true;
}
}
if (columnsChanged) {
header.reapplyColumnWidths();
body.reapplyColumnWidths();
footer.reapplyColumnWidths();
}

scroller.attachScrollListener(verticalScrollbar.getElement()); scroller.attachScrollListener(verticalScrollbar.getElement());
scroller.attachScrollListener(horizontalScrollbar.getElement()); scroller.attachScrollListener(horizontalScrollbar.getElement());
scroller.attachMousewheelListener(getElement()); scroller.attachMousewheelListener(getElement());
return null; return null;
} }


/**
* Forces the escalator to recalculate the widths of its columns.
* <p>
* All columns that haven't been assigned an explicit width will be resized
* to fit all currently visible contents.
*
* @see ColumnConfiguration#setColumnWidth(int, int)
*/
public void calculateColumnWidths() {
boolean widthsHaveChanged = false;
for (int colIndex = 0; colIndex < columnConfiguration.getColumnCount(); colIndex++) {
if (columnConfiguration.getColumnWidth(colIndex) >= 0) {
continue;
}

final int oldColumnWidth = columnConfiguration
.getColumnWidthActual(colIndex);

int maxColumnWidth = 0;
maxColumnWidth = Math.max(maxColumnWidth,
header.calculateMaxColWidth(colIndex));
maxColumnWidth = Math.max(maxColumnWidth,
body.calculateMaxColWidth(colIndex));
maxColumnWidth = Math.max(maxColumnWidth,
footer.calculateMaxColWidth(colIndex));

Logger.getLogger("Escalator.calculateColumnWidths").info(
"#" + colIndex + ": " + maxColumnWidth + "px");

if (oldColumnWidth != maxColumnWidth) {
columnConfiguration.setCalculatedColumnWidth(colIndex,
maxColumnWidth);
widthsHaveChanged = true;
}
}

if (widthsHaveChanged) {
header.reapplyColumnWidths();
body.reapplyColumnWidths();
footer.reapplyColumnWidths();
recalculateElementSizes();
}
}

@Override @Override
public void setStylePrimaryName(String style) { public void setStylePrimaryName(String style) {
super.setStylePrimaryName(style); super.setStylePrimaryName(style);


@Override @Override
public boolean isWorkPending() { public boolean isWorkPending() {
return body.domSorter.waiting;
return body.domSorter.waiting
|| columnAutoWidthAssignScheduler.isScheduled;
} }


@Override @Override

+ 132
- 17
client/src/com/vaadin/client/ui/grid/Grid.java View File

import com.vaadin.client.ui.grid.sort.SortEvent; import com.vaadin.client.ui.grid.sort.SortEvent;
import com.vaadin.client.ui.grid.sort.SortHandler; import com.vaadin.client.ui.grid.sort.SortHandler;
import com.vaadin.client.ui.grid.sort.SortOrder; import com.vaadin.client.ui.grid.sort.SortOrder;
import com.vaadin.shared.ui.grid.GridColumnState;
import com.vaadin.shared.ui.grid.GridConstants; import com.vaadin.shared.ui.grid.GridConstants;
import com.vaadin.shared.ui.grid.GridStaticCellType; import com.vaadin.shared.ui.grid.GridStaticCellType;
import com.vaadin.shared.ui.grid.HeightMode; import com.vaadin.shared.ui.grid.HeightMode;
}); });
header.getDefaultRow().getCell(this).setWidget(checkBox); header.getDefaultRow().getCell(this).setWidget(checkBox);
} }

setWidth(-1);

initDone = true; initDone = true;
} }


} }
} }


private final class AsyncWidthAutodetectRunner {
private static final int POLLING_PERIOD_MS = 50;

private final Timer timer = new Timer() {
@Override
public void run() {
/* Detaching the column from the grid should've cancelled */
assert grid != null : "Column was detached from Grid before width autodetection completed";

/*
* setting a positive value for the width should've
* cancelled
*/
assert widthUser < 0 : "User defined width is not negative (to indicate autodetection) anymore!";

if (!grid.dataIsBeingFetched) {
setWidthForce(widthUser);
} else {
timer.schedule(POLLING_PERIOD_MS);
return;
}
}
};

/**
* Schedules an width autodetection.
* <p>
* It's not done immediately in case we're retrieving some lazy
* data, that will affect the appropriate width of the cells.
*/
public void reschedule() {
/*
* Check immediately. This will be _actually_ rescheduled if
* things don't work out. Otherwise, autodetectionage will
* happen.
*/
timer.schedule(0);
}

public void stop() {
timer.cancel();
}

public boolean isRunning() {
return timer.isRunning();
}
}

/** /**
* the column is associated with * the column is associated with
*/ */
private Grid<T> grid; private Grid<T> grid;


/** /**
* Width of column in pixels
* Should the column be visible in the grid
*/ */
private int width = 100;
private boolean visible = true;

/** Width of column in pixels as {@link #setWidth(int)} has been called */
private int widthUser = GridColumnState.DEFAULT_COLUMN_WIDTH_PX;


/** /**
* Renderer for rendering a value into the cell * Renderer for rendering a value into the cell


private String headerText = ""; private String headerText = "";


private final AsyncWidthAutodetectRunner asyncAutodetectWidth = new AsyncWidthAutodetectRunner();

/** /**
* Constructs a new column with a simple TextRenderer. * Constructs a new column with a simple TextRenderer.
*/ */
this.grid = grid; this.grid = grid;
if (grid != null) { if (grid != null) {
updateHeader(); updateHeader();
} else {
asyncAutodetectWidth.stop();
} }
} }


* @return the column itself * @return the column itself
*/ */
public GridColumn<C, T> setWidth(int pixels) { public GridColumn<C, T> setWidth(int pixels) {
width = pixels;
widthUser = pixels;
if (pixels < 0) {
setWidthAutodetect();
} else {
setWidthAbsolute(pixels);
}

return (GridColumn<C, T>) this;
}


private void setWidthAutodetect() {
if (grid != null) { if (grid != null) {
int index = grid.indexOfColumn((GridColumn<?, T>) this);
ColumnConfiguration conf = grid.escalator
.getColumnConfiguration();
conf.setColumnWidth(index, pixels);
asyncAutodetectWidth.reschedule();
} }


return (GridColumn<C, T>) this;
/*
* It's okay if the colum isn't attached to a grid immediately. The
* width will be re-set once it gets attached.
*/
}

private void setWidthAbsolute(int pixels) {
asyncAutodetectWidth.stop();
if (grid != null) {
setWidthForce(pixels);
}
}

private void setWidthForce(int pixels) {
int index = grid.columns.indexOf(this);
ColumnConfiguration conf = grid.escalator.getColumnConfiguration();
conf.setColumnWidth(index, pixels);
} }


/** /**
* Returns the pixel width of the column
* Returns the pixel width of the column as given by the user.
* <p>
* <em>Note:</em> If a negative value was given to
* {@link #setWidth(int)}, that same negative value is returned here.
* *
* @return pixel width of the column
* @return pixel width of the column, or a negative number if the column
* width has been automatically calculated.
* @see #setWidth(int)
* @see #getWidthActual()
*/ */
public int getWidth() { public int getWidth() {
return width;
return widthUser;
}

/**
* Returns the effective pixel width of the column.
* <p>
* This differs from {@link #getWidth()} only when the column has been
* automatically resized.
*
* @return pixel width of the column.
*/
public int getWidthActual() {
return grid.escalator.getColumnConfiguration()
.getColumnWidthActual(grid.columns.indexOf(this));
} }


void reapplyWidth() { void reapplyWidth() {
setWidth(width);
setWidth(getWidth());
} }


/** /**


return getClass().getSimpleName() + "[" + details.trim() + "]"; return getClass().getSimpleName() + "[" + details.trim() + "]";
} }

boolean widthCalculationPending() {
return asyncAutodetectWidth.isRunning();
}
} }


protected class BodyUpdater implements EscalatorUpdater { protected class BodyUpdater implements EscalatorUpdater {
body.removeRows(newSize, oldSize - newSize); body.removeRows(newSize, oldSize - newSize);
} }


dataIsBeingFetched = true;
Range visibleRowRange = escalator.getVisibleRowRange(); Range visibleRowRange = escalator.getVisibleRowRange();
dataSource.ensureAvailability(visibleRowRange.getStart(), dataSource.ensureAvailability(visibleRowRange.getStart(),
visibleRowRange.length()); visibleRowRange.length());
cellFocusHandler.offsetRangeBy(1); cellFocusHandler.offsetRangeBy(1);
selectionColumn = new SelectionColumn(selectColumnRenderer); selectionColumn = new SelectionColumn(selectColumnRenderer);


// FIXME: this needs to be done elsewhere, requires design...
selectionColumn.setWidth(40);
addColumnSkipSelectionColumnCheck(selectionColumn, 0); addColumnSkipSelectionColumnCheck(selectionColumn, 0);
selectionColumn.initDone(); selectionColumn.initDone();
} else { } else {
Scheduler.get().scheduleFinally(new ScheduledCommand() { Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override @Override
public void execute() { public void execute() {
handler.onDataAvailable(new DataAvailableEvent(
currentDataAvailable));
if (!dataIsBeingFetched) {
handler.onDataAvailable(new DataAvailableEvent(
currentDataAvailable));
}
} }
}); });
return addHandler(handler, DataAvailableEvent.TYPE); return addHandler(handler, DataAvailableEvent.TYPE);


@Override @Override
public boolean isWorkPending() { public boolean isWorkPending() {
return escalator.isWorkPending() || dataIsBeingFetched;
return escalator.isWorkPending() || dataIsBeingFetched
|| anyColumnIsBeingResized();
}

private boolean anyColumnIsBeingResized() {
for (AbstractGridColumn<?, ?> column : columns) {
if (column.widthCalculationPending()) {
return true;
}
}
return false;
} }


/** /**

+ 0
- 1
client/src/com/vaadin/client/ui/grid/GridColumn.java View File

*/ */
package com.vaadin.client.ui.grid; package com.vaadin.client.ui.grid;



/** /**
* Represents a column in the {@link Grid}. * Represents a column in the {@link Grid}.
* *

+ 5
- 2
shared/src/com/vaadin/shared/ui/grid/GridColumnState.java View File

*/ */
public class GridColumnState implements Serializable { public class GridColumnState implements Serializable {


public static final int DEFAULT_COLUMN_WIDTH_PX = -1;

/** /**
* Id used by grid connector to map server side column with client side * Id used by grid connector to map server side column with client side
* column * column
public String id; public String id;


/** /**
* Column width in pixels. Default column width is 100px.
* Column width in pixels. Default column width is
* {@value #DEFAULT_COLUMN_WIDTH_PX}.
*/ */
public int width = 100;
public int width = DEFAULT_COLUMN_WIDTH_PX;


/** /**
* The connector for the renderer used to render the cells in this column. * The connector for the renderer used to render the cells in this column.

+ 94
- 0
uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java View File

/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.grid;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.tests.tb3.MultiBrowserTest;

@SuppressWarnings("boxing")
public abstract class AbstractGridColumnAutoWidthTest extends MultiBrowserTest {

public static final int TOTAL_MARGIN_PX = 13;

@Before
public void before() {
openTestURL();
}

@Test
public void testNarrowHeaderWideBody() {
WebElement[] col = getColumn(1);
int headerWidth = col[0].getSize().getWidth();
int bodyWidth = col[1].getSize().getWidth();
int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX;

assertLessThan("header should've been narrower than body", headerWidth,
bodyWidth);
assertEquals("column should've been roughly as wide as the body",
bodyWidth, colWidth, 5);
}

@Test
public void testWideHeaderNarrowBody() {
WebElement[] col = getColumn(2);
int headerWidth = col[0].getSize().getWidth();
int bodyWidth = col[1].getSize().getWidth();
int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX;

assertGreater("header should've been wider than body", headerWidth,
bodyWidth);
assertEquals("column should've been roughly as wide as the header",
headerWidth, colWidth, 5);
}

@Test
public void testTooNarrowColumn() {
WebElement[] col = getColumn(3);
int headerWidth = col[0].getSize().getWidth();
int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX;

assertLessThan("column should've been narrower than content", colWidth,
headerWidth);
}

@Test
public void testTooWideColumn() {
WebElement[] col = getColumn(4);
int headerWidth = col[0].getSize().getWidth();
int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX;

assertGreater("column should've been wider than content", colWidth,
headerWidth);
}

private WebElement[] getColumn(int i) {
WebElement[] col = new WebElement[3];
col[0] = getDriver().findElement(
By.xpath("//thead//th[" + (i + 1) + "]/span"));
col[1] = getDriver().findElement(
By.xpath("//tbody//td[" + (i + 1) + "]/span"));
col[2] = getDriver().findElement(
By.xpath("//tbody//td[" + (i + 1) + "]"));
return col;
}

}

+ 62
- 0
uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidth.java View File

/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.grid;

import com.vaadin.data.Container;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.SelectionMode;
import com.vaadin.ui.components.grid.renderers.HtmlRenderer;

public class GridColumnAutoWidth extends AbstractTestUI {
@Override
protected void setup(VaadinRequest request) {
Grid grid = new Grid(createContainer());
grid.getColumn("fixed width narrow").setWidth(50);
grid.getColumn("fixed width wide").setWidth(200);

for (Object propertyId : grid.getContainerDataSource()
.getContainerPropertyIds()) {
Column column = grid.getColumn(propertyId);
column.setRenderer(new HtmlRenderer());
grid.getHeaderRow(0).getCell(propertyId)
.setHtml("<span>" + column.getHeaderCaption() + "</span>");
}

grid.setSelectionMode(SelectionMode.NONE);
grid.setWidth("700px");
addComponent(grid);
}

private static Container.Indexed createContainer() {
IndexedContainer c = new IndexedContainer();
c.addContainerProperty("equal width", String.class,
"<span>equal width</span>");
c.addContainerProperty("short", String.class,
"<span>a very long cell content</span>");
c.addContainerProperty("a very long header content", String.class,
"<span>short</span>");
c.addContainerProperty("fixed width narrow", String.class,
"<span>fixed width narrow</span>");
c.addContainerProperty("fixed width wide", String.class,
"<span>fixed width wide</span>");
c.addItem();
return c;
}
}

+ 35
- 0
uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClient.java View File

/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.grid;

import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.tests.widgetset.TestingWidgetSet;
import com.vaadin.ui.AbstractComponent;

@Widgetset(TestingWidgetSet.NAME)
public class GridColumnAutoWidthClient extends AbstractTestUI {

public static class GridColumnAutoWidthClientComponent extends
AbstractComponent {
}

@Override
protected void setup(VaadinRequest request) {
addComponent(new GridColumnAutoWidthClientComponent());
}
}

+ 27
- 0
uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java View File

/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.grid;

import com.vaadin.tests.annotations.TestCategory;

@TestCategory("grid")
public class GridColumnAutoWidthClientTest extends
AbstractGridColumnAutoWidthTest {
@Override
protected Class<?> getUIClass() {
return GridColumnAutoWidthClient.class;
}
}

+ 27
- 0
uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java View File

/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.grid;

import com.vaadin.tests.annotations.TestCategory;

@TestCategory("grid")
public class GridColumnAutoWidthServerTest extends
AbstractGridColumnAutoWidthTest {
@Override
protected Class<?> getUIClass() {
return GridColumnAutoWidth.class;
}
}

+ 1
- 0
uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java View File

protected static final String REMOVE_50_ROWS_FROM_ALMOST_BOTTOM = "Remove 50 rows from almost bottom"; protected static final String REMOVE_50_ROWS_FROM_ALMOST_BOTTOM = "Remove 50 rows from almost bottom";
protected static final String ADD_ONE_OF_EACH_ROW = "Add one of each row"; protected static final String ADD_ONE_OF_EACH_ROW = "Add one of each row";
protected static final String RESIZE_FIRST_COLUMN_TO_MAX_WIDTH = "Resize first column to max width"; protected static final String RESIZE_FIRST_COLUMN_TO_MAX_WIDTH = "Resize first column to max width";
protected static final String RESIZE_FIRST_COLUMN_TO_100PX = "Resize first column to 100 px";


protected static final String HEADER_ROWS = "Header Rows"; protected static final String HEADER_ROWS = "Header Rows";
protected static final String BODY_ROWS = "Body Rows"; protected static final String BODY_ROWS = "Body Rows";

+ 6
- 3
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java View File

} }


private void assertCellPresent(String content) { private void assertCellPresent(String content) {
assertNotNull(findByXPath("//td[text()='" + content + "']"));
assertNotNull("A cell with content \"" + content
+ "\" should've been found", findByXPath("//td[text()='"
+ content + "']"));
} }


private void assertCellNotPresent(String content) { private void assertCellNotPresent(String content) {
assertNull(findByXPath("//td[text()='" + content + "']"));
assertNull("A cell with content \"" + content
+ "\" should've not been found", findByXPath("//td[text()='"
+ content + "']"));
} }


private void scrollToTop() { private void scrollToTop() {
} }


private Object executeScript(String script, Object args) { private Object executeScript(String script, Object args) {
@SuppressWarnings("hiding")
final WebDriver driver = getDriver(); final WebDriver driver = getDriver();
if (driver instanceof JavascriptExecutor) { if (driver instanceof JavascriptExecutor) {
final JavascriptExecutor je = (JavascriptExecutor) driver; final JavascriptExecutor je = (JavascriptExecutor) driver;

+ 6
- 5
uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java View File

int width = getGridElement().getCell(0, col).getSize().getWidth(); int width = getGridElement().getCell(0, col).getSize().getWidth();
if (col <= 6) { if (col <= 6) {
// Growing column widths // Growing column widths
assertEquals(50 + col * 25, width);
} else {
assertEquals(100, width);
int expectedWidth = 50 + col * 25;
assertEquals("column " + col + " has incorrect width",
expectedWidth, width);
} }
} }
} }
assertEquals(200, width); assertEquals(200, width);


selectMenuPath("Component", "Columns", "Column 0", "Width", "auto"); selectMenuPath("Component", "Columns", "Column 0", "Width", "auto");
width = getGridElement().getCell(0, 0).getSize().getWidth();
assertEquals(100, width);
int autoWidth = getGridElement().getCell(0, 0).getSize().getWidth();
assertLessThan("Automatic sizing should've shrunk the column",
autoWidth, width);
} }


@Test @Test

+ 3
- 2
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java View File

openTestURL(); openTestURL();
populate(); populate();


int singleCellWidth = getWidth(getBodyCell(0, 0));
int doubleCellWidth = singleCellWidth * 2;
int firstCellWidth = getWidth(getBodyCell(0, 0));
int secondCellWidth = getWidth(getBodyCell(0, 1));
int doubleCellWidth = firstCellWidth + secondCellWidth;


selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL); selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL);



+ 4
- 0
uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java View File

openTestURL(); openTestURL();
selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); selectMenuPath(GENERAL, POPULATE_COLUMN_ROW);


selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, RESIZE_FIRST_COLUMN_TO_100PX);
int originalWidth = getBodyCell(0, 0).getSize().getWidth(); int originalWidth = getBodyCell(0, 0).getSize().getWidth();

assertEquals(100, originalWidth);

selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, selectMenuPath(COLUMNS_AND_ROWS, COLUMNS,
RESIZE_FIRST_COLUMN_TO_MAX_WIDTH); RESIZE_FIRST_COLUMN_TO_MAX_WIDTH);
int newWidth = getBodyCell(0, 0).getSize().getWidth(); int newWidth = getBodyCell(0, 0).getSize().getWidth();

+ 3
- 2
uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java View File

cell = getGridElement().getCell(0, 1); cell = getGridElement().getCell(0, 1);
assertEquals(150, cell.getSize().getWidth()); assertEquals(150, cell.getSize().getWidth());


// Set first column to be auto sized (defaults to 100px currently)
selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width", selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width",
"Auto"); "Auto");


// since the column 0 was previously 200, it should've shrunk when
// autoresizing.
cell = getGridElement().getCell(0, 0); cell = getGridElement().getCell(0, 0);
assertEquals(100, cell.getSize().getWidth());
assertLessThan("", cell.getSize().getWidth(), 200);
} }


@Test @Test

+ 8
- 1
uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java View File

@Override @Override
public void execute() { public void execute() {
escalator.getColumnConfiguration() escalator.getColumnConfiguration()
.setColumnWidthToContent(0);
.setColumnWidth(0, -1);
} }
}, menupath); }, menupath);

addMenuCommand("Resize first column to 100 px", new ScheduledCommand() {
@Override
public void execute() {
escalator.getColumnConfiguration().setColumnWidth(0, 100);
}
}, menupath);
} }


private void createHeaderRowsMenu() { private void createHeaderRowsMenu() {

+ 0
- 11
uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java View File

return columnConfiguration.getColumnWidthActual(index); return columnConfiguration.getColumnWidthActual(index);
} }


@Override
public void setColumnWidthToContent(int index)
throws IllegalArgumentException {
int oldWidth = columnConfiguration.getColumnWidthActual(index);
columnConfiguration.setColumnWidthToContent(index);
int newWidth = columnConfiguration.getColumnWidthActual(index);
logWidget.log("Changed column " + index + " width from " + oldWidth
+ "px to " + newWidth + "px");
logWidget.updateDebugLabel();
}

@Override @Override
public void refreshColumns(int index, int numberOfColumns) public void refreshColumns(int index, int numberOfColumns)
throws IndexOutOfBoundsException, IllegalArgumentException { throws IndexOutOfBoundsException, IllegalArgumentException {

+ 31
- 0
uitest/src/com/vaadin/tests/widgetset/client/grid/GridColumnAutoWidthClientConnector.java View File

/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.widgetset.client.grid;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.shared.ui.Connect;
import com.vaadin.tests.components.grid.GridColumnAutoWidthClient.GridColumnAutoWidthClientComponent;

@Connect(GridColumnAutoWidthClientComponent.class)
public class GridColumnAutoWidthClientConnector extends
AbstractComponentConnector {
@Override
public Widget getWidget() {
return GWT.create(GridColumnAutoWidthClientWidget.class);
}
}

+ 71
- 0
uitest/src/com/vaadin/tests/widgetset/client/grid/GridColumnAutoWidthClientWidget.java View File

/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.widgetset.client.grid;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.vaadin.client.ui.grid.Grid;
import com.vaadin.client.ui.grid.Grid.SelectionMode;
import com.vaadin.client.ui.grid.GridColumn;
import com.vaadin.client.ui.grid.datasources.ListDataSource;
import com.vaadin.client.ui.grid.renderers.HtmlRenderer;

public class GridColumnAutoWidthClientWidget extends
PureGWTTestApplication<Grid<List<String>>> {

private Grid<List<String>> grid;

private class Col extends GridColumn<String, List<String>> {
public Col(String header) {
super(header, new HtmlRenderer());
}

@Override
public String getValue(List<String> row) {
int index = grid.getColumns().indexOf(this);
return "<span>" + String.valueOf(row.get(index)) + "</span>";
}
}

protected GridColumnAutoWidthClientWidget() {
super(new Grid<List<String>>());
grid = getTestedWidget();
grid.setSelectionMode(SelectionMode.NONE);
grid.setWidth("700px");

List<List<String>> list = new ArrayList<List<String>>();
list.add(Arrays.asList("equal length", "a very long cell content",
"short", "fixed width narrow", "fixed width wide"));
grid.setDataSource(new ListDataSource<List<String>>(list));

addColumn("equal length");
addColumn("short");
addColumn("a very long header content");
addColumn("fixed width narrow").setWidth(50);
addColumn("fixed width wide").setWidth(200);

addNorth(grid, 400);
}

private Col addColumn(String header) {
Col column = (Col) grid.addColumn(new Col(header));
grid.getHeaderRow(0).getCell(column)
.setHtml("<span>" + header + "</span>");
return column;
}
}

Loading…
Cancel
Save