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 6: Synchronizing data in components

by Trilemetry

Trilemetry
  • Trilemetry, Inc.

Content

  • Animating text fields bound to an ArrayCollection
  • Propagating data changes from a TextInput control

Modified

3 August 2009

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
Flex 3 Flex Builder 3

Requirements

Prerequisite knowledge

  • 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: Synchronizing data in components

User level

All

Required products

  • Flex Builder (Download trial)

Sample files

  • sap_ri_pt6_starter.zip (26 KB)
  • sap_ri_pt6_solution.zip (26 KB)

Additional Requirements

Note: The ZIP files are Flex Builder project archives. The starter archive is the completed Part 5 project archive. The solution archive contains the completed code and assets associated with this part. The latter is provided to you to compare against your own completed code.

Welcome to Part 6 of this tutorial series. In this part, you will animate the inventory amounts in the colored bins to count down based on the production rate. The bins will change color when each reaches its threshold value and the clock stops when there is no more inventory or the time runs out.

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 application with animated clock and bins
Figure 1. The application with animated clock and bins

Animating text fields bound to an ArrayCollection

In this section, you synchronize the clock animation to the wagon assembly animation by decreasing the bin inventory quantity as the clock counts down. Every 6 seconds (the current production rate) a wagon is created and inventory is decreased in the bins.

  1. Open ShopFloorBins.mxml.
  2. In the Script block, declare a private variable named _productionRateCounter and data type it to the uint class and assign a value of 0 (zero) to it.
private var _productionRateCounter:uint = 0;

The _productionRateCounter variable is incremented each time the timer event is called; currently that is every second. You will programmatically check the value of this variable and decrease inventory at the set production rate (currently every 6 seconds).

  1. Locate the timerEventHandler() function in the Script block.
  2. Before the conditional statement, declare a local variable named partsLeftInBin and data type it to the uint class.
  3. Declare another local variable named partsNeededPerWagon and data type it to the uint class.

    Note: Remember that these variables are evaluated for each inventory bin. For example, the number of parts needed per wagon for the wheels bin is four while the parts needed per wagon for the axels is two.

  4. After the stopTimer() function, but still in the conditional statement, reset the _productionRateCounter variable to 0 (zero).
  5. In the else statement, after the current code, increment the _productionRateCounter variable using ++ syntax.
private function timerEventHandler(event:TimerEvent):void { var partsLeftInBin:uint; var partsNeededPerWagon:uint; if (_secondsToCreateAvailableWagons == 0) { stopTimer(); _productionRateCounter = 0; } else { _secondsToCreateAvailableWagons--; setClockDisplay(); _productionRateCounter++; } }
  1. After the _productionRateCounter variable in the else statement, create another conditional statement that tests whether dividing the _productionRateCounter variable by the _wagonProductionRate is equivalent to 0 (zero) or has a remainder. Use the modulus operator (%).

    The current _wagonProductionRate variable is set to 6 seconds so you want wagon inventory to decrement every 6 seconds; however, you still need the clock to decrement every second. Since the _productionRateCounter will maintain a running count of seconds, you can divide it by the _wagonProductionRate to check whether the current second is on a 6-second increment.

    The modulus operator divides the first variable by the second and gives you the remainder. If the remainder is not zero, then you know that the current second is not on a 6-second increment and you should only update the clock display but not the inventory. If the remainder is zero, then you should update the clock as well as the inventory.

_productionRateCounter++; if(_productionRateCounter % _wagonProductionRate == 0) { }
  1. Within the conditional statement, use a for loop to loop over the _wagonInventory ArrayCollection instance. In the for statement, create a local iterant named x and data type it to the uint class with a value of 0 (zero). While x is less than _wagonInventory.length, iterate the loop using the x++ syntax.

    You loop over the data in the ArrayCollection to decrease each bin's inventory.

if(_productionRateCounter % _wagonProductionRate == 0) { for(var x:uint = 0; x < _wagonInventory.length; x++) { } }
  1. In the loop assign the Quantity of the current index of the _wagonInventory object to the partsLeftInBin variable. Use the getItemAt() function.
  2. Next, assign the Parts key of the current index of the _wagonInventory ArrayCollection object to the partsNeededPerWagon variable. Use the getItemAt() function.

    You create these variables to shorten the variable references for convenience sake. Otherwise this step is not necessary.

if(_productionRateCounter % _wagonProductionRate == 0) { for(var x:uint = 0; x < _wagonInventory.length; x++) { partsLeftInBin = _wagonInventory.getItemAt(x).Quantity; partsNeededPerWagon = _wagonInventory.getItemAt(x).Parts; } }
  1. After variables in the loop, create a conditional statement that tests if the partsLeftInBin variable is less than the partsNeededPerWagon variable.
partsLeftInBin = _wagonInventory.getItemAt(x).Quantity; partsNeededPerWagon = _wagonInventory.getItemAt(x).Parts; if (partsLeftInBin < partsNeededPerWagon) { }
  1. If the conditional statement is true, call the stopTimer() function and set the _secondsToCreateAvailableWagons variable to 0.
  2. Set the _productionRateCounter variable to 0.
  3. Break out of the loop by using the break keyword.

    If the inventory is too low to create a wagon, then you must stop the timer and set the clock display and production counter to zero.

if (partsLeftInBin < partsNeededPerWagon) { stopTimer(); _secondsToCreateAvailableWagons = 0; _productionRateCounter = 0 break; }
  1. Create an else statement that will run if the statement evaluates to false.
