cell - One element of a grid; the intersection of a row and column.
column heading, column header - A column heading is the title that appears above one column, and the column header is the group that contains all of the column headings.
data item - An element of the grid's dataProvider. Different aspects of a single data item are used to display all of the cells in a grid row.
grid - A two dimensional table of cells, like a simple spreadsheet or an HTML table.
indicator - A visual element that highlights a property of a grid cell or row.
IPE - An ItemPendingError. Some dataProviders backed by remote collections throw an IPE to indicate that the requested data item isn't available yet.
item renderer - A visual element used to render the contents of a grid cell. Also the factory (IFactory) used to create the visual elements. And sadly: also the class that such a factory represents.
row, column - The vertical and horizontal addresses of a grid cell.
separator - A visual element placed in between rows or columns.
smooth scrolling - For DataGrid: indicates that the scrollbar thumb corresponds to the pixel origin of the grid's viewport. In contrast to row-quantized scrolling, where the first grid row displayed is always completely visible because the scrollbar thumb's position correspond to a row index, not a pixel offset.
DataGrid is a Spark component that displays a mutable list of data items in a scrollable table or "grid", one item per row. Each of the grid's columns displays a value based on the item for the corresponding row. The DataGrid's list of columns is mutable: columns can be moved, added, and removed. The DataGrid displays a row of column headings above the scrollable grid. Column headings are used to identify what's displayed in each column and the and can be configured to sort the DatGrid's list according to a per-column sort key. Columns can be interactively resized or moved.
Each grid cell can contain any Flex visual element, from simple graphic elements, to complex forms.
DataGrid supports interactive (and progamatic) row or cell selection based on mouse or keyboard input. Single and multiple selection modes are supported. DataGrid also supports interactively editing row or cell values.
DataGrid can support large grids efficiently. It's possible to smoothly scroll through a list of tens of thousands of rows (items) and hundreds of columns. Row heights can vary and can be automatically sized to reflect their contents. Initial column widths can be based on the rendered size of a typical data item.
DataGrid is skinnable. The DataGrid skin is responsible for laying out the grid, column header, and scroller and for configuring the graphic elements used to render visual elements used as indicators, separators, and backgrounds. The DataGrid skin can also provide a default item renderer, used to display the contents of each cell, for columns that don't specify one.
The Spark DataGrid is quite similar to MX version, both in terms of overall structure and features. Some notable differences:
Disclaimer: The usage scenarios in this section focus on the GridColumn GridItemRenderer classes as well as DataGrid's visual element properties. The goal of this section is to highlight the Spark DataGrid features that are substantially different from the MX DataGrid class. It is not intended to be a comprehensive overview of the API.
DataGrid displays the items in its IList dataProvider according to its list of GridColumns. Here's a complete application example in MXML:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
import mx.collections.IList;
<a href="Bindable">Bindable</a> public var gridData:IList = new ArrayList([
{firstName: "Fred", lastName: "Flintsone", food: "hamburger", drink: "beer"},
// ... more similar objects
]);
</fx:Script>
<s:DataGrid id="dataGrid" dataProvider="{gridData}" width="100%" height="100%">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="firstName"/>
<s:GridColumn dataField="lastName"/>
<s:GridColumn dataField="food"/>
<s:GridColumn dataField="drink"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:Application>
In this example the DataGrid's dataProvider is a list of objects, which of which contains firstName, lastName, food, and drink properties. The DataGrid includes one column for each property and the GridColumn dataField property is used to select the dataProvider item property to display in that column. This example takes advantage of the fact that the default itemRenderer displays the string value of data[column.dataField], where data is dataProvider.getItemAt(rowIndex), aka the "data item" for the specified grid row.
A GridColumn's itemRenderer is an IVisualElement that implements IGridItemRenderer. The GridItemRenderer base class is a Group that implements IGridItemRenderer and is convenient for creating custom item renderers. The code fragment below is a replacement for the first two GridColumns in the previous example. It defines a single GridColumn with a custom itemRenderer that displays both the firstName and lastName properties by binding to the GridItemRenderer's's data property:
<s:GridColumn>
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:Label text="{data.firstName} {data.lastName}"
left="10" right="5" paddingTop="10" paddingBottom="5"/>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
Note: for simplicity's sake we haven't made each property of the dataProvider's items bindable. Although the example will correctly display the initial value of each data item property, the binding system will issue a warning because it can not track subequent changes to these properties. A real application whose item renderer was bound to data item properties would have to ensure that those properties were defined with the Bindable metadata.
In this case the GridItemRenderer just contains a single Label. In addition to including a bindable data property that corresponds to the dataProvider item for the current row, GridItemRenderer has bindable rowIndex and column properties that specify the current row index and [GridColumn. Cell item renderers can bind to these properties as well, for example:
<s:GridColumn>
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:Label text="{rowIndex}"
left="10" right="5" paddingTop="10" paddingBottom="5"/>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
This column just displays the current row number (rowIndex).
Item renderers aren't required to use data binding to configure their visual elements. It can be more efficient and flexible to override the GridItemRenderer prepare() method, which is called after the item renderer has been configured and just before it's displayed. The example below is a generic checkbox item renderer that displays the boolean value selected by the column's dataField:
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
override public function prepare(hasBeenRecycled:Boolean):void
{
valueDisplay.selected = data<a href="column.dataField">column.dataField</a> as Boolean;
}
]]>
</fx:Script>
<s:CheckBox id="valueDisplay"/>
</s:GridItemRenderer>
The prepare() hasBeenRecycled parameter lets the method know if the renderer has just been created, or if it's being reused. In some cases developers might want to do one-time item renderer initializations when hasBeenRecycled=false.
Not all of the visual elements of a DataGrid can be displayed with item renderers. Row and column separators and row backgrounds are visual elements that would be clumsy to render, if each item renderer was responsibe for contributing one cell's worth of the overall visual. Even visual aspects like the selection or hover indicators, which are the exclusive responsibility of item renderers in the Spark List, are rendered separately in the Spark DataGrid. This is because the shape of these indicators depends on the selection mode. If the DataGrid's selectionMode is "row" or "multipleRows", then the indicators span each affected row.
In addition to the per-column item renderer, DataGrid defines six skin parts that are used to display repeating elements and indicators:
selectionIndicator - A visual element that's displayed for each selected row or cell (depends on the DataGrid selectionMode property).
caretIndicator - A single visual element that's displayed for the caret row or cell (depends on the DataGrid selectionMode property).
hoverIndicator - A single visual element that's displayed for the row or cell under the mouse (depends on the DataGrid selectionMode property).
rowSeparator - A visual element that's displayed in between each row.
columnSeparator - A visual element that's displayed in between each column.
rowBackground - A visual element that's displayed for each row. It's used to implement the alternatingRowColors style.
All of these DataGrid IFactory skin parts are required to be IVisualElements. In many cases they're just GraphicElements like Rects or Lines, which can be renderered quite efficiently because the Flex runtime's "display object sharing" support uses a single DisplayObject to render all of them. Just like item renderers, these visual elements are internally pooled and recycled, to avoid the cost creating and adding them when the DataGrid is scrolled.
A DataGrid skin, defined as a subclass of the default DataGridSkin, can replace one or more default visual element skin parts by including the new values in an fx:Declarations section. For example, to define a DataGrid skin derived from the default, with new values for the caretIndicator and selectionIndicator:
<?xml version="1.0" encoding="utf-8"?>
<spark:DataGridSkin
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:spark="spark.skins.spark.*">
<fx:Declarations>
<fx:Component id="caretIndicator">
<s:Rect>
<s:stroke>
<s:SolidColorStroke color="0xFFBC7A" weight="2"/>
</s:stroke>
</s:Rect>
</fx:Component>
<fx:Component id="selectionIndicator">
<s:Rect>
<s:fill>
<s:SolidColor color="0xC082FF"/>
</s:fill>
</s:Rect>
</fx:Component>
</fx:Declarations>
</spark:DataGridSkin>
This survey of DataGrid features is by no means comprehensive, more details about the corrresponding APIs follow. Note that in most cases capabilities that were present in the MX DataGrid, save the ones explicitly listed in the "Summary and Background" section, are also available in the Spark Datagrid, usually with the same API.
The skinnable DataGrid component is really a special purpose container for its Grid and a GridColumnHeaderGroup skin parts. It's the Grid component that actually displays the rows and columns and manages the selection, caret and so on. The DataGrid's skin is responsible for arranging these elements and a Scroller. Structually the DataGrid is similar to the Spark List component, which also delegates responsibility for displaying its items to a separate, non-skinnable, component, the DataGroup. Most of the DataGroup's properties and methods are just "covers" for its grid skin part. The DataGrid adds its own mouse and keyboard event handling to support Grid selection, cell editing, and scrolling. Similarly, DataGrid event handlers added to the GridColumnHeaderGroup enable interactive column operations, like resizing.
The DataGrid displays its dataProvider, an IList whose Object elements are referred to as "data items" or just "items". Each row in the DataGrid displays different aspects of a data item, one aspect per column. Rows and columns define grid "cells" and a cell's location is typically defined by a pair of "rowIndex", "columnIndex" integers. The DataGrid's columns define the aspect of the data item to be displayed and the "item renderer" used to display it. The DataGrid's columns are also defined by an IList and each column must be an instance of GridColumn]. Typically the GridColumn's "dataField" property is used to define the data item property to be displayed (as a string) in that column. All of the cells in a column are displayed with the same item renderer, a factory that produces instances of IGridItemRenderer.
The figure below illustrates how DataGrid has been factored into classes and parts:
The "indicator" suffix is used to identify visual elements that reflect the state of the row or cell. Not shown is the "rowSeparator", which is displayed in between rows.
To make reviewing the complete specifications for all of the classes a little more manageable, they have been broken down into several categories. The material for each category appears in a separate document. Note that the Grid and DataGrid classes have a great deal of API in common, because DataGrid "covers" many of the methods and properties defined by its grid skin part.
The visual elements for Grid and DataGrid. This document covers the Grid, DataGrid, GridColumn, GridItemRenderer, IGridItemRenderer classes and interfaces.
The default value of the DataGrid's columnHeaderGroup skin part is a GridColumnHeaderGroup.
How the DataGrid computes row heights, column widths, and its measured size.
The Grid class dispatches some grid-specific events in response to mouse events, to simplify event handling for features like selection. This document covers the Grid and GridEvent classes.
The Grid class provides a rich selection model and the DataGrid adds mouse and keyboard handlers that use it. This document covers the Grid and DataGrid, GridSelectionMode, GridCaretEvent, GridSelectionEvent classes.
Grid and DataGrid provide an API that exposes the visible and overall geometry of the grid. This document covers the DataGrid and Grid classes.
The DataGrid's skin is responsible for laying it the grid, columnHeaderGroup, and scroller skin parts. This document covers the DataGrid and DataGridSkin classes.
This document covers the support for cell editing and for keyboard focus management within the DataGrid.
Detail features here that are to be considered for B Feature time.
Include examples of how this feature would be used in practice, from MXML and ActionScript code, or from the command line, or from other mechanisms as appropriate
Enter implementation/design details for the feature here. This section may be updated after the spec signs off.
Will this feature require any compiler changes? If so, describe here, if not already included in the Detailed Description.
List any syntax changes (MXML tags, attributes, AS syntax changes) that may affect backward compatibility with existing applications.
Does any part of this feature support the -compatibility-version compiler argument?
List any changes to existing MXML tags, attributes, etc.
Clearly identify anything that existing features that will become deprecated. Identify any warnings that will be issued (if any) as a result. Identify recommended documentation changes that should accompany.
Describe any accessibility considerations.
Performance goals below are based on a 952-cell Spark DataGrid of 28 columns by 34 rows, using the default item renderer.
The Windows XP benchmark machine referenced below is an Intel Core2 CPU 6400 @ 2.13GHz with 2GB of RAM.
The performance goals will be as follows:
All components that deal with text will need to be globalization-aware. This means that text in any supported language can be used with the component.
The component must use the Unicode character set (mostly comes for free from Flash Player) and must interoperate with IME's (Input Method Editors) for foreign languages (also mostly supported via Flash Player).
Globalization also includes issues with date/time formatting and currency formatting for specific locales.
European (French, German, etc.) and Asian (Japanese, Korean, Chinese) languages are of particular concern.
Note any specific globalization issues here.
Command-line help descriptions should be added to sdk/modules/compiler/src/java/flex2/configuration_en.properties and configuration_ja.properties.
Error/warning messages that are related to the compiler core (flex2.compiler.* packages) should be added to sdk/modules/compiler/src/java/flex2/compiler_en.properties and compiler_ja.properties.
Error/warning messages that are related to the linker (flex2.linker.* packages) should be added to sdk/modules/compiler/src/java/flex2/linker_en.properties and linker_ja.properties.
CompilerMessage subclasses should be created to support the messages in the .properties files.
The _ja.properties files are unicode-escaped files.
List the RTE message strings that will require localization. (They must all come from .properties files.)
List all UI text that will require localization, such as the month and day names in a DateChooser__. (All such text must all come from .properties files.)
List all UI images, skins, sounds, etc. that will require localization.
Discuss any locale-specific formatting requirements for numbers, dates, currency, etc.
Discuss any locale-specific sorting requirements.
Does this feature apply differently to Windows versus Mac platforms, or require different testing depending on platform?
Enumerate open issues needing resolution, along with recommended solutions, if any.
\
Wiki: AsyncListView Specification
Wiki: Data Grid Column Headers
Wiki: Data Grid Editing
Wiki: Data Grid Geometry
Wiki: Data Grid Layout
Wiki: Data Grid Mouse Events
Wiki: Data Grid Selection
Wiki: Data Grid Skin
Wiki: Data Grid Visuals
Wiki: Flex 4.5
Wiki: Spark DataGrid
Wiki: Spark DataGroup