View comments | RSS feed

Using the CellRenderer API

You must write a class with four methods (CellRenderer.getPreferredHeight(), CellRenderer.getPreferredWidth(), CellRenderer.setSize() and CellRenderer.setValue()) that the list-based component uses to communicate with the cell (if the class extends UIObject, you can use size() instead of CellRenderer.setSize()). The class must be specified in the AS 2.0 Class text box in the Linkage Properties dialog box of a movie clip symbol in your Flash application.



You can look at the CheckCellRenderer class that implements the Cell Renderer API for an example; it's located in First Run/classes/mx/controls/cells. Also, see the DataGrid component documentation for CellRenderer related information, including DataGrid performance strategies.

There are two methods and a property (CellRenderer.getCellIndex(), CellRenderer.getDataLabel(), and CellRenderer.listOwner) that are given automatically to a cell to allow it to communicate with the list-based component. For example, suppose a cell contains a check box that, when selected, causes a row to be selected. The cell renderer needs a reference to the list-based component that contains it in order to call the component's selectedIndex property. Also, the cell needs to know which item index it is currently rendering so that it can set selectedIndex to the correct number; the cell can use CellRenderer.listOwner and CellRenderer.getCellIndex() to do so. You do not need to implement these ActionScript elements; the cell receives them automatically when it is placed in the list-based component.

Simple cell renderer example

This section presents an example of a cell renderer that displays multiple lines of text in a cell.

The following tutorial shows how to create a cell renderer class that displays multiple lines of text in the cells of a DataGrid component.

The completed files, MultiLineCell.as and CellRenderer_tutorial.fla are located at www.macromedia.com/go/component_samples.

Creating the MultiLineCell cell renderer class

A cell renderer class must implement the following methods:

A cell renderer class must also declare the methods and property received from the List class:

The following steps show how to create an ActionScript 2.0 cell renderer class file called MultiLineCell.as and link it to a new movie clip symbol in a new Flash document. Then, you can add a DataGrid component to the Flash document library. On the first frame, you add ActionScript that creates the DataGrid dynamically and assigns the MultiLineCell class as the cell renderer for one of its columns:

To create the multiLineCell cell renderer class:

  1. In Flash, select File > New > ActionScript File (not Flash Document). Save the document as MultiLineCell.as.
  2. Enter the following code into MultiLineCell.as:
    // ActionScript 2.0 class.
    class MultiLineCell extends mx.core.UIComponent
    {
        private var multiLineLabel; // The label to be used for text.
        private var owner; // The row that contains this cell.
        private var listOwner; // The List, data grid or tree containing this cell.
    
        // Cell height offset from the row height total and preferred cell width.
        private static var PREFERRED_HEIGHT_OFFSET = 4; 
        private static var PREFERRED_WIDTH = 100;
        // Starting depth.
        private var startDepth:Number = 1;
    
        // Constructor. Should be empty.
        public function MultiLineCell()
        {
        }
    
        /* UIObject expects you to fill in createChildren by instantiating all the movie clip assets you might need upon initialization. In this case we are creating one label*/
        public function createChildren():Void
        {
            // The createLabel method is a useful method of UIObject and a handy
            // way to make labels in components.
            var c = multiLineLabel = this.createLabel("multiLineLabel", startDepth);
            // Links the style of the label to the style of the grid
            c.styleName = listOwner;
            c.selectable = false;
            c.tabEnabled = false;
            c.background = false;
            c.border = false;
            c.multiline = true;
            c.wordWrap = true;
        }
    
        public function size():Void
        {
    /* By extending UIComponent which imports UIObject, you get setSize automatically, however, UIComponent expects you to implement size(). Assume __width and __height are set for you now. You're going to expand the cell to fit the whole rowHeight. The rowHeight itself is a property of the list type component that we are rendering a cell in. Since we want the rowHeight to fit two lines, when creating the list type component using this cellRenderer class, make sure its rowHeight property is set large enough that two lines of text can render within it.*/
        
    /*__width and __height are the underlying variables of the getter/setters .width and .height.*/
            var c = multiLineLabel;
            c.setSize(__width, __height);
        }
    
        // Provides the preferred height of the cell. Inherited method.
        public function getPreferredHeight():Number
        {
    /* The cell is given a property, "owner", that references the row. It's always preferred that the cell take up most of the row's height. In this case we will keep the cell slightly smaller.*/
            return owner.__height - PREFERRED_HEIGHT_OFFSET;
        }
    
        // Called by the owner to set the value in the cell. Inherited method.
        public function setValue(suggestedValue:String, item:Object, selected:Boolean):Void
        {
    /* If item is undefined, nothing should be rendered in the cell, so set the label as invisible. Note: For scrolling List type components like a scrolling datagrid, the cells are intended to be empty as they scroll just out of sight, and then the cell is reused again and set to a new value producing an animated effect of scrolling. For this reason, you cannot rely on any one cell always having data to show or the same value.*/
            if (item!=undefined){
                multiLineLabel.text._visible = false;
            }
            multiLineLabel.text = suggestedValue;
        }
        // function getPreferredWidth :: only for menus and DataGrid headers
        // function getCellIndex :: not used in this cell renderer
        // function getDataLabel :: not used in this cell renderer
    }
    

