Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection /

Exploring Rich Island development with Flex Builder – Part 4: Creating a custom component

by Trilemetry

Trilemetry
  • Trilemetry, Inc.

Content

  • Reviewing the architecture
  • Creating and using a custom component
  • Creating class properties using setter and getter functions
  • Creating functionality in a custom component

Modified

3 August 2009

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
Flex 3 Flex Builder 3 getter | setter

Requirements

Prerequisite knowledge

  • Part 1: Getting started
  • Part 2: Laying out and styling visual elements
  • Part 3: Handling data and binding it to controls

User level

All

Required products

  • Flash Builder (Download trial)

Sample files

  • sap_ri_pt4_starter.zip (316 KB)
  • sap_ri_pt4_solution.zip (25 KB)

Welcome to Part 4 of this tutorial series. In this part, you will make the code more flexible by creating reusable custom components. Figure 1 shows you the wagon assembly line that you laid out in Part 2 and added data to in Part 3. In this tutorial, you will transfer existing code for the colored bins and clock from the main application to custom component files. You will also create additional code to handle the bin color change and implement getter and setter functions for class properties.

Note: Parts 1 through 6 focus on teaching Flex development to SAP developers. Part 7 teaches Flex developers how to create a Web Dynpro application. Parts 8 and 9 show both SAP and Flex developers how to integrate the Flex application as a Rich Island into the Web Dynpro application.

The Wagon Assembly Line application
Figure 1. The Wagon Assembly Line application

Reviewing the architecture

Figure 2 outlines the Flex framework controls and containers that you will use in this application. Note that containers (such as Application, VBox, or Canvas containers) hold other containers or controls and are used to lay out visual elements in an application. In this tutorial you create a reusable custom component by transferring the VBox code layout, relevant variables, and functions from the main application.

The current application architecture
Figure 2. The current application architecture

Variables used

You used the following variables in previous tutorials:

  • _wagonInventory: The inventory data that populates the colored bins.
  • _wagonYellowWarningAmount: The minimum number of wagons that can be created, based on the available inventory, when a bin turns yellow.
  • _inventoryNeededForYellow: The number of parts needed in a bin to make the wagons for the _wagonYellowWarningAmount.
  • _wagonRedWarningAmount: The minimum number of wagons that can be created, based on available inventory, when you want the bin to turn red and the assembly line to stop.
  • _inventoryNeededForRed: The number of parts needed in the bin to make the wagons for the _wagonRedWarningAmount.

This tutorial introduces the following variable:

  • _binPosition: The index of the data in the _wagonInventory ArrayCollection that populates the bin.

Creating and using a custom component

In this section, you will create a reusable custom component file for the bins and transfer code from the main application to the new component.

  1. In the Flex Builder Navigator view, right-click on the src folder of the ShopFloorBins project and select New > Folder.
  2. Name the folder components.
  3. Click Finish.
  4. Right-click the components folder and select New > MXML Component.
  5. Name the component BinComponent.

    The component is based on the VBox.

  6. Click Finish.
  7. Locate the opening VBox tag and delete the width and height properties.
  8. After the opening VBox tag, create a Script block tag set.
<?xml version="1.0" encoding="utf-8"?> <mx:VBox xmlns:mx=http://www.adobe.com/2006/mxml> <mx:Script> <![CDATA[ ]]> </mx:Script> </mx:VBox>
  1. Open ShopFloorBins.mxml from the src folder.
  2. Copy the binTitle0 Label control and the binCanvas0 Canvas container and its contents from the first VBox bin container and paste it into BinComponent.mxml after the closing Script tag.
. . . <mx:Label id="binTitle0" text="{_wagonInventory.getItemAt(0).Title}" textAlign="center" width="100" styleName="titleFont"/> <mx:Canvas id="binCanvas0" width="100" height="100" styleName="binStyle"> <mx:TextInput id="binData0" text="{_wagonInventory.getItemAt(0).Quantity}" editable="false" width="60" height="30" textAlign="center" horizontalCenter="0" verticalCenter="0" styleName="titleFont" fontSize="18"/> </mx:Canvas>
  1. Delete the binTitle0 text property value.
  2. Delete the binData0 text property value.
  3. Change binTitle0 to binTitle.
  4. Change binCanvas0 to binCanvas.
  5. Change binData0 to binData.
  6. Save the file.
  7. Return to ShopFloorBins.mxml.
  8. Delete all the VBox code blocks for all of the bins.
  9. Save the file and run it.