if (partsLeftInBin < partsNeededPerWagon) { . . . } else { }
  1. Decrease the partsLeftInBin variable by the partsNeededPerWagon variable using the -= syntax.
  2. Next, assign the partsLeftInBin to the _wagonInventory Quantity using the getItemAt() function and x as the index value.
  3. Call the refresh() function on _wagonInventory.

    You decrease each bin inventory by the parts needed per wagon and set the new value for Quantity in the ArrayCollection. You must refresh the data in the ArrayCollection instance.

} else { partsLeftInBin -= partsNeededPerWagon; _wagonInventory.getItemAt(x).Quantity = partsLeftInBin; _wagonInventory.refresh(); }
  1. Save the file and run it.

    You should see that the clock animation is synchronized with inventory reduction in the colored bins and DataGrid control. Note that the inventory in the colored bins is decremented every 6 seconds. However, if you make a change in the DataGrid control, the clock does not adjust properly.

  2. Return to ShopFloorBins.mxml.
  3. Within the Script block, create a private function named recalculate() that takes one argument named event with a data type of the CollectionEvent class and with a value of null. The function returns a void data type.
private function recalculate(event:CollectionEvent = null):void { }
  1. In the function, set the _productionRateCounter to 0, then call the stopTimer() function, call the calculateMaxWagonsPossibleFromInventory() function and finally call the startTimer() function.

    This function will run when you need to reset the clock display. Remember that the _productionRateCounter variable is a counter that is incremented every second. You call the stopTimer() function, to stop the timer before you use the calculateMaxWagonsPossibleFromInventory() function to start the process of calculating the minutes and seconds on the clock. After that calculation is complete, you start the clock animation again.

private function recalculate(event:CollectionEvent = null):void { _productionRateCounter = 0; stopTimer(); calculateMaxWagonsPossibleFromInventory(); startTimer(); }
  1. Locate the startProduction() function.
  2. After the populateData() function call, add an event listener on the _wagonInventory data that listens for the CollectionEvent.COLLECTION_CHANGE event and calls the recalculate() function.

    This code will ensure that the recalculate() function is called each time the _wagonInventory ArrayCollection data is changed.

populateData(); _wagonInventory.addEventListener(CollectionEvent.COLLECTION_CHANGE, recalculate);
  1. Save the file and run it.

Change the quantity for the handles to 100 in the DataGrid control and press Enter. You should see that the clock time adjusts.

Propagating data changes from a TextInput control

In this section, you will allow the user to change the quantity in the TextInput control within the bin and ensure that changes to the inventory quantities in the colored bins are properly reflected in the application display. This will require that you handle the change by updating the _wagonInventory ArrayCollection data. This will ensure that all UI components, like the DataGrid control, that are bound to the ArrayCollection data will reflect the data update.

  1. Open the BinComponent.mxml and locate the binData TextInput control.
  2. Change the editable property value to true.
<mx:TextInput id="binData" text="{_wagonInventory.getItemAt(_binPosition).Quantity}" editable="true" . . . />
  1. Save the file and return to ShopFloorBins.mxml and run it.

    Make a change to a bin TextInput control and press Enter. You should see that the change you made has no effect on the corresponding DataGrid control's quantity or the clock time.

  2. Return to BinComponent.mxml.
  3. Locate the binData TextInput control and add an enter event with a value of updateBinInventory().

    You will create the updateBinInventory() function next.

<mx:TextInput id="binData" . . . enter="updateBinInventory()"/>
  1. Before the end of the Script block, create a private function named updateBinInventory() that takes no arguments and has a void return type.
private function updateBinInventory():void { }
  1. In the function, cast the binData text property value to the uint class and assign it to _wagonInventory.getItemAt(_binPosition).Quantity.

    Data in a text field is always treated as a string. You must cast the string data into whatever data type is appropriate. In this case, you use the uint() function to cast the string data as a uint (unsigned integer) data type to match the Quantity data type.

private function updateBinInventory():void { _wagonInventory.getItemAt(_binPosition).Quantity = uint(binData.text); }
  1. Next, call the binColorHandler() function to calculate whether the bin color should change.
  2. Use the refresh() function of _wagonInventory to update the ArrayCollection data.
private function updateBinInventory():void { _wagonInventory.getItemAt(_binPosition).Quantity = uint(binData.text); binColorHandler(); _wagonInventory.refresh(); }
  1. Save the file and run ShopFloopBins.mxml.

Change a bin quantity to 20 in the DataGrid control and press Enter. Note that the clock time adjusts and the data in the TextInput control changes to match the DataGrid control. Change the same quantity to 50 in the TextInput control and press Enter. Notice that the clock time adjusts again and the data in the DataGrid changes to match the TextInput control.

The finished application after the clock has counted down to zero based on inventory running out in the handles bin
Figure 2. The finished application after the clock has counted down to zero based on inventory running out in the handles bin

Where to go from here

In this tutorial, you animated the inventory quantities in the colored bins with the clock animation. You also allowed the user to change the inventory quantity in the bins and reflect that change in the both the clock display and DataGrid control.

In Part 7, experienced Flex developers will create the Web Dynpro application and generally familiarize themselves with the NetWeaver ABAP interface. Experienced SAP developers can skip to Part 8, where you will integrate the Rich Island you have built in Parts 1 through 6 into a provided Web Dynpro application.

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