Creating an application to test the MultiLineCell cell renderer class

In the following steps, you will create the DataGrid instance and implement the MultiLineCell class.

To create an application with a DataGrid component that uses the MultiLineCell cell renderer class:

  1. In Flash, select File > New > Flash Document.
  2. Select File > Save As, name the file cellRender_tutorial.fla, and save the file to the same folder as the MultiLineCell.as file.
  3. To create a new movieClip symbol to link to the MultiLineCell class, select Insert > New Symbol.
  4. Click the Advanced button in the lower-right corner of the Create New Symbol dialog box to enable more options.

    The Advanced button is available when you are in the basic mode of the Create New Symbol dialog box. If you don't see the Advanced button, you are probably already in the Advanced view of the dialog box.

  5. In the Name text box, type MultiLineCell.

    The default value for Type is Movie Clip. Leave Movie Clip selected.

  6. Click the Export for ActionScript check box in the Linkage section.

    Enabling this option allows you to dynamically attach instances of this symbol to your Flash documents during runtime. The Identifier text box will automatically show MultiLineCell.

  7. Set the ActionScript 2.0 Class to MultiLineCell (to match the class name of the MultiLineCell cell renderer class created previously).
  8. Enable the Export in first frame check box and click OK to apply your changes and close the dialog box.

    NOTE

     

    If you need to modify the MultiLineCell Movie Clip symbol's Linkage properties at a later time, you can right click the symbol in the document's library and select Properties or Linkage from the menu.

  9. Drag the DataGrid component from the Components panel to the library.

    The DataGrid instance will be created dynamically through ActionScript in the following step.

  10. Select the first frame on the main Timeline (make sure you are not still in the MultiLineCell movie-clip editing mode).
  11. In the Actions panel for the first frame, enter the following code to create a DataGrid dynamically, assign data to the DataGrid, and assign your new cell renderer class:
    // Create a new DataGrid component instance 
    this.createClassObject(mx.controls.DataGrid, "myGrid_dg", 1);
    
    // Build a data provider for the data grid with four columns of data.
    myDP = new Array();
    var aLongString:String = "An example of a cell renderer class that displays a multiple line TextField";
    myDP.addItem({firstName:"Winston", lastName:"Elstad", note:aLongString, item:100});
    myDP.addItem({firstName:"Ric", lastName:"Dietrich", note:aLongString, item:101});   
    myDP.addItem({firstName:"Ewing", lastName:"Canepa", note:aLongString, item:102});   
    myDP.addItem({firstName:"Kevin", lastName:"Wade", note:aLongString, item:103});   
    myDP.addItem({firstName:"Kimberly", lastName:"Dietrich", note:aLongString, item:104});   
    myDP.addItem({firstName:"AJ", lastName:"Bilow", note:aLongString, item:105});   
    myDP.addItem({firstName:"Chuck", lastName:"Yushan", note:aLongString, item:106});
    myDP.addItem({firstName:"John", lastName:"Roo", note:aLongString, item:107});
    
    /* Assign the data provider to the DataGrid to populate it. Note: This has to be done before applying the cellRenderers. */
    myGrid_dg.dataProvider = myDP;
    
    /* Set some basic grid properties. Note: The data grid's row height should reflect the number of lines you expect to show in the MultiLineCell cell renderer. The cell renderer will size to the row height. This should be about 40 for 2 lines or 60 for 3 lines at default text size.*/
    myGrid_dg.setSize(430,200);
    myGrid_dg.move(40,40);
    myGrid_dg.rowHeight = 40; // Allows for 2 lines of text at default text size.
    myGrid_dg.getColumnAt(0).width = 70;
    myGrid_dg.getColumnAt(1).width = 70;
    myGrid_dg.getColumnAt(2).width = 220;
    myGrid_dg.resizableColumns = true;
    myGrid_dg.vScrollPolicy = "auto";
    myGrid_dg.setStyle("backgroundColor", 0xD5D5FF); 
    
    // Assign cellRenderers.
    myGrid_dg.getColumnAt(2).cellRenderer = "MultiLineCell";
    
  12. Save the Flash document, and select Control > Test Movie.

    A data grid appears. The third column of the data grid contains a multiple line cell.



    The completed MultiLineCell cell renderer example.