Your application should appear as shown in Figure 3.

The bin code is removed.
Figure 3. The bin code is removed.

Using a custom component

MXML custom components are equivalent to ActionScript class files. You define all of the class properties and functions in the MXML custom component code and then create instances of the component with specific properties for each instance. In this section, you use the custom component in the main application to display the bins.

  1. Return to ShopFloorBins.mxml.
  2. Locate the opening Application tag.
  3. Create a new xml namespace named comp from the path components.*.

    Note: This code allows you to access all custom components in the components directory through the user-defined comp namespace. Remember that the pre-built Flex framework components are referenced from the mx namespace.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" backgroundGradientColors="[0xFFFFFF, 0xFFFFFF]" initialize="startProduction()" xmlns:comp="components.*">
  1. After the closing clockBase Canvas container tag, add five BinComponent tags from the comp namespace and add the following properties and values to each:
<comp:BinComponent x="47" y="178"/> <comp:BinComponent x="186" y="178"/> <comp:BinComponent x="331" y="178"/> <comp:BinComponent x="471" y="178"/> <comp:BinComponent x="614" y="178"/>
  1. Save the file and run it.

The application should appear as shown in Figure 4. The bin quantities are not displayed.

The application now uses the custom bin component.
Figure 4. The application now uses the custom bin component.

Adding properties to each custom component

You send the custom component the very same data used in the main application, except for the binPosition property value, by assigning the values to the properties. The class properties are created within the custom component in the next section.

  1. In the Script block, locate the _wagonRedWarningAmount and the _wagonYellowWarningAmount variables and make them bindable.
[Bindable] private var _wagonYellowWarningAmount:uint = 50; [Bindable] private var _wagonRedWarningAmount:uint = 0;
  1. Add the following properties and values to each BinComponent component:
<comp:BinComponent binPosition="0" wagonInventory="{_wagonInventory}" wagonRedWarningAmount="{_wagonRedWarningAmount}" wagonYellowWarningAmount="{_wagonYellowWarningAmount}" x="47" y="178"/> <comp:BinComponent binPosition="1" wagonInventory="{_wagonInventory}" wagonRedWarningAmount="{_wagonRedWarningAmount}" wagonYellowWarningAmount="{_wagonYellowWarningAmount}" x="186" y="178"/> <comp:BinComponent binPosition="2" wagonInventory="{_wagonInventory}" wagonRedWarningAmount="{_wagonRedWarningAmount}" wagonYellowWarningAmount="{_wagonYellowWarningAmount}" x="331" y="178"/> <comp:BinComponent binPosition="3" wagonInventory="{_wagonInventory}" wagonRedWarningAmount="{_wagonRedWarningAmount}" wagonYellowWarningAmount="{_wagonYellowWarningAmount}" x="471" y="178"/> <comp:BinComponent binPosition="4" wagonInventory="{_wagonInventory}" wagonRedWarningAmount="{_wagonRedWarningAmount}" wagonYellowWarningAmount="{_wagonYellowWarningAmount}" x="614" y="178"/>

Creating class properties using setter and getter functions

In this section, you use accessor methods (setters and getters) to isolate class properties from direct public access and to dispatch an event when the variable data changes. By convention, you will create private variables for use in the class that are named with a preceding underscore. In the accessor methods you will assign the public variables to these private class properties so that you can explicitly control their usage within the class.

  1. In the Script block of BinComponent.mxml, import the ArrayCollection class from the mx.collections package.
  2. After the import statement, import the CollectionEvent class from the mx.events package.
<mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.events.CollectionEvent; ]]> </mx:Script>
  1. After the import statements, using the set keyword, create a public function named wagonInventory(), that takes one argument named _wagonInventory with a data type of the ArrayCollection class. The return type is void.
  2. Within the function, assign _wagonInventory to this._wagonInventory.

    The public argument _wagonInventory is assigned to the private variable _wagonInventory of this application.

public function set wagonInventory(_wagonInventory:ArrayCollection):void { this._wagonInventory = _wagonInventory; }
  1. After the setter function, using the get keyword create a public function named _wagonInventory() that takes no arguments and has a return type of the ArrayCollection class.
  2. Within the function, return _wagonInventory.
public function get wagonInventory():ArrayCollection { return _wagonInventory; }
  1. Using the set keyword create a public function named wagonYellowWarningAmount(), that takes one argument named _wagonYellowWarningAmount with a data type of the uint class. The return type is void.
  2. Within the function, assign _wagonYellowWarningAmount to this._wagonYellowWarningAmount.
public function set wagonYellowWarningAmount(_wagonYellowWarningAmount:uint):void { this._wagonYellowWarningAmount = _wagonYellowWarningAmount; }
  1. After the setter function, using the get keyword create a public function named _wagonYellowWarningAmount() that takes no arguments and has a return type of the uint class.
  2. Within the function, return _wagonYellowWarningAmount.
public function get wagonYellowWarningAmount():uint { return _wagonYellowWarningAmount; }
  1. Using the set keyword create a public function named wagonRedWarningAmount(), that takes one argument named _wagonRedWarningAmount with a data type of the uint class. The return type is void.
  2. Within the function, assign _wagonRedWarningAmount to this._wagonRedWarningAmount.
public function set wagonRedWarningAmount(_wagonRedWarningAmount:uint):void { this._wagonRedWarningAmount = _wagonRedWarningAmount; }
  1. After the setter function, using the get keyword create a public function named _wagonRedWarningAmount() that takes no arguments and has a return type of the uint class.
  2. Within the function, return _wagonRedWarningAmount.
public function get wagonRedWarningAmount():uint { return _wagonRedWarningAmount; }
  1. Using the set keyword create a public function named binPosition(), that takes one argument named _binPosition with a data type of the uint class. The return type is void.
  2. Within the function, assign _binPosition to this._ binPosition.The _binPosition represents the index of the data in the ArrayCollection that populates the DataGrid control.
public function set binPosition(_binPosition:uint):void { this._binPosition = _binPosition; }
  1. After the setter function, using the get keyword, create a public function named _binPosition() that takes no arguments and has a return type of the uint class.
  2. In the function, return _binPosition.
public function get binPosition():uint { return _binPosition; }

Creating private properties for the custom component

In this section, you will transfer all the relevant ActionScript from the main application to the custom component Script block.

  1. In ShopFloorBins.mxml copy the five variables from the Script block.
  2. Return to BinComponent.mxml and paste the code between the Script block tags after the import statements.
<mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.events.CollectionEvent; [Bindable] private var _wagonInventory:ArrayCollection; [Bindable] private var _wagonYellowWarningAmount:uint = 50; [Bindable] private var _wagonRedWarningAmount:uint = 0; private var _inventoryNeededForYellow:uint; private var _inventoryNeededForRed:uint; . . . ]]> </mx:Script>
  1. Make all the variables Bindable.
  2. Instantiate _wagonInventory as an ArrayCollection class.
  3. Remove the value from the _wagonYellowWarningAmount variable.

    You passed this value in as a property of each component instance.

  4. Remove the value from the _wagonRedWarningAmount variable.

    You passed this value in as a property of each component instance.

[Bindable] private var _wagonInventory:ArrayCollection = new ArrayCollection(); [Bindable] private var _wagonYellowWarningAmount:uint; [Bindable] private var _wagonRedWarningAmount:uint; [Bindable] private var _inventoryNeededForYellow:uint; [Bindable] private var _inventoryNeededForRed:uint;
  1. After the last variable in the Script block, create a new private variable named _binPosition with a data type of uint that is bound.

    This variable represents the index of the data in the ArrayCollection.

