*/
public void recalculateScrollbarsForVirtualViewport() {
int scrollContentHeight = body.calculateEstimatedTotalRowHeight();
- int scrollContentWidth = columnConfiguration.calculateRowWidth();
+ double scrollContentWidth = columnConfiguration.calculateRowWidth();
double tableWrapperHeight = heightOfEscalator;
double tableWrapperWidth = widthOfEscalator;
*/
double prevScrollPos = horizontalScrollbar.getScrollPos();
- int unfrozenPixels = columnConfiguration
+ double unfrozenPixels = columnConfiguration
.getCalculatedColumnsWidth(Range.between(
columnConfiguration.getFrozenColumnCount(),
columnConfiguration.getColumnCount()));
- int frozenPixels = scrollContentWidth - unfrozenPixels;
+ double frozenPixels = scrollContentWidth - unfrozenPixels;
double hScrollOffsetWidth = tableWrapperWidth - frozenPixels;
horizontalScrollbar.setOffsetSize(hScrollOffsetWidth);
horizontalScrollbar.setScrollSize(unfrozenPixels);
* structure effectively means that scrollLeft also ignores the
* frozen columns.
*/
- final int frozenPixels = columnConfiguration
+ final double frozenPixels = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(0,
columnConfiguration.frozenColumns));
- final int targetStartPx = columnConfiguration
+ final double targetStartPx = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(0, columnIndex))
- frozenPixels;
- final int targetEndPx = targetStartPx
+ final double targetEndPx = targetStartPx
+ columnConfiguration.getColumnWidthActual(columnIndex);
final double viewportStartPx = getScrollLeft();
double viewportEndPx = viewportStartPx
- + getElement().getOffsetWidth() - frozenPixels;
+ + getPreciseWidth(getElement()) - frozenPixels;
if (verticalScrollbar.showsScrollHandle()) {
viewportEndPx -= Util.getNativeScrollbarSize();
}
tr.addClassName(getStylePrimaryName() + "-row");
for (int col = 0; col < columnConfiguration.getColumnCount(); col++) {
- final int colWidth = columnConfiguration
+ final double colWidth = columnConfiguration
.getColumnWidthActual(col);
final TableCellElement cellElem = createCellElement(
rowHeight, colWidth);
* @return a set-up empty cell element
*/
public TableCellElement createCellElement(final int height,
- final int width) {
+ final double colWidth) {
final TableCellElement cellElem = TableCellElement.as(DOM
.createElement(getCellElementTagName()));
cellElem.getStyle().setHeight(height, Unit.PX);
- cellElem.getStyle().setWidth(width, Unit.PX);
+ cellElem.getStyle().setWidth(colWidth, Unit.PX);
cellElem.addClassName(getStylePrimaryName() + "-cell");
return cellElem;
}
final int rowHeight = getDefaultRowHeight();
for (FlyweightCell cell : cells) {
- final int colWidth = columnConfiguration
+ final double colWidth = columnConfiguration
.getColumnWidthActual(cell.getColumn());
final TableCellElement cellElem = createCellElement(rowHeight,
colWidth);
* the index of the column to inspect
* @return the pixel width of the widest element in the indicated column
*/
- public int calculateMaxColWidth(int index) {
+ public double calculateMaxColWidth(int index) {
TableRowElement row = TableRowElement.as(root
.getFirstChildElement());
- int maxWidth = 0;
+ double maxWidth = 0;
while (row != null) {
final TableCellElement cell = row.getCells().getItem(index);
final boolean isVisible = !cell.getStyle().getDisplay()
.equals(Display.NONE.getCssName());
if (isVisible) {
- maxWidth = Math.max(maxWidth, cell.getScrollWidth());
+ maxWidth = Math.max(maxWidth, getPreciseWidth(cell));
}
row = TableRowElement.as(row.getNextSiblingElement());
}
Element cell = row.getFirstChildElement();
int columnIndex = 0;
while (cell != null) {
- final int width = getCalculatedColumnWidthWithColspan(cell,
- columnIndex);
+ final double width = getCalculatedColumnWidthWithColspan(
+ cell, columnIndex);
/*
* TODO Should Escalator implement ProvidesResize at some
reapplyRowWidths();
}
- private int getCalculatedColumnWidthWithColspan(final Element cell,
+ private double getCalculatedColumnWidthWithColspan(final Element cell,
final int columnIndex) {
final int colspan = cell.getPropertyInt(FlyweightCell.COLSPAN_ATTR);
Range spannedColumns = Range.withLength(columnIndex, colspan);
* cells within.
*/
protected void reapplyRowWidths() {
- int rowWidth = columnConfiguration.calculateRowWidth();
+ double rowWidth = columnConfiguration.calculateRowWidth();
com.google.gwt.dom.client.Element row = root.getFirstChildElement();
while (row != null) {
return new Cell(domRowIndex, domColumnIndex, cellElement);
}
- int getMaxCellWidth(int colIndex) throws IllegalArgumentException {
- int maxCellWidth = -1;
+ double getMaxCellWidth(int colIndex) throws IllegalArgumentException {
+ double maxCellWidth = -1;
assert isAttached() : "Can't measure max width of cell, since Escalator is not attached to the DOM.";
cellClone.getStyle().clearWidth();
rowElement.insertBefore(cellClone, cellOriginal);
- maxCellWidth = Math.max(cellClone.getOffsetWidth(),
+ maxCellWidth = Math.max(getPreciseWidth(cellClone),
maxCellWidth);
cellClone.removeFromParent();
}
public class Column {
private static final int DEFAULT_COLUMN_WIDTH_PX = 100;
- private int definedWidth = -1;
- private int calculatedWidth = DEFAULT_COLUMN_WIDTH_PX;
+ private double definedWidth = -1;
+ private double calculatedWidth = DEFAULT_COLUMN_WIDTH_PX;
private boolean measuringRequested = false;
/**
*/
private boolean widthHasBeenFinalized = false;
- public void setWidth(int px) {
+ public void setWidth(double px) {
definedWidth = px;
if (px < 0) {
}
}
- public int getDefinedWidth() {
+ public double getDefinedWidth() {
return definedWidth;
}
* @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 double getCalculatedWidth() {
/*
* This might return an untrue value (e.g. during init/onload),
* since we haven't had a proper chance to actually calculate
*
* @see #getCalculatedColumnWidths()
*/
- private int[] widthsArray = null;
+ private double[] widthsArray = null;
/**
* {@inheritDoc}
*
* @return the width of a row, in pixels
*/
- public int calculateRowWidth() {
+ public double calculateRowWidth() {
return getCalculatedColumnsWidth(Range.between(0, getColumnCount()));
}
}
// Adjust scrollbar
- int pixelsToInsertedColumn = columnConfiguration
+ double pixelsToInsertedColumn = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(0, index));
final boolean columnsWereAddedToTheLeftOfViewport = scroller.lastScrollLeft > pixelsToInsertedColumn;
if (columnsWereAddedToTheLeftOfViewport) {
- int insertedColumnsWidth = columnConfiguration
+ double insertedColumnsWidth = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(index,
numberOfColumns));
horizontalScrollbar.setScrollPos(scroller.lastScrollLeft
}
@Override
- public void setColumnWidth(int index, int px)
+ public void setColumnWidth(int index, double px)
throws IllegalArgumentException {
checkValidColumnIndex(index);
}
@Override
- public int getColumnWidth(int index) throws IllegalArgumentException {
+ public double getColumnWidth(int index) throws IllegalArgumentException {
checkValidColumnIndex(index);
return columns.get(index).getDefinedWidth();
}
@Override
- public int getColumnWidthActual(int index) {
+ public double getColumnWidthActual(int index) {
return columns.get(index).getCalculatedWidth();
}
- private int getMaxCellWidth(int colIndex)
+ private double getMaxCellWidth(int colIndex)
throws IllegalArgumentException {
- int headerWidth = header.getMaxCellWidth(colIndex);
- int bodyWidth = body.getMaxCellWidth(colIndex);
- int footerWidth = footer.getMaxCellWidth(colIndex);
+ double headerWidth = header.getMaxCellWidth(colIndex);
+ double bodyWidth = body.getMaxCellWidth(colIndex);
+ double footerWidth = footer.getMaxCellWidth(colIndex);
- int maxWidth = Math.max(headerWidth,
+ double maxWidth = Math.max(headerWidth,
Math.max(bodyWidth, footerWidth));
- assert maxWidth > 0 : "Got a negative max width for a column, which should be impossible.";
+ assert maxWidth >= 0 : "Got a negative max width for a column, which should be impossible.";
return maxWidth;
}
* @return the total width of the columns in the given
* <code>columns</code>
*/
- int getCalculatedColumnsWidth(final Range columns) {
+ double getCalculatedColumnsWidth(final Range columns) {
/*
* This is an assert instead of an exception, since this is an
* internal method.
+ ", but was given :"
+ columns;
- int sum = 0;
+ double sum = 0;
for (int i = columns.getStart(); i < columns.getEnd(); i++) {
- int columnWidthActual = getColumnWidthActual(i);
+ double columnWidthActual = getColumnWidthActual(i);
sum += columnWidthActual;
}
return sum;
}
- int[] getCalculatedColumnWidths() {
+ double[] getCalculatedColumnWidths() {
if (widthsArray == null || widthsArray.length != getColumnCount()) {
- widthsArray = new int[getColumnCount()];
+ widthsArray = new double[getColumnCount()];
for (int i = 0; i < columns.size(); i++) {
widthsArray[i] = columns.get(i).getCalculatedWidth();
}
--- /dev/null
+/*
+ * 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.basicfeatures;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Random;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.data.sort.Sort;
+import com.vaadin.data.sort.SortOrder;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.SortOrderChangeEvent;
+import com.vaadin.event.SortOrderChangeEvent.SortOrderChangeListener;
+import com.vaadin.shared.ui.grid.GridStaticCellType;
+import com.vaadin.shared.ui.grid.HeightMode;
+import com.vaadin.shared.ui.grid.SortDirection;
+import com.vaadin.tests.components.AbstractComponentTest;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.CellStyleGenerator;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Grid.FooterCell;
+import com.vaadin.ui.Grid.HeaderCell;
+import com.vaadin.ui.Grid.HeaderRow;
+import com.vaadin.ui.Grid.MultiSelectionModel;
+import com.vaadin.ui.Grid.SelectionMode;
+<<<<<<< HEAD
+import com.vaadin.ui.renderer.DateRenderer;
+import com.vaadin.ui.renderer.HtmlRenderer;
+import com.vaadin.ui.renderer.NumberRenderer;
+=======
+import com.vaadin.ui.components.grid.SortOrderChangeEvent;
+import com.vaadin.ui.components.grid.SortOrderChangeListener;
+import com.vaadin.ui.components.grid.renderers.DateRenderer;
+import com.vaadin.ui.components.grid.renderers.HtmlRenderer;
+import com.vaadin.ui.components.grid.renderers.NumberRenderer;
+import com.vaadin.ui.components.grid.selection.MultiSelectionModel;
+import com.vaadin.ui.components.grid.sort.Sort;
+import com.vaadin.ui.components.grid.sort.SortOrder;
+>>>>>>> Columns can now have subpixel accuracy widths (#13334)
+
+/**
+ * Tests the basic features like columns, footers and headers
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class GridBasicFeatures extends AbstractComponentTest<Grid> {
+
+ private static final int MANUALLY_FORMATTED_COLUMNS = 5;
+ public static final int COLUMNS = 12;
+ public static final int ROWS = 1000;
+
+ private int columnGroupRows = 0;
+ private IndexedContainer ds;
+ private Grid grid;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Grid constructComponent() {
+
+ // Build data source
+ ds = new IndexedContainer() {
+ @Override
+ public List<Object> getItemIds(int startIndex, int numberOfIds) {
+ log("Requested items " + startIndex + " - "
+ + (startIndex + numberOfIds));
+ return super.getItemIds(startIndex, numberOfIds);
+ }
+ };
+
+ {
+ int col = 0;
+ for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; col++) {
+ ds.addContainerProperty(getColumnProperty(col), String.class,
+ "");
+ }
+
+ ds.addContainerProperty(getColumnProperty(col++), Integer.class,
+ Integer.valueOf(0));
+ ds.addContainerProperty(getColumnProperty(col++), Date.class,
+ new Date());
+ ds.addContainerProperty(getColumnProperty(col++), String.class, "");
+
+ // Random numbers
+ ds.addContainerProperty(getColumnProperty(col++), Integer.class, 0);
+ ds.addContainerProperty(getColumnProperty(col++), Integer.class, 0);
+
+ }
+
+ {
+ Random rand = new Random();
+ rand.setSeed(13334);
+ long timestamp = 0;
+ for (int row = 0; row < ROWS; row++) {
+ Item item = ds.addItem(Integer.valueOf(row));
+ int col = 0;
+ for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; col++) {
+ item.getItemProperty(getColumnProperty(col)).setValue(
+ "(" + row + ", " + col + ")");
+ }
+ item.getItemProperty(getColumnProperty(1)).setReadOnly(true);
+
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ Integer.valueOf(row));
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ new Date(timestamp));
+ timestamp += 91250000; // a bit over a day, just to get
+ // variation
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ "<b>" + row + "</b>");
+
+ // Random numbers
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ rand.nextInt());
+ // Random between 0 - 5 to test multisorting
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ rand.nextInt(5));
+ }
+ }
+
+ // Create grid
+ Grid grid = new Grid(ds);
+
+ {
+ int col = grid.getContainerDataSource().getContainerPropertyIds()
+ .size()
+ - MANUALLY_FORMATTED_COLUMNS;
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new NumberRenderer(new DecimalFormat("0,000.00",
+ DecimalFormatSymbols.getInstance(new Locale("fi",
+ "FI")))));
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new DateRenderer(new SimpleDateFormat("dd.MM.yy HH:mm")));
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new HtmlRenderer());
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new NumberRenderer());
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new NumberRenderer());
+ }
+
+ // Create footer
+ grid.appendFooterRow();
+ grid.setFooterVisible(false);
+
+ // Add footer values (header values are automatically created)
+ for (int col = 0; col < COLUMNS; col++) {
+ grid.getFooterRow(0).getCell(getColumnProperty(col))
+ .setText("Footer " + col);
+ }
+
+ // Set varying column widths
+ for (int col = 0; col < COLUMNS; col++) {
+ grid.getColumn(getColumnProperty(col)).setWidth(100 + col * 50);
+ }
+
+ grid.addSortOrderChangeListener(new SortOrderChangeListener() {
+ @Override
+ public void sortOrderChange(SortOrderChangeEvent event) {
+
+ log("SortOrderChangeEvent: isUserOriginated? "
+ + event.isUserOriginated());
+ }
+ });
+
+ grid.setSelectionMode(SelectionMode.NONE);
+
+ grid.setPropertyEditable(getColumnProperty(3), false);
+
+ createGridActions();
+
+ createColumnActions();
+
+ createPropertyActions();
+
+ createHeaderActions();
+
+ createFooterActions();
+
+ createRowActions();
+
+ createEditorRowActions();
+
+ addHeightActions();
+
+ createClickAction("Column 1 starts with \"(23\"", "Filter",
+ new Command<Grid, Void>() {
+ @Override
+ public void execute(Grid grid, Void value, Object data) {
+ ds.addContainerFilter(new Filter() {
+
+ @Override
+ public boolean passesFilter(Object itemId, Item item)
+ throws UnsupportedOperationException {
+ return item.getItemProperty("Column 1")
+ .getValue().toString()
+ .startsWith("(23");
+ }
+
+ @Override
+ public boolean appliesToProperty(Object propertyId) {
+ return propertyId.equals("Column 1");
+ }
+ });
+ }
+ }, null);
+
+ this.grid = grid;
+ return grid;
+ }
+
+ protected void createGridActions() {
+ LinkedHashMap<String, String> primaryStyleNames = new LinkedHashMap<String, String>();
+ primaryStyleNames.put("v-grid", "v-grid");
+ primaryStyleNames.put("v-escalator", "v-escalator");
+ primaryStyleNames.put("my-grid", "my-grid");
+
+ createMultiClickAction("Primary style name", "State",
+ primaryStyleNames, new Command<Grid, String>() {
+
+ @Override
+ public void execute(Grid grid, String value, Object data) {
+ grid.setPrimaryStyleName(value);
+
+ }
+ }, primaryStyleNames.get("v-grid"));
+
+ LinkedHashMap<String, SelectionMode> selectionModes = new LinkedHashMap<String, Grid.SelectionMode>();
+ selectionModes.put("single", SelectionMode.SINGLE);
+ selectionModes.put("multi", SelectionMode.MULTI);
+ selectionModes.put("none", SelectionMode.NONE);
+ createSelectAction("Selection mode", "State", selectionModes, "none",
+ new Command<Grid, Grid.SelectionMode>() {
+ @Override
+ public void execute(Grid grid, SelectionMode selectionMode,
+ Object data) {
+ grid.setSelectionMode(selectionMode);
+ }
+ });
+
+ LinkedHashMap<String, Integer> selectionLimits = new LinkedHashMap<String, Integer>();
+ selectionLimits.put("2", Integer.valueOf(2));
+ selectionLimits.put("1000", Integer.valueOf(1000));
+ selectionLimits.put("Integer.MAX_VALUE",
+ Integer.valueOf(Integer.MAX_VALUE));
+ createSelectAction("Selection limit", "State", selectionLimits, "1000",
+ new Command<Grid, Integer>() {
+ @Override
+ public void execute(Grid grid, Integer limit, Object data) {
+ if (!(grid.getSelectionModel() instanceof MultiSelectionModel)) {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ }
+
+ ((MultiSelectionModel) grid.getSelectionModel())
+ .setSelectionLimit(limit.intValue());
+ }
+ });
+
+ LinkedHashMap<String, List<SortOrder>> sortableProperties = new LinkedHashMap<String, List<SortOrder>>();
+ for (Object propertyId : ds.getSortableContainerPropertyIds()) {
+ sortableProperties.put(propertyId + ", ASC", Sort.by(propertyId)
+ .build());
+ sortableProperties.put(propertyId + ", DESC",
+ Sort.by(propertyId, SortDirection.DESCENDING).build());
+ }
+ createSelectAction("Sort by column", "State", sortableProperties,
+ "Column 9, ascending", new Command<Grid, List<SortOrder>>() {
+ @Override
+ public void execute(Grid grid, List<SortOrder> sortOrder,
+ Object data) {
+ grid.setSortOrder(sortOrder);
+ }
+ });
+
+ createBooleanAction("Reverse Grid Columns", "State", false,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid c, Boolean value, Object data) {
+ List<Object> ids = new ArrayList<Object>();
+ ids.addAll(ds.getContainerPropertyIds());
+ if (!value) {
+ c.setColumnOrder(ids.toArray());
+ } else {
+ Object[] idsArray = new Object[ids.size()];
+ for (int i = 0; i < ids.size(); ++i) {
+ idsArray[i] = ids.get((ids.size() - 1) - i);
+ }
+ c.setColumnOrder(idsArray);
+ }
+ }
+ });
+
+ LinkedHashMap<String, CellStyleGenerator> styleGenerators = new LinkedHashMap<String, CellStyleGenerator>();
+ styleGenerators.put("None", null);
+ styleGenerators.put("Row only", new CellStyleGenerator() {
+ @Override
+ public String getStyle(Grid grid, Object itemId, Object propertyId) {
+ if (propertyId == null) {
+ return "row" + itemId;
+ } else {
+ return null;
+ }
+ }
+ });
+ styleGenerators.put("Cell only", new CellStyleGenerator() {
+ @Override
+ public String getStyle(Grid grid, Object itemId, Object propertyId) {
+ if (propertyId == null) {
+ return null;
+ } else {
+ return propertyId.toString().replace(' ', '-');
+ }
+ }
+ });
+ styleGenerators.put("Combined", new CellStyleGenerator() {
+ @Override
+ public String getStyle(Grid grid, Object itemId, Object propertyId) {
+ int rowIndex = ((Integer) itemId).intValue();
+ if (propertyId == null) {
+ if (rowIndex % 4 == 0) {
+ return null;
+ } else {
+ return "row" + itemId;
+ }
+ } else {
+ if (rowIndex % 4 == 1) {
+ return null;
+ } else if (rowIndex % 4 == 3
+ && "Column 1".equals(propertyId)) {
+ return null;
+ }
+ return propertyId.toString().replace(' ', '_');
+ }
+ }
+ });
+ createSelectAction("Style generator", "State", styleGenerators, "None",
+ new Command<Grid, CellStyleGenerator>() {
+ @Override
+ public void execute(Grid grid,
+ CellStyleGenerator generator, Object data) {
+ grid.setCellStyleGenerator(generator);
+ }
+ });
+
+ LinkedHashMap<String, Integer> frozenOptions = new LinkedHashMap<String, Integer>();
+ for (int i = -1; i <= COLUMNS; i++) {
+ frozenOptions.put(String.valueOf(i), Integer.valueOf(i));
+ }
+ createSelectAction("Frozen column count", "State", frozenOptions, "0",
+ new Command<Grid, Integer>() {
+ @Override
+ public void execute(Grid c, Integer value, Object data) {
+ c.setFrozenColumnCount(value.intValue());
+ }
+ });
+ }
+
+ protected void createHeaderActions() {
+ createCategory("Header", null);
+
+ createBooleanAction("Visible", "Header", true,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid grid, Boolean value, Object data) {
+ grid.setHeaderVisible(value);
+ }
+ });
+
+ LinkedHashMap<String, String> defaultRows = new LinkedHashMap<String, String>();
+ defaultRows.put("Top", "Top");
+ defaultRows.put("Bottom", "Bottom");
+ defaultRows.put("Unset", "Unset");
+
+ createMultiClickAction("Default row", "Header", defaultRows,
+ new Command<Grid, String>() {
+
+ @Override
+ public void execute(Grid grid, String value, Object data) {
+ HeaderRow defaultRow = null;
+ if (value.equals("Top")) {
+ defaultRow = grid.getHeaderRow(0);
+ } else if (value.equals("Bottom")) {
+ defaultRow = grid.getHeaderRow(grid
+ .getHeaderRowCount() - 1);
+ }
+ grid.setDefaultHeaderRow(defaultRow);
+ }
+
+ }, defaultRows.get("Top"));
+
+ createClickAction("Prepend row", "Header", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.prependHeaderRow();
+ }
+
+ }, null);
+ createClickAction("Append row", "Header", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.appendHeaderRow();
+ }
+
+ }, null);
+
+ createClickAction("Remove top row", "Header",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeHeaderRow(0);
+ }
+
+ }, null);
+ createClickAction("Remove bottom row", "Header",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeHeaderRow(grid.getHeaderRowCount() - 1);
+ }
+
+ }, null);
+ }
+
+ protected void createFooterActions() {
+ createCategory("Footer", null);
+
+ createBooleanAction("Visible", "Footer", false,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid grid, Boolean value, Object data) {
+ grid.setFooterVisible(value);
+ }
+ });
+
+ createClickAction("Prepend row", "Footer", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.prependFooterRow();
+ }
+
+ }, null);
+ createClickAction("Append row", "Footer", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.appendFooterRow();
+ }
+
+ }, null);
+
+ createClickAction("Remove top row", "Footer",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeFooterRow(0);
+ }
+
+ }, null);
+ createClickAction("Remove bottom row", "Footer",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeFooterRow(grid.getFooterRowCount() - 1);
+ }
+
+ }, null);
+ }
+
+ protected void createColumnActions() {
+ createCategory("Columns", null);
+
+ for (int c = 0; c < COLUMNS; c++) {
+ final int index = c;
+ createCategory(getColumnProperty(c), "Columns");
+
+ createClickAction("Add / Remove", getColumnProperty(c),
+ new Command<Grid, String>() {
+
+ @Override
+ public void execute(Grid grid, String value, Object data) {
+ String columnProperty = getColumnProperty((Integer) data);
+ if (grid.getColumn(columnProperty) == null) {
+ grid.addColumn(columnProperty);
+ } else {
+ grid.removeColumn(columnProperty);
+ }
+ }
+ }, null, c);
+
+ createBooleanAction("Sortable", getColumnProperty(c), true,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid grid, Boolean value,
+ Object columnIndex) {
+ Object propertyId = getColumnProperty((Integer) columnIndex);
+ Column column = grid.getColumn(propertyId);
+ column.setSortable(value);
+ }
+ }, c);
+
+ createCategory("Column " + c + " Width", getColumnProperty(c));
+
+ createClickAction("Auto", "Column " + c + " Width",
+ new Command<Grid, Integer>() {
+
+ @Override
+ public void execute(Grid grid, Integer value,
+ Object columnIndex) {
+ Object propertyId = getColumnProperty((Integer) columnIndex);
+ Column column = grid.getColumn(propertyId);
+ column.setWidthUndefined();
+ }
+ }, -1, c);
+
+ createClickAction("25.5px", "Column " + c + " Width",
+ new Command<Grid, Void>() {
+ @Override
+ @SuppressWarnings("boxing")
+ public void execute(Grid grid, Void value,
+ Object columnIndex) {
+ grid.getColumns().get((Integer) columnIndex)
+ .setWidth(25.5);
+ }
+ }, null, c);
+
+ for (int w = 50; w < 300; w += 50) {
+ createClickAction(w + "px", "Column " + c + " Width",
+ new Command<Grid, Integer>() {
+
+ @Override
+ public void execute(Grid grid, Integer value,
+ Object columnIndex) {
+ Object propertyId = getColumnProperty((Integer) columnIndex);
+ Column column = grid.getColumn(propertyId);
+ column.setWidth(value);
+ }
+ }, w, c);
+ }
+
+ LinkedHashMap<String, GridStaticCellType> defaultRows = new LinkedHashMap<String, GridStaticCellType>();
+ defaultRows.put("Text Header", GridStaticCellType.TEXT);
+ defaultRows.put("Html Header ", GridStaticCellType.HTML);
+ defaultRows.put("Widget Header", GridStaticCellType.WIDGET);
+
+ createMultiClickAction("Header Type", getColumnProperty(c),
+ defaultRows, new Command<Grid, GridStaticCellType>() {
+
+ @Override
+ public void execute(Grid grid,
+ GridStaticCellType value, Object columnIndex) {
+ final Object propertyId = getColumnProperty((Integer) columnIndex);
+ final HeaderCell cell = grid.getDefaultHeaderRow()
+ .getCell(propertyId);
+ switch (value) {
+ case TEXT:
+ cell.setText("Text Header");
+ break;
+ case HTML:
+ cell.setHtml("HTML Header");
+ break;
+ case WIDGET:
+ cell.setComponent(new Button("Button Header",
+ new ClickListener() {
+
+ @Override
+ public void buttonClick(
+ ClickEvent event) {
+ log("Button clicked!");
+ }
+ }));
+ default:
+ break;
+ }
+ }
+
+ }, c);
+
+ defaultRows = new LinkedHashMap<String, GridStaticCellType>();
+ defaultRows.put("Text Footer", GridStaticCellType.TEXT);
+ defaultRows.put("Html Footer", GridStaticCellType.HTML);
+ defaultRows.put("Widget Footer", GridStaticCellType.WIDGET);
+
+ createMultiClickAction("Footer Type", getColumnProperty(c),
+ defaultRows, new Command<Grid, GridStaticCellType>() {
+
+ @Override
+ public void execute(Grid grid,
+ GridStaticCellType value, Object columnIndex) {
+ final Object propertyId = getColumnProperty((Integer) columnIndex);
+ final FooterCell cell = grid.getFooterRow(0)
+ .getCell(propertyId);
+ switch (value) {
+ case TEXT:
+ cell.setText("Text Footer");
+ break;
+ case HTML:
+ cell.setHtml("HTML Footer");
+ break;
+ case WIDGET:
+ cell.setComponent(new Button("Button Footer",
+ new ClickListener() {
+
+ @Override
+ public void buttonClick(
+ ClickEvent event) {
+ log("Button clicked!");
+ }
+ }));
+ default:
+ break;
+ }
+ }
+
+ }, c);
+ }
+ }
+
+ private static String getColumnProperty(int c) {
+ return "Column " + c;
+ }
+
+ protected void createPropertyActions() {
+ createCategory("Properties", null);
+
+ createBooleanAction("Prepend property", "Properties", false,
+ new Command<Grid, Boolean>() {
+ private final Object propertyId = new Object();
+
+ @Override
+ public void execute(Grid c, Boolean enable, Object data) {
+ if (enable.booleanValue()) {
+ ds.addContainerProperty(propertyId, String.class,
+ "property value");
+ grid.getColumn(propertyId).setHeaderCaption(
+ "new property");
+ grid.setColumnOrder(propertyId);
+ } else {
+ ds.removeContainerProperty(propertyId);
+ }
+ }
+ }, null);
+ }
+
+ protected void createRowActions() {
+ createCategory("Body rows", null);
+
+ class NewRowCommand implements Command<Grid, String> {
+ private final int index;
+
+ public NewRowCommand() {
+ this(0);
+ }
+
+ public NewRowCommand(int index) {
+ this.index = index;
+ }
+
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Item item = ds.addItemAt(index, new Object());
+ for (int i = 0; i < COLUMNS; i++) {
+ Class<?> type = ds.getType(getColumnProperty(i));
+ if (String.class.isAssignableFrom(type)) {
+ Property<String> itemProperty = getProperty(item, i);
+ itemProperty.setValue("newcell: " + i);
+ } else if (Integer.class.isAssignableFrom(type)) {
+ Property<Integer> itemProperty = getProperty(item, i);
+ itemProperty.setValue(Integer.valueOf(i));
+ } else {
+ // let the default value be taken implicitly.
+ }
+ }
+ }
+
+ private <T extends Object> Property<T> getProperty(Item item, int i) {
+ @SuppressWarnings("unchecked")
+ Property<T> itemProperty = item
+ .getItemProperty(getColumnProperty(i));
+ return itemProperty;
+ }
+ }
+ final NewRowCommand newRowCommand = new NewRowCommand();
+
+ createClickAction("Add 18 rows", "Body rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ for (int i = 0; i < 18; i++) {
+ newRowCommand.execute(c, value, data);
+ }
+ }
+ }, null);
+
+ createClickAction("Add first row", "Body rows", newRowCommand, null);
+
+ createClickAction("Add second row", "Body rows", new NewRowCommand(1),
+ null);
+
+ createClickAction("Remove first row", "Body rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Object firstItemId = ds.getIdByIndex(0);
+ ds.removeItem(firstItemId);
+ }
+ }, null);
+
+ createClickAction("Remove 18 first rows", "Body rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ for (int i = 0; i < 18; i++) {
+ Object firstItemId = ds.getIdByIndex(0);
+ ds.removeItem(firstItemId);
+ }
+ }
+ }, null);
+
+ createClickAction("Modify first row (getItemProperty)", "Body rows",
+ new Command<Grid, String>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Object firstItemId = ds.getIdByIndex(0);
+ Item item = ds.getItem(firstItemId);
+ for (int i = 0; i < COLUMNS; i++) {
+ Property<?> property = item
+ .getItemProperty(getColumnProperty(i));
+ if (property.getType().equals(String.class)) {
+ ((Property<String>) property)
+ .setValue("modified: " + i);
+ }
+ }
+ }
+ }, null);
+
+ createClickAction("Modify first row (getContainerProperty)",
+ "Body rows", new Command<Grid, String>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Object firstItemId = ds.getIdByIndex(0);
+ for (Object containerPropertyId : ds
+ .getContainerPropertyIds()) {
+ Property<?> property = ds.getContainerProperty(
+ firstItemId, containerPropertyId);
+ if (property.getType().equals(String.class)) {
+ ((Property<String>) property)
+ .setValue("modified: "
+ + containerPropertyId);
+ }
+ }
+ }
+ }, null);
+
+ createBooleanAction("Select first row", "Body rows", false,
+ new Command<Grid, Boolean>() {
+ @Override
+ public void execute(Grid grid, Boolean select, Object data) {
+ final Object firstItemId = grid
+ .getContainerDataSource().firstItemId();
+ if (select.booleanValue()) {
+ grid.select(firstItemId);
+ } else {
+ grid.deselect(firstItemId);
+ }
+ }
+ });
+
+ createClickAction("Remove all rows", "Body rows",
+ new Command<Grid, String>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ ds.removeAllItems();
+ }
+ }, null);
+ }
+
+ protected void createEditorRowActions() {
+ createBooleanAction("Enabled", "Editor row", false,
+ new Command<Grid, Boolean>() {
+ @Override
+ public void execute(Grid c, Boolean value, Object data) {
+ c.setEditorRowEnabled(value);
+ }
+ });
+
+ createClickAction("Edit item 5", "Editor row",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.editItem(5);
+ }
+ }, null);
+
+ createClickAction("Edit item 100", "Editor row",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.editItem(100);
+ }
+ }, null);
+ createClickAction("Save", "Editor row", new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ try {
+ c.saveEditorRow();
+ } catch (CommitException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }, null);
+ createClickAction("Cancel edit", "Editor row",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.cancelEditorRow();
+ }
+ }, null);
+ }
+
+ @SuppressWarnings("boxing")
+ protected void addHeightActions() {
+ createCategory("Height by Rows", "Size");
+
+ createBooleanAction("HeightMode Row", "Size", false,
+ new Command<Grid, Boolean>() {
+ @Override
+ public void execute(Grid c, Boolean heightModeByRows,
+ Object data) {
+ c.setHeightMode(heightModeByRows ? HeightMode.ROW
+ : HeightMode.CSS);
+ }
+ }, null);
+
+ addActionForHeightByRows(1d / 3d);
+ addActionForHeightByRows(2d / 3d);
+
+ for (double i = 1; i < 5; i++) {
+ addActionForHeightByRows(i);
+ addActionForHeightByRows(i + 1d / 3d);
+ addActionForHeightByRows(i + 2d / 3d);
+ }
+
+ Command<Grid, String> sizeCommand = new Command<Grid, String>() {
+ @Override
+ public void execute(Grid grid, String height, Object data) {
+ grid.setHeight(height);
+ }
+ };
+
+ createCategory("Height", "Size");
+ // header 20px + scrollbar 16px = 36px baseline
+ createClickAction("86px (no drag scroll select)", "Height",
+ sizeCommand, "86px");
+ createClickAction("96px (drag scroll select limit)", "Height",
+ sizeCommand, "96px");
+ createClickAction("106px (drag scroll select enabled)", "Height",
+ sizeCommand, "106px");
+ }
+
+ private void addActionForHeightByRows(final Double i) {
+ DecimalFormat df = new DecimalFormat("0.00");
+ createClickAction(df.format(i) + " rows", "Height by Rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.setHeightByRows(i);
+ }
+ }, null);
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12829;
+ }
+
+ @Override
+ protected Class<Grid> getTestClass() {
+ return Grid.class;
+ }
+
+}