Additional cell renderer examples

Additional examples of cell renderer classes that display a ComboBox and a CheckCell component are also provided. These files are located in the CellRenderers_sample folder within the Samples and Tutorials folder on your hard disk at www.macromedia.com/go/component_samples.



The additional installed sample named CellRenderers_Sample displaying a ComboBox and CheckBox.


Methods to implement for the CellRenderer API

You must write a class with the following methods so that the List, DataGrid, Tree, or Menu component can communicate with the cell.

Method

Description

CellRenderer.getPreferredHeight()

Returns the preferred height of a cell.

CellRenderer.getPreferredWidth()

The preferred width of a cell.

CellRenderer.setSize()

Sets the width and height of a cell.

CellRenderer.setValue()

Sets the content to be displayed in the cell.

Methods provided by the CellRenderer API

The List, DataGrid, Tree, and Menu components give the following methods to the cell when it is created within the component. You do not need to implement these methods.

Method

Description

CellRenderer.getCellIndex()

Returns an object with two fields, columnIndex and itemIndex, that indicate the position of the cell.

CellRenderer.getDataLabel()

Returns a string containing the name of the cell renderer's data field.

Properties provided by the CellRenderer API

The List, DataGrid, Tree, and Menu component give the following properties to the cell when it is created within the component. You do not need to implement these properties.

Property

Description

CellRenderer.listOwner

A reference to the List component that contains the cell.

CellRenderer.owner

A reference to the row that contains the cell.


Version 8

Comments


Mozilla By said on Sep 16, 2005 at 6:25 AM :
if (item!=undefined){
multiLineLabel.text._visible = false;
}

maybe "item==undefined"?
djtechwriter said on Sep 16, 2005 at 1:10 PM :
Mozilla By is correct. The above MultiLineCell.as sample in "To create the multiLineCell cell renderer class" uses the wrong operator, it should be "==". The sample file at http:// www.macromedia.com/go/component_samples has been updated.
rollingsj said on Feb 6, 2006 at 7:10 PM :
Documentation on implementing/maintaining setFocus and tabIndex functionality within the CellRenderer API should be included here.
No screen name said on Dec 2, 2006 at 11:31 PM :
This code does not work. I have tried CheckCellRenderer under both flash mx 2004 and flash 8. In both scenarios the click event fails to fire.
No screen name said on Mar 14, 2007 at 7:36 AM :
If you want to render say a dropdown populated with a dataset from another dropdown on stage then thats fine at the stage the grid is built, but the refreshing of this isnt very good. Say for example the data is changed for the on stage dropdown (master) then all of the rows dropdowns dont automatically change, doing it on an enter frame within the cell render class causes such big performance problems it isnt working.
Would be great if an update method for a grid existed. Invalidate method doesnt seem to do anything.
No screen name said on Mar 16, 2007 at 12:37 PM :
**Error** MultiLineCell.as: Line 3: The name of this class, 'MultiLineCell', conflicts with the name of another class that was loaded, 'MultiLineCell'.
class MultiLineCell extends mx.core.UIComponent

Total ActionScript Errors: 1 Reported Errors: 1

 

RSS feed | Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/flash/8/main/00003131.html