[Bindable] private var _binPosition:uint;
  1. Return to ShopFloorBins.mxml, locate the Script block and delete the _inventoryNeededForYellow and _inventoryNeededForRed variables.
  2. Save the file.

Displaying data in the custom component

In this section you display the _wagonInventory data in the Label and TextInput controls.

  1. Return to BinComponent.mxml.
  2. Locate the binTitle Label control.
  3. Retrieve the Title value by passing _binPosition to the getItemAt() method of the _wagonInventory ArrayCollection, and bind it to the text property of binTitle.
<mx:Label id="binTitle" text="{_wagonInventory.getItemAt(_binPosition).Title}" textAlign="center" width="100" styleName="titleFont"/>
  1. Locate the binData TextInput control.
  2. Retrieve the Quantity value by passing _binPosition to the getItemAt() method of the _wagonInventory ArrayCollection, and bind it to the text property.
<mx:TextInput id="binData" text="{_wagonInventory.getItemAt(_binPosition).Quantity}" editable="false" width="60" height="30" textAlign="center" horizontalCenter="0" verticalCenter="0" styleName="titleFont" fontSize="18"/>

Creating functionality in a custom component

In this section, you will create and modify functions that allow the bin to change color if it is within the threshold when the user makes a change to the value in the DataGrid control.

  1. Return to ShopFloorBins.mxml and copy the binColorHandler() function.
  2. In BinComponent.mxml, paste the binColorHandler() function into the Script block after the variables.
  3. Delete the for loop in the function.

Note: You will not need to loop over the _wagonInventory ArrayCollection because the binColorHandler() function is now specific to each instance of the colored bins. That means that the function only needs to determine the bin color for one specific bin at a time.

. . . private function binColorHandler(event:CollectionEvent = null):void { _inventoryNeededForYellow = _wagonYellowWarningAmount * _wagonInventory.getItemAt(x).Parts; _inventoryNeededForRed = _wagonRedWarningAmount * _wagonInventory.getItemAt(x).Parts; if (_wagonInventory.getItemAt(x).Quantity <= _inventoryNeededForRed || _wagonInventory.getItemAt(x).Quantity < _wagonInventory.getItemAt(x).Parts) { this["binCanvas"+x].setStyle("backgroundColor", 0xCC0000); } else if (_wagonInventory.getItemAt(x).Quantity > _inventoryNeededForRed && _wagonInventory.getItemAt(x).Quantity <= _inventoryNeededForYellow) { this["binCanvas"+x].setStyle("backgroundColor", 0xE5E006); } else { this["binCanvas"+x].setStyle("backgroundColor", 0x339933); } }
  1. Save the file.
  2. Return to ShopFloorBins.mxml and delete the binColorHandler() function.
  3. Locate the startProduction() function and delete the _wagonInventory event listener code.
  4. Save the ShopFloorBins.mxml file.

The listener event code had a reference to the binColorHandler() function which you just removed from the main application and moved to the custom bin component.

Modifying the binColorHandler() function

In this section, you modify the reusable custom component to accept unique properties for each instance.

  1. Return to BinComponent.mxml.
  2. Locate the binColorHandler() function.
  3. Change this["binCanvas"+x] to binCanvas in three places.

Note: You are no longer looping over the entire ArrayCollection and therefore do not need to use the dynamic instance name.

if (_wagonInventory.getItemAt(x).Quantity <= _inventoryNeededForRed || _wagonInventory.getItemAt(x).Quantity < _wagonInventory.getItemAt(x).Parts) { binCanvas.setStyle("backgroundColor", 0xCC0000); } else if (_wagonInventory.getItemAt(x).Quantity > _inventoryNeededForRed && _wagonInventory.getItemAt(x).Quantity <= _inventoryNeededForYellow) { binCanvas.setStyle("backgroundColor", 0xE5E006); } else { binCanvas.setStyle("backgroundColor", 0x339933); }

Creating and modifying functions

