(
columnGroupRows));
}
/**
* Used internally by the {@link Grid} to get a {@link GridColumn} by
* referencing its generated state id. Also used by {@link GridColumn} to
* verify if it has been detached from the {@link Grid}.
*
* @param columnId
* the client id generated for the column when the column is
* added to the grid
* @return the column with the id or null
if not found
*/
GridColumn getColumnByColumnId(String columnId) {
Object propertyId = getPropertyIdByColumnId(columnId);
return getColumn(propertyId);
}
/**
* Used internally by the {@link Grid} to get a property id by referencing
* the columns generated state id.
*
* @param columnId
* The state id of the column
* @return The column instance or null if not found
*/
Object getPropertyIdByColumnId(String columnId) {
return columnKeys.get(columnId);
}
@Override
protected GridState getState() {
return (GridState) super.getState();
}
@Override
protected GridState getState(boolean markAsDirty) {
return (GridState) super.getState(markAsDirty);
}
/**
* Creates a new column based on a property id and appends it as the last
* column.
*
* @param datasourcePropertyId
* The property id of a property in the datasource
*/
private GridColumn appendColumn(Object datasourcePropertyId) {
if (datasourcePropertyId == null) {
throw new IllegalArgumentException("Property id cannot be null");
}
assert datasource.getContainerPropertyIds().contains(
datasourcePropertyId) : "Datasource should contain the property id";
GridColumnState columnState = new GridColumnState();
columnState.id = columnKeys.key(datasourcePropertyId);
getState().columns.add(columnState);
GridColumn column = new GridColumn(this, columnState);
columns.put(datasourcePropertyId, column);
return column;
}
/**
* Sets (or unsets) the rightmost frozen column in the grid.
*
* All columns up to and including the given column will be frozen in place
* when the grid is scrolled sideways.
*
* @param lastFrozenColumn
* the rightmost column to freeze, or null
to not
* have any columns frozen
* @throws IllegalArgumentException
* if {@code lastFrozenColumn} is not a column from this grid
*/
void setLastFrozenColumn(GridColumn lastFrozenColumn) {
/*
* TODO: If and when Grid supports column reordering or insertion of
* columns before other columns, make sure to mention that adding
* columns before lastFrozenColumn will change the frozen column count
*/
if (lastFrozenColumn == null) {
getState().lastFrozenColumnId = null;
} else if (columns.containsValue(lastFrozenColumn)) {
getState().lastFrozenColumnId = lastFrozenColumn.getState().id;
} else {
throw new IllegalArgumentException(
"The given column isn't attached to this grid");
}
}
/**
* Sets (or unsets) the rightmost frozen column in the grid.
*
* All columns up to and including the indicated property will be frozen in
* place when the grid is scrolled sideways.
*
* Note: If the container used by this grid supports a propertyId
* null
, it can never be defined as the last frozen column, as
* a null
parameter will always reset the frozen columns in
* Grid.
*
* @param propertyId
* the property id corresponding to the column that should be the
* last frozen column, or null
to not have any
* columns frozen.
* @throws IllegalArgumentException
* if {@code lastFrozenColumn} is not a column from this grid
*/
public void setLastFrozenPropertyId(Object propertyId) {
final GridColumn column;
if (propertyId == null) {
column = null;
} else {
column = getColumn(propertyId);
if (column == null) {
throw new IllegalArgumentException(
"property id does not exist.");
}
}
setLastFrozenColumn(column);
}
/**
* Gets the rightmost frozen column in the grid.
*
* Note: Most often, this method returns the very value set with
* {@link #setLastFrozenPropertyId(Object)}. This value, however, can be
* reset to null
if the column is detached from this grid.
*
* @return the rightmost frozen column in the grid, or null
if
* no columns are frozen.
*/
public Object getLastFrozenPropertyId() {
return columnKeys.get(getState().lastFrozenColumnId);
}
/**
* Scrolls to a certain item, using {@link ScrollDestination#ANY}.
*
* @param itemId
* id of item to scroll to.
* @throws IllegalArgumentException
* if the provided id is not recognized by the data source.
*/
public void scrollToItem(Object itemId) throws IllegalArgumentException {
scrollToItem(itemId, ScrollDestination.ANY);
}
/**
* Scrolls to a certain item, using user-specified scroll destination.
*
* @param itemId
* id of item to scroll to.
* @param destination
* value specifying desired position of scrolled-to row.
* @throws IllegalArgumentException
* if the provided id is not recognized by the data source.
*/
public void scrollToItem(Object itemId, ScrollDestination destination)
throws IllegalArgumentException {
int row = datasource.indexOfId(itemId);
if (row == -1) {
throw new IllegalArgumentException(
"Item with specified ID does not exist in data source");
}
GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class);
clientRPC.scrollToRow(row, destination);
}
/**
* Scrolls to the beginning of the first data row.
*/
public void scrollToStart() {
GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class);
clientRPC.scrollToStart();
}
/**
* Scrolls to the end of the last data row.
*/
public void scrollToEnd() {
GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class);
clientRPC.scrollToEnd();
}
/**
* Sets the number of rows that should be visible in Grid's body, while
* {@link #getHeightMode()} is {@link HeightMode#ROW}.
*
* If Grid is currently not in {@link HeightMode#ROW}, the given value is
* remembered, and applied once the mode is applied.
*
* @param rows
* The height in terms of number of rows displayed in Grid's
* body. If Grid doesn't contain enough rows, white space is
* displayed instead. If null
is given, then Grid's
* height is undefined
* @throws IllegalArgumentException
* if {@code rows} is zero or less
* @throws IllegalArgumentException
* if {@code rows} is {@link Double#isInifinite(double)
* infinite}
* @throws IllegalArgumentException
* if {@code rows} is {@link Double#isNaN(double) NaN}
*/
public void setHeightByRows(double rows) {
if (rows <= 0.0d) {
throw new IllegalArgumentException(
"More than zero rows must be shown.");
} else if (Double.isInfinite(rows)) {
throw new IllegalArgumentException(
"Grid doesn't support infinite heights");
} else if (Double.isNaN(rows)) {
throw new IllegalArgumentException("NaN is not a valid row count");
}
getState().heightByRows = rows;
}
/**
* Gets the amount of rows in Grid's body that are shown, while
* {@link #getHeightMode()} is {@link HeightMode#ROW}.
*
* @return the amount of rows that are being shown in Grid's body
* @see #setHeightByRows(double)
*/
public double getHeightByRows() {
return getState(false).heightByRows;
}
/**
* {@inheritDoc}
*
* Note: This method will change the widget's size in the browser
* only if {@link #getHeightMode()} returns {@link HeightMode#CSS}.
*
* @see #setHeightMode(HeightMode)
*/
@Override
public void setHeight(float height, Unit unit) {
super.setHeight(height, unit);
}
/**
* Defines the mode in which the Grid widget's height is calculated.
*
* If {@link HeightMode#CSS} is given, Grid will respect the values given
* via a {@code setHeight}-method, and behave as a traditional Component.
*
* If {@link HeightMode#ROW} is given, Grid will make sure that the body
* will display as many rows as {@link #getHeightByRows()} defines.
* Note: If headers/footers are inserted or removed, the widget
* will resize itself to still display the required amount of rows in its
* body. It also takes the horizontal scrollbar into account.
*
* @param heightMode
* the mode in to which Grid should be set
*/
public void setHeightMode(HeightMode heightMode) {
/*
* This method is a workaround for the fact that Vaadin re-applies
* widget dimensions (height/width) on each state change event. The
* original design was to have setHeight an setHeightByRow be equals,
* and whichever was called the latest was considered in effect.
*
* But, because of Vaadin always calling setHeight on the widget, this
* approach doesn't work.
*/
getState().heightMode = heightMode;
}
/**
* Returns the current {@link HeightMode} the Grid is in.
*
* Defaults to {@link HeightMode#CSS}.
*
* @return the current HeightMode
*/
public HeightMode getHeightMode() {
return getState(false).heightMode;
}
}