Grid is a Spark component that displays a list of data items, the dataProvider, in a scrollable table or "grid", one item per row. Each of the grid's columns, defined by a GridColumn object, displays a value based on the item for the corresponding row. The grid's dataProvider is mutable, dataProvider items can be added or removed, or changed. Similarly the Grid's list of columns is mutable.
The Grid component is intended to be used as a DataGrid skin part, or as an element of other custom composite components. As such it is not skinnable, it does not include a scroller or scrollbars, and it does not provide default mouse or keyboard event handling. Its role is similar to DataGroup, the workhorse skin part for the Spark List.
Each visible Grid cell is displayed by an IGridItemRenderer instance created using the itemRenderer factory. One item renderer (factory) is specified for each column and, before it's displayed, each item renderer instance is configured with the value of the dataProvider item for that row, and its row and column indices. Item renderers are created as needed and then, to keep creation overhead to a minimum, pooled and "recycled".
Grids support selection, according the selectionMode property. The set of selected row or cell indices can be modified or queried programatically using the selection methods like setSelectedIndex() or selectionContainsIndex().
Grids display hover, caret, and selection indicators per the selectionMode and the corresponding row,columnIndex properties like hoverRowIndex and columnRowIndex. An indicator can be any visual element. Indicators that implement IGridElement can configure themselves according to the row and column they're displayed on.
Grids support smooth scrolling. Their vertical and horizontal scroll positions define the pixel origin of the visible part of the grid and the grid's layout only displays as many cell item renderers as are needed to fill the available space. Grids support variable height rows that automatically compute their height based on the item renderers' contents. This support is called grid "virtualization" because the mapping from (pixel) scroll positions to row and column indices is typically based on incomplete information about the preferred sizes for grid cells. The Grid caches the computed heights of rows that have been scrolled into view and estimates the rest based on a single typicalItem.
The API for the DataGrid,Grid class shown below is incomplete, only the properties relevant to this section are shown.
All of the API listed below is common to both the Grid and DataGrid. The DataGrid properties simply "cover" eponymous properties on the DataGrid's grid skin part. The descriptions of the DataGrid version of each of these covered properties is the same as for Grid. The Grid caretIndicator, hoverIndicator, selectionIndicator, columnSeparator, rowSeparator, rowBackground are covered by eponymous DataGrid properties that are also skin parts.
package spark.components
{
public class Grid extends Group
{
/**
* A single visual element that's displayed for the caret row, if
* selectionMode is GridSelectionMode.SINGLE_ROW or
* GridSelectionMode.MULTIPLE_ROWS, or for the caret
* cell, if selectionMode is
* SelectionMode.SINGLE_CELL or
* GridSelectionMode.MULTIPLE_CELLS.
*
* @default null
*/
public function get caretIndicator():IFactory
public function set caretIndicator(value:IFactory):void
/**
* The list of GridColumns displayed by this grid. Each column
* selects different dataProvider item properties to display in grid cells.
*
* @default null
*
* @see spark.components.Grid#dataProvider
*/
public function get columns():IList
public function set columns(value:IList):void
/**
* A visual element that's displayed in between each column.
*
* @default null
*/
public function get columnSeparator():IFactory
public function set columnSeparator(value:IFactory):void
/**
* A list of items that correspond to the rows in the grid. The grid's columns
* select different item properties to display in grid cells.
*
* @default null
*
* @see spark.components.Grid#columns
*/
public function get dataProvider():IList
public function set dataProvider(value:IList):void
/**
* The dataTipField that's used for columns that do not specify one.
*
* @default null
*/
public function get dataTipField():String
public function set dataTipField(value:String):void
/**
* The dataTipFunction that's used for columns that do not specify one.
*
* @default null
*/
public function get dataTipFunction():Function
public function set dataTipFunction(value:Function):void
/**
* The default headerRenderer for the columnHeaderGroup skin part.
*
* @default null
*/
public function get headerRenderer():IFactory
public function set headerRenderer(value:IFactory):void
/**
* A single visual element that's displayed for the row under the
* mouse, if selectionMode is SelectionMode.SINGLE_ROW, or
* GridSelectionMode.MULTIPLE_ROWS, or for the caret cell, if selectionMode is
* SelectionMode.SINGLE_CELL or GridSelectionMode.MULTIPLE_CELLS.
*
* @default null
*/
public function get hoverIndicator():IFactory
public function set hoverIndicator(value:IFactory):void
/**
* The item renderer that's used for columns that do not specify one.
*
* @default null
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4.5
*/
public function get itemRenderer():IFactory
public function set itemRenderer(value:IFactory):void
/**
* A flag that indicates whether the user can change the size of
* the columns. If true, the user can stretch or shrink the
* columns of the DataGrid control by dragging the grid lines
* between the header cells. If true, individual columns must
* also have their resizable properties set to to false to
* prevent the user from resizing a particular column.
*
* @default true
*/
public function get resizableColumns():Boolean
public function set resizableColumns(value:Boolean):void
/**
* A visual element that's displayed for each row.
*
* @default null
*/
public function get rowBackground():IFactory
public function set rowBackground(value:IFactory):void
/**
* A visual element that's displayed in between each row.
*
* @default null
*/
public function get rowSeparator():IFactory
public function set rowSeparator(value:IFactory):void
/**
* A visual element that's displayed for each selected row, if selectionMode
* is SelectionMode.SINGLE_ROW or GridSelectionMode.MULTIPLE_ROWS, or for each
* selected cell, if selectionMode is SelectionMode.SINGLE_CELL or
* GridSelectionMode.MULTIPLE_CELLS.
*
* @default null
*/
public function get selectionIndicator():IFactory
public function set selectionIndicator(value:IFactory):void
/**
* If true then a dataTip is displayed for all visible cells. If false (the default),
* then a dataTip is only displayed if the column's showDataTips property is true.
*
* @default false
*/
public function get showDataTips():Boolean
public function set showDataTips(value:Boolean):void
/**
* A flag that indicates whether the user can interactively sort columns.
* If true, the user can sort the dataProvider by the
* dataField of a column by clicking on the column's header.
* If true, individual columns must have their
* sortable properties set to false to
* prevent the user from sorting by a particular column.
*
* @default true
*/
public function get sortableColumns():Boolean
public function set sortableColumns(value:Boolean):void
//... Remaining DataGrid,Grid API appears elsewhere in this spec
}
}
The API for the Grid class shown below is incomplete, only the properties relevant to this section are shown.
The API below only appears in the Grid class and is used to track ephemeral state of interest to GridEvent handlers. None of the properties are "covered" by DataGrid.
package spark.components
{
public class Grid extends Group
{
/**
* The column index of the "anchor" for the next shift selection.
* Grid event handlers should use this property to record the
* location of the most recent unshifted mouse down or keyboard
* event that defines one end of the next potential shift
* selection. The caret index defines the other end.
*
* @default 0
*
* @see spark.components.Grid#caretRowIndex
* @see spark.components.Grid#caretColumnIndex
*/
public function get anchorColumnIndex():int
public function set anchorColumnIndex(value:int):void
/**
* The row index of the "anchor" for the next shift selection.
* Grid event handlers should use this property to record the
* location of the most recent unshifted mouse down or keyboard
* event that defines one end of the next potential shift
* selection. The caret index defines the other end.
*
* @default 0
*
* @see spark.components.Grid#caretRowIndex
* @see spark.components.Grid#caretColumnIndex
*/
public function get anchorRowIndex():int
public function set anchorRowIndex(value:int):void
/**
* The column index of the caretIndicator visualElement if
* showCaretIndicator is true. If selectionMode is
* SelectionMode.SINGLE_ROW or
* GridSelectionMode.MULTIPLE_ROWS then the indicator
* occupies the entire row and caretColumnIndex is ignored. If
* selectionMode is GridSelectionMode.SINGLE_CELL or
* GridSelectionMode.MULTIPLE_CELLS then the caretIndicator
* occupies the specified cell.
*
* Setting careColumnIndex to -1 means that the column index is undefined and
* a cell caret will not be shown.
*
* @default -1
*/
public function get caretColumnIndex():int
public function set caretColumnIndex(value:int):void
/**
* The row index of the caretIndicator visualElement if
* showCaretIndicator is true. If selectionMode is
* SelectionMode.SINGLE_ROW or
* GridSelectionMode.MULTIPLE_ROWS then the indicator
* occupies the entire row and caretColumnIndex is ignored. If
* selectionMode is SelectionMode.SINGLE_CELL or
* GridSelectionMode.MULTIPLE_CELLS then the caretIndicator
* occupies the specified cell.
*
* Setting caretRowIndex to -1 means that the row index is undefined and
* the caret will not be shown.
*
* @default -1
*/
public function get caretRowIndex():int
public function set caretRowIndex(value:int):void
/**
* Specifies column index of the hoverIndicator visualElement if
* showHoverIndicator is true. If selectionMode is SelectionMode.SINGLE_ROW or
* GridSelectionMode.MULTIPLE_ROWS then the indicator occupies the entire row
* and hoverColumnIndex is ignored. If selectionMode is SelectionMode.SINGLE_CELL or
* GridSelectionMode.MULTIPLE_CELLS then the hoverIndicator
* occupies the specified cell.
*
* Setting hoverRowIndex to -1 (the default) means that the row index
* is undefined and a hover indicator will not be displayed.
*
* @default -1
*/
public function get hoverRowIndex():int
public function set hoverRowIndex(value:int):void
/**
* Specifies column index of the hoverIndicator visualElement if
* showHoverIndicator is true. If selectionMode is SelectionMode.SINGLE_ROW
* or GridSelectionMode.MULTIPLE_ROWS then the indicator occupies
* the entire row and hoverColumnIndex is ignored. If selectionMode is
* SelectionMode.SINGLE_CELL or GridSelectionMode.MULTIPLE_CELLS then the
* hoverIndicator occupies the specified cell.
*
* Setting hoverColumnIndex to -1 (the default) means that the column index
* is undefined and a cell hover indicator will not be displayed.
*
* @default -1
*/
public function get hoverColumnIndex():int
public function set hoverColumnIndex(value:int):void
/**
* The GridLayer objects that define the stacking order or "layering" for Grid visual elements.
*
* The GridLayout adds rowBackround and hoverIndicator elements to the backgroundLayer,
* selectionIndicators to the selectionLayer, item renderers to the rendererLayer, caretIndicator,
* row and column separators to the overlayLayer.
*
* If a value for this property isn't specified, then at commitProperties() time
* a Vector of the four minimum GridLayers expected by the Grid's layout is created. The layers
* have the following ids: "backgroundLayer", "selectionLayer", "rendererLayer", "overlayLayer".
* The rendererLayer's root is this Grid.
*
* @default Four layers with the following ids: "backgroundLayer", "selectionLayer", "rendererLayer", "overlayLayer".
*/
public function get layers():Vector.<GridLayer>
public function set layers(value:Vector.<GridLayer>):void
/**
* Returns the GridLayer element of the layers property with the specified id, or null.
*
* Grid's layout uses this method to lookup GridLayers.
*
* @param id The id of the GridLayer to be returned.
*/
public function getLayer(id:String):GridLayer
//... Remaining Grid API appears elsewhere in this spec
}
}
The DataGrid API below supports dataProvider sorting.
package spark.components
{
public class DataGrid extends Group
{
/**
* A flag that indicates whether the user can interactively sort columns.
* If true, the user can sort the dataProvider by the
* dataField of a column by clicking on the column's header.
* If true, individual columns must have their
* sortable properties set to false to
* prevent the user from sorting by a particular column.
*
* @default true
*/
public function get sortableColumns():Boolean
public function set sortableColumns(value:Boolean):void
/**
* Sort the DataGrid by one or more columns and refresh the display.
*
* If the dataProvider is an ICollectionView, then it's sort property will be
* set to a value based on each column's dataField, sortCompareFunction,
* and sortDescending flag, and then the dataProvider's refresh() method will be called.
* To be sorted, each column must have either a dataField or labelFunction.
*
* If the dataProvider is not an ICollectionView, then this method has no effect.
*
* @param columnIndices The indices of the columns by which to sort the dataProvider.
*
* @param isInteractive If true, GridSortEvent.SORT_CHANGING and
* GridSortEvent.SORT_CHANGE events are dispatched and the column header group
* visibleSortIndicatorIndices is updated with columnIndices if the GridSortEvent.SORT_CHANGING
* event is not cancelled.
*
* @return true if the dataProvider can be sorted with the provided column indices.
*/
public function sortByColumns(columnIndices:Vector.<int>, isInteractive:Boolean=false):Boolean
//... Remaining DataGrid API appears elsewhere in this spec
}
}
The "sortChanging" and "sortChange" events are dispatched for interactive sorting operations. Typically this is when the user releases the mouse button on a column header but the events are also dispatched when sortByColumns() is called with the isInteractive parameter set to true. The sort is "proposed" and, if not canceled by the developer, is committed. The GridSortEvent "sortChanging" which is dispatched when the sort is "proposed" may be canceled by the developer by calling the event's preventDefault() method. If the "sortChanging" event is not cancelled, the sort can be modified by changing parameter values in the "sortChanging" event. The GridSortEvent "sortChanged" is dispatched after the data provider has been sorted.
The default sort behavior is a single column-sort which is the reverse of the value of the column's sortDescending property. Multiple-column sort can be implemented by calling the "sortChanging" event's preventDefault() method to prevent the default sort behavior and modifying the values of the newSortFields and columnIndices properties. newSortFields should contain the desired sort fields. columnIndices should contain the indices of the columns which should have visible sort indicators in the column header bar.
/**
* Dispatched before the sort has been applied to the data provider's collection.
* Typically this is when the user releases the mouse button on a column header
* to request the control to sort the grid contents based on the contents of the column.
* Only dispatched if the column is sortable and the data provider supports sorting.
*
* The DataGrid control has a default handler for this event that implements
* a single-column sort and updates the visibleSortIndices in the grid's
* columnHeaderGroup with the columnIndices.
* Multiple-column sort can be implemented by calling the preventDefault() method
* to prevent the single column sort and setting the columnIndices and
* newSortFields parameters of the event to change the default behavior.
*
* This event is dispatched when the user interacts with the control.
* When you sort the data provider's collection programmatically,
* the component does not dispatch the sortChanging event.
*
* @eventType spark.events.GridSelectionEvent.SORT_CHANGING
*/
<a href="Event%28name%3D%26quot%3BsortChanging%26quot%3B%2C%20type%3D%26quot%3Bspark.events.GridSortEvent%26quot%3B%29">Event(name="sortChanging", type="spark.events.GridSortEvent")</a>
/**
* Dispatched after the sort has been applied to the data provider's collection.
* Typically this is after the user releases the mouse button on a column header and
* the sort has been applied to the data provider's collection.
*
* This event is dispatched when the user interacts with the control.
* When you sort the data provider's collection programmatically,
* the component does not dispatch the sortChanging event.
*
* @eventType spark.events.GridSelectionEvent.SELECTION_CHANGE
*/
<a href="Event%28name%3D%26quot%3BsortChange%26quot%3B%2C%20type%3D%26quot%3Bspark.events.GridSortEvent%26quot%3B%29">Event(name="sortChange", type="spark.events.GridSortEvent")</a>
package spark.events
{
/**
* The GridSortEvent class represents events that are dispatched when
* the data provider of a Spark DataGrid control is sorted as the
* result of the user clicking on the header of a column in the DataGrid.
*/
public class GridSortEvent extends Event
{
/**
* The GridSortEvent.SORT_CHANGE constant defines
* the value of the type property of the event object for a
* sortChange event, which indicates that a sort filter has just been
* applied to the grid's dataProvider collection.
*
* Typically, if a column header mouse click triggered the sort, then the last index of
* columnIndices is the column's index.
* Note that interactive sorts are not necessarily triggered by a mouse click.
*
* This event is dispatched when the user interacts with the control.
* When you sort the data provider's collection programmatically,
* the component does not dispatch the sortChange event.
*/
public static const SORT_CHANGE:String = "sortChange";
/**
* The GridSortEvent.SORT_CHANGING constant defines
* the value of the type property of the event object for a
* sortChanging event, which indicates that a sort filter is about to be
* applied to the grid's dataProvider collection.
* Call preventDefault() on this event to prevent the sort from occurring
* or you modify columnIndices and newSortFields if you want to
* change the default behavior of the sort.
*/
public static const SORT_CHANGING:String = "sortChanging";
/**
* Constructor.
*
* @param type The event type; indicates the action that caused the event.
*
* @param bubbles Specifies whether the event can bubble
* up the display list hierarchy.
*
* @param cancelable Specifies whether the behavior
* associated with the event can be prevented.
*
* @param columnIndices The vector of column indices of the sorted columns.
*
* @param oldSortFields The array of ISortFields for the last sort.
*
* @param newSortFields The array of ISortFields for this sort.
*/
public function GridSortEvent(type:String,
bubbles:Boolean,
cancelable:Boolean,
columnIndices:Vector.<int>,
oldSortFields:Array, /* ISortField */
newSortFields:Array); /* ISortField */
/**
* The vector of column indices of the sorted columns.
* If type is GridSelectionEvent.SORT_CHANGING this value
* can be modified and it will be used to update the grid's columnHeaderGroup
* visibleSortIndicatorIndices.
*
* @see spark.components.DataGrid#columnHeaderGroup
* @see spark.components.gridClasses.GridColumnHeaderGroup#visibleSortIndicatorIndices
* @see spark.components.gridClasses.GridColumn#columnIndex
*/
public var columnIndices:Vector.<int>;
/**
* The array of ISortFields for this sort.
* If type is GridSelectionEvent.SORT_CHANGING this value
* can be modified and it will be used to sort the dataProvider of the grid.
*/
public var newSortFields:Array; /* of ISortField */
/**
* The array of ISortFields for the last sort. This can be null.
* The elements in this Array should not be modified.
*/
public function get oldSortFields():Array
{
return _oldSortFields;
}
}
}
The Spark GridColumn column is very similar to MX DataGridColumn. There are a few minor differences:
One prima facie quirk of the GridColumn (and MX DataGridColumn) API is that the type of the showDataTips property is "*" rather than Boolean. It's this way so that the DataGrid showDataTips property can be used to define the value for columns whose showDataTips property is undefined (the default). A typical use case is for DataGrid showDataTips="false" (the default) which is overridden by a few columns which specify showDataTips="true".
This is in contrast to the Boolean editable property. For a column to be editable both the DataGrid and the column's editable property must be true. This is to simplify disabling editing for all columns, by setting the DataGrid's editable property (default true) to false. This behavior is the same as it was in the MX DataGridColumn.
The GridColumn resizable and sortable properties are similar to the editable property. Interactive column resizing or sorting is only enabled if DataGrid/Grid's resizableColumns or sortableColumns property is true (the default for both) and the column's resizable or sortable property is true.
For sorting, GridColumn also provides a read-only property, sortField, that when called, creates and returns a SortField that can be used to sort the data provider by this column. The SortField applies all of the relevant fields for sorting including dataField, sortCompareFunction, and the sortDescending flag. When sorting, the sortCompareFunction is always used when provided. The dataField is the default field used by the sort. If a labelFunction is provided, a sortCompareFunction must also be provided for sorting.
It's also worth noting that Spark GridColumns instances can only belong to single Grid (DataGrid). This was implicitly true for MX as well.
package spark.components.gridClasses
{
/**
* A non-visual object that defines the mapping from each dataProvider item to a Grid column.
* Each dataProvider item corresponds to one Grid row and this object specifies the item property
* whose value is to be displayed in one column, the item renderer to display that value, the editor
* that's used to change the value, and so on.
*/
public class GridColumn extends EventDispatcher
{
/**
* The return value for itemToLabel() or itemToDataTip() if resolving the corresponding
* property name (path) fails. The value of this constant is a single space: " ".
*
* @see itemToLabel
* @see itemToDataTip
*/
public static const ERROR_TEXT:String = new String(" ");
/**
* Constructor.
*
* @param columnName Initial value for the dataField and
* headerText properties.
*/
public function GridColumn(columnName:String = null);
/**
* The position of this column in the grid's column list, or -1 if this column's grid is null.
*/
public function get columnIndex():int
/**
* Names the dataProvider property whose value is used to initialize item renderer's
* label string. In other words, the value of the itemRenderer's label property
* for the row at rowIndex in this column is:
* grid.dataProvider.getItemAt(rowIndex).dataField.toString().
*
* If this column or its grid specifies a labelFunction, then the
* dataField is not used.
*
* @default null
*
* @see itemToLabel
* @see labelFunction
*/
public function get dataField():String
public function set dataField(value:String):void
/**
* The property of the dataProvider item to display as the dataTip for this column.
* By default, if showDataTips=true, the itemRenderer's label is displayed
* as the dataTip. This property, which is similar to dataField, can
* be specified to show a different value for the dataTip.
*
* If this column or its grid specifies a dataTipFunction, then the
* dataTipField is not used.
*
* @default null
* @see dataTipFunction
* @see itemToDataTip
*/
public function get dataTipField():String
public function set dataTipField(value:String):void
/**
* Specifies the formatter used by the column's itemToDataTip() method to
* convert dataProvider items to strings.
*
* If the formatter's styleParent wasn't specified, it's set
* to the column's grid, so that the formatter inherits the grid's "locale" style.
*
* @default null
*
* @see #itemToDataTip
* @see #formatter
*
* @default null
*/
public function get dataTipFormatter():IFormatter;
public function set dataTipFormatter(value:IFormatter):void
/**
* A function that converts a dataProvider item into a column-specific string
* which will be displayed as a dataTip, if showDataTips=true.
* A dataTipFunction can be use to combine the values of several dataProvider item
* properties into a single string. If specified, this property is used by the
* itemToDataTip() method.
*
* The dataTipFunction's signature must match the following:
*
* dataTipFunction(item:Object, column:GridColumn):String
*
* The item parameter is the dataProvider item for an entire row; it's
* the value of grid.dataProvider.getItemAt(rowIndex). The second
* parameter is this column.
*
* A typical dataTipFunction might concatenate the item's firstName and
* lastName properties, or do some custom formatting on a Date valued
* item property.
*
* @default null
*
* @see itemToDataTip
* @see dataTipField
*/
public function get dataTipFunction():Function
public function set dataTipFunction(value:Function):void
/**
* A flag that indicates whether the items in the column are editable.
* If true, and the DataGrid's editable
* property is also true, the items in a column are
* editable and can be individually edited
* by clicking on a selected item or by navigating to the item and
* pressing the F2 key.
*
* @default true
*/
public function get editable():Boolean
public function set editable(value:Boolean):void
/**
* Specifies the formatter used by the column's itemToLabel() method to
* convert dataProvider items to strings.
*
* If the formatter's styleParent wasn't specified, it's set
* to the column's grid, so that the formatter inherits the grid's "locale" style.
*
* @default null
*
* @see #itemToLabel
* @see #dataTipFormatter
*/
public function get formatter():IFormatter;
public function set formatter(value:IFormatter):void;
/**
* The Grid this whose list of columns contains this Column, or null.
*/
public function get grid():Grid
/**
* A factory for the IGridItemRenderer used as the header for this column. If null,
* the value of the DataGrid headerRenderer property is returned.
*/
public function get headerRenderer():IFactory
public function set headerRenderer(value:IFactory):void
/**
* Text for the header of this column. By default, the Grid
* control uses the value of the dataField property
* as the header text.
*/
public function get headerText():String
public function set headerText(value:String):void
/**
* A factory for IGridItemEditors used to edit individual grid
* cells in this column.
*
* If this property is null, and the column grid's owner is a
* DataGrid, then the value of the DataGrid's itemEditor property
* is used. The default DataGrid item editor is TextGridItemEditor.
*
* @default null
*/
public function get itemEditor():IFactory
public function set itemEditor(value:IFactory):void
/**
* A factory for IGridItemRenderers used to render individual grid cells. If not specified,
* the grid's itemRenderer is return.
*
* The default item renderer just displays the value of its label property,
* which is based on the dataProvider item for the cell's row, and on the column's dataField
* property. Custom item renderers that derive more values from the data item and include
* more complex visuals are easily created by subclassing GridItemRenderer.
*
* @default The value of the grid's itemRenderer, or null.
*/
public function get itemRenderer():IFactory
public function set itemRenderer(value:IFactory):void
* If specified, the value of this property must be an idempotent function
* that returns an item renderer IFactory based on its dataProvider item
* and column parameters. Specifying an itemRendererFunction makes it possible to
* employ more than one item renderer in this column.
*
* The itemRendererFunction's signature must match the following:
*
* itemRendererFunction(item:Object, column:GridColumn):IFactory
*
* The item parameter is the dataProvider item for an entire row; it's
* the value of grid.dataProvider.getItemAt(rowIndex). The second
* parameter is this column.
*
* Here's an example of an itemRendererFunction:
*
* function myItemRendererFunction(item:Object, column:GridColumn):IFactory
* {
* return (item is Array) ? myArrayItemRenderer : myItemRenderer;
* }
*
* @default null
*/
public function get itemRendererFunction():Function
public function set itemRendererFunction(value:Function):void
/**
* An idempotent function that converts a dataProvider item into a column-specific string
* that's used to initialize the item renderer's label property.
*
* A labelFunction can be use to combine the values of several dataProvider item
* properties into a single string. If specified, this property is used by the
* itemToLabel() method, which computes the value of each item
* renderer's label property in this column.
*
* The labelFunction's signature must match the following:
*
* labelFunction(item:Object, column:GridColumn):String
*
* The item parameter is the dataProvider item for an entire row; it's
* the value of grid.dataProvider.getItemAt(rowIndex). The second
* parameter is this column.
*
* A typical labelFunction might concatenate the item's firstName and
* lastName properties, or do some custom formatting on a Date valued
* item property.
*
* @default null
*/
public function get labelFunction():Function
public function set labelFunction(value:Function):void
/**
* The minimum width of this column in pixels. If specified, the grid's layout will
* make the column's layout width the larger of the typicalItem's width and the minWidth.
* If this column is resizable, this property limits how small the user can make this column.
* Setting this property will not change the width or maxWidth properties.
*
* @default 20
*/
public function get minWidth():Number
public function set minWidth(value:Number):void
/**
* The maximum width of this column in pixels. If specified, the grid's layout will make
* the column's layout width the smaller of the typicalItem's width and the maxWidth.
* If this column is resizable, this property limits how wide the user can make this column.
* Setting this property will not change the width or minWidth properties.
*
* @default NaN
*/
public function get maxWidth():Number
public function set maxWidth(value:Number):void
/**
* Determines whether any of the item renderer's controls are editable.
* If the column is editable, the focusable controls in the item renderer
* will be given keyboard focus when the user starts editing the item
* renderer.
*
* @default false
*/
public function get rendererIsEditable():Boolean
public function set renderIsEditable(value:Boolean):void
/**
* Enable interactive resizing of this column's width if the grid's
* resizableColumns property is also true.
*
* @default true
*/
public function get resizable():Boolean
public function set resizable(value:Boolean):void
/**
* Returns a SortField that can be used to sort a collection by this
* column's dataField.
*
* If the sortCompareFunction property is defined,
* the SortField's compare function is assigned to a closure around
* the sortCompareFunction that uses the right signature
* for the SortField and captures this column.
*
* If the sortCompareFunction property is not defined
* and the dataField is complex, then the SortField's
* compare function is assigned to a closure around a default compare
* function that handles the complex dataField.
*/
public function get sortField():SortField
/**
* Show dataTips for the cells in this column.
*
* If this property's value is undefined(the default), then the grid's showDataTips
* property determines if dataTips will be shown. If this property is set, then
* the grid's showDataTips property is ignored.
*
* @default undefined
*/
public function get showDataTips():*
public function set showDataTips(value:*):void
/**
* If true, and if the grid's data provider is an ICollectionView,
* and if the associated grid's sortableColumns property is true,
* then this column supports interactive sorting.
* Typically the column's header handles mouse clicks by setting the data provider's
* sort> property to a Sort object whose SortField is this column's dataField.
*
* If the data provider is not an ICollectionView, then this property has no effect.
*
* @default true
*/
public function get sortable():Boolean
public function set sortable(value:Boolean):void
/**
* The function that compares two elements during a sort of on the
* data elements of this column. When unspecified, the sort will
* use a basic string or number sort on the data instead.
*
* The sortCompareFunction's signature must match the following:
*
* sortCompareFunction(obj1:Object, obj2:Object, column:GridColumn):int
*
* The function should return a value based on the comparison
* of the objects:
* -1 if obj1 should appear before obj2 in ascending order.
* 0 if obj1 = obj2.
* 1 if obj1 should appear after obj2 in ascending order.
*
* The function may use the column parameter to write generic compare functions.
*
* Note: The obj1 and objs parameters are entire data provider elements and not
* just the data for the item.
*
* @default null
*/
public function get sortCompareFunction():Function
public function set sortCompareFunction(value:Function):void
/**
* If true, this column is sorted in descending order. For example if the column's dataField
* selects a numeric value, then the first row would be the one with the largest value
* for this column.
*
* @default false;
*/
public function get sortDescending():Boolean
public function set sortDescending(value:Boolean):void
/**
* If true, then display this column. If false, no space will be allocated
* for this column; it will not be included in the layout.
*
* @default true
*/
public function get visible():Boolean
public function set visible(value:Boolean):void
/**
* The width of this column in pixels. If specified, the grid's layout will ignore its
* typicalItem and this column's minWidth and maxWidth.
*
* @default NaN
*/
public function get width():Number
public function set width(value:Number):void
/**
* Convert the specified dataProvider item to a column-specific String.
* The value of this method is used to initialize item renderers' label property.
*
* If labelFunction is null, and dataField
* is a string that does not contain "." field name separator characters,
* and formatter is null, then this method is equivalent to:
*
* item<a href="dataField">dataField</a>.toString()
*
* If the formatter was specified, then this method's value is:
*
* formatter.format(item<a href="dataField">dataField</a>)
*
* If dataField is a "." separated
* path, then this method looks up each successive path element.
* For example if ="foo.bar.baz", then this method returns
* a string based on the value of item.foo.bar.baz.
* If resolving the item's dataField
* causes an error to be thrown, ERROR_TEXT is returned.
*
* If item and labelFunction are not null then this method returns
* labelFunction(item, this), where the second argument is
* this GridColumn.
*
* @param item The value of grid.dataProvider.getItemAt(rowIndex)
*
* @return A column-specific string for the specified dataProvider item or ERROR_TEXT.
*/
public function itemToLabel(item:Object):String
/**
* Convert the specified data provider item to a column-specific datatip String.
*
* This method uses the values dataTipField
* and dataTipFunction.
* If those properties are null, it uses the corresponding properties
* from the associated grid control.
* If dataTipField properties is also null in the grid control,
* then use the dataField property.
*
* If dataTipFunction and dataTipFormatter are
* null, then this method's value is the same as:
* item<a href="dataTipField">dataTipField</a>.toString(). If dataTipFormatter is
* specified then this method's value is the same as:
* dataTipFormatter.format(item<a href="dataTipField">dataTipField</a>)
* If resolving the item's dataField
* causes an error to be thrown, ERROR_TEXT is returned.
*
* If item and dataTipFunction
* are not null, then this method returns
* dataTipFunction(item, this), where the second argument is
* this GridColumn.
*
* @param item The value of grid.dataProvider.getItemAt(rowIndex).
*
* @return A column-specific string for the specified data provider item
* or ERROR_TEXT.
*/
public function itemToDataTip(item:Object):String
/**
* Convert the specified dataProvider item to a column-specific item renderer factory.
* By default this method calls the itemRendererFunction if it's
* non-null, otherwise it just returns the value of the column's itemRenderer
* property.
*
* @param item The value of grid.dataProvider.getItemAt(rowIndex)
*
* @return A column-specific item renderer factory for the specified dataProvider item.
*/
public function itemToRenderer(item:Object):IFactory
}
}
Grid and Header renderers must implement this interface. It's similar to IItemRenderer with the addition of a column:GridColumn property. It also includes a pair of methods, prepare() and discard(), which enable developers to initialize the renderer each time it's reused, and to cleanup when the renderer is moved to the Grid's internal free-list.
package spark.components
{
/**
* Grid item renderers must implement this interface. The Grid component
* uses this API to provide the item renderer with the information needed
* to render one grid cell.
*
* All of the renderer's properties are set by Grid during updateDisplayList().
* After they've been set, the renderer's prepare() method is called. IGridItemRenderer
* implementations should override the prepare() method to make any final adjustments to
* its properties or any aspect of its visual elements. When an item renderer is no longer
* needed, either because it's going to be added to the Grid's internal reusable renderer "free"
* list, or because it's no longer needed, the discard() method is called.
*/
public interface IGridItemRenderer extends IDataRenderer, IVisualElement
{
/**
* The Grid associated with this item renderer, typically just the value of
* column.grid.
*/
function get grid():Grid;
/**
* The dataProvider index of the item being displayed by this item renderer.
*/
function get rowIndex():int;
function set rowIndex(value:int):void;
/**
* The column index for the column displayed by this item renderer. Just a convenient
* way to access column index.
*/
function get columnIndex():int;
/**
* True if the item renderer is being dragged, typically as part of a drag and drop operation.
* Currently not supported by DataGrid.
*/
function get dragging():Boolean;
function set dragging(value:Boolean):void;
/**
* True if the item renderer is being hovered over by the mouse.
* Unlike a List item renderer, grid item renderers do not have exclusive
* responsibility for displaying the hovered indicator. The Grid itself
* renders the hovered indicator for the selected row or cell.
* The item renderer can also change its visual properties to emphasize
* that it's being hovered over.
*/
function get hovered():Boolean;
function set hovered(value:Boolean):void;
/**
* The string to display in the item renderer's cell.
*
* The GridItemRenderer class automatically copies the
* value of this property to the text property of its labelDisplay.
* The Grid sets the label to the value returned by the column's
* itemToLabel() method.
*/
function get label():String;
function set label(value:String):void;
/**
* True if the item renderer's cell is part
* of the current selection. Unlike a List item renderer,
* grid item renderers do not have exclusive responsibility for displaying the
* selection indicator. The Grid itself renders the selection indicator for the
* selected row or cell. The item renderer can also change its visual properties
* to emphasize that it's part of the selection.
*/
function get selected():Boolean;
function set selected(value:Boolean):void;
/**
* True if the item renderer's cell is contained within the caret indicator.
* As with the selected property, grid item renderers do not have exclusive
* responsibility for displaying the caret indicator. Contains true
* if the item renderer can show itself as focused.
*/
function get showsCaret():Boolean;
function set showsCaret(value:Boolean):void;
/**
* The column for the item renderer's cell. This property is set by the Grid by its
* updateDisplayList() method.
*/
function get column():GridColumn;
function set column(value:GridColumn):void;
/**
* Called from the Grid's updateDisplayList() method after all of the
* column's properties have been set. The hasBeenRecycled parameter is false
* if this renderer hasn't been used be for, i.e. if it wasn't "recycled". This method is
* called when a renderer is about to become visible, typically because it was
* scrolled into view.
*
* This method is not intended to be called directly, it's called by the Grid implementation.
*
* @param hasBeenRecycled True if this renderer is being reused.
*/
function prepare(hasBeenRecycled:Boolean):void;
/**
* Called from the Grid's updateDisplayList() when it has been determined
* that this renderer will no longer be visible. If the willBeRecycled parameter
* is true, then the Grid will add this renderer to its internal "free" list. Implementations
* can use this method to clear any renderer properties that are no longer needed.
*
* This method is not intended to be called directly, it's called by the Grid implementation.
*
* @param willBeRecycled True if this renderer is going to be added to the Grid's internal free list, to be reused later.
*/
function discard(willBeRecycled:Boolean):void;
}
}
package spark.components.gridClasses
{
/**
* A convenient base class for custom grid item renderers. Grid item renderers
* are only required to display some column-specific aspect of their data. They're
* not responsible for displaying the selection or hover indicators, the alternating
* background color (if any), or row/column separators.
*
*/
public class GridItemRenderer extends Group implements IGridItemRenderer
{
// ... Same API as IGridItemRenderer
}
}
DataGrid cell rendering presents some difficult performance problems, particularly for grids where a large number of cells is visible. To enable smooth scrolling over a very large grid when the user drags a scrollbar thumb, it must be possible to configure and display all of the visible cell renderers rather quickly. A large grid might have 100,000 rows and 1000 columns, so dragging the scroller the thumb is likely to continuously expose completely new "pages" of cells. If the the grid is configured so that 200 cells are visible, to achieve a reasonable frame rate of 20 frames or "full pages" per second, each cell needs to be configured and displayed in 1/4 of a millisecond. If 500 cells are visible that falls to 1/10 of a millisecond.
As of this writing it's not possible to achieve that kind of performance with complex custom Spark item renderers based on GridItemRenderer. For that reason the default grid item renderer is a carefully coded ActionScript class based on UIFTETextField. It performs reasonably well on all Flash platforms. The best possible performance on Windows can be achieved by using the older, Flash TextField based, UITextField class. The UITextFieldGridItemRenderer provides the best performance on Windows.
/**
* A simple and efficent IGridItemRenderer that displays a single text label. This
* class is the default value for the s:DataGrid itemRenderer property. It's based
* on FTE, the FlashTextEngine, It is based on FTE, the “FlashTextEngine”, which supports
* high-quality international typography and font embedding in the same way as other
* Spark controls.
*
* Label text wrapping can be controlled with the lineBreak style. For example
* a DataGrid configured like this:
* lineBreak="explicit" variableRowHeight="false" yields fixed height
* DataGrid cells whose labels do not wrap.
*
* DefaultGridItemRenderer is not intended to be subclassed or copied, it is
* effectively final. Custom item renderers can be created in MXML with the
* GridItemRenderer component.
*
* @see spark.components.gridClasses.GridItemRenderer
*/
public class DefaultGridItemRenderer extends UIFTETextField implements IGridItemRenderer, IStyleClient
{
// ... Same API as IGridItemRenderer
}
/**
* A simple and efficent IGridItemRenderer that displays a single text label. For
* applications displaying Grids with large numbers of visible cells, this renderer
* provides optimum performance on Windows. It is based on TextField, not FTE,
* so it lacks support for some Spark text features.
*
* Label text wrapping can be controlled with the lineBreak style. For example
* a DataGrid configured like this:
* lineBreak="explicit" variableRowHeight="false" yields fixed height
* DataGrid cells whose labels do not wrap.
*
* This class is not intended to be subclassed or copied, it is
* effectively final. Custom item renderers can be created in MXML with the
* GridItemRenderer component.
*
* @see spark.components.gridClasses.GridItemRenderer
*/
public class UITextFieldGridItemRenderer extends UITextField implements IGridItemRenderer, IStyleClient
{
// ... Same API as IGridItemRenderer
}
Although both item renderer classes are documented as being "effectively final", they can be subclassed and styled in MXML as explained in the following section.
One feature of Spark DataGrid that was not carried over from MX, is the support for setting styles on columns directly. Rather specifying styles on GridColumn objects directly, we just support styling item renderers.
To configure styles for a Spark DataGrid GridColumn, specify an item renderer for the column:
<s:GridColumn dataField="myDataField">
<s:itemRenderer>
<fx:Component>
<s:DefaultGridItemRenderer fontSize="24"/>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
Using GridItemRenderer is similar:
<s:GridColumn dataField="myDataField">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:Label id="labelDisplay" fontSize="24"/>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
The same approach can be used with the DataGrid itemRenderer property to configure the default item renderer for all columns.
One can also use the styleName property to specify the styles for a column, for example:
<s:GridColumn dataField="myDataField">
<s:itemRenderer>
<fx:Component>
<s:DefaultGridItemRenderer styleName="myDataFieldColumn"/>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<fx:Style>
.myDataFieldColumn {
fontSize: 48;
}
</fx:Style>
/**
* The element type for the Grid layers property.
*
* A GridLayer is a non-visual object that has a simple no-layout container for Grid visual elements.
* Visual elements are added to the layer's (internal) container with addElement() and removed with
* removeElement(). GridLayer containers must not impose a layout on their elements, the Grid's
* layout is responsible for sizing and positioning all GridLayer elements.
*/
public class GridLayer
{
/**
* A unique identifier for this layer. The Grid's layout looks up layers by id.
*/
public function get id():String
public function set id(value:String):void
/**
* The root of the hierarchy that addElement() adds visual elements to and
* removeElement() removes them from. To add a GridLayer to another Group,
* add its root: myGroup.addElement(myGridLayer.root).
*
* @default A Group configured with a no-op layout.
*/
public function get root():IVisualElement
public function set root(value:IVisualElement):void
/**
* Add the specified element to this GridLayer. The relative order of elements
* is not guaranteed.
*/
public function addElement(elt:IVisualElement):void
{
if (elt.parent != root)
IVisualElementContainer(root).addElement(elt);
}
/**
* Remove the specified element from this GridLayer.
*/
public function removeElement(elt:IVisualElement):void
{
if (elt.parent == root)
IVisualElementContainer(root).removeElement(elt);
}
/**
* Validate this layer's display list.
*/
public function validateNow():void
{
IInvalidating(root).validateNow();
}
}
}