In this section, you add an event listener and use the _binPosition index to retrieve data from the _wagonInventory ArrayCollection.

  1. Create a new private function named init() that takes no arguments and has a return type of void.
  2. Use the addEventListener() function of _wagonInventory to listen for the CollectionEvent.COLLECTION_CHANGE event which will be handled by the binColorHandler() function.

    Note: Since you defined the _wagonInventory ArrayCollection instance as a bindable variable, any changes to the data will automatically be reflected everywhere it is used. However, if you want additional functions to run when the data changes, you need to add the COLLECTION_CHANGE event handler. In this case, you are adding the binColorHandler() function as the event handler when the wagon inventory data changes. This function determines the current bin color.

private function init():void { _wagonInventory.addEventListener (CollectionEvent.COLLECTION_CHANGE, binColorHandler); }
  1. Locate the opening VBox tag for this custom component and add the creationComplete property with the value of init().
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">

This code ensures that the event listener is added when the custom component is created.

  1. In the Script block, create a private function named calculateQuantity() that takes no arguments and has a return type of void.

    You are making a reusable function that is called within other functions.

  2. Locate the binColorHandler() function and move the _wagonYellowWarningAmount and _inventoryNeededForRed code to the calculateQuantity() function.
  3. Change the value in the getItemAt() function from x to _binPosition.
private function calculateQuantity():void { _inventoryNeededForYellow = _wagonYellowWarningAmount * _wagonInventory.getItemAt(_binPosition).Parts; _inventoryNeededForRed = _wagonRedWarningAmount * _wagonInventory.getItemAt(_binPosition).Parts; }
  1. Locate the binColorHandler() function.
  2. After the opening function code but before the conditional statement, call the calculateQuantity() function.
private function binColorHandler(event:CollectionEvent = null):void { calculateQuantity(); . . .

The values from the calculateQuantity() function are needed for the conditional statements.

  1. In the binColorHandler() function, change the value in the getItemAt() function from x to _binPosition in five places.

    Note: You are no longer using a for loop and will use the _binPosition value which will identify the index of the bin from the _wagonInventory ArrayCollection that you want evaluated.

. . . if (_wagonInventory.getItemAt(_binPosition).Quantity <= _inventoryNeededForRed || _wagonInventory.getItemAt(_binPosition).Quantity < _wagonInventory.getItemAt(_binPosition).Parts) { binCanvas.setStyle("backgroundColor", 0xCC0000); } else if (_wagonInventory.getItemAt(_binPosition).Quantity > _inventoryNeededForRed && _wagonInventory.getItemAt(_binPosition).Quantity <= _inventoryNeededForYellow) { binCanvas.setStyle("backgroundColor", 0xE5E006); } else { binCanvas.setStyle("backgroundColor", 0x339933); }
  1. Save the file, return to ShopFloorBins.mxml and run it.

Change the quantity of any of the bins to 5 and press Enter. Change the quantity of any of the bins to 0 and press Enter. You should see the bin color change and the application is working as it did in Part 3.

Test the custom components in the application.
Figure 5. Test the custom components in the application.

Where to go from here

In this tutorial, you transferred code from the main application into a reusable custom component that replaced the hard-coded colored bins. You also learned how to create setters and getters for class properties and how to create methods for the class file.

If you are interested in learning more about the topics in this tutorial, refer to the following resources:

  • Creating custom MXML components (8:42)
  • Creating custom components
  • Scoping in custom components
  • Building components by using code behind
  • Creating ActionScript components
  • Understanding variable scope
  • Class property attributes
  • Creating getters and setters

In Part 5, you will create another custom component for the clock display and animate the clock using the ActionScript Timer class.

Exploring Rich Island development with Flex Builder

For your reference, here are all the parts in this series:

  • SAP developers: Build an interactive Flex application from scratch
    • Part 1: Getting started
    • Part 2: Laying out and styling visual elements
    • Part 3: Handling data and binding it to controls
    • Part 4: Creating a custom component
    • Part 5: Animating with ActionScript
    • Part 6: Synchronizing data in components
  • Flex developers: Create a Web Dynpro application
    • Part 7: Creating an SAP application
  • Flex and SAP developers: Create a working Rich Island
    • Part 8: Creating a Rich Island and handling data
    • Part 9: Communicating between a Rich Island and a Web Dynpro application
 

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement