diff options
author | John Ahlroos <john@vaadin.com> | 2013-11-26 16:30:52 +0200 |
---|---|---|
committer | John Ahlroos <john@vaadin.com> | 2013-12-04 09:43:57 +0200 |
commit | 692ab52c37179870ac8011346c6deea164959208 (patch) | |
tree | 9b0a424cb3c4a7b91a81c37a78a982718b8c953e | |
parent | 076aa0e6201db1fe9345e256266cb9227384e290 (diff) | |
download | vaadin-framework-692ab52c37179870ac8011346c6deea164959208.tar.gz vaadin-framework-692ab52c37179870ac8011346c6deea164959208.zip |
Support widgets in Grid body row cells #12993
Change-Id: I8000efd86b5d860d241daea57f70a6626ca8d3dc
10 files changed, 304 insertions, 90 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/Cell.java b/client/src/com/vaadin/client/ui/grid/Cell.java index 09bc5da344..31156ffe7b 100644 --- a/client/src/com/vaadin/client/ui/grid/Cell.java +++ b/client/src/com/vaadin/client/ui/grid/Cell.java @@ -17,6 +17,7 @@ package com.vaadin.client.ui.grid; import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.HasOneWidget; /** * A representation of a single cell. @@ -27,7 +28,8 @@ import com.google.gwt.user.client.Element; * @since 7.2 * @author Vaadin Ltd */ -public interface Cell { +public interface Cell extends HasOneWidget { + /** * Gets the index of the row this cell is in. * diff --git a/client/src/com/vaadin/client/ui/grid/ColumnGroup.java b/client/src/com/vaadin/client/ui/grid/ColumnGroup.java index c37068def7..0b9cbee13c 100644 --- a/client/src/com/vaadin/client/ui/grid/ColumnGroup.java +++ b/client/src/com/vaadin/client/ui/grid/ColumnGroup.java @@ -29,7 +29,7 @@ import java.util.List; * @since 7.2 * @author Vaadin Ltd */ -public class ColumnGroup { +public class ColumnGroup<T> { /** * The text shown in the header @@ -45,7 +45,7 @@ public class ColumnGroup { * The columns included in the group when also accounting for subgroup * columns */ - private final List<GridColumn> columns; + private final List<GridColumn<?, T>> columns; /** * The grid associated with the column group @@ -55,14 +55,14 @@ public class ColumnGroup { /** * Constructs a new column group */ - ColumnGroup(Grid grid, Collection<GridColumn> columns) { + ColumnGroup(Grid grid, Collection<GridColumn<?, T>> columns) { if (columns == null) { throw new IllegalArgumentException( "columns cannot be null. Pass an empty list instead."); } this.grid = grid; - this.columns = Collections.unmodifiableList(new ArrayList<GridColumn>( - columns)); + this.columns = Collections + .unmodifiableList(new ArrayList<GridColumn<?, T>>(columns)); } /** @@ -111,7 +111,7 @@ public class ColumnGroup { * * @return unmodifiable list of columns */ - public List<GridColumn> getColumns() { + public List<GridColumn<?, T>> getColumns() { return columns; } } diff --git a/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java b/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java index 6bbc9bc9eb..113e0b34c6 100644 --- a/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java +++ b/client/src/com/vaadin/client/ui/grid/ColumnGroupRow.java @@ -27,20 +27,22 @@ import java.util.Set; * A column group row represents an auxiliary header or footer row added to the * grid. A column group row includes column groups that group columns together. * + * @param <T> + * Row type * @since 7.2 * @author Vaadin Ltd */ -public class ColumnGroupRow { +public class ColumnGroupRow<T> { /** * The column groups in this row */ - private List<ColumnGroup> groups = new ArrayList<ColumnGroup>(); + private List<ColumnGroup<T>> groups = new ArrayList<ColumnGroup<T>>(); /** * The grid associated with the column row */ - private final Grid grid; + private final Grid<T> grid; /** * Is the header shown @@ -59,7 +61,7 @@ public class ColumnGroupRow { * Grid associated with this column * */ - ColumnGroupRow(Grid grid) { + ColumnGroupRow(Grid<T> grid) { this.grid = grid; } @@ -71,9 +73,9 @@ public class ColumnGroupRow { * @return a column group representing the collection of columns added to * the group. */ - public ColumnGroup addGroup(GridColumn... columns) { + public ColumnGroup<T> addGroup(GridColumn<?, T>... columns) { - for (GridColumn column : columns) { + for (GridColumn<?, T> column : columns) { if (isColumnGrouped(column)) { throw new IllegalArgumentException("Column " + String.valueOf(column.getHeaderCaption()) @@ -81,7 +83,7 @@ public class ColumnGroupRow { } } - ColumnGroup group = new ColumnGroup(grid, Arrays.asList(columns)); + ColumnGroup<T> group = new ColumnGroup<T>(grid, Arrays.asList(columns)); groups.add(group); grid.refreshHeader(); grid.refreshFooter(); @@ -97,15 +99,15 @@ public class ColumnGroupRow { * the group. * */ - public ColumnGroup addGroup(ColumnGroup... groups) { + public ColumnGroup<T> addGroup(ColumnGroup<T>... groups) { assert groups != null : "groups cannot be null"; - Set<GridColumn> columns = new HashSet<GridColumn>(); - for (ColumnGroup group : groups) { + Set<GridColumn<?, T>> columns = new HashSet<GridColumn<?, T>>(); + for (ColumnGroup<T> group : groups) { columns.addAll(group.getColumns()); } - ColumnGroup group = new ColumnGroup(grid, columns); + ColumnGroup<T> group = new ColumnGroup<T>(grid, columns); this.groups.add(group); grid.refreshHeader(); grid.refreshFooter(); @@ -118,7 +120,7 @@ public class ColumnGroupRow { * @param group * The group to remove */ - public void removeGroup(ColumnGroup group) { + public void removeGroup(ColumnGroup<T> group) { groups.remove(group); grid.refreshHeader(); grid.refreshFooter(); @@ -129,7 +131,7 @@ public class ColumnGroupRow { * * @return unmodifiable list of groups in this row */ - public List<ColumnGroup> getGroups() { + public List<ColumnGroup<T>> getGroups() { return Collections.unmodifiableList(groups); } @@ -177,8 +179,8 @@ public class ColumnGroupRow { * Iterates all the column groups and checks if the columns alread has been * added to a group. */ - private boolean isColumnGrouped(GridColumn column) { - for (ColumnGroup group : groups) { + private boolean isColumnGrouped(GridColumn<?, T> column) { + for (ColumnGroup<T> group : groups) { if (group.getColumns().contains(column)) { return true; } diff --git a/client/src/com/vaadin/client/ui/grid/Escalator.java b/client/src/com/vaadin/client/ui/grid/Escalator.java index 2f5f28871b..e3aae2eb13 100644 --- a/client/src/com/vaadin/client/ui/grid/Escalator.java +++ b/client/src/com/vaadin/client/ui/grid/Escalator.java @@ -246,10 +246,6 @@ public class Escalator extends Widget { * escalator DOM). NOTE: these bits can most often also be identified by * searching for code that call scrollElem.getScrollTop();. */ - /* - * [[widgets]]: This needs to be re-inspected once GWT/Vaadin widgets are - * being supported. - */ /** * A utility class that contains utility methods that are usually called @@ -1236,8 +1232,9 @@ public class Escalator extends Widget { final Node tr = childNodes.getItem(visualRowIndex); for (int column = 0; column < numberOfColumns; column++) { - // TODO [[widgets]] - tr.getChild(offset).removeFromParent(); + Element cellElement = tr.getChild(offset).cast(); + detachPossibleWidgetFromCell(cellElement); + cellElement.removeFromParent(); } recalculateRowWidth((Element) tr); } @@ -1269,6 +1266,18 @@ public class Escalator extends Widget { } } + void detachPossibleWidgetFromCell(Node cellNode) { + // Detach possible widget + Widget widget = getWidgetFromCell(cellNode); + if (widget != null) { + // Orphan. + setParent(widget, null); + + // Physical detach. + cellNode.removeChild(widget.getElement()); + } + } + protected void paintInsertColumns(final int offset, final int numberOfColumns, boolean frozen) { final NodeList<Node> childNodes = root.getChildNodes(); @@ -1370,7 +1379,10 @@ public class Escalator extends Widget { protected void paintRemoveRows(final int index, final int numberOfRows) { for (int i = index; i < index + numberOfRows; i++) { final Element tr = (Element) root.getChild(index); - // TODO [[widgets]] + for (int c = 0; c < tr.getChildCount(); c++) { + detachPossibleWidgetFromCell((Element) tr.getChild(c) + .cast()); + } tr.removeFromParent(); } recalculateSectionHeight(); @@ -1935,7 +1947,10 @@ public class Escalator extends Widget { for (int i = 0; i < escalatorRowsToRemove; i++) { final Element tr = visualRowOrder .remove(removedVisualInside.getStart()); - // TODO [[widgets]] + for (int c = 0; c < tr.getChildCount(); c++) { + detachPossibleWidgetFromCell((Element) tr.getChild( + c).cast()); + } tr.removeFromParent(); rowTopPosMap.remove(tr); } @@ -2429,8 +2444,11 @@ public class Escalator extends Widget { final ListIterator<Element> iter = visualRowOrder .listIterator(visualRowOrder.size()); for (int i = 0; i < -neededEscalatorRowsDiff; i++) { - // TODO [[widgets]] final Element last = iter.previous(); + for (int c = 0; c < last.getChildCount(); c++) { + detachPossibleWidgetFromCell((Element) last.getChild(c) + .cast()); + } last.removeFromParent(); iter.remove(); } @@ -3177,4 +3195,33 @@ public class Escalator extends Widget { fireEvent(new RowVisibilityChangeEvent(visibleRangeStart, visibleRowCount)); } + + /** + * Accesses the package private method Widget#setParent() + * + * @param widget + * The widget to access + * @param parent + * The parent to set + */ + static native final void setParent(Widget widget, Widget parent) + /*-{ + widget.@com.google.gwt.user.client.ui.Widget::setParent(Lcom/google/gwt/user/client/ui/Widget;)(parent); + }-*/; + + /** + * Returns the widget from a cell node or <code>null</code> if there is no + * widget in the cell + * + * @param cellNode + * The cell node + */ + static Widget getWidgetFromCell(Node cellNode) { + Node possibleWidgetNode = cellNode.getFirstChild(); + if (possibleWidgetNode != null + && possibleWidgetNode.getNodeType() == Node.ELEMENT_NODE) { + return Util.findWidget((Element) possibleWidgetNode, null); + } + return null; + } } diff --git a/client/src/com/vaadin/client/ui/grid/FlyweightCell.java b/client/src/com/vaadin/client/ui/grid/FlyweightCell.java index 08c27fa859..3613e73aff 100644 --- a/client/src/com/vaadin/client/ui/grid/FlyweightCell.java +++ b/client/src/com/vaadin/client/ui/grid/FlyweightCell.java @@ -19,7 +19,10 @@ import java.util.List; import com.google.gwt.dom.client.Style.Display; import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ui.grid.FlyweightRow.CellIterator; /** @@ -39,11 +42,16 @@ class FlyweightCell implements Cell { private final int column; private final FlyweightRow row; + private CellIterator currentIterator = null; - public FlyweightCell(final FlyweightRow row, final int column) { + private final Escalator escalator; + + public FlyweightCell(final FlyweightRow row, final int column, + Escalator escalator) { this.row = row; this.column = column; + this.escalator = escalator; } @Override @@ -146,4 +154,50 @@ class FlyweightCell implements Cell { } } } + + @Override + public Widget getWidget() { + return Escalator.getWidgetFromCell(getElement()); + } + + @Override + public void setWidget(Widget widget) { + + Widget oldWidget = getWidget(); + + // Validate + if (oldWidget == widget) { + return; + } + + // Detach old child. + if (oldWidget != null) { + // Orphan. + Escalator.setParent(oldWidget, null); + + // Physical detach. + getElement().removeChild(oldWidget.getElement()); + } + + // Remove any previous text nodes from previous + // setInnerText/setInnerHTML + getElement().removeAllChildren(); + + // Attach new child. + if (widget != null) { + // Detach new child from old parent. + widget.removeFromParent(); + + // Physical attach. + DOM.appendChild(getElement(), widget.getElement()); + + Escalator.setParent(widget, escalator); + } + } + + @Override + public void setWidget(IsWidget w) { + setWidget(Widget.asWidgetOrNull(w)); + } + } diff --git a/client/src/com/vaadin/client/ui/grid/FlyweightRow.java b/client/src/com/vaadin/client/ui/grid/FlyweightRow.java index fc1c977052..c386b7dd1f 100644 --- a/client/src/com/vaadin/client/ui/grid/FlyweightRow.java +++ b/client/src/com/vaadin/client/ui/grid/FlyweightRow.java @@ -157,7 +157,7 @@ class FlyweightRow implements Row { void addCells(final int index, final int numberOfColumns) { for (int i = 0; i < numberOfColumns; i++) { final int col = index + i; - cells.add(col, new FlyweightCell(this, col)); + cells.add(col, new FlyweightCell(this, col, escalator)); } updateRestOfCells(index + numberOfColumns); } @@ -172,7 +172,7 @@ class FlyweightRow implements Row { private void updateRestOfCells(final int startPos) { // update the column number for the cells to the right for (int col = startPos; col < cells.size(); col++) { - cells.set(col, new FlyweightCell(this, col)); + cells.set(col, new FlyweightCell(this, col, escalator)); } } diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java index 66f37c7620..25e6596a35 100644 --- a/client/src/com/vaadin/client/ui/grid/Grid.java +++ b/client/src/com/vaadin/client/ui/grid/Grid.java @@ -21,6 +21,7 @@ import java.util.List; import com.google.gwt.core.shared.GWT; import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.data.DataChangeHandler; import com.vaadin.client.data.DataSource; import com.vaadin.shared.util.SharedUtil; @@ -64,14 +65,14 @@ public class Grid<T> extends Composite { /** * List of columns in the grid. Order defines the visible order. */ - private final List<GridColumn<T>> columns = new ArrayList<GridColumn<T>>(); + private final List<GridColumn<?, T>> columns = new ArrayList<GridColumn<?, T>>(); private DataSource<T> dataSource; /** * The column groups rows added to the grid */ - private final List<ColumnGroupRow> columnGroupRows = new ArrayList<ColumnGroupRow>(); + private final List<ColumnGroupRow<T>> columnGroupRows = new ArrayList<ColumnGroupRow<T>>(); /** * Are the headers for the columns visible @@ -83,16 +84,19 @@ public class Grid<T> extends Composite { */ private boolean columnFootersVisible = false; - private GridColumn<T> lastFrozenColumn; + private GridColumn<?, T> lastFrozenColumn; /** * Base class for grid columns internally used by the Grid. The user should * use {@link GridColumn} when creating new columns. * + * @param <C> + * the column type + * * @param <T> * the row type */ - public static abstract class AbstractGridColumn<T> { + public static abstract class AbstractGridColumn<C, T> { /** * The grid the column is associated with @@ -115,6 +119,44 @@ public class Grid<T> extends Composite { private String footer; /** + * Renderer for rendering a value into the cell + */ + private Renderer<C> renderer = new Renderer<C>() { + + @Override + public void renderCell(Cell cell, C value) { + if (value instanceof Widget) { + cell.setWidget((Widget) value); + } else if (value instanceof String) { + cell.getElement().setInnerText(value.toString()); + } else { + throw new IllegalArgumentException( + "Cell value cannot be converted into a String. Please use a custom renderer to convert the value."); + } + } + }; + + /** + * Constructs a new column. + */ + public AbstractGridColumn() { + + } + + /** + * Constructs a new column with a custom renderer. + * + * @param renderer + * The renderer to use for rendering the cells + */ + public AbstractGridColumn(Renderer<C> renderer) { + if (renderer == null) { + throw new IllegalArgumentException("Renderer cannot be null."); + } + this.renderer = renderer; + } + + /** * Internally used by the grid to set itself * * @param grid @@ -218,22 +260,36 @@ public class Grid<T> extends Composite { } else { conf.removeColumns(index, 1); } - - // TODO should update body as well } this.visible = visible; } /** - * Returns the text that should be displayed in the cell. + * Returns the data that should be rendered into the cell. By default + * returning Strings and Widgets are supported. If the return type is a + * String then it will be treated as preformatted text. + * <p> + * To support other types you will need to pass a custom renderer to the + * column via the column constructor. * * @param row * The row object that provides the cell content. * * @return The cell content */ - public abstract String getValue(T row); + public abstract C getValue(T row); + + /** + * The renderer to render the cell width. By default renders the data as + * a String or adds the widget into the cell if the column type is of + * widget type. + * + * @return The renderer to render the cell content with + */ + public Renderer<C> getRenderer() { + return renderer; + } /** * Finds the index of this column instance @@ -276,9 +332,12 @@ public class Grid<T> extends Composite { /** * Gets the header/footer caption value * + * @param column + * The column to get the value for. + * * @return The value that should be rendered for the column caption */ - public abstract String getColumnValue(GridColumn column); + public abstract String getColumnValue(GridColumn<?, T> column); /** * Gets the group caption value @@ -287,14 +346,17 @@ public class Grid<T> extends Composite { * The group for with the caption value should be returned * @return The value that should be rendered for the column caption */ - public abstract String getGroupValue(ColumnGroup group); + public abstract String getGroupValue(ColumnGroup<T> group); /** * Is the row visible in the header/footer * + * @param row + * the row to check + * * @return <code>true</code> if the row should be visible */ - public abstract boolean isRowVisible(ColumnGroupRow row); + public abstract boolean isRowVisible(ColumnGroupRow<T> row); /** * Should the first row be visible @@ -317,7 +379,7 @@ public class Grid<T> extends Composite { // column headers for (Cell cell : cellsToUpdate) { int columnIndex = cell.getColumn(); - GridColumn column = columns.get(columnIndex); + GridColumn<?, T> column = columns.get(columnIndex); cell.getElement().setInnerText(getColumnValue(column)); } @@ -328,7 +390,7 @@ public class Grid<T> extends Composite { } // Adjust for previous invisible header rows - ColumnGroupRow groupRow = null; + ColumnGroupRow<T> groupRow = null; for (int i = 0, realIndex = 0; i < columnGroupRows.size(); i++) { groupRow = columnGroupRows.get(i); if (isRowVisible(groupRow)) { @@ -344,8 +406,8 @@ public class Grid<T> extends Composite { for (Cell cell : cellsToUpdate) { int columnIndex = cell.getColumn(); - GridColumn column = columns.get(columnIndex); - ColumnGroup group = getGroupForColumn(groupRow, column); + GridColumn<?, T> column = columns.get(columnIndex); + ColumnGroup<T> group = getGroupForColumn(groupRow, column); if (group != null) { // FIXME Should merge the group cells when escalator @@ -398,17 +460,17 @@ public class Grid<T> extends Composite { return new HeaderFooterEscalatorUpdater(escalator.getHeader(), true) { @Override - public boolean isRowVisible(ColumnGroupRow row) { + public boolean isRowVisible(ColumnGroupRow<T> row) { return row.isHeaderVisible(); } @Override - public String getGroupValue(ColumnGroup group) { + public String getGroupValue(ColumnGroup<T> group) { return group.getHeaderCaption(); } @Override - public String getColumnValue(GridColumn column) { + public String getColumnValue(GridColumn<?, T> column) { return column.getHeaderCaption(); } @@ -437,9 +499,9 @@ public class Grid<T> extends Composite { } for (Cell cell : cellsToUpdate) { - String value = getColumn(cell.getColumn()) - .getValue(rowData); - cell.getElement().setInnerText(value); + GridColumn column = getColumn(cell.getColumn()); + Object value = column.getValue(rowData); + column.getRenderer().renderCell(cell, value); } } @@ -461,17 +523,17 @@ public class Grid<T> extends Composite { return new HeaderFooterEscalatorUpdater(escalator.getFooter(), false) { @Override - public boolean isRowVisible(ColumnGroupRow row) { + public boolean isRowVisible(ColumnGroupRow<T> row) { return row.isFooterVisible(); } @Override - public String getGroupValue(ColumnGroup group) { + public String getGroupValue(ColumnGroup<T> group) { return group.getFooterCaption(); } @Override - public String getColumnValue(GridColumn column) { + public String getColumnValue(GridColumn<?, T> column) { return column.getFooterCaption(); } @@ -498,7 +560,7 @@ public class Grid<T> extends Composite { // Count needed rows int totalRows = firstRowIsVisible ? 1 : 0; - for (ColumnGroupRow row : columnGroupRows) { + for (ColumnGroupRow<T> row : columnGroupRows) { if (isHeader ? row.isHeaderVisible() : row.isFooterVisible()) { totalRows++; } @@ -540,7 +602,7 @@ public class Grid<T> extends Composite { * @param column * the column to add */ - public void addColumn(GridColumn<T> column) { + public void addColumn(GridColumn<?, T> column) { ColumnConfiguration conf = escalator.getColumnConfiguration(); addColumn(column, conf.getColumnCount()); } @@ -553,10 +615,10 @@ public class Grid<T> extends Composite { * @param column * the column to add */ - public void addColumn(GridColumn<T> column, int index) { + public void addColumn(GridColumn<?, T> column, int index) { // Register this grid instance with the column - ((AbstractGridColumn<T>) column).setGrid(this); + ((AbstractGridColumn<?, T>) column).setGrid(this); columns.add(index, column); @@ -564,7 +626,7 @@ public class Grid<T> extends Composite { conf.insertColumns(index, 1); if (lastFrozenColumn != null - && ((AbstractGridColumn<T>) lastFrozenColumn) + && ((AbstractGridColumn<?, T>) lastFrozenColumn) .findIndexOfColumn() < index) { refreshFrozenColumns(); } @@ -576,13 +638,13 @@ public class Grid<T> extends Composite { * @param column * the column to remove */ - public void removeColumn(GridColumn<T> column) { + public void removeColumn(GridColumn<?, T> column) { int columnIndex = columns.indexOf(column); columns.remove(columnIndex); // de-register column with grid - ((AbstractGridColumn<T>) column).setGrid(null); + ((AbstractGridColumn<?, T>) column).setGrid(null); ColumnConfiguration conf = escalator.getColumnConfiguration(); conf.removeColumns(columnIndex, 1); @@ -608,8 +670,8 @@ public class Grid<T> extends Composite { * * @return A unmodifiable list of the columns in the grid */ - public List<GridColumn<T>> getColumns() { - return Collections.unmodifiableList(new ArrayList<GridColumn<T>>( + public List<GridColumn<?, T>> getColumns() { + return Collections.unmodifiableList(new ArrayList<GridColumn<?, T>>( columns)); } @@ -622,7 +684,8 @@ public class Grid<T> extends Composite { * @throws IllegalArgumentException * if the column index does not exist in the grid */ - public GridColumn<T> getColumn(int index) throws IllegalArgumentException { + public GridColumn<?, T> getColumn(int index) + throws IllegalArgumentException { if (index < 0 || index >= columns.size()) { throw new IllegalStateException("Column not found."); } @@ -749,8 +812,8 @@ public class Grid<T> extends Composite { * * @return a column group row instance you can use to add column groups */ - public ColumnGroupRow addColumnGroupRow() { - ColumnGroupRow row = new ColumnGroupRow(this); + public ColumnGroupRow<T> addColumnGroupRow() { + ColumnGroupRow<T> row = new ColumnGroupRow<T>(this); columnGroupRows.add(row); refreshHeader(); refreshFooter(); @@ -767,8 +830,8 @@ public class Grid<T> extends Composite { * the index where the column group row should be added * @return a column group row instance you can use to add column groups */ - public ColumnGroupRow addColumnGroupRow(int rowIndex) { - ColumnGroupRow row = new ColumnGroupRow(this); + public ColumnGroupRow<T> addColumnGroupRow(int rowIndex) { + ColumnGroupRow<T> row = new ColumnGroupRow<T>(this); columnGroupRows.add(rowIndex, row); refreshHeader(); refreshFooter(); @@ -781,7 +844,7 @@ public class Grid<T> extends Composite { * @param row * The row to remove */ - public void removeColumnGroupRow(ColumnGroupRow row) { + public void removeColumnGroupRow(ColumnGroupRow<T> row) { columnGroupRows.remove(row); refreshHeader(); refreshFooter(); @@ -793,8 +856,8 @@ public class Grid<T> extends Composite { * @return a unmodifiable list of column group rows * */ - public List<ColumnGroupRow> getColumnGroupRows() { - return Collections.unmodifiableList(new ArrayList<ColumnGroupRow>( + public List<ColumnGroupRow<T>> getColumnGroupRows() { + return Collections.unmodifiableList(new ArrayList<ColumnGroupRow<T>>( columnGroupRows)); } @@ -808,10 +871,10 @@ public class Grid<T> extends Composite { * @return A column group for the row and column or <code>null</code> if not * found. */ - private static ColumnGroup getGroupForColumn(ColumnGroupRow row, - GridColumn column) { - for (ColumnGroup group : row.getGroups()) { - List<GridColumn> columns = group.getColumns(); + private ColumnGroup<T> getGroupForColumn(ColumnGroupRow<T> row, + GridColumn<?, T> column) { + for (ColumnGroup<T> group : row.getGroups()) { + List<GridColumn<?, T>> columns = group.getColumns(); if (columns.contains(column)) { return group; } @@ -888,7 +951,7 @@ public class Grid<T> extends Composite { * @throws IllegalArgumentException * if {@code lastFrozenColumn} is not a column from this grid */ - public void setLastFrozenColumn(GridColumn<T> lastFrozenColumn) { + public void setLastFrozenColumn(GridColumn<?, T> lastFrozenColumn) { this.lastFrozenColumn = lastFrozenColumn; refreshFrozenColumns(); } @@ -918,7 +981,7 @@ public class Grid<T> extends Composite { * @return the rightmost frozen column in the grid, or <code>null</code> if * no columns are frozen. */ - public GridColumn<T> getLastFrozenColumn() { + public GridColumn<?, T> getLastFrozenColumn() { return lastFrozenColumn; } } diff --git a/client/src/com/vaadin/client/ui/grid/GridColumn.java b/client/src/com/vaadin/client/ui/grid/GridColumn.java index 992bfae014..ad74a008b9 100644 --- a/client/src/com/vaadin/client/ui/grid/GridColumn.java +++ b/client/src/com/vaadin/client/ui/grid/GridColumn.java @@ -18,13 +18,16 @@ package com.vaadin.client.ui.grid; /** * Represents a column in the {@link Grid}. * + * @param <C> + * The column type + * * @param <T> * The row type * * @since 7.2 * @author Vaadin Ltd */ -public abstract class GridColumn<T> extends Grid.AbstractGridColumn<T> { +public abstract class GridColumn<C, T> extends Grid.AbstractGridColumn<C, T> { /* * This class is a convenience class so you do not have to reference diff --git a/client/src/com/vaadin/client/ui/grid/GridConnector.java b/client/src/com/vaadin/client/ui/grid/GridConnector.java index ac209b9c2c..47558b2f22 100644 --- a/client/src/com/vaadin/client/ui/grid/GridConnector.java +++ b/client/src/com/vaadin/client/ui/grid/GridConnector.java @@ -44,9 +44,9 @@ public class GridConnector extends AbstractComponentConnector { /** * Custom implementation of the custom grid column using a String[] to - * represent the cell value + * represent the cell value and String as a column type. */ - private class CustomGridColumn extends GridColumn<String[]> { + private class CustomGridColumn extends GridColumn<String, String[]> { private final int columnIndex; @@ -147,7 +147,7 @@ public class GridConnector extends AbstractComponentConnector { * The index of the column to update */ private void updateColumnFromStateChangeEvent(int columnIndex) { - GridColumn<String[]> column = getWidget().getColumn(columnIndex); + GridColumn<?, String[]> column = getWidget().getColumn(columnIndex); GridColumnState columnState = getState().columns.get(columnIndex); updateColumnFromState(column, columnState); } @@ -176,7 +176,7 @@ public class GridConnector extends AbstractComponentConnector { * @param state * The state to get the data from */ - private static void updateColumnFromState(GridColumn<String[]> column, + private static void updateColumnFromState(GridColumn<?, String[]> column, GridColumnState state) { column.setVisible(state.visible); column.setHeaderCaption(state.header); @@ -216,22 +216,22 @@ public class GridConnector extends AbstractComponentConnector { // FIXME When something changes the header/footer rows will be // re-created. At some point we should optimize this so partial updates // can be made on the header/footer. - for (ColumnGroupRow row : getWidget().getColumnGroupRows()) { + for (ColumnGroupRow<String[]> row : getWidget().getColumnGroupRows()) { getWidget().removeColumnGroupRow(row); } for (ColumnGroupRowState rowState : getState().columnGroupRows) { - ColumnGroupRow row = getWidget().addColumnGroupRow(); + ColumnGroupRow<String[]> row = getWidget().addColumnGroupRow(); row.setFooterVisible(rowState.footerVisible); row.setHeaderVisible(rowState.headerVisible); for (ColumnGroupState groupState : rowState.groups) { - List<GridColumn> columns = new ArrayList<GridColumn>(); + List<GridColumn<String, String[]>> columns = new ArrayList<GridColumn<String, String[]>>(); for (String columnId : groupState.columns) { CustomGridColumn column = columnIdToColumn.get(columnId); columns.add(column); } - ColumnGroup group = row.addGroup(columns + ColumnGroup<String[]> group = row.addGroup(columns .toArray(new GridColumn[columns.size()])); group.setFooterCaption(groupState.footer); group.setHeaderCaption(groupState.header); diff --git a/client/src/com/vaadin/client/ui/grid/Renderer.java b/client/src/com/vaadin/client/ui/grid/Renderer.java new file mode 100644 index 0000000000..7ead3ad9b5 --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/Renderer.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2013 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.client.ui.grid; + +/** + * Renderer for rending a value <T> into cell. + * <p> + * You can add a renderer to any column by overring the + * {@link GridColumn#getRenderer()} method and returning your own renderer. You + * can retrieve the cell element using {@link Cell#getElement()}. + * + * @param <T> + * The row type + * + * @since 7.2 + * @author Vaadin Ltd + */ +public interface Renderer<T> { + + /** + * Called whenever the {@link Grid} updates a cell + * + * @param cell + * The cell that gets updated + * + * @param data + * The row data object + */ + public void renderCell(Cell cell, T data); +} |