ADOBE FLEX 4.5 User Manual

Page 1
Using
ADOBE® FLEX® 4.5
Page 2

Legal notices

Legal notices
Dernière mise à jour le 19/6/2011
Page 3

Sommaire

Chapitre 1 : Introduction to Flex 4.5
Getting started with Flex 4.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Chapitre 2 : Getting started
Developing applications in MXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
MXML syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Using ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
SDK configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Chapitre 3 : Application architecture
Application development phases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Application structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Modular applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Developing and loading sub-applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Flex Ajax Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Communicating with the wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Runtime Shared Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
iii
Chapitre 4 : Building the user interface
Visual components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Data binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Introduction to containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Laying out components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Application containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Spark containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
Custom Spark item renderers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
Spark list-based controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514
Spark DataGrid and Grid controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
MX layout containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
MX navigator containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
UI Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643
Spark text controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734
MX text controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805
Using the Flex AIR components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 835
Dynamically repeating controls and containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 868
Chapitre 5 : Using data-driven UI components
Representing data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 886
Storing data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 890
Data providers and collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
MX data-driven controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944
Dernière mise à jour le 19/6/2011
Page 4
USING FLEX 4.5
Sommaire
Menu-based controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
MX item renderers and item editors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1007
Advanced data display with MX item editors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1049
Introduction to charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1076
Chart types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1124
Formatting charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1170
Displaying data and labels in charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1247
Events and effects in charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1325
AdvancedDataGrid control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1398
OLAPDataGrid control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1455
Chapitre 6 : Enhancing the user interface
Styles and themes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1493
Fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1569
Spark Skinning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1602
Skinning MX components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1654
Embedding assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1698
FXG and MXML graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1713
Introduction to effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1784
Spark effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1804
Using MX effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1827
View states . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1846
Transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1869
Drag and drop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1892
iv
Chapitre 7 : Enhancing usability
ToolTip controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1932
Cursor Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1958
Validating Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1963
Formatting Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2002
Deep linking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2020
Printing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2035
Localization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2053
Mirroring and bidirectional text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2065
Resource Bundles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2089
Accessible applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2120
Chapitre 8 : Developer tools
Building overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2159
Flex compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2162
Command-line debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2207
Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2220
Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2236
ASDoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2239
Chapitre 9 : Testing and automation
Creating applications for testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2268
Optimizing applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2298
Dernière mise à jour le 19/6/2011
Page 5
USING FLEX 4.5
Sommaire
Improving startup performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2332
Ant tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2342
Chapitre 10 : Custom components
Custom Flex components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2355
Custom ActionScript components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2363
Custom events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2369
Metadata tags in custom components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2376
Component compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2392
Simple MXML components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2399
Advanced MXML components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2412
Create simple visual components in ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2433
Create advanced Spark visual components in ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2451
Create advanced MX visual components in ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2475
Custom style properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2500
Template components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2507
Custom formatters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2513
Custom validators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2520
Custom effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2525
v
Chapitre 11 : Deploying applications
Deploying applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2544
Creating a wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2553
Dernière mise à jour le 19/6/2011
Page 6

Chapitre 1 : Introduction to Flex 4.5

Adobe® Flex® 4.5 introduces new features and continues to build upon the major architectural changes in Flex 4.
If you are a new Flex developer, and have not previously developed applications in Flex, you can use the many available resources to learn more about Flex. For more information on the resources available for new Flex developers, see « Getting started with Flex 4.5 » à la page 1.
If you are an existing Flex developer, you can use the information in « Migration » à la page 2 to decide how best to upgrade your applications to the newest SDK.

Getting started with Flex 4.5

Adobe and the Flex developer community provide many resources that you can use to get started with Flex development. These resources are helpful for new users, and for experienced users seeking to increase their knowledge of Flex.
The Flex Developer Center contains many resources that you can help you start using Flex 4.5, including:
1
Getting Started articles, links and tutorials
Samples of real applications built in Flex
The Flex Cookbook, which contains answers to common coding problems
Links to the Flex community and to other sites devoted to Flex
As a new Flex user, there are other Adobe sites that you can also use to get familiar with Flex, including the following:
Adobe Flex in a Week at http://www.adobe.com/devnet/flex/videotraining/
Flex Test Drive at http://www.adobe.com/devnet/flex/testdrive.html
Flex video training at Adobe Flex TV

Features new for Flex 4.5

Flex 4.5 contains several new features, including:
Support for mobile applications
More Spark UI components including Image, DataGrid, and Form
Integration with Flash Player’s globalization classes
RSL enhancements
TLF 2.0
OSMF 1.0 integration
Spark validators and formatters
This list is a subset of the new features in Flex 4.5 SDK. For more information on additional features, see What's New
in Flex 4.5 SDK. You can get more information about productivity enhancements in Flash Builder 4.5 at What's New in Flash Builder 4.5.
Dernière mise à jour le 19/6/2011
Page 7
USING FLEX 4.5
Introduction to Flex 4.5

Development tools for Flex 4.5

Flex developers typically use two development tools:
Adobe® Flash® Builder™
Flash Builderis an integrated development environment (IDE) for building cross-platform, rich Internet applications (RIAs). Using Flash Builder, you build applications that use the Adobe Flex framework, MXML, Adobe Flash Player, Adobe AIR, ActionScript 3.0, Adobe® LiveCycle® Data Services ES, and the Adobe Flex Charting components. Flash Builder also includes testing, debugging, and profiling tools that lead to increased levels of productivity and effectiveness.
For more information on Flash Builder, see About Flash Builder.
Adobe® Flash® Catalyst™
Catalyst makes it easy for designers to create Flex-based RIA UI's from artwork imported from Adobe® Creative Suite® tools, and to define interactions and behaviors within Catalyst. The applications created in Catalyst are Flex applications. Flash Builder 4.5 provides a simple workflow for importing these applications, which allows designers to collaborate with developers more easily than ever before.
For more information on Flash Catalyst, see About Flash Catalyst.
2

Migration

If you are an existing Flex customer, you might migrate your existing applications from Flex 4 to Flex 4.5, or even from Flex 3.
For Flex 4 users, migrating to Flex 4.5 is relatively simple. The differences are largely cosmetic and are summarized in
Flex 4.5 Backwards Compatibility.
For Flex 3 users, before starting the migration process, you should be aware of all new Flex 4 and 4.5 features, and be familiar with changes to existing features. The greatest differences are from Flex 3 to Flex 4. For information on migrating applications from Flex 3 to Flex 4, see the Adobe Flex 4 Features and Migration Guideat
www.adobe.com/go/learn_flex4_featuremigrate_fr.
If you upgrade to a new version of Flash Builder to take advantage of new features in the IDE but do not want to use the new compiler features, you can downgrade the output application. You do this by setting the compiler option. You can also select an older SDK to compile against. For more information, see « Backward
compatibility » à la page 2237.
player-version
Dernière mise à jour le 19/6/2011
Page 8

Chapitre 2 : Getting started

Developing applications in MXML

MXML is an XML language that you use to lay out user interface components for applications built in Adobe® Flex®. You also use MXML to declaratively define nonvisual aspects of an application, such as access to server-side data sources and data bindings between user interface components and server-side data sources.
For information on MXML syntax, see « MXML syntax » à la page 21.

About MXML

You use two languages to write applications in Flex: MXML and ActionScript. MXML is an XML markup language that you use to lay out user interface components. You also use MXML to declaratively define nonvisual aspects of an application, such as access to data sources on the server and data bindings between user interface components and data sources on the server.
Like HTML, MXML provides tags that define user interfaces. MXML will seem very familiar if you have worked with HTML. However, MXML is more structured than HTML, and it provides a much richer tag set. For example, MXML includes tags for visual components such as data grids, trees, tab navigators, accordions, and menus, as well as nonvisual components that provide web service connections, data binding, and animation effects. You can also extend MXML with custom components that you reference as MXML tags.
3
One of the biggest differences between MXML and HTML is that MXML-defined applications are compiled into SWF files and rendered by Adobe® Flash® Player or Adobe® AIR™, which provides a richer and more dynamic user interface than page-based HTML applications.
You can write an MXML application in a single file or in multiple files. MXML also supports custom components written in MXML and ActionScript files.
Using Spark and MX component sets
Flex defines two sets of components: MX and Spark. The MX component set was included in previous releases of Flex, and is defined in the mx.* packages. The Spark component set is new for Flex 4 and is defined in the spark.* packages. The Spark components use a new architecture for skinning and have other advantages over the MX components.
The MX and Spark component sets contain many of the same components. For example, both component sets defines a Button control, TextInput control, and List control. However, while you can use MX components to perform most of the same actions that you can perform by using the Spark components, Adobe recommends that you use the Spark components when possible.
Writing a simple application in MXML
Because MXML files are ordinary XML files, you have a wide choice of development environments. You can write MXML code in a simple text editor, a dedicated XML editor, or an integrated development environment (IDE) that supports text editing. Flex supplies a dedicated IDE, called Adobe® Flash™ Builder™, that you can use to develop your applications.
Dernière mise à jour le 19/6/2011
Page 9
USING FLEX 4.5
Getting started
The following example shows a simple “Hello World” application that contains just an <s:Application> tag and three child tags, the defines the Application container that is always the root tag of an application. The container that includes a title bar, a title, a status message, a border, and a content area for its children. The
<s:Panel> tag and the <s:Label> tags, plus a <s:layout> tag. The <s:Application> tag
<s:Panel> tag defines a Panel
<s:Label>
tag represents a Label control, a very simple user interface component that displays text.
<?xml version="1.0"?> <!-- mxml\HellowWorld.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <s:Panel title="My Application"> <s:Label text="Hello World" fontWeight="bold" fontSize="24"/> </s:Panel> </s:Application>
Save this code to a file named hello.mxml. MXML filenames must end in a lowercase .mxml file extension.
About XML encoding
The first line of the document specifies an optional declaration of the XML version. It is good practice to include encoding information that specifies how the MXML file is encoded. Many editors let you select from a range of file encoding options. On North American operating systems, ISO-8859-1 is the dominant encoding format, and most programs use that format by default. You can use the UTF-8 encoding format to ensure maximum platform compatibility. UTF-8 provides a unique number for every character in a file, and it is platform-, program-, and language-independent.
4
If you specify an encoding format, it must match the file encoding you use. The following example shows an XML declaration tag that specifies the UTF-8 encoding format:
<?xml version="1.0" encoding="utf-8"?>
About the <s:Application> tag
In addition to being the root tag of an application, the
<s:Application> tag represents a Spark Application container.
A container is a user-interface component that contains other component sets, and uses layout rules for positioning its child components. By default, the Spark Application container lets that you set the position of its children. In the previous example, you set the layout of the container to VerticalLayout so that the Application container automatically lays out its children in a vertical column.
You can nest other types of containers inside an Application container, such as the Panel container shown above, to position user interface components according to other rules. For more information, see « Visual components » à la page 281.
About namespaces
In an XML document, tags are associated with a namespace. XML namespaces let you refer to more than one set of XML tags in the same XML document. The
xmlns property in an MXML tag specifies an XML namespace.
In Flex, you typically define three namespaces:
xmlns:fx="http://ns.adobe.com/mxml/2009" The namespace for top-level ActionScript elements, such as
Object and Array, and for tags built into the MXML compiler, such as
<fx:Script>.
xmlns:mx="library://ns.adobe.com/flex/mx" The namespace for the MX component set.
Dernière mise à jour le 19/6/2011
Page 10
USING FLEX 4.5
Getting started
xmlns:s="library://ns.adobe.com/flex/spark" The namespace for the Spark component set.
In general, you include the Spark and MX component namespaces so that you can use any components from those sets. Where possible, use the Spark components. However, not all MX components have Spark counterparts, so the components in the MX namespace are also sometimes necessary.
You can define additional namespaces for your custom component libraries. For more information on namespaces, see « Using XML namespaces » à la page 9.
About MXML tag properties
The properties of an MXML tag, such as the you declaratively configure the initial state of the component. You can use ActionScript code in an
text, fontWeight, and fontSize properties of the <s:Label> tag, let
<fx:Script> tag
to change the state of a component at run time. For more information, see « Using ActionScript » à la page 32.
Compiling MXML to SWF Files
If you are using Flash Builder, you compile and run the compiled SWF file from within Flash Builder. After your application executes correctly, you deploy it by copying it to a directory on your web server or application server.
You can deploy your application as a compiled SWF file, as a SWF file included in an AIR application or, if you have Adobe LiveCycle Data Services ES, you can deploy your application as a set of MXML and AS files.
End users of the application do not typically reference the SWF file directly in an HTTP request. Instead, you embed the application SWF file in an HTML page. The HTML page then uses a script to load the SWF file. Collectively, the HTML page and the script are known as the wrapper.
5
When the SWF file is embedded in the HTML page, users then access the deployed SWF file by making an HTTP request to the HTML page, in the form:
http://hostname/path/filename.html
For more information on wrappers, see « Creating a wrapper » à la page 2553.
Flex also provides a command-line MXML compiler, mxmlc, that lets you compile MXML files. You can use mxmlc to compile hello.mxml from a command line, as the following example shows:
cd flex_install_dir/bin mxmlc --show-actionscript-warnings=true --strict=true c:/app_dir/hello.mxml
In this example, flex_install_dir is the Flex installation directory, and app_dir is the directory containing hello.mxml. The resultant SWF file, hello.swf, is written to the same directory as hello.mxml.
For more information about mxmlc, see « Flex compilers » à la page 2162.
The relationship of MXML tags to ActionScript classes
Adobe implemented Flex as an ActionScript class library. That class library contains components (containers and controls), manager classes, data-service classes, and classes for all other features. You develop applications by using the MXML and ActionScript languages with the class library.
MXML tags correspond to ActionScript classes or properties of classes. Flex parses MXML tags and compiles a SWF file that contains the corresponding ActionScript objects. For example, Flex provides the ActionScript Button class that defines the Flex Button control. In MXML, you create a Button control by using the following MXML statement:
<s:Button label="Submit"/>
When you declare a control using an MXML tag, you create an instance of that class. This MXML statement creates a Button object, and initializes the
label property of the Button object to the string "Submit".
Dernière mise à jour le 19/6/2011
Page 11
USING FLEX 4.5
Getting started
An MXML tag that corresponds to an ActionScript class uses the same naming conventions as the ActionScript class. Class names begin with an uppercase letter, and uppercase letters separate the words in class names. Every MXML tag attribute corresponds to a property of the ActionScript object, a style applied to the object, or an event listener for the object. For a complete description of the Flex class library and MXML tag syntax, see the ActionScript 3.0 Reference for
the Adobe Flash Platform.
Understanding the structure of an application built with Flex
You can write an MXML application in a single file or in multiple files. You typically define a main file that contains
<s:Application> tag. From within your main file, you can then reference additional files written in MXML,
the ActionScript, or a combination of the two languages.
A common coding practice is to divide your Flex application into functional units, or modules, where each module performs a discrete task. In Flex, you can divide your application into separate MXML files and ActionScript files, where each file corresponds to a different module. By dividing your application into modules, you provide many benefits, including the following:
Ease of development Different developers or development groups can develop and debug modules independently of
each other.
Reusability You can reuse modules in different applications so that you do not have to duplicate your work.
Maintainability You can isolate and debug errors faster than if your application is developed in a single file.
6
In Flex, a module corresponds to a custom component implemented either in MXML or in ActionScript. These custom components can reference other custom components. There is no restriction on the level of nesting of component references in Flex. You define your components as required by your application.
You can also use sub-applications rather than modules to develop applications that are not monolithic.

Developing applications

MXML development is based on the same iterative process used for other types of web application files such as HTML, JavaServer Pages (JSP), Active Server Pages (ASP), and ColdFusion Markup Language (CFML). Developing a useful Flex application is as easy as opening your favorite text editor, typing some XML tags, saving the file, requesting the file’s URL in a web browser, and then repeating the same process.
Flex also provides tools for code debugging. For more information, see « Command-line debugger » à la page 2207.
Laying out a user interface using containers
In the Flex model-view design pattern, user interface components represent the view. The MXML language supports two types of user interface components: controls and containers. Controls are form elements, such as buttons, text fields, and list boxes. Containers are rectangular regions of the screen that contain controls and other containers.
You use container components for laying out a user interface, and for controlling user navigation through the application. Examples of layout containers include the HGroup container for laying out child components horizontally and the VGroup container for laying out child components vertically. Examples of navigator containers include the MX TabNavigator container for creating tabbed panels and the MX Accordion navigator container for creating collapsible panels. Typical properties of a container tag include about the standard Flex containers, see « Introduction to containers » à la page 328.
id, width, and height. For more information
The following example application contains a Spark List control on the left side of the user interface and an MX TabNavigator container on the right side. Both controls are enclosed in a Spark Panel container:
Dernière mise à jour le 19/6/2011
Page 12
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/LayoutExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <s:Panel title="My Application"> <s:HGroup> <!-- List with three items --> <s:List> <s:dataProvider> <mx:ArrayCollection> <fx:String>Item 1</fx:String> <fx:String>Item 2</fx:String> <fx:String>Item 3</fx:String> </mx:ArrayCollection> </s:dataProvider> </s:List> <!-- First pane of TabNavigator --> <mx:TabNavigator borderStyle="solid"> <s:NavigatorContent label="Pane1" width="300"> <s:layout> <s:VerticalLayout/> </s:layout> <s:TextArea text="Hello World"/> <s:Button label="Submit"/> </s:NavigatorContent> <!-- Second pane of TabNavigator --> <s:NavigatorContent label="Pane2" width="300" height="150"> <!-- Stock view goes here --> </s:NavigatorContent> </mx:TabNavigator> </s:HGroup> </s:Panel> </s:Application>
7
The List control and TabNavigator container are laid out side by side because they are in an HGroup container. The controls in the TabNavigator container are laid out from top to bottom because they are in a NavigatorContent containers that use the VerticalLayout class.
For more information about laying out user interface components, see « Visual components » à la page 281.
Adding user interface controls
Flex includes a large selection of user interface components, such as Button, TextInput, and ComboBox controls. After you define the layout and navigation of your application by using container components, you add the user interface controls.
The following example contains an HGroup (horizontal group) container with two child controls, a TextInput control and a Button control. An HGroup container lays out its children horizontally.
Dernière mise à jour le 19/6/2011
Page 13
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/AddUIControls.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script> <![CDATA[ private function storeZipInDatabase(s:String):void { // event handler code here } ]]> </fx:Script> <s:HGroup> <s:TextInput id="myText"/> <s:Button click="storeZipInDatabase(myText.text);"/> </s:HGroup> </s:Application>
Typical properties of a control tag include id, width, height, fontSize, color, event listeners for events such as
click and change, and effect triggers such as showEffect and rollOverEffect. For information about the standard
Flex controls, see « UI Controls » à la page 643.
8
Using the id property with MXML tags
With a few exceptions (see « MXML tag rules » à la page 32), an MXML tag has an optional id property, which must be unique within the MXML file. If a tag has an ActionScript.
The following example uses the
trace() function to write the value of the text property of a TextInput control to the
log file:
<?xml version="1.0"?> <!-- mxml/UseIDProperty.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script> <![CDATA[ private function writeToLog():void { trace(myText.text); } ]]> </fx:Script> <s:VGroup id="myVGroup"> <s:TextInput id="myText" text="Hello World!" /> <s:Button id="mybutton" label="Get Weather" click="writeToLog();"/> </s:VGroup> </s:Application>
id property, you can reference the corresponding object in
Dernière mise à jour le 19/6/2011
Page 14
USING FLEX 4.5
Getting started
This code causes the MXML compiler to generate a public variable named myText that contains a reference to the TextInput instance. This variable lets you access the component instance in ActionScript. You can explicitly refer to the TextInput control’s instance with its
id instance reference in any ActionScript class or script block. By referring to
a component’s instance, you can modify its properties and call its methods.
9
Because each qualify an object by referencing its parent with dot notation, as in
id value in an MXML file is unique, all objects in a file are part of the same flat namespace. You do not
myVGroup.myText.text.
For more information, see « Referring to components » à la page 36.
Using XML namespaces
The xmlns property in an MXML tag specifies an XML namespace. To use the default namespace, specify no prefix. Typically, you specify a tag prefix and a namespace.
For example, the Spark component set use the prefix s:.
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" >
Flex defines the following Universal Resource Identifiers (URI) for the Flex namespaces:
xmlns:fx="http://ns.adobe.com/mxml/2009"
The MXML language namespace URI. This namespace includes the top-level ActionScript language elements, such as Object, Number, Boolean, and Array. For a complete list of the top-level elements, see the Top Level package in the ActionScript 3.0 Reference for the Adobe Flash Platform.
This namespace also includes the tags built in to the MXML compiler, such as
<fx:Style> tags. For a list of the compiler elements, see the MXML Only Tags appendix in the ActionScript
and
3.0 Reference for the Adobe Flash Platform.
xmlns properties in the following <s:Application> tag indicates that tags corresponding to the
<fx:Script>, <fx:Declarations>,
This namespace does not include the MX or Spark component sets.
The complete list of top-level ActionScript language elements included in this namespace is defined by the frameworks\mxml-2009-manifest.xml manifest file in your Flex SDK installation directory. Note that this file does not list the MXML compiler tags because they are built in to the MXML compiler.
xmlns:mx="library://ns.adobe.com/flex/mx"
The MX component set namespace URI. This namespace includes all of the components in the Flex mx.* packages, the Flex charting components, and the Flex data visualization components.
The complete list of elements included in this namespace is defined by the frameworks\mx-manifest.xml manifest file in your Flex SDK installation directory.
xmlns:s="library://ns.adobe.com/flex/spark"
The Spark component set namespace URI. This namespace includes all of the components in the Flex spark.* packages and the text framework classes in the flashx.* packages.
This namespace includes the RPC classes for the WebService, HTTPService, and RemoteObject components and additional classes to support the RPC components. These classes are included in the provided as a convenience so that you can also reference them by using the
s: namespace.
mx: namespace, but are
Dernière mise à jour le 19/6/2011
Page 15
USING FLEX 4.5
Getting started
This namespace also includes several graphics, effect, and state classes from the mx.* packages. These classes are included in the
s: namespace.
mx: namespace, but are provided as a convenience so that you can also reference them by using the
The complete list of elements included in this namespace is defined by the frameworks\spark-manifest.xml manifest file in your Flex SDK installation directory.
The following table lists the classes from the mx.* packages included in this namespace:
10
Dernière mise à jour le 19/6/2011
Page 16
USING FLEX 4.5
Getting started
Category Class
RPC classes mx.messaging.channels.AMFChannel
mx.rpc.CallResponder
mx.messaging.ChannelSet
mx.messaging.Consumer
mx.messaging.channels.HTTPChannel
mx.rpc.http.mxml.HTTPService
mx.messaging.Producer
mx.rpc.remoting.mxml.RemoteObject
mx.rpc.remoting.mxml.Operation
mx.messaging.channels.RTMPChannel
mx.messaging.channels.SecureAMFChannel
mx.messaging.channels.SecureStreamingAMFChannel
mx.messaging.channels.SecureHTTPChannel
mx.messaging.channels.SecureStreamingHTTPChannel
mx.messaging.channels.SecureRTMPChannel
mx.messaging.channels.StreamingAMFChannel
mx.messaging.channels.StreamingHTTPChannel
mx.rpc.soap.mxml.WebService
mx.rpc.soap.mxml.Operation
mx.data.mxml.DataService
11
Graphics classes mx.graphics.BitmapFill
mx.geom.CompoundTransform
mx.graphics.GradientEntry
mx.graphics.LinearGradient
mx.graphics.LinearGradientStroke
mx.graphics.RadialGradient
mx.graphics.RadialGradientStroke
mx.graphics.SolidColor
mx.graphics.SolidColorStroke
mx.graphics.Stroke
mx.geom.Transform
Dernière mise à jour le 19/6/2011
Page 17
USING FLEX 4.5
Getting started
Category Class
Effect classes mx.effects.Parallel
mx.effects.Sequence
mx.states.Transition
mx.effects.Wait
States classes mx.states.State
mx.states.AddItems
Component classes mx.controls.Spacer
mx.controls.SWFLoader
XML namespaces give you the ability to use classes in custom packages that are not in the Flex namespaces. The following example shows an application that contains a custom component called CustomBox. The namespace value
myComponents.boxes.* indicates that an MXML component called CustomBox is in the myComponents/boxes
directory.
<?xml version="1.0"?> <!-- mxml/XMLNamespaces.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:MyComps="myComponents.boxes.*">
<s:Panel title="My Application" height="150"> <MyComps:CustomBox/> </s:Panel> </s:Application>
12
The myComponents/boxes directory can be a subdirectory of the directory that contains the application file, or it can be a subdirectory of one of the ActionScript source path directories assigned in the flex-config.xml file. If copies of the same file exist in both places, Flex uses the file in the application file directory. The prefix name is arbitrary, but it must be used as declared.
When using a component contained in a SWC file, the package name and the namespace must match, even though the SWC file is in the same directory as the MXML file that uses it. A SWC file is an archive file for Flex components. SWC files make it easy to exchange components among Flex developers. You exchange only a single file, rather than the MXML or ActionScript files and images, along with other resource files. Also, the SWF file inside a SWC file is compiled, which means that the source code is obfuscated from casual view.
For more information on SWC files, see « Flex compilers » à la page 2162.
Using MXML to trigger run-time code
Flex applications are driven by run-time events, such as when a user selects a Button control. You can specify event listeners, which consist of code for handling run-time events, in the event properties of MXML tags. For example, the
<s:Button> tag has a click event property in which you can specify ActionScript code that executes when the Button
control is clicked at run time. You can specify simple event listener code directly in event properties. To use more complex code, you can specify the name of an ActionScript function defined in an
The following example shows an application that contains a Button control and a TextArea control. The property of the Button control contains a simple event listener that sets the value of the TextArea control’s property to the text
Hello World.
<fx:Script> tag.
click
text
Dernière mise à jour le 19/6/2011
Page 18
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/TriggerCodeExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<s:Panel title="My Application"> <s:layout> <s:VerticalLayout/> </s:layout> <s:TextArea id="textarea1"/> <s:Button label="Submit" click="textarea1.text='Hello World';"/> </s:Panel> </s:Application>
The following example shows the code for a version of the application in which the event listener is contained in an ActionScript function in an
<?xml version="1.0"?> <!-- mxml/TriggerCodeExample2.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script> <![CDATA[ private function hello():void { textarea1.text="Hello World"; } ]]> </fx:Script>
<s:Panel title="My Application"> <s:layout> <s:VerticalLayout/> </s:layout> <s:TextArea id="textarea1"/> <s:Button label="Submit" click="hello();"/> </s:Panel> </s:Application>
<fx:Script> tag:
13
For more information about using ActionScript with MXML, see « Using ActionScript » à la page 32.
Binding data between components
Flex provides simple syntax for binding the properties of components to each other. In the following example, the value inside the curly braces ({ }) binds the control. When the application initializes, both controls display the text both controls display the text
Goodbye.
text property of a TextArea control to the text property of a TextInput
Hello. When the user clicks the Button control,
Dernière mise à jour le 19/6/2011
Page 19
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/BindingExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<s:Panel title="My Application"> <s:VGroup left="10" right="10" top="10" bottom="10"> <s:Label text="Enter Text:"/> <s:TextInput id="textinput1" text="Hello"/> <s:Label text="Bind Text to the TextArea control:"/> <s:TextArea id="textarea1" text="{textinput1.text}"/> <s:Button label="Submit" click="textinput1.text='Goodbye';"/> </s:VGroup> </s:Panel> </s:Application>
As an alternative to the curly braces ({ }) syntax, you can use the <fx:Binding> tag, in which you specify the source and destination of a binding. For more information about data binding, see « Data binding » à la page 300.
14
Using RPC services
Remote-procedure-call (RPC) services let your application interact with remote servers to provide data to your applications, or for your application to send data to a server.
Flex is designed to interact with several types of RPC services that provide access to local and remote server-side logic. For example, a Flex application can connect to a web service that uses the Simple Object Access Protocol (SOAP), a Java object residing on the same application server as Flex using AMF, or an HTTP URL that returns XML.
The MXML components that provide data access are called RPC components. MXML includes the following types of RPC components:
WebService provides access to SOAP-based web services.
HTTPService provides access to HTTP URLs that return data.
RemoteObject provides access to Java objects using the AMF protocol (Adobe LiveCycle Data Services ES only).
In MXML, define the RPC components in an declare non-visual components an MXML file.
The following example shows an application that calls a web service that provides weather information, and displays the current temperature for a given ZIP code. The application binds the ZIP code that a user enters in a TextInput control to a web service input parameter. It binds the current temperature value contained in the web service result to a TextArea control.
<fx:Declarations> tag. You use the <fx:Declarations> tag to
Dernière mise à jour le 19/6/2011
Page 20
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/RPCExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations> <!-- Define the web service connection (the specified WSDL URL is not functional). --> <s:WebService id="WeatherService" wsdl="http:/example.com/ws/WeatherService?wsdl" useProxy="false"> <!-- Bind the value of the ZIP code entered in the TextInput control to the ZipCode parameter of the GetWeather operation. --> <s:operation name="GetWeather"> <s:request> <ZipCode>{zip.text}</ZipCode> </s:request> </s:operation> </s:WebService> </fx:Declarations>
<s:Panel title="My Application"> <s:VGroup left="10" right="10" top="10" bottom="10"> <!-- Provide a ZIP code in a TextInput control. --> <s:TextInput id="zip" width="200" text="Zipcode please?"/> <!-- Call the web service operation with a Button click. --> <s:Button width="60" label="Get Weather" click="WeatherService.GetWeather.send();"/> <!-- Display the location for the specified ZIP code. --> <s:Label text="Location:"/> <s:TextArea text="{WeatherService.GetWeather.lastResult.Location}"/> <!-- Display the current temperature for the specified ZIP code. --> <s:Label text="Temperature:"/> <s:TextArea text="{WeatherService.GetWeather.lastResult.CurrentTemp}"/> </s:VGroup> </s:Panel> </s:Application>
15
For more information about using RPC services, see Accessing Server-Side Data with Flex.
Storing data in a data model
You can use a data model to store application-specific data. A data model is an ActionScript object that provides properties for storing data, and optionally contains methods for additional functionality. Data models provide a way to store data in the Flex application before it is sent to the server, or to store data sent from the server before using it in the application.
You can declare a simple data model that does not require methods in an tag. In MXML, define a data model in an
<fx:Declarations> tag. You use the <fx:Declarations> tag to declare
non-visual components an MXML file.
The following example shows an application that contains TextInput controls for entering personal contact information and a data model, represented by the
<fx:Model> tag, for storing the contact information:
Dernière mise à jour le 19/6/2011
<fx:Model>, <fx:XML>, or <fx:XMLList>
Page 21
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/StoringData.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Declarations> <!-- A data model called "contact" stores contact information. The text property of each TextInput control shown above is passed to a field of the data model by using data binding. --> <fx:Model id="contact"> <info> <homePhone>{homePhoneInput.text}</homePhone> <cellPhone>{cellPhoneInput.text}</cellPhone> <email>{emailInput.text}</email> </info> </fx:Model> </fx:Declarations> <s:Panel title="My Application"> <s:VGroup left="10" right="10" top="10" bottom="10"> <!-- The user enters contact information in TextInput controls. --> <s:TextInput id="homePhoneInput" text="This isn't a valid phone number."/> <s:TextInput id="cellPhoneInput" text="(999)999-999"/> <s:TextInput id="emailInput" text="me@somewhere.net"/> </s:VGroup> </s:Panel> </s:Application>
16
This example uses data binding in the model definition to automatically copy data from the UI controls to the data model.
Validating data
Flex includes a set of standard validator components for data such as phone numbers, social security numbers, and ZIP codes. You can also create your own custom validator.
In MXML, define validators in an visual components an MXML file.
The following example uses validator components for validating that the expected type of data is entered in the TextInput fields. In this example, you validate a phone number by using the PhoneNumberValidator class and an e­mail address by using the EmailValidator class. Validation is triggered automatically when the user edits a TextInput control. If validation fails, the user receives immediate visual feedback.
<fx:Declarations> tag. You use the <fx:Declarations> tag to declare non-
Dernière mise à jour le 19/6/2011
Page 22
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/ValidatingExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations> <!-- Validator components validate data entered into the TextInput controls. --> <mx:PhoneNumberValidator id="pnV" source="{homePhoneInput}" property="text"/> <mx:EmailValidator id="emV" source="{emailInput}" property="text" /> </fx:Declarations> <s:Panel title="My Application"> <s:VGroup left="10" right="10" top="10" bottom="10"> <s:Label text="Enter phone number:"/> <s:TextInput id="homePhoneInput"/> <s:Label text="Enter email address:"/> <s:TextInput id="emailInput"/> </s:VGroup> </s:Panel> </s:Application>
17
A component with a validation failure displays a red border. If the component has focus, it also displays a validation error message. Set the component to a valid value to remove the error indication.
For more information about using data models, see « Storing data » à la page 890. For more information on validators, see « Validating Data » à la page 1963.
Formatting data
Formatter components are ActionScript components that perform a one-way conversion of raw data to a formatted string. They are triggered just before data is displayed in a text field. Flex includes a set of standard formatters. You can also create your own formatters.
In MXML, define formatters in an visual components an MXML file.
The following example shows an application that uses the standard ZipCodeFormatter component to format the value of a variable:
<fx:Declarations> tag. You use the <fx:Declarations> tag to declare non-
Dernière mise à jour le 19/6/2011
Page 23
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/FormatterExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script> <![CDATA[ [Bindable] private var storedZipCode:Number=123456789; ]]> </fx:Script> <fx:Declarations> <!-- Declare a ZipCodeFormatter and define parameters. --> <mx:ZipCodeFormatter id="ZipCodeDisplay" formatString="#####-####"/> </fx:Declarations> <s:Panel title="My Application"> <!-- Trigger the formatter while populating a string with data. --> <s:TextInput text="{ZipCodeDisplay.format(storedZipCode)}"/> </s:Panel> </s:Application>
For more information about formatter components, see « Formatting Data » à la page 2002.
18
Using Cascading Style Sheets (CSS)
You can use style sheets based on the CSS standard to declare styles to Flex components. The MXML <fx:Style> tag contains inline style definitions or a reference to an external file that contains style definitions.
<fx:Style> tag must be an immediate child of the root tag of the MXML file. You can apply styles to an individual
The component using a class selector, or to all components of a certain type using a type selector.
Namespace qualification is required for type selectors in the
@namespace tag.
the
The following example defines a class selector and a type selector in the the type selector are applied to the Button control.
<fx:Style> tag. Prefix the namespace qualification with
<fx:Style> tag. Both the class selector and
Dernière mise à jour le 19/6/2011
Page 24
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/CSSExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/mx";
/* class selector */ .myClass { color: Red }
/* type selector */ s|Button { font-size: 18pt } </fx:Style> <s:Panel title="My Application"> <s:Button styleName="myClass" label="This is red 18 point text."/> </s:Panel> </s:Application>
19
A class selector in a style definition, defined as a label preceded by a period, defines a new named style, such as myClass in the preceding example. After you define it, you can apply the style to any component by using the
styleName
property. In the preceding example, you apply the style to the Button control to set the font color to red.
A type selector applies a style to all instances of a particular component type. In the preceding example, you set the font size for all Spark Button controls to 18 points.
For more information about using Cascading Style Sheets, see « Styles and themes » à la page 1493.
Using skins
Skinning is the process of changing the appearance of a component by modifying or replacing its visual elements. These elements can be made up of bitmap images, SWF files, or class files that contain drawing methods that define vector images. Skins can define the entire appearance, or only a part of the appearance, of a component in various states.
One of the big differences between Spark and MX components is that Spark components rely on the component skin to define its layout and appearance. When working with Spark components, you often define a custom skin to modify the component appearance.
MX components use a combination of CSS styles and skins to control their appearance. With MX components, you can use styles to modify much of the appearance of the component without having to define a custom skin.
For more information about using Spark skins, see « Spark Skinning » à la page 1602. For more information about using MX skins, see « Skinning MX components » à la page 1654.
Using effects
An effect is a change to a component that occurs over a brief period of time. Examples of effects are fading, resizing, and moving a component. In MXML, you apply effects as properties of a control or container. Flex provides a set of built-in effects with default properties.
Dernière mise à jour le 19/6/2011
Page 25
USING FLEX 4.5
Getting started
In MXML, define effects in an <fx:Declarations> tag. You use the <fx:Declarations> tag to declare non-visual components an MXML file.
20
The following example shows an application that contains a Button control with its
click property set to use the
Resize effect when the user moves the mouse over it:
<?xml version="1.0"?> <!-- behaviors\TargetProp.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations> <s:Resize id="myResize" heightBy="25" widthBy="50" target="{myButton}"/> </fx:Declarations>
<s:Button id="myButton" label="Resize target" click="myResize.end();myResize.play();"/> </s:Application>
For more information about effects, see « Introduction to effects » à la page 1784.
Defining custom MXML components
Custom MXML components are MXML files that you create and use as custom MXML tags in other MXML files. They encapsulate and extend the functionality of existing Flex components. Just like MXML application files, MXML component files can contain a mix of MXML tags and ActionScript code. The name of the MXML file becomes the class name with which you refer to the component in another MXML file.
The following example shows a custom ComboBox control that is prepopulated with list items:
<?xml version="1.0"?> <!-- mxml/myComponents/boxes/MyComboBox.mxml --> <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<s:ComboBox> <s:dataProvider> <s:ArrayCollection> <fx:String>Dogs</fx:String> <fx:String>Cats</fx:String> <fx:String>Mice</fx:String> </s:ArrayCollection> </s:dataProvider> </s:ComboBox> </s:VGroup>
The following example shows an application that uses the MyComboBox component as a custom tag. The value
myComponents.boxes.* assigns the MyComps namespace to the myComponents/boxes sub-directory. To run this
example, store the MyComboBox.mxml file in that sub-directory.
Dernière mise à jour le 19/6/2011
Page 26
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml/CustomMXMLComponent.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:MyComps="myComponents.boxes.*"> <s:Panel title="My Application" height="150"> <MyComps:MyComboBox/> </s:Panel> </s:Application>
For more information about MXML components, see « Simple MXML components » à la page 2399. You can also define custom Flex components in ActionScript. For more information, see « Create simple visual components in
ActionScript » à la page 2433.

MXML syntax

MXML is an XML language that you use to lay out user-interface components for Adobe® Flex® applications.
21

Basic MXML syntax

Most MXML tags correspond to ActionScript 3.0 classes or properties of classes. Flex parses MXML tags and compiles a SWF file that contains the corresponding ActionScript objects.
ActionScript 3.0 uses syntax based on the ECMAScript edition 4 draft language specification. ActionScript 3.0 includes the following features:
Formal class definition syntax
Formal packages structure
Typing of variables, parameters, and return values (compile-time only)
Implicit getters and setters that use the get and set keywords
Inheritance
Public and private members
Static members
Cast operator
For more information about ActionScript 3.0, see « Using ActionScript » à la page 32.
Naming MXML files
MXML filenames must adhere to the following naming conventions:
Filenames must be valid ActionScript identifiers, which means they must start with a letter or underscore character
(_), and they can only contain letters, numbers, and underscore characters after that.
Filenames must not be the same as ActionScript class names, component id values, or the word application. Do not
use filenames that match the names of MXML tags that are in the
Filenames must end with a lowercase .mxml file extension.
fx:, s:, or mx: namespace.
Dernière mise à jour le 19/6/2011
Page 27
USING FLEX 4.5
Getting started
Using tags that represent ActionScript classes
An MXML tag that corresponds to an ActionScript class uses the same naming conventions as the ActionScript class. Class names begin with a capital letter, and capital letters separate the words in class names. For example, when a tag corresponds to an ActionScript class, its properties correspond to the properties and events of that class.

Setting component properties

In MXML, a component property uses the same naming conventions as the corresponding ActionScript property. A property name begins with a lowercase letter, and capital letters separate words in the property names.
You can set most component properties as tag attributes, in the form:
<s:Label width="50" height="25" text="Hello World"/>
You can set all component properties as child tags, in the form:
<s:Label> <s:width>50</s:width> <s:height>25</s:height> <s:text>Hello World</s:text> </s:Label>
You often use child tags when setting the value of a property to a complex Object because it is not possible to specify a complex Object as the value of tag attribute. In the following example, you use child tags to set the data provider of a Spark List control to an ArrayCollection object:
22
<s:List> <s:dataProvider> <s:ArrayCollection> <fx:String>AK</fx:String> <fx:String>AL</fx:String> <fx:String>AR</fx:String> </s:ArrayCollection> </s:dataProvider> </s:List>
The one restriction on setting properties that use child tags is that the namespace prefix of a child tag, s: in the previous example, must match the namespace prefix of the component tag. Note that the value of the property in the previous example does not have to use the same namespace as the property tag.
Each of a component’s properties is one of the following types:
Scalar properties, such as a number or string
Array of scalar values, such as an array of numbers or strings
ActionScript object
Array of ActionScript objects
ActionScript properties
XML data
Adobe recommends that you assign scalar values using tag attributes, and that you assign complex types, such as ActionScript objects, by using child tags.
Setting scalar properties
You usually specify the value of a scalar property as a property of a component tag, as the following example shows:
Dernière mise à jour le 19/6/2011
Page 28
USING FLEX 4.5
Getting started
<s:Label width="50" height="25" text="Hello World"/>
Setting properties using constants
The valid values of many component properties are defined by static constants, where these static constants are defined in an ActionScript class. In MXML, you can either use the static constant to set the property value, or use the value of the static constant, as the following example shows:
<!-- Set the property using the static constant. --> <s:Wipe direction="{spark.effects.WipeDirection.LEFT}"> ... </s:Wipe>
<!-- Set the property using the value of the static constant. --> <s:Wipe direction="left"> ... </s:Wipe>
The Wipe effect defines a property named direction that defines the direction of the wipe effect. In this example, you explicitly set the
direction property to cause the wipe effect to move left.
23
In the first example, you set the
direction property using a static constant named LEFT, which is defined in the
spark.effects.WipeDirection class. In MXML, you must use data binding syntax when setting a property value to a static constant. The advantage of using the static constant is that the Flex compiler recognizes incorrect property values, and issues an error message at compile time.
Alternatively, you can set the value of the static constant is
"left". When you use the value of the static constant to set the property value, the Flex compiler
direction property to the value of the static constant. The value of the LEFT
cannot determine if you used an unsupported value. If you incorrectly set the property, you will not know until you get a run-time error.
In ActionScript, you should use static constants to set property values whenevera possible, as the following example shows:
var myWipe:Wipe = new Wipe(); myWipe.direction=spark.effects.WipeDirection.LEFT;
Setting the default property
Many Flex components define a single default property. The default property is the MXML tag that is implicit for content inside of the MXML tag if you do not explicitly specify a property. For example, consider the following MXML tag definition:
<s:SomeTag> anything here </s:SomeTag>
If this tag defines a default property named default_property, the preceding tag definition is equivalent to the following code:
<s:SomeTag> <s:default_property> anything here </s:default_property> </s:SomeTag>
It is also equivalent to the following code:
<s:SomeTag default_property="anything here"/>
Dernière mise à jour le 19/6/2011
Page 29
USING FLEX 4.5
Getting started
The default property provides a shorthand mechanism for setting a single property. For a Spark List, the default property is the
<?xml version="1.0"?> <!-- mxml\DefProp.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:HorizontalLayout/> </s:layout> <!-- Omit the default property. --> <s:List> <s:ArrayCollection> <fx:String>AK</fx:String> <fx:String>AL</fx:String> <fx:String>AR</fx:String> </s:ArrayCollection> </s:List>
<!-- Explicitly speficy the default property. --> <s:List> <s:dataProvider> <s:ArrayCollection> <fx:String>AK</fx:String> <fx:String>AL</fx:String> <fx:String>AR</fx:String> </s:ArrayCollection> </s:dataProvider> </s:List> </s:Application>
dataProvider property. Therefore, the two List definitions in the following code are equivalent:
24
Not all Flex components define a default property. To determine the default property for each component, see the
ActionScript 3.0 Reference for the Adobe Flash Platform.
You can also define a default property when you create a custom component. For more information, see « Metadata
tags in custom components » à la page 2376.
Escaping characters using the backslash character
When setting a property value in MXML, you can escape a reserved character by prefixing it with the backslash character (\), as the following example shows:
<?xml version="1.0"?> <!-- mxml\EscapeChar.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:Label text="\{\}"/> </s:Application>
In this example, you want to use literal curly brace characters ({ }) in a text string. But Flex uses curly braces to indicate a data binding operation. Therefore, you prefix each curly brace with the backslash character to cause the MXML compiler to interpret them as literal characters.
Dernière mise à jour le 19/6/2011
Page 30
USING FLEX 4.5
Getting started
Setting String properties using the backslash character
The MXML compiler automatically escapes the backslash character in MXML when the character is part of the value specified for a property of type String. Therefore, it always converts
"\" to "\\".
25
This is necessary because the ActionScript compiler recognizes
"\\" as the character sequence for a literal "\"
character, and strips out the leading backslash when it initializes the property value.
Remarque : Do not use the backslash character (\) as a separator in the path to an application asset. You should always use a forward slash character (/) as the separator.
Including a newline character in a String value
For properties of type String, you can insert a newline character in the String in several ways:
By using data binding with the '\n' characters in your String value in MXML
By inserting the code in your String value in MXML
By inserting "\n" in an ActionScript String variable used to initialize the MXML property
To use data binding, wrap the newline character in curly brace characters ({ }), as the following example shows:
<s:TextArea width="100%" text="Display{'\n'}Content"/>
To use the code to insert a newline character, include that code in the property value in MXML, as the following example shows:
<s:TextArea width="100%" text="Display Content"/>
To use an ActionScript String variable to insert a newline character, create an ActionScript variable, and then use data binding to set the property in MXML, as the following example shows:
<fx:Script> <![CDATA[ [Bindable] public var myText:String = "Display" + "\n" + "Content"; ]]> </fx:Script>
<s:TextArea width="100%" text="{myText}"/>
In this example, you set the text property of the TextArea control to a value that includes a newline character.
Notice that this example includes the specifies that the copies the value of a
source property changes.
myText property can be used as the source of a data binding expression. Data binding automatically
source property of one object to the destination property of another object at run time when the
[Bindable] metadata tag before the property definition. This metadata tag
If you omit this metadata tag, the compiler issues a warning message specifying that the property cannot be used as the source for data binding. For more information, see « Data binding » à la page 300.
Mixing content types
Flex supports the mixing of content for attribute values. The attribute must correspond to a property of type Object or Array. Mixed content consists of non white space character data and MXML tags, as the following example shows:
Dernière mise à jour le 19/6/2011
Page 31
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- mxml\DefPropMixed.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:RichText fontFamily="Verdana" fontWeight="bold"> <s:content> <fx:String>Hello World!</fx:String><s:br/> <fx:String>Hello Universe</fx:String><s:br/> Hello Flex! </s:content> </s:RichText> </s:Application>
In this example, the RichText.content property is of type Object. The property value contains values defined by
<fx:String> tag, and by character data (“Hello Flex!”). Character data is almost always converted to a value of type
String. However, an Array property may be defined to support an explicit data type for its values. In that case, the compiler converts the character data to the appropriate data type.
Setting Arrays of scalar values
When a class has a property that takes an Array as its value, you can represent the property in MXML using child tags. The component in the following example has a
children property that contains an Array of numbers:
26
<mynamespace:MyComponent> <mynamespace:children> <fx:Array> <fx:Number>94062</fx:Number> <fx:Number>14850</fx:Number> <fx:Number>53402</fx:Number> </fx:Array> </mynamespace:children> </mynamespace:MyComponent>
The <fx:Array> and </fx:Array> tags around the Array elements are optional. Therefore, you can also write this example as the following code shows:
<mynamespace:MyComponent>
<mynamespace:children>
<fx:Number>94062</fx:Number> <fx:Number>14850</fx:Number> <fx:Number>53402</fx:Number>
</mynamespace:children>
</mynamespace:MyComponent>
In this example, since the data type of the children property is defined as Array, Flex automatically converts the three number definitions into a three-element array.
Component developers may have specified additional information within the component definition that defines the data type of the Array elements. For example, if the developer specified that the
dataProvider property supports only
String elements, this example would cause a compiler error because you specified numbers to it. The ActionScript 3.0
Reference for the Adobe Flash Platform documents the Array properties that define a required data type for the Array
elements.
Setting Object properties
When a component has a property that takes an object as its value, you can represent the property in MXML using a child tag with tag attributes, as the following example shows:
Dernière mise à jour le 19/6/2011
Page 32
USING FLEX 4.5
Getting started
<mynamespace:MyComponent> <mynamespace:nameOfProperty> <mynamespace:typeOfObject prop1="val1" prop2="val2"/> </mynamespace:nameOfProperty> </mynamespace:MyComponent>
The following example shows an ActionScript class that defines an Address object. This object is used as a property of the PurchaseOrder component in the next example.
class Address { public var name:String; public var street:String; public var city:String; public var state:String; public var zip:Number; }
The following example shows an ActionScript class that defines a PurchaseOrder component that has a property type of Address:
import example.Address;
class PurchaseOrder { public var shippingAddress:Address; public var quantity:Number; ... }
27
In MXML, you define the PurchaseOrder component as the following example shows:
<mynamespace:PurchaseOrder quantity="3" xmlns:e="example">
<mynamespace:shippingAddress> <mynamespace:Address name="Fred" street="123 Elm St."/> </mynamespace:shippingAddress> </mynamespace:PurchaseOrder>
If the value of the shippingAddress property is a subclass of Address (such as DomesticAddress), you can declare the property value, as the following example shows:
<mynamespace:PurchaseOrder quantity="3" xmlns:e="example"> <mynamespace:shippingAddress> <mynamespace:DomesticAddress name="Fred" street="123 Elm St."/> </mynamespace:shippingAddress> </mynamespace:PurchaseOrder>
If the property is explicitly typed as Object like the value property in the following example, you can specify an anonymous object using the
class ObjectHolder { public var value:Object }
<fx:Object> tag.
The following example shows how you specify an anonymous object as the value of the value property:
<mynamespace:ObjectHolder> <mynamespace:value> <fx:Object foo='bar'/> </mynamespace:value> </mynamespace:ObjectHolder>
Dernière mise à jour le 19/6/2011
Page 33
USING FLEX 4.5
Getting started
Populating an Object with an Array
When a component has a property of type Object that takes an Array as its value, you can represent the property in MXML using child tags, as the following example shows:
<mynamespace:MyComponent> <mynamespace:nameOfObjectProperty> <fx:Array> <fx:Number>94062</fx:Number> <fx:Number>14850</fx:Number> <fx:Number>53402</fx:Number> </fx:Array> </mynamespace:nameOfObjectProperty> </mynamespace:MyComponent>
In this example, you initialize the Object property to a three-element array of numbers.
28
As described in the section « Setting Arrays of scalar values » à la page 26, the
<fx:Array> tag and the </fx:Array>
tag around the Array elements are optional and may be omitted, as the following example shows:
<mynamespace:MyComponent> <mynamespace:nameOfObjectProperty> <fx:Number>94062</fx:Number> <fx:Number>14850</fx:Number> <fx:Number>53402</fx:Number> </mynamespace:nameOfObjectProperty> </mynamespace:MyComponent>
The only exception to this rule is when you specify a single Array element for the Object property. In that case, Flex does not create an Object containing a single-element array, but instead creates an object and sets it to the specified value. This is a difference between the following two lines:
object=[element] // Object containing a one-element array object=element // object equals value
If you want to create a single-element array, include the <fx:Array> and </fx:Array> tags around the array element, as the following example shows:
<mynamespace:MyComponent> <mynamespace:nameOfObjectProperty> <fx:Array> <fx:Number>94062</fx:Number> </fx:Array> </mynamespace:nameOfObjectProperty> </mynamespace:MyComponent>
Populating Arrays of objects
When a component has a property that takes an Array of objects as its value, you can represent the property in MXML using child tags, as the following example shows:
<mynamespace:MyComponent> <mynamespace:nameOfProperty> <fx:Array> <mynamespace:objectType prop1="val1" prop2="val2"/> <mynamespace:objectType prop1="val1" prop2="val2"/> <mynamespace:objectType prop1="val1" prop2="val2"/> </fx:Array> </mynamespace:nameOfProperty> </mynamespace:MyComponent>
Dernière mise à jour le 19/6/2011
Page 34
USING FLEX 4.5
Getting started
The component in the following example contains an Array of ListItem objects. Each ListItem object has properties
label and data.
named
<mynamespace:MyComponent> <mynamespace:dataProvider> <fx:Array> <mynamespace:ListItem label="One" data="1"/> <mynamespace:ListItem label="Two" data="2"/> </fx:Array> </mynamespace:dataProvider> </mynamespace:MyComponent>
The following example shows how you specify an anonymous object as the value of the dataProvider property:
<mynamespace:MyComponent> <mynamespace:dataProvider> <fx:Array> <fx:Object label="One" data="1"/> <fx:Object label="Two" data="2"/> </fx:Array> </mynamespace:dataProvider> </mynamespace:MyComponent>
As described in the section « Setting Arrays of scalar values » à la page 26, the <fx:Array> tag and the </fx:Array> tag around the Array elements are optional and may be omitted, as the following example shows:
29
<mynamespace:MyComponent> <mynamespace:dataProvider> <fx:Object label="One" data="1"/> <fx:Object label="Two" data="2"/> </mynamespace:dataProvider> </mynamespace:MyComponent>
Populating a Vector
The Vector class lets you access and manipulate a vector. A Vector is an array whose elements all have the same data type. The data type of a Vector's elements is known as the Vector's base type. The base type can be any class, including built in classes and custom classes. The base type is specified when declaring a Vector variable as well as when creating an instance by calling the class constructor.
In MXML, define an instance of a Vector class in a
<fx:Declarations>
<fx:Vector type="String">
<fx:String>one</fx:String> <fx:String>two</fx:String> <fx:String>three</fx:String>
</fx:Vector>
<fx:Vector type="Vector.<String>">
<fx:Vector type="String">
<fx:String>one</fx:String> <fx:String>two</fx:String> <fx:String>three</fx:String>
</fx:Vector>
</fx:Vector> </fx:Declarations>
<fx:Declarations> block, as the following example shows:
Dernière mise à jour le 19/6/2011
Page 35
USING FLEX 4.5
Getting started
The first example defines a Vector with a base type of String. The second example defines a Vector of Vectors of type String. Notice that you use the HTML escape characters
< and > , instead of < and >, in the nested Vector. This
syntax is necessary to conform to XML syntax rules.
Setting properties that contain XML data
If a component contains a property that takes XML data, the value of the property is an XML fragment to which you can apply a namespace. In the following example, the
<mynamespace:MyComponent> <mynamespace:value xmlns:a="http://www.example.com/myschema"> <fx:XML> <a:purchaseorder> <a:billingaddress> ... </a:billingaddress> ... </a:purchaseorder> </fx:XML> </mynamespace:value> </mynamespace:MyComponent>
value property of the MyComponent object is XML data:
30
Setting style properties in MXML
A style property of an MXML tag differs from other properties because it corresponds to an ActionScript style, rather than to a property of an ActionScript class. You set these properties in ActionScript using the
setStyle(stylename,
value) method rather than object.property=value notation.
For example, you can set the
<s:TextArea id="myText" text="hello world" fontFamily="Tahoma"/>
fontFamily style property in MXML, as the following code shows:
This MXML code is equivalent to the following ActionScript code:
myText.setStyle("fontFamily", "Tahoma");
You define style properties in custom ActionScript classes by using the [Style] metadata tags, rather than defining them as ActionScript variables or setter/getter methods. For more information, see « Metadata tags in custom
components » à la page 2376.
Setting event properties in MXML
An event property of an MXML tag lets you specify the event listener function for an event. This property corresponds to setting the event listener in ActionScript using the
For example, you can set the
<s:TextArea id="myText" creationComplete="creationCompleteHandler();"/>
creationComplete event property in MXML, as the following code shows:
This MXML code is equivalent to the following ActionScript code:
myText.addEventListener("creationComplete", creationCompleteHandler);
addEventListener() method.
You define event properties in custom ActionScript classes by using the [Event] metadata tags, rather than defining them as ActionScript variables or setter/getter methods. For more information, see « Metadata tags in custom
components » à la page 2376.
Dernière mise à jour le 19/6/2011
Page 36
USING FLEX 4.5
Getting started
Specifying a URL value
Some MXML tags, such as the <fx:Script> tag, have a property that takes a URL of an external file as a value. For example, you can use the typing ActionScript directly in the body of the
source property in an <fx:Script> tag to reference an external ActionScript file instead of
<fx:Script> tag.
31
Remarque : You specify a script in the
source property. For information on using ActionScript classes, see « Creating ActionScript components » à la
in the
source property of an <fx:Script> tag. You do not specify ActionScript classes
page 49.
MXML supports the following types of URLs:
Absolute, as in the following example:
<fx:Style source="http://www.somesite.com/mystyles.css">
A path used at compile time that is relative to the application, as in the following example:
<fx:Script source="/myscript.as"/>
Relative to the current file location, as in the following example:
<fx:Script source="../myscript.as"/>
A path used at run time that is relative to the context root of the Java web application in which a Flex application is
running. For example:
<mx:HTTPService url="@ContextRoot()/directory/myfile.xml"/>
You can only use the @ContextRoot() token if you are using the web-tier compiler or if you set the value of the
context-root compiler argument
Specifying a RegExp value
For a property of type RegExp, you can specify its value in MXML using the following format:
"/pattern/flags"
pattern Specifies the regular expression within the two slashes. Both slashes are required.
flags (Optional) Specifies any flags for the regular expression.
For example, the
regExpression property of an MXML component is of type RegExp. Therefore, you can set its value
as the following example shows:
<mynamespace:MyComponent regExpression="/\Wcat/gi"/>
Or set it using child tags, as the following example shows:
<mynamespace:MyComponent> <mynamespace:regExpression>/\Wcat/gi</mynamespace:regExpression> </mynamespace:MyComponent>
The flags portion of the regular expression is optional, so you can also specify it as the following example shows:
<mynamespace:MyComponent regExpression="/\Wcat/"/>
Using compiler tags
Compiler tags are tags that do not directly correspond to ActionScript objects or properties. They include the following:
<fx:Binding>
<fx:Component>
<fx:Declarations>
Dernière mise à jour le 19/6/2011
Page 37
USING FLEX 4.5
Getting started
<fx:Definition>
<fx:DesignLayer>
<fx:Library>
<fx:Metadata>
<fx:Model>
<fx:Private>
<fx:Reparent>
<fx:Script>
<fx:Style>
MXML tag rules
MXML has the following syntax requirements:
The id property is not required on any tag.
The id property is not allowed on the root tag.
Boolean properties take only true and false values.
The <fx:Binding> tag requires both source and destination properties.
The <fx:Binding> tag cannot contain an id property.
32

Using ActionScript

Flex developers can use ActionScript to extend the functionality of their Adobe® Flex® applications. ActionScript provides flow control and object manipulation features that are not available in MXML. For a complete introduction to ActionScript and a reference for using the language, see ActionScript 3.0 Developer's Guide and ActionScript 3.0
Reference for the Adobe Flash Platform.

Using ActionScript in applications

Flex developers can use ActionScript to implement custom behavior within their applications. You first use MXML tags to declare things like the containers, controls, effects, formatters, validators, and web services that your application requires, and to lay out its user interface. Each of these components provides the standard behavior you’d expect. For example, a button automatically highlights when you roll over it, without requiring you to write any ActionScript. But a declarative language like MXML is not appropriate for coding what you want to happen when the user clicks a button. For that, you need to use a procedural language like ActionScript, which offers executable methods, various types of storage variables, and flow control such as conditionals and loops. In a general sense, MXML implements the static aspects of your application, and ActionScript implements its dynamic aspects.
ActionScript is an object-oriented procedural programming language, based on the ECMAScript (ECMA-262) edition 4 draft language specification. You can use a variety of methods to mix ActionScript and MXML, including the following:
Define event listeners inside MXML event attributes.
Add script blocks using the <fx:Script> tag.
Include external ActionScript files.
Dernière mise à jour le 19/6/2011
Page 38
USING FLEX 4.5
Getting started
Import ActionScript classes.
Create ActionScript components.
ActionScript compilation
Although a simple application can be written in a single MXML or ActionScript (AS) file, most applications will be broken into multiple files. For example, it is common to move the AS and CSS files that the application then includes.
It is also common for an application to import custom MXML and ActionScript components. These must be defined in other files, and MXML components may put their own
<fx:Script> blocks into yet more AS files that they include.
Components may also be imported from precompiled SWC files rather than source code. Finally, SWF files containing executable code can also be embedded in an application. The end result of all these input files is a single SWF file.
The Flex compiler transforms the main MXML file and other files it includes into a single ActionScript class. As a result, you cannot define classes or use statements outside of functions in the MXML files and the included ActionScript files.
You can reference imported ActionScript classes from your MXML application files, and those classes are added to the final SWF file. When the transformation to an ActionScript file is complete, Flex links all the ActionScript components and includes those classes in the final SWF file.
<fx:Script> and <fx:Style> blocks into separate
33
About generated ActionScript
When you write an MXML file and compile it, the Flex compiler creates a class and generates ActionScript that the class uses. MXML tags and ActionScript are used by the resulting class in several ways. This information is useful for understanding what is happening in the background of the application.
An MXML application (a file that starts with the class. Similarly, an MXML component (a file that starts with some other component’s tag, such as defines a subclass of that component.
The name of the subclass is the name of the file. The base class is the class of the top-level tag. An MXML application actually defines the following:
class MyApp extends Application
If MyButton.mxml starts with <s:Button>, you are actually defining the following:
class MyButton extends Button
The variable and function declarations in an <fx:Script> block define properties and methods of the subclass.
Setting an
id property on a component instance within a class results in a public variable being autogenerated in the
subclass that contains a reference to that component instance. For example, if the is nested deeply inside several containers, you can still refer to it as
Event attributes become the bodies of autogenerated event listener methods in the subclass. For example:
<s:Button id="myButton" click="foo = 1; doSomething()">
becomes
<s:Application> tag) defines a subclass of the Spark Application
<s:Button>)
<s:Button id="myButton"/> tag
myButton.
private function __myButton_click(event:MouseEvent):void { foo = 1; doSomething() }
The event attributes become method bodies, so they can access the other properties and methods of the subclass.
Dernière mise à jour le 19/6/2011
Page 39
USING FLEX 4.5
Getting started
All the ActionScript anywhere in an MXML file, whether in its <fx:Script> block or inside tags, executes with the
this keyword referring to an instance of the subclass.
The public properties and methods of the class are accessible by ActionScript code in other components, as long as that code “dots down” (for example, up using the
parentDocument, parentApplication, or FlexGlobals.topLevelApplication properties to specify
myCheckoutAccordion.myAddressForm.firstNameTextInput.text) or reaches
which component the property or method exists on.
Using ActionScript in MXML event handlers
One way to use ActionScript code in an application is to include it within the MXML tag’s event handler, as the following example shows:
<?xml version="1.0"?> <!-- usingas/HelloWorldAS.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:BasicLayout/> </s:layout> <s:Panel title="My Application" height="128" x="226" y="24"> <s:TextArea id="textarea1" width="155" x="0" y="0"/> <s:Button label="Click Me" click="textarea1.text='Hello World';" width="92" x="31.5" y="56"/> </s:Panel> </s:Application>
34
In this example, you include ActionScript code for the body of the click event handler of the Button control. The MXML compiler takes the attribute
public function __myButton_click(event:MouseEvent):void { textarea1.text='Hello World'; }
click="..." and generates the following event handler method:
When the user clicks the button, this code sets the value of the TextArea control’s text property to the String "Hello
World." In most cases, you do not need to look at the generated code, but it is useful to understand what happens
when you write an inline event handler.
To see the generated code, set the value of the
keep-generated-actionscript compiler option to true. The
compiler then stores the *.as helper file in the /generated directory, which is a subdirectory of the location of the SWF file.
For more information about events, see « Events » à la page 54. For more information on using the command-line compilers, see « Flex compilers » à la page 2162.
Using ActionScript blocks in MXML files
You use the <fx:Script> tag to insert an ActionScript block in an MXML file. ActionScript blocks can contain ActionScript functions and variable declarations used in MXML applications. Code inside declare constants (with the
include), import declarations (with import), and use namespaces (with use namespace).
<fx:Script> tag must be a child of the <s:Application> or other top-level component tag.
The
const statement) and namespaces (with namespace), include ActionScript files (with
<fx:Script> tags can also
Dernière mise à jour le 19/6/2011
Page 40
USING FLEX 4.5
Getting started
Statements and expressions are allowed only if they are wrapped in a function. In addition, you cannot define new classes or interfaces in
<fx:Script> blocks. Instead, you must place new classes or interfaces in separate AS files and
import them.
All ActionScript in the block is added to the enclosing file’s class when Flex compiles the application. The following example declares a variable and sets the value of that variable inside a function:
<?xml version="1.0"?> <!-- usingas/StatementSyntax.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="doSomething()"> <s:layout> <s:VerticalLayout/> </s:layout>
<fx:Script> <![CDATA[ public var s:Boolean;
public function doSomething():void { // The following statements must be inside a function. s = label1.visible; label1.text = "label1.visible = " + String(s); } ]]> </fx:Script>
<s:Label id="label1"/>
</s:Application>
35
Most ActionScript statements must be inside functions in an <fx:Script> block. However, the following statements can be outside functions:
import
var
include
const
namespace
use namespace
When using an <fx:Script> block, you should wrap the contents in a CDATA construct. This prevents the compiler from interpreting the contents of the script block as XML, and allows the ActionScript to be properly generated. Adobe recommends that you write all your
<fx:Script> <![CDATA[ ... ]]> </fx:Script>
<fx:Script> open and close tags as the following example shows:
Dernière mise à jour le 19/6/2011
Page 41
USING FLEX 4.5
Getting started
Flex does not parse text in a CDATA construct, which means that you can use XML-parsed characters such as angle brackets (< and >) and ampersand (&). For example, the following script that includes a greater-than (>) comparison must be in a CDATA construct:
<?xml version="1.0"?> <!-- usingas/UsingCDATA.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="doSomething()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ public var m:Number; public var n:Number;
public function doSomething():void { n = 40; m = 42; label1.text = "40 < 42 = " + String(n < m); } ]]> </fx:Script>
<s:Label id="label1"/>
</s:Application>
36
Accessing ActionScript documentation
The ActionScript 3.0 programming language can be used from within several development environments, including Adobe® Flash® Professional and Adobe® Flash® Builder™.
The Flex documentation includes ActionScript 3.0 Developer's Guide, which describes the ActionScript language. The ActionScript API reference is included as part of the ActionScript 3.0 Reference for the Adobe Flash Platform.

Working with components

The primary use of ActionScript in your applications is probably going to be for working with the visual controls and containers in your application. Flex provides several techniques for doing this, including referencing a Flex control in ActionScript and manipulating properties during the instantiation of controls and containers.
Referring to components
To work with a component in ActionScript, you usually define an id property for that component in the MXML tag. For example, the following code sets the
<s:Button id="myButton" label="Click Me"/>
This property is optional if you do not want to access the component with ActionScript.
id property of the Button control to the String "myButton":
Dernière mise à jour le 19/6/2011
Page 42
USING FLEX 4.5
Getting started
This code causes the MXML compiler to autogenerate a public variable named myButton that contains a reference to that Button instance. This autogenerated variable lets you access the component instance in ActionScript. You can explicitly refer to the Button control’s instance with its
id instance reference in any ActionScript class or script block.
By referring to a component’s instance, you can modify its properties and call its methods.
37
For example, the following ActionScript block changes the value of the Button control’s
label property when the user
clicks the button:
<?xml version="1.0"?> <!-- usingas/ButtonExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ private function setLabel():void { if (myButton.label=="Click Me") { myButton.label = "Clicked"; } else { myButton.label = "Click Me"; } } ]]> </fx:Script> <s:Button id="myButton" label="Click Me" click="setLabel();"/>
</s:Application>
The IDs for all tags in an MXML component, no matter how deeply nested they are, generate public variables of the component being defined. As a result, all
id properties must be unique within a document. This also means that if you
specified an ID for a component instance, you can access that component from anywhere in the application: from functions, external class files, imported ActionScript files, or inline scripts.
You can refer to a component if it does not have an such as the
getElementAt() method. For MX containers, you can use the getChildAt() method.
You can refer to the current enclosing document or current object using the
id property by using methods of the component’s Spark container,
this keyword.
You can also get a reference to a component when you have a String that matches the name. To access an object on the application, you use the
this keyword, followed by square brackets, with the String inside the square brackets. The
result is a reference to the objects whose name matches the String.
The following example changes style properties on each Button control using a compound String to get a reference to the object:
Dernière mise à jour le 19/6/2011
Page 43
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/FlexComponents.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ private var newFontStyle:String; private var newFontSize:int; public function changeLabel(s:String):void { s = "myButton" + s; if (this[s].getStyle("fontStyle")=="normal") { newFontStyle = "italic"; newFontSize = 18; } else { newFontStyle = "normal"; newFontSize = 10; } this[s].setStyle("fontStyle",newFontStyle); this[s].setStyle("fontSize",newFontSize); } ]]> </fx:Script> <s:Button id="myButton1" click="changeLabel('2')" label="Change Other Button's Styles"/> <s:Button id="myButton2" click="changeLabel('1')" label="Change Other Button's Styles"/> </s:Application>
38
This technique is especially useful if you use a Repeater control or when you create objects in ActionScript and do not necessarily know the names of the objects you want to refer to prior to run time. However, when you instantiate an object in ActionScript, to add that object to the properties array, you must declare the variable as public and declare it in the class’s scope, not inside a function.
The following example uses ActionScript to declare two Label controls in the application scope. During initialization, the labels are instantiated and their
text properties are set. The example then gets a reference to the Label controls by
appending the passed-in variable to the String when the user clicks the Button controls.
Dernière mise à jour le 19/6/2011
Page 44
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/ASLabels.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initLabels()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Label; public var label1:Label; public var label2:Label; // Objects must be declared in the application scope. Adds the names to // the application's properties array. public function initLabels():void { label1 = new Label(); label1.text = "Change Me"; label2 = new Label(); label2.text = "Change Me"; addElement(label1); addElement(label2); } public function changeLabel(s:String):void { // Create a String that matches the name of the Label control. s = "label" + s; // Get a reference to the label control using the // application's properties array. this[s].text = "Changed"; } ]]> </fx:Script> <s:Button id="b1" click="changeLabel('2')" label="Change Other Label"/> <s:Button id="b2" click="changeLabel('1')" label="Change Other Label"/> </s:Application>
39
Calling component methods
You can invoke the public methods of a component instance in your application by using the following dot-notation syntax:
componentInstance.method([parameters]);
The following example invokes the adjustThumb() method when the user clicks the button, which invokes the public
setThumbValueAt() method of the HSlider control:
Dernière mise à jour le 19/6/2011
Page 45
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/ComponentMethods.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ public function adjustThumb(s:HSlider):void { var randomNumber:int = (Math.floor(Math.random() * 10)); s.setThumbValueAt(0, randomNumber); } ]]> </fx:Script> <mx:HSlider id="slider1" tickInterval="1" labels="[1,2,3,4,5,6,7,8,9,10]" width="282"/> <s:Button id="myButton" label="Change Thumb Position" click="adjustThumb(slider1);"/> </s:Application>
40
To invoke a method from a child document (such as a custom MXML component), you can use the
parentApplication, parentDocument, or FlexGlobals.topLevelApplication properties. For more
information, see « Application containers » à la page 394.
Remarque : Because Flex invokes the position information of that component from within the
creationComplete event handler. For more information on the order of initialization events, see « About startup
initialize event before drawing the component, you cannot access size and
initialize event handler unless you use the
order » à la page 2333.
Creating visual components in ActionScript
You can use ActionScript to programmatically create visual components using the new operator, in the same way that you create instances of any ActionScript class. The created component has default values for its properties, but it does not yet have a parent or any children (including any kind of internal DisplayObjects), and it is not yet on the display list in Flash Player or Adobe® AIR™, so you can’t see it. After creating the component, you should use standard assignment statements to set any properties whose default values aren’t appropriate.
Finally, you must add the new component to a container, by using the Spark container’s
addElementAt() methods, so that it becomes part of the visual hierarchy of an application. (For MX containers, you
can use the
addChild() or addChildAt() methods.) The first time that it is added to a container, a component’s
children are created. Children are created late in the component’s life cycle so that you can set properties that can affect children as they are created.
When creating visual controls, you must import the appropriate package. In most cases, this is the mx.controls package, although you should check the ActionScript 3.0 Reference for the Adobe Flash Platform.
addElement() or
The following example creates a Button control inside the HGroup container:
Dernière mise à jour le 19/6/2011
Page 46
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/ASVisualComponent.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import spark.components.Button; public var button2:Button; public function createObject():void { button2 = new Button(); button2.label = "Click Me"; hb1.addElement(button2); } ]]> </fx:Script> <s:HGroup id="hb1"> <s:Button label="Create Object" click="createObject()"/> </s:HGroup> </s:Application>
41
Flex creates the new child as the last child in the container. If you do not want the new child to be the last in the Spark container, use the call to the
setChildIndex(), and addChild() methods.
addElementAt() method to change the order. You can use the setItemIndex() method after the
addElement() method, but this is less efficient. For MX containers, you use the addChildAt(),
You should declare an instance variable for each dynamically created component and store a reference to the newly created component in it, just as the MXML compiler does when you set an
id property for a component instance tag.
You can then access your dynamically created components in the same way as those declaratively created in MXML.
To programmatically remove a control in Spark containers, you can use the
removeAllElements() methods. For MX containers, you use the removeChild() or removeChildAt()
and methods. You can also use the
removeAllChildren() method to remove all child controls from a container.
removeElement(), removeElementAt(),
Calling the “remove” methods does not actually delete the objects from memory. If you do not have any other references to the child, Flash Player includes the object in garbage collection at some future point. But if you have a reference to that child, the child is not garbage collected.
In some cases, you declaratively define a component with an MXML tag. You can set the of the component’s container to
none to defer the creation of the controls inside that container. You can then create
the component programmatically rather than declaratively. For information on using the
creationPolicy property
creationPolicy property,
see « Improving startup performance » à la page 2332.
The only component you can pass to the
addElement() method is a class that implements the IVisualElement
interface. In other words, if you create a new object that is not a subclass of mx.core.IVisualElement, you must wrap it in a class that implments IVisualElement before you can attach it to a container. The following example creates a new Sprite object, which is not a subclass of IVisualElement, and adds it as a child of the UIComponent (which implements IVisualElement) before adding it to the Panel container:
Dernière mise à jour le 19/6/2011
Page 47
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/AddingChildrenAsUIComponents.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import flash.display.Sprite; import mx.core.UIComponent; private var xLoc:int = 20; private var yLoc:int = 20; private var circleColor:Number = 0xFFCC00; private function addChildToPanel():void { var circle:Sprite = new Sprite(); circle.graphics.beginFill(circleColor); circle.graphics.drawCircle(xLoc, yLoc, 15); var c:UIComponent = new UIComponent(); c.addChild(circle); panel1.addElement(c);
xLoc = xLoc + 5; yLoc = yLoc + 1; circleColor = circleColor + 20; } ]]> </fx:Script> <s:Panel id="panel1" height="250" width="300"/> <s:Button id="myButton" label="Click Me" click="addChildToPanel();"/>
</s:Application>
42
About scope
Scoping in ActionScript is largely a description of what the this keyword refers to at a particular point. In your application’s core MXML file, you can access the Application object by using the MXML component,
In an ActionScript class file, the keyword refers to an instance of myClass. Because
this is a reference to the current instance of that component.
this keyword refers to the instance of that class. In the following example, the this
this is implicit, you do not have to include it, but it is shown here
to illustrate its meaning.
Dernière mise à jour le 19/6/2011
this keyword. In a file defining an
Page 48
USING FLEX 4.5
Getting started
class myClass { var _x:Number = 3; function get x():Number { return this._x; } function set x(y:Number):void { if (y > 0) { this._x = y; } else { this._x = 0; } } }
However, in custom ActionScript and MXML components or external ActionScript class files, Flex executes in the context of those objects and classes, and the
this keyword refers to the current scope and not the Application object
scope.
43
Flex includes a some cases, you can also use the application, or the
FlexGlobals.topLevelApplication property that you can use to access the root application. In
parentDocument property to access the next level up in the document chain of an
parentApplication property to access the next level up in the application chain when one
Application object loads another Application object.
You cannot use these properties to access the root application if the loaded application was loaded into a separate ApplicationDomain or SecurityDomain, as is the case with sandboxed and multi-versioned applications. For more information, see « Accessing the main application from sub-applications » à la page 197.
If you write ActionScript in a component’s event listener, the scope is not the component but rather the application. For example, the following code changes the label of the Button control to
"Clicked" once the Button control is
pressed:
<?xml version="1.0"?> <!-- usingas/ButtonScope.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:BasicLayout/> </s:layout> <s:Panel width="250" height="100" x="65" y="24"> <s:Button id="myButton" label="Click Me" click="myButton.label='Clicked'" x="79.5" y="20"/> </s:Panel> <s:Button label="Reset" x="158" y="149" click="myButton.label='Click Me'"/> </s:Application>
Contrast the previous example with the following code:
Dernière mise à jour le 19/6/2011
Page 49
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/AppScope.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <!-- The following throws a compiler error because the app level scope does not have a label to set. --> <!-- <s:Button id="myButton" label="Click Me" click="{this.label='Clicked'}"/> --> <!-- <s:Button label="Reset" click="myButton.label='Click Me'"/> --> </s:Application>
This code does not work because when an event listener executes, the this keyword does not refer to the Button instance; the attempts to set the
this keyword refers to the Application or other top-level component instance. The second example
label property of the Application object, not the label property of the Button.
Variables declared within a function are locally scoped to that function. These variables can share the same name as variables in outer scopes, and they do not affect the outer-scoped variable. If a variable is just used temporarily by a single method, make it a local variable of that method rather than an instance variable. Use instance variables only for storing the state of an instance, because each instance variable will take up memory for the entire lifetime of the instance. You can refer to the outer-scoped variable with the
this. prefix.
44

Including versus importing ActionScript code

To make your MXML code more readable, you can reference ActionScript files in your <fx:Script> tags, rather than insert large blocks of script. You can either include or import ActionScript files.
There is a distinct difference between including and importing code in ActionScript. Including copies lines of code from one file into another, as if they had been pasted at the position of the reference to a class file or package so that you can access objects and properties defined by external classes. Files that you import must be found in the source path. Files that you include must be located relative to the file that uses the
include statement, or you must use an absolute path.
You use the
include statement or the <fx:Script source="filename"> tag to add ActionScript code to your
applications.
You use
import statements in an <fx:Script> block to define the locations of ActionScript classes and packages that
your applications might use.
Including ActionScript files
To include ActionScript code, you reference an external ActionScript file in your <fx:Script> tags. At compile time, the compiler copies the entire contents of the file into your MXML application, as if you had actually typed it. As with ActionScript in an declare constants and namespaces, include other ActionScript files, import declarations, and use namespaces. You cannot define classes in included files.
Variables and functions defined in an included ActionScript file are available to any component in the MXML file. An included ActionScript file is not the same as an imported ActionScript class. Flex provides access to the included file’s variables and functions, but does not add a new class, because the MXML file itself is a class.
<fx:Script> block, ActionScript statements can only be inside functions. Included files can also
include statement. Importing adds a
Included ActionScript files do not need to be in the same directory as the MXML file. However, you should organize your ActionScript files in a logical directory structure.
Dernière mise à jour le 19/6/2011
Page 50
USING FLEX 4.5
Getting started
There are two ways to include an external ActionScript file in your application:
The source attribute of the <fx:Script> tag. This is the preferred method for including external ActionScript
class files.
The include statement inside <fx:Script> blocks.
Using the source attribute to include ActionScript files
You use the
source attribute of the <fx:Script> tag to include external ActionScript files in your applications. This
provides a way to make your MXML files less cluttered and promotes code reuse across different applications.
Do not give the script file the same name as the application file. This causes a compiler error.
The following example shows the contents of the IncludedFile.as file:
// usingas/includes/IncludedFile.as public function computeSum(a:Number, b:Number):Number { return a + b; }
The following example uses the <fx:Script> tag to include the contents of the IncludedFile.as file. This file is located in the /includes subdirectory.
<?xml version="1.0"?> <!-- usingas/SourceInclude.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script source="includes/IncludedFile.as"/> <s:TextInput id="ta1st" text="3" width="40" x="170" y="24" textAlign="right"/> <s:TextInput id="ta2nd" text="3" width="40" x="170" y="52" textAlign="right"/> <s:TextArea id="taMain" height="25" width="78" x="132" y="82" textAlign="right"/> <s:Button id="b1" label="Compute Sum" click="taMain.text=String(computeSum(Number(ta1st.text), Number(ta2nd.text)));" x="105" y="115"/> <s:Label x="148" y="52" text="+" fontWeight="bold" fontSize="17" width="23"/> </s:Application>
45
The source attribute of the <fx:Script> tag supports both relative and absolute paths. For more information, see « Referring to external files that have been included » à la page 46.
You cannot use the
<fx:Script> tag. To include a file and write ActionScript in the MXML file, use two <fx:Script> tags.
source attribute of an <fx:Script> tag and wrap ActionScript code inside that same
Using the include directive
include directive is an ActionScript statement that copies the contents of the specified file into your MXML file.
The
include directive uses the following syntax:
The
include "file_name";
The following example includes the myfunctions.as file:
Dernière mise à jour le 19/6/2011
Page 51
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/IncludeASFile.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ /* The myfunctions.as file defines two methods that return Strings. */ include "includes/myfunctions.as"; ]]> </fx:Script> <s:Button id="myButton" label="Call Methods in Included File" click="ta1.text=doSomething();ta1.text+=doSomethingElse()"/> <s:TextArea width="268" id="ta1"/> <s:Button label="Clear" click="ta1.text=''"/> </s:Application>
46
You can specify only a single file for each include directive, but you can use any number of include directives. You can nest
The
include directives; files with include directives can include files that have include directives.
include directive supports only relative paths. For more information, see « Referring to external files that have
been included » à la page 46.
You can use the
if (expr) include "foo.as"; // First statement is guarded by IF, but rest are not. ...
include only where multiple statements are allowed. For example, the following is not allowed:
The following is allowed:
if (expr) { include "foo.as"; // All statements inside { } are guarded by IF. }
The use of curly braces ({ }) allows multiple statements because you can add multiple statements inside the braces.
Adobe recommends that you not use the
include directive if you use a large number of included ActionScript files.
You should try to break the code into separate class files where appropriate and store them in logical package structures.
Referring to external files that have been included
source attribute of the <fx:Script> tag and the include directive refer to files in different ways.
The
The following are the valid paths to external files that are referenced in an
<fx:Script> tag’s source attribute:
Absolute URLs, such as http://www.macromedia.com or file:///C|/site_flashteam/foo.gif.
Relative URLs, such as ../myscript.as. A relative URL that does not start with a slash is resolved relative to the file
that uses it. If the tag
<fx:Script source="../IncludedFile.as"> is included in
“mysite/myfiles/myapp.mxml,” the system searches for “mysite/IncludedFile.as”.
For an ActionScript
include directive, you can reference only relative URLs.
Dernière mise à jour le 19/6/2011
Page 52
USING FLEX 4.5
Getting started
Flex searches the source path for imported classes and packages. Flex does not search the source path for files that are included using the
include directive or the source attribute of the <fx:Script> tag.
Importing classes and packages
If you create many utility classes or include multiple ActionScript files to access commonly used functions, you might want to store them in a set of classes in their own package. You can import ActionScript classes and packages using
import statement. By doing this, you do not have to explicitly enter the fully qualified class names when accessing
the classes within ActionScript.
The following example imports the MyClass class in the MyPackage.Util package:
<?xml version="1.0"?> <!-- usingas/AccessingPackagedClasses.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import MyPackage.Util.MyClass; private var mc:MyClass = new MyClass; ]]> </fx:Script> <s:Button id="myButton" label="Click Me" click="myButton.label=mc.returnAString()"/> </s:Application>
47
In your ActionScript code, instead of referring to the class with its fully qualified package name (MyPackage.Util.MyClass), you refer to it as MyClass.
You can also use the wildcard character (*) to import the entire package. For example, the following statement imports the entire MyPackage.Util package:
import MyPackage.Util.*;
Flex searches the source path for imported files and packages, and includes only those that are used in the final SWF file.
It is not sufficient to simply specify the fully qualified class name. You should use fully qualified class names only when necessary to distinguish two classes with the same class name that reside in different packages.
If you import a class but do not use it in your application, the class is not included in the resulting SWF file’s bytecode. As a result, importing an entire package with a wildcard does not create an unnecessarily large SWF file.

Techniques for separating ActionScript from MXML

The following sample application, which calls a single function, shows several methods of separating ActionScript from the MXML.
The Temperature application takes input from a single input field and uses a function to convert the input from Fahrenheit to Celsius. It then displays the resulting temperature in a Label control.
One MXML document (event handling logic in event attribute)
The following code shows the ActionScript event handling logic inside the MXML tag’s click event:
Dernière mise à jour le 19/6/2011
Page 53
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/ASOneFile.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" width="700"> <s:layout> <s:VerticalLayout/> </s:layout> <s:Panel title="Temperature Application" width="90%"> <s:HGroup> <s:Label text="Temperature in Fahrenheit:"/> <s:TextInput id="fahrenheit" width="120"/> <s:Button label="Convert" click="celsius.text=String(Math.round((Number(fahrenheit.text)-32)/1.8 *
10)/10);"/> <s:Label text="Temperature in Celsius:"/> <s:Label id="celsius" width="120" fontSize="24"/> </s:HGroup> </s:Panel> </s:Application>
48
One MXML document (event handling logic in <fx:Script> block)
In this example, the logic for the function is inside an <fx:Script> block in the MXML document, and is called from the MXML tag’s
<?xml version="1.0"?> <!-- usingas/ASScriptBlock.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" width="700"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ public function calculate():void { var n:Number = Number(fahrenheit.text); var t:Number = Math.round((n-32)/1.8*10)/10; celsius.text=String(t); } ]]> </fx:Script> <s:Panel title="Temperature Application" width="90%"> <s:HGroup> <s:Label text="Temperature in Fahrenheit:"/> <s:TextInput id="fahrenheit" width="120"/> <s:Button label="Convert" click="calculate();" /> <s:Label text="Temperature in Celsius:"/> <s:Label id="celsius" width="120" fontSize="24"/> </s:HGroup> </s:Panel> </s:Application>
click event, as the following code shows:
Dernière mise à jour le 19/6/2011
Page 54
USING FLEX 4.5
Getting started
One MXML document and one ActionScript file (event handling logic in separate script file)
Here, the function call is in an MXML event attribute, and the function is defined in a separate ActionScript file, as the following code shows:
<?xml version="1.0"?> <!-- usingas/ASSourceFile.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" width="700"> <s:layout> <s:VerticalLayout/> </s:layout> <!-- Specify the ActionScript file that contains the function. --> <fx:Script source="includes/Sample3Script.as"/> <s:Panel title="Temperature Application" width="90%"> <s:HGroup> <s:Label text="Temperature in Fahrenheit:"/> <s:TextInput id="fahrenheit" width="120"/> <s:Button label="Convert" click="celsius.text=calculate(fahrenheit.text);"/> <s:Label text="Temperature in Celsius:"/> <s:Label id="celsius" width="120" fontSize="24"/> </s:HGroup> </s:Panel> </s:Application>
49
The Sample3Script.as ActionScript file contains the following code:
// usingas/includes/Sample3Script.as public function calculate(s:String):String { var n:Number = Number(s); var t:Number = Math.round((n-32)/1.8*10)/10; return String(t); }

Creating ActionScript components

You can create reusable components that use ActionScript and reference these components in your applications as MXML tags. Components created in ActionScript can contain graphical elements, define custom business logic, or extend existing components. They can inherit from any components available in Flex.
Defining your own components in ActionScript has several benefits. Components let you divide your applications into individual modules that you can develop and maintain separately. By implementing commonly used logic within custom components, you can build a suite of reusable components that you can share among multiple applications.
Also, you can base your custom components on the set of components by extending from the Flex class hierarchy. You can create custom versions of Flex visual controls, as well as custom versions on nonvisual components, such as data validators, formatters, and effects.
For example, you can define a custom button, derived from the Button control, in the myControls package, as the following example shows:
Dernière mise à jour le 19/6/2011
Page 55
USING FLEX 4.5
Getting started
package myControls { import mx.controls.Button; public class MyButton extends Button { public function MyButton() { ... } ... } }
In this example, you write your MyButton control to the MyButton.as file, and you store the file in the myControls subdirectory of the root directory of your application. The fully qualified class name of your component reflects its location. In this example, the component’s fully qualified class name is myControls.MyButton.
You can reference your custom Button control from an application file, such as MyApp.mxml, as the following example shows:
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:cmp="myControls.*"> <cmp:MyButton label="Jack"/> </s:Application>
50
In this example, you define the cmp namespace that defines the location of your custom component in the application’s directory structure. You then reference the component as an MXML tag using the namespace prefix.
Typically, you put custom ActionScript components in directories that are in the source path. These include any directory that you specify in the source path.
You can also create custom components using MXML. For more information, see « Custom components » à la page 2355.
Types of custom components
You can create the following types of components in ActionScript:
User-interface components User-interface components contain both processing logic and visual elements. These
components usually extend the component hierarchy. You can extend from the UIComponent classes, or any of the components, such as Button, ComboBox, or DataGrid. Your custom ActionScript component inherits all of the public methods, along with public and protected properties of its base class.
Nonvisual components Nonvisual components define no visual elements. A nonvisual component is an ActionScript
class that does not extend the UIComponent class. They can provide greater efficiency at run time.

Performing object introspection

Object introspection is a technique for determining the elements of a class at run time, such as its properties and methods. There are two ways to do introspection in ActionScript:
Using for..in loops
Using the introspection API
You might find object introspection a useful technique when debugging your application. For example, you might write a method that takes a generic object of type Object as an argument. You can use introspection to output all of the properties and methods of the Object to determine exactly what your application passed to it.
Dernière mise à jour le 19/6/2011
Page 56
USING FLEX 4.5
Getting started
Using for..in loops
You can use a for..in loop to iterate over objects and output their properties and their values. A for..in loop enumerates only dynamically added properties. Declared variables and methods of classes are not enumerated in
for..in loops. This means that most classes in the ActionScript API will not display any properties in a for..in loop.
However, the generic type Object is still a dynamic object and will display properties in a
The following example creates a generic Object, adds properties to that object, and then iterates over that object when you click the button to inspect its properties:
<?xml version="1.0"?> <!-- usingas/IntrospectionForIn.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ private var obj:Object = new Object(); private function initApp():void { // Create the object. obj.a = "Schotten Totten"; obj.b = "Taj Majal"; obj.c = "Durche die Wuste"; } public function dumpObj():void { for (var p:String in obj) { ta1.text += p + ":" + obj[p] + "\n"; } } ]]> </fx:Script> <s:TextArea id="ta1" width="400" height="200"/> <s:Button label="Dump Object" click="dumpObj()"/> </s:Application>
for..in loop.
51
You can also use the mx.utils.ObjectUtil.toString() method to print all the dynamically added properties of an object, for example:
Dernière mise à jour le 19/6/2011
Page 57
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/ObjectUtilToString.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.utils.ObjectUtil; private var obj:Object = new Object(); private function initApp():void { // Create the object. obj.a = "Schotten Totten"; obj.b = "Taj Majal"; obj.c = "Durche die Wuste"; } public function dumpObj():void { ta1.text = ObjectUtil.toString(obj); } ]]> </fx:Script> <s:TextArea id="ta1" width="400" height="200"/> <s:Button label="Dump Object" click="dumpObj()"/> </s:Application>
52
The mx.utils.ObjectUtil class has other useful methods such as compare(), copy(), and isSimple(). For more information, see the ActionScript 3.0 Reference for the Adobe Flash Platform.
Using the introspection API
If you want to list all the public properties and methods of a nondynamic (or sealed) class or class instance, use the
describeType() method and parse the results using the E4X API. The describeType() method is in the flash.utils
package. The method’s only parameter is the target object that you want to introspect. You can pass it any ActionScript value, including all available ActionScript types such as object instances, primitive types such as objects. The return value of the
describeType() method is an E4X XML object that contains an XML description of
the object’s type.
describeType() method returns only public members. The method does not return private members of the
The caller’s superclass or any other class where the caller is not an instance. If you call
describeType(this), the method
returns information only about nonstatic members of the class. If you call
describeType(getDefinitionByName("MyClass")), the method returns information only about the target’s static
members.
The following example introspects the Button control and prints the details to TextArea controls:
uint, and class
Dernière mise à jour le 19/6/2011
Page 58
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- usingas/IntrospectionAPI.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="getDetails()"> <s:layout> <s:VerticalLayout/> </s:layout>
<fx:Script> <![CDATA[ import flash.utils.*; public function getDetails():void { // Get the Button control's E4X XML object description. var classInfo:XML = describeType(button1); // Dump the entire E4X XML object into ta2. ta2.text = classInfo.toString(); // List the class name. ta1.text = "Class " + classInfo.@name.toString() + "\n"; // List the object's variables, their values, and their types. for each (var v:XML in classInfo..variable) { ta1.text += "Variable " + v.@name + "=" + button1[v.@name] + " (" + v.@type + ")\n"; } // List accessors as properties. for each (var a:XML in classInfo..accessor) { // Do not get the property value if it is write only. if (a.@access == 'writeonly') { ta1.text += "Property " + a.@name + " (" + a.@type +")\n"; } else { ta1.text += "Property " + a.@name + "=" + button1[a.@name] + " (" + a.@type +")\n"; } } // List the object's methods. for each (var m:XML in classInfo..method) { ta1.text += "Method " + m.@name + "():" + m.@returnType + "\n"; } } ]]> </fx:Script> <s:Button label="This Button Does Nothing" id="button1"/> <s:TextArea id="ta1" width="400" height="200"/> <s:TextArea id="ta2" width="400" height="200"/> </s:Application>
53
The output displays accessors, variables, and methods of the Button control, and appears similar to the following:
Dernière mise à jour le 19/6/2011
Page 59
USING FLEX 4.5
Getting started
Class mx.controls::Button ... Variable id=button1 (String) Variable __width=66 (Number) Variable layoutWidth=66 (Number) Variable __height=22 (Number) Variable layoutHeight=22 (Number) ... Property label=Submit (String) Property enabled=true (Boolean) Property numChildren=2 (uint) Property enabled=true (Boolean) Property visible=true (Boolean) Property toolTip=null (String) ... Method dispatchEvent():Boolean Method hasEventListener():Boolean Method layoutContents():void Method getInheritingStyle():Object Method getNonInheritingStyle():Object
Another useful method is the ObjectUtil’s getClassInfo() method. This method returns an Object with the name and properties of the target object. The following example uses the
getClassInfo() and toString() methods to
show the properties of the Button control:
54
<?xml version="1.0"?> <!-- usingas/IntrospectionObjectUtil.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" height="650"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ import mx.controls.Alert; import mx.utils.ObjectUtil; private function showProps(b:Button):void { var o:Object = ObjectUtil.getClassInfo(b); ta1.text = ObjectUtil.toString(o); } ]]> </fx:Script> <s:Button id="b1" label="Show Properties" click="showProps(b1)"/> <s:TextArea id="ta1" width="300" height="500"/> </s:Application>
For more information about using E4X, see Working with XML.

Events

One of the most important parts of your Adobe® Flex™ application is handling events by using controls and ActionScript.
Dernière mise à jour le 19/6/2011
Page 60
USING FLEX 4.5
Getting started

About events

Events let a developer know when something happens within an application. They can be generated by user devices, such as the mouse and keyboard, or other external input, such as the return of a web service call. Events are also triggered when changes happen in the appearance or life cycle of a component, such as the creation or destruction of a component or when the component is resized.
Any user interaction with your application can generate events. Events can also occur without any direct user interaction, such as when data finishes loading from a server or when an attached camera becomes active. You can “handle” these events in your code by adding an event handler. Event handlers are the functions or methods that you write to respond to specific events. They are also sometimes referred to as event listeners.
The Flex event model is based on the Document Object Model (DOM) Level 3 events model. Although Flex does not adhere specifically to the DOM standard, the implementations are very similar. The event model in Flex comprises the Event object and its subclasses, and the event dispatching model. For a quick start in using events in Flex, see the sample code in « Using events » à la page 57.
Components generate and dispatch events and consume (listen to) other events. An object that requires information about another object’s events registers a listener with that object. When an event occurs, the object dispatches the event to all registered listeners by calling a function that was requested during registration. To receive multiple events from the same object, you must register your listener for each event.
55
Components have built-in events that you can handle in ActionScript blocks in your MXML applications. You can also take advantage of the Flex event system’s dispatcher-listener model to define your own event listeners outside of your applications, and define which methods of your custom listeners will listen to certain events. You can register listeners with the target object so that when the target object dispatches an event, the listeners get called.
All visual objects, including Flex controls and containers, are subclasses of the DisplayObject class. They are in a tree of visible objects that make up your application. The root of the tree is the Stage. Below that is the SystemManager object, and then the Application object. Child containers and components are leaf nodes of the tree. That tree is known as the display list. An object on the display list is analogous to a node in the DOM hierarchical structure. The terms display list object and node are used interchangeably.
For information about each component’s events, see the component’s description in « UI Controls » à la page 643 or the control’s entry in ActionScript 3.0 Reference for the Adobe Flash Platform.
For a detailed description of a component’s startup life cycle, including major events in that life cycle, see « Create
advanced MX visual components in ActionScript » à la page 2475.
About the Event flow
You can instruct any container or control to listen for events dispatched by another container or control. When Adobe® Flash® Player dispatches an Event object, that Event object makes a roundtrip journey from the root of the display list to the target node, checking each node for registered listeners. The target node is the node in the display list where the event occurred. For example, if a user clicks a Button control named Child1, Flash Player dispatches an Event object with Child1 defined as the target node.
The event flow is conceptually divided into three parts: the capturing phase, the targeting phase, and the bubbling phase, as briefly described next. For more information about the event flow, see « Event propagation » à la page 81.
Dernière mise à jour le 19/6/2011
Page 61
USING FLEX 4.5
Getting started
About the capturing phase
The first part of the event flow is called the capturing phase. This phase comprises all of the nodes from the root node to the parent of the target node. During this phase, Flash Player examines each node, starting with the root, to see if it has a listener registered to handle the event. If it does, Flash Player sets the appropriate values of the Event object and then calls that listener. Flash Player stops after it reaches the target node’s parent and calls any listeners registered on the parent. For more information, see « Capturing phase » à la page 82.
About the targeting phase
The second part of the event flow, the targeting phase, consists solely of the target node. Flash Player sets the appropriate values on the Event object, checks the target node for registered event listeners, and then calls those listeners. For more information, see « Targeting phase » à la page 83.
About the bubbling phase
The third part of the event flow, the bubbling phase, comprises all of the nodes from the target node’s parent to the root node. Starting with the target node’s parent, Flash Player sets the appropriate values on the Event object and then calls event listeners on each of these nodes. Flash Player stops after calling any listeners on the root node. For more information about the bubbling phase, see « Bubbling phase » à la page 83.
About the Event class
The flash.events.Eventclass is an ActionScript class with properties that contain information about the event that occurred. An Event object is an implicitly created object, similar to the request and response objects in a JavaServer Page (JSP) that are implicitly created by the application server.
56
Flex creates an Event object each time an event is dispatched. You can use the Event object inside an event listener to access details about the event that was dispatched, or about the component that dispatched the event. Passing an Event object to, and using it in, an event listener is optional. However, if you want to access the Event object’s properties inside your event listeners, you must pass the Event object to the listener.
Flex creates only one Event object when an event is dispatched. During the bubbling and capturing phases, Flex changes the values on the Event object as it moves up or down the display list, rather than creating a new Event object for each node.
About event subclasses
There are many classes that extend the flash.events.Event class. These classes are defined mostly in the following packages:
spark.events.*
mx.events.*
flash.events.*
The mx.events package defines event classes that are specific to most Flex controls, including the DataGridEvent, DragEvent, and ColorPickerEvent. The spark.events package defines event classes that are specific to a few Spark controls, including the TextOperationEvent and VideoEvent. The flash.events package describes events that are not unique to Flex but are instead defined by Flash Player. These event classes include MouseEvent, DataEvent, and TextEvent. All of these events are commonly used in applications.
In addition to these packages, some packages also define their own event objects: for example, mx.messaging.events.ChannelEvent and mx.logging.LogEvent.
Dernière mise à jour le 19/6/2011
Page 62
USING FLEX 4.5
Getting started
Child classes of the Event class have additional properties and methods that may be unique to them. In some cases, you will want to use a more specific event type rather than the generic Event object so that you can access these unique properties or methods. For example, the LogEvent class has a
getLevelString()
method that the Event class does not.
For information on using Event subclasses, see « Using event subclasses » à la page 89.
About the EventDispatcher class
Every object in the display list can trace its class inheritance back to the DisplayObject class. The DisplayObject class, in turn, inherits from the EventDispatcher class. The EventDispatcher class is a base class that provides important event model functionality for every object on the display list. Because the DisplayObject class inherits from the EventDispatcher class, any object on the display list has access to the methods of the EventDispatcher class.
This is significant because every item on the display list can participate fully in the event model. Every object on the display list can use its particular event, but only if the listening object is part of the event flow for that event.
Although the name EventDispatcher seems to imply that this class’s main purpose is to send (or dispatch) Event objects, the methods of this class are used much more frequently to register event listeners, check for event listeners, and remove event listeners.
The EventDispatcher class implements the IEventDispatcher interface. This allows developers who create custom classes that cannot inherit from EventDispatcher or one of its subclasses to implement the IEventDispatcher interface to gain access to its methods.
addEventListener() method—inherited from the EventDispatcher class—to listen for a
57
addEventListener() method is the most commonly used method of this class. You use it to register your event
The listeners. For information on using the
addEventListener() method, see « Using the addEventListener() method »
à la page 64.
Advanced programmers use the
dispatchEvent() method to manually dispatch an event or to send a custom Event
object into the event flow. For more information, see « Manually dispatching events » à la page 78.
Several other methods of the EventDispatcher class provide useful information about the existence of event listeners.
hasEventListener() method returns true if an event listener is found for that specific event type on a particular
The display list object. The checks for listeners on all of that display list object’s ancestors for all phases of the event flow. The method returns
willTrigger() method checks for event listeners on a particular display list object, but it also
true
if it finds one.

Using events

Using events in Flex is a two-step process. First, you write a function or class method, known as an event listener or event handler, that responds to events. The function often accesses the properties of the Event object or some other
settings of the application state. The signature of this function usually includes an argument that specifies the event type being passed in.
The following example shows a simple event listener function that reports when a control triggers the event that it is listening for:
Dernière mise à jour le 19/6/2011
Page 63
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/SimpleEventHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp();"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function initApp():void { b1.addEventListener(MouseEvent.CLICK, myEventHandler); } private function myEventHandler(event:Event):void { Alert.show("An event occurred."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me"/> </s:Application>
As you can see in this example, you also register that function or class method with a display list object by using the addEventListener() method.
58
Most Flex controls simplify listener registration by letting you specify the listener inside the MXML tag. For example, instead of using the you specify it in the
<?xml version="1.0"?> <!-- events/SimplerEventHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script> <![CDATA[ import mx.controls.Alert; private function myEventHandler(event:Event):void { Alert.show("An event occurred."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" click="myEventHandler(event)"/> </s:Application>
addEventListener() method to specify a listener function for the Button control’s click event,
click attribute of the <mx:Button> tag:
This is equivalent to the addEventListener() method in the previous code example. However, it is best practice to
addEventListener() method. This method gives you greater control over the event by letting you configure
use the the priority and capturing settings, and use event constants. In addition, if you use event handler, you can use an event handler inline, you cannot call
removeEventListener() to remove the handler when you no longer need it. If you add
removeEventListener() on that handler.
addEventListener() to add an
Each time a control generates an event, Flex creates an Event object that contains information about that event, including the type of event and a reference to the dispatching control. To use the Event object, you specify it as a parameter in the event handler function, as the following example shows:
Dernière mise à jour le 19/6/2011
Page 64
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/EventTypeHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function myEventHandler(e:Event):void { Alert.show("An event of type '" + e.type + "' occurred."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" click="myEventHandler(event)"/> </s:Application>
If you want to access the Event object in an event handler that was triggered by an inline event, you must add the event keyword inside the MXML tag so that Flex explicitly passes it to the handler, as in the following:
<mx:Button id="b1" label="Click Me" click="myEventHandler(event)"/>
You are not required to use the Event object in a handler function. The following example creates two event handler functions and registers them with the events of a ComboBox control. The first event handler, arguments. The second event handler, access the
value and selectedIndex of the ComboBox control that triggered the event.
changeEvt(), takes the Event object as an argument and uses this object to
openEvt(), takes no
59
<?xml version="1.0"?> <!-- events/MultipleEventHandlers.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ private function openEvt():void { forChange.text=""; } private function changeEvt(e:Event):void { forChange.text = "Value: " + e.currentTarget.selectedItem + "\n" + "Index: " + e.currentTarget.selectedIndex; } ]]></fx:Script> <s:ComboBox open="openEvt()" change="changeEvt(event)"> <s:dataProvider> <s:ArrayList> <fx:String>AK</fx:String> <fx:String>AL</fx:String> <fx:String>AR</fx:String> </s:ArrayList> </s:dataProvider> </s:ComboBox> <s:TextArea id="forChange" width="150" height="100"/> </s:Application>
Dernière mise à jour le 19/6/2011
Page 65
USING FLEX 4.5
Getting started
This example shows accessing the target property of the Event object. For more information, see « Accessing the
currentTarget property » à la page 60.
Specifying the Event object
You specify the object in a listener function’s signature as type Event, as the following example shows:
function myEventListener(e:Event):void { ... }
However, if you want to access properties that are specific to the type of event that was dispatched, you must instead specify a more specific event type, such as ToolTipEvent or KeyboardEvent, as the following example shows:
import mx.events.ToolTip function myEventListener(e:ToolTipEvent):void { ... }
In some cases, you must import the event’s class in your ActionScript block.
Most objects have specific events that are associated with them, and most of them can dispatch more than one type of event.
If you declare an event of type Event, you can cast it to a more specific type to access its event-specific properties. For more information, see « Using event subclasses » à la page 89.
Accessing the currentTarget property
Event objects include a reference to the instance of the dispatching component (or target), which means that you can access all the properties and methods of that instance in an event listener. The following example accesses the Button control that triggered the event:
id of the
60
<?xml version="1.0"?> <!-- events/AccessingCurrentTarget.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function myEventHandler(e:Event):void { Alert.show("The button '" + e.currentTarget.id + "' was clicked."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" click="myEventHandler(event)"/> </s:Application>
You can access members of the currentTarget. If you do not cast the current target to a specific type, the compiler assumes that it is of type Object. Objects can have any property or method because the Object type is dynamic in ActionScript. Therefore, when accessing methods and properties of the
currentTarget to whatever class you anticipate will dispatch that event. This gives you strong type checking at
currentTarget, it is best practice to cast
compile time, and helps avoid the risk of throwing a run-time error.
The following example casts the current target to a TextInput class before calling the does not cast it before trying to set the
tmesis property. The tmesis property does not exist on the TextInput class.
selectRange() method, but
This illustrates that you will get a run-time error but not a compile-time error when you try to access members that don’t exist, unless you cast
currentTarget to a specific type so that type checking can occur:
Dernière mise à jour le 19/6/2011
Page 66
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/InvokingOnCurrentTarget.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" width="500"> <fx:Script> <![CDATA[ import mx.core.UIComponent; private function tiHandler(e:Event):void { /* The following enforces type checking: */ TextInput(e.currentTarget).selectRange(0,3); /* The following throws a run-time error but not a compile-time error: e.currentTarget.tmesis = 4; */ /* ... unless you cast it to the expected type like the following. Then the compiler throws an error. TextInput(e.currentTarget).tmesis = 4; */ } ]]> </fx:Script> <s:TextInput id="ti1" click="tiHandler(event)" text="When you click on this control, the first three characters are selected." width="400"/> </s:Application>
61
You could also cast currentTarget to UIComponent or some other more general class that still has methods of display objects. That way, if you don’t know exactly which control will dispatch an event, at least you can ensure there is some type checking.
You can also access methods and properties of the
target property, which contains a reference to the current node in
the display list. For more information, see « About the target and currentTarget properties » à la page 81.
Registering event handlers
There are several strategies that you can employ when you register event handlers with your Flex controls:
1 Define an event handler inline. This binds a call to the handler function to the control that triggers the event.
Dernière mise à jour le 19/6/2011
Page 67
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/SimplerEventHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script> <![CDATA[ import mx.controls.Alert; private function myEventHandler(event:Event):void { Alert.show("An event occurred."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" click="myEventHandler(event)"/> </s:Application>
In this example, whenever the user clicks the Button control, Flex calls the myClickHandler() function.
For more information on defining event handlers inline, see « Defining event listeners inline » à la page 63.
2 Use the addEventListener() method, as follows:
<?xml version="1.0"?> <!-- events/SimpleEventHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp();"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function initApp():void { b1.addEventListener(MouseEvent.CLICK, myEventHandler); } private function myEventHandler(event:Event):void { Alert.show("An event occurred."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me"/> </s:Application>
62
As with the previous example, whenever the user clicks the Button control, Flex calls the myClickHandler() handler function. However, registering your event handlers using this method provides more flexibility. You can register multiple components with this event handler, add multiple handlers to a single component, or remove the handler. For more information, see « Using the addEventListener() method » à la page 64.
3 Create an event handler class and register components to use the class for event handling. This approach to event
handling promotes code reuse and lets you centralize event handling outside your MXML files. For more information on creating custom event handler classes, see « Creating event handler classes » à la page 69.
Dernière mise à jour le 19/6/2011
Page 68
USING FLEX 4.5
Getting started
Defining event listeners inline
The simplest method of defining event handlers in applications is to point to a handler function in the component’s MXML tag. To do this, you add any of the component’s events as a tag attribute followed by an ActionScript statement or function call.
You add an event handler inline using the following syntax:
<s:tag_nameevent_name="handler_function"/>
For example, to listen for a Button control’s click event, you add a statement in the <mx:Button> tag’s click attribute. If you add a function, you define that function in an ActionScript block. The following example defines the
submitForm() function as the handler for the Button control’s click event:
<fx:Script><![CDATA[ function submitForm():void { // Do something. } ]]></fx:Script> <s:Button label="Submit" click="submitForm();"/>
Event handlers can include any valid ActionScript code, including code that calls global functions or sets a component property to the return value. The following example calls the
<s:Button label="Get Ver" click="trace('The button was clicked');"/>
trace() global function:
63
There is one special parameter that you can pass in an inline event handler definition: the event parameter. If you add
event keyword as a parameter, Flex passes the Event object and inside the handler function, you can then access
the all the properties of the Event object.
The following example passes the Event object to the
submitForm() handler function and specifies it as type
MouseEvent:
<?xml version="1.0"?> <!-- events/MouseEventHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script> <![CDATA[ import mx.controls.Alert;
private function myEventHandler(event:MouseEvent):void { // Do something with the MouseEvent object. Alert.show("An event of type '" + event.type + "' occurred."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" click="myEventHandler(event)"/> </s:Application>
It is best practice to include the event keyword when you define all inline event listeners and to specify the most stringent Event object type in the resulting listener function (for example, specify MouseEvent instead of Event).
You can use the Event object to access a reference to the target object (the object that dispatched the event), the type of event (for example,
click), or other relevant properties, such as the row number and value in a list-based control.
You can also use the Event object to access methods and properties of the target component, or the component that dispatched the event.
Dernière mise à jour le 19/6/2011
Page 69
USING FLEX 4.5
Getting started
Although you will most often pass the entire Event object to an event listener, you can just pass individual properties, as the following example shows:
<?xml version="1.0"?> <!-- events/PropertyHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script> <![CDATA[ import mx.controls.Alert;
private function myEventHandler(s:String):void { Alert.show("Current Target: " + s); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" click="myEventHandler(event.currentTarget.id)"/> </s:Application>
Registering an event listener inline provides less flexibility than using the addEventListener() method to register event listeners. The drawbacks are that you cannot set the
useCapture or priority properties on the Event object
and that you cannot remove the listener once you add it.
64
Using the addEventListener() method
The addEventListener() method lets you register event listener functions with the specified control or object. The following example adds the b1, Flex calls the
b1.addEventListener(MouseEvent.CLICK, myClickListener);
myClickListener() method:
myClickListener() function to the b1 instance of a Button control. When the user clicks
The addEventListener() method has the following signature:
componentInstance.addEventListener(
event_type:String,
event_listener:Function,
use_capture:Boolean,
priority:int,
weakRef:Boolean
)
The event_type argument is the kind of event that this component dispatches. This can be either the event type String (for example, “click” or “mouseOut”) or the event type static constant (such as
MouseEvent.MOUSE_OUT). This argument is required.
MouseEvent.CLICK or
The constants provide an easy way to refer to specific event types. You should use these constants instead of the strings that they represent. If you misspell a constant name in your code, the compiler catches the mistake. If you instead use strings and make a typographical error, it can be harder to debug and could lead to unexpected behavior.
You should use the constants wherever possible. For example, when you are testing to see whether an Event object is of a certain type, use the following code:
if (myEventObject.type == MouseEvent.CLICK) {/* your code here */}
Do not use the following code:
if (myEventObject.type == "click") {/* your code here */}
Dernière mise à jour le 19/6/2011
Page 70
USING FLEX 4.5
Getting started
The event_listener argument is the function that handles the event. This argument is required.
use_capture parameter of the addEventListener() method lets you control the phase in the event flow in
The which your listener will be active. It sets the value of the
true, your listener is active during the capturing phase of the event flow. If useCapture is set to false, your
set to
useCapture property of the Event object. If useCapture is
listener is active during the targeting and bubbling phases of the event flow, but not during the capturing phase. The default value is determined by the type of event, but is
false in most cases.
65
To listen for an event during all phases of the event flow, you must call
useCapture parameter set to true, and again with use_capture set to false. This argument is optional. For more
addEventListener() twice, once with the
information, see « Capturing phase » à la page 82.
The priority parameter sets the priority for that event listener. The higher the number, the sooner that event handler executes relative to other event listeners for the same event. Event listeners with the same priority are executed in the order that they were added. This parameter sets the
priority property of the Event object. The default value is 0, but
you can set it to negative or positive integer values. If several event listeners are added without priorities, the earlier a listener is added, the sooner it is executed. For more information on setting priorities, see « Event priorities » à la page 88.
The weakRef parameter provides you with some control over memory resources for listeners. A strong reference (when
weakRef is false) prevents the listener from being garbage collected. A weak reference (when weakRef is true) does
not. The default value is
false.
When you add a listener function and that function is invoked, Flex implicitly creates an Event object for you and passes it to the listener function. You must declare the Event object in the signature of your listener function.
If you add an event listener by using the a parameter of the
b1.addEventListener(MouseEvent.CLICK, performAction);
listener_function, as the following example shows:
addEventListener() method, you are required to declare an event object as
In the listener function, you declare the Event object as a parameter, as follows:
public function performAction(e:MouseEvent):void { ... }
The following example defines a new handler function myClickListener(). It then registers the click event of the Button control with that handler. When the user clicks the button, Flex calls the
myClickHandler() function.
Dernière mise à jour le 19/6/2011
Page 71
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/AddEventListenerExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="createListener()"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function createListener():void { b1.addEventListener(MouseEvent.CLICK, myClickHandler, false, 0); } private function myClickHandler(e:MouseEvent):void { Alert.show("The button was clicked."); } ]]> </fx:Script> <s:Button label="Click Me" id="b1"/> </s:Application>
Using addEventListener() inside an MXML tag
You can add event listeners with the following Button control definition adds the call to the
initialize property:
addEventListener() method inline with the component definition. The
addEventListener() method inline with the Button control’s
66
<?xml version="1.0"?> <!-- events/CallingAddEventListenerInline.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function myClickHandler(event:Event):void { Alert.show("The button was clicked."); } ]]> </fx:Script> <s:Button id='b1' label="Click Me" initialize='b1.addEventListener(MouseEvent.CLICK, myClickHandler, false, 1);' /> </s:Application>
This is the equivalent of defining the event handler inline. However, defining a handler by using the
addEventListener() method rather than setting click="handler_function" lets you set the value of the useCapture and priority properties of the Event object. Furthermore, you cannot remove a handler added inline,
but when you use the
addEventListener() method to add a handler, you can call the removeEventListener()
method to remove that handler.
Using nested inner functions as event listeners
Rather than passing the name of an event listener function to the inner function (also known as a closure).
Dernière mise à jour le 19/6/2011
addEventListener() method, you can define an
Page 72
USING FLEX 4.5
Getting started
In the following example, the nested inner function is called when the button is clicked:
<?xml version="1.0"?> <!-- events/AddingInnerFunctionListener.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function initApp():void { b1.addEventListener("click", function(e:Event):void { Alert.show("The button was clicked."); } ); } ]]> </fx:Script> <s:Button id='b1' label="Click Me"/> </s:Application>
67
Function closures are created any time a function is executed apart from an object or a class. They retain the scope in which they were defined. This creates interesting results when a function is passed as an argument or a return value into a different scope.
For example, the following code creates two functions: that calculates the area of a rectangle, and variable named the function closure
bar() function therefore returns the product of the numbers in the TextInput controls, rather than 8.
<?xml version="1.0"?> <!-- events/FunctionReturnsFunction.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="foo()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ [Bindable] private var answer:String; private function foo():Function { var x:int = int(ti1.text); function rectArea(y:int):int { // function closure defined return x * y; } return rectArea; } private function bar():void {
myProduct. Even though the bar() function defines its own local variable x (with a value of 2), when
myProduct() is called, it retains the variable x (with a value of 40) defined in function foo(). The
bar(), which calls foo() and stores the returned function closure in a
foo(), which returns a nested function named rectArea()
Dernière mise à jour le 19/6/2011
Page 73
USING FLEX 4.5
Getting started
var x:int = 2; // ignored var y:int = 4; // ignored var myProduct:Function = foo(); answer = myProduct(int(ti2.text)); // function closure called }
]]> </fx:Script> <s:Form width="107"> <s:FormItem label="X"> <s:TextInput id="ti1" text="10" width="37" textAlign="right"/> </s:FormItem> <s:FormItem label="Y" width="71"> <s:TextInput id="ti2" text="20" width="38" textAlign="right"/> </s:FormItem> <s:Label id="label1" text="{answer}" width="71" textAlign="right"/> </s:Form> <s:Button id='b1' label="Compute Product" click="bar()"/>
</s:Application>
If the listener that you pass to addEventListener() method is a nested inner function, you should not pass true for
useWeakReference argument. For example:
the
68
addEventListener("anyEvent", function(e:Event) { /* My listener function. */ }, false, 0, true);
In this example, passing true as the last argument can lead to unexpected results. To Flex, an inner function is actually an object, and can be freed by the garbage collector. If you set the value of the
useWeakReference argument to true,
as shown in the previous example, there are no persistent references at all to the inner function. The next time the garbage collector runs, it might free the function, and the function will not be called when the event is triggered.
If there are other references to the inner function (for example, if you saved it in another variable), the garbage collector will not free it.
Regular class-level member functions are not subject to garbage collection; as a result, you can set the value of the
useWeakReference argument to true and they will not be garbage collected.
Removing event handlers
It is a good idea to remove any handlers that will no longer be used. This removes references to objects so that they can be targeted for garbage collection. You can use the you no longer need. All components that can call method. The syntax for the
componentInstance.removeEventListener(event_type:String, listener_function:Function, use_capture:Boolean)
removeEventListener() method is as follows:
removeEventListener() method to remove an event handler that addEventListener() can also call the removeEventListener()
For example, consider the following code:
myButton.removeEventListener(MouseEvent.CLICK, myClickHandler);
The event_type and listener_function parameters are required. These are the same as the required parameters for the
addEventListener() method.
Dernière mise à jour le 19/6/2011
Page 74
USING FLEX 4.5
Getting started
The use_capture parameter is also identical to the parameter used in the addEventListener() method. Recall that you can listen for events during all event phases by calling
true, and again with it set to false. To remove both event listeners, you must call removeEventListener() twice:
once with use_capture set to
true, and again with it set to false.
addEventListener() twice: once with use_capture set to
69
You can remove only event listeners that you added with the
addEventListener() method in an ActionScript block.
You cannot remove an event listener that was defined in the MXML tag, even if it was registered using a call to the
addEventListener() method that was made inside a tag attribute.
The following sample application shows what type of handler can be removed and what type cannot:
<?xml version="1.0"?> <!-- events/RemoveEventListenerExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="createHandler(event)"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert; private function createHandler(e:Event):void { b1.addEventListener(MouseEvent.CLICK, myClickHandler); } private function removeMyHandlers(e:Event):void { /* Remove listener for b1's click event because it was added with the addEventListener() method. */ b1.removeEventListener(MouseEvent.CLICK, myClickHandler); /* Does NOT remove the listener for b2's click event because it was added inline in an MXML tag. */ b2.removeEventListener(MouseEvent.CLICK, myClickHandler); } private function myClickHandler(e:Event):void { Alert.show("The button was clicked."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me"/> <s:Button label="Click Me Too" id="b2" click="myClickHandler(event)"/> <s:Button label="Remove Event Listeners" id="b3" click="removeMyHandlers(event)"/> </s:Application>
Creating event handler classes
You can create an external class file and use the methods of this class as event handlers. Objects themselves cannot be event handlers, but methods of an object can be. By defining one class that handles all your event handlers, you can use the same event handling logic across applications, which can make your MXML applications more readable and maintainable.
To create a class that handles events, you usually import the flash.events.Event class. You also usually write an empty constructor. The following ActionScript class file calls the Alert control’s with the
handleAllEvents() method:
show() method whenever it handles an event
Dernière mise à jour le 19/6/2011
Page 75
USING FLEX 4.5
Getting started
// events/MyEventHandler.as package { // Empty package. import flash.events.Event; import mx.controls.Alert; public class MyEventHandler { public function MyEventHandler() { // Empty constructor. } public function handleAllEvents(event:Event):void { Alert.show("Some event happened."); } } }
In your MXML file, you declare a new instance of MyEventHandler and use the addEventListener() method to register its
handleAllEvents() method as a handler to the Button control’s click event, as the following example
shows:
<?xml version="1.0"?> <!-- events/CustomHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="createHandler()"> <fx:Script> <![CDATA[ private var myListener:MyEventHandler = new MyEventHandler(); private function createHandler():void { b1.addEventListener(MouseEvent.CLICK, myListener.handleAllEvents); } ]]> </fx:Script> <s:Button label="Submit" id="b1"/> </s:Application>
70
The best approach is to define the event handler’s method as static. When you make the event handler method static, you are not required to instantiate the class inside your MXML application. The following registers the
<?xml version="1.0"?> <!-- events/CustomHandlerStatic.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="createHandler()"> <fx:Script> <![CDATA[ private function createHandler():void { b1.addEventListener(MouseEvent.CLICK, MyStaticEventHandler.handleAllEvents); } ]]> </fx:Script> <s:Button label="Submit" id="b1"/> </s:Application>
handleAllEvents() method as an event handler without instantiating the MyStaticEventHandler class:
createHandler() function
In the class file, you just add the static keyword to the method signature:
Dernière mise à jour le 19/6/2011
Page 76
USING FLEX 4.5
Getting started
// events/MyStaticEventHandler.as package { // Empty package. import flash.events.Event; import mx.controls.Alert; public class MyStaticEventHandler { public function MyStaticEventHandler() { // Empty constructor. } public static function handleAllEvents(event:Event):void { Alert.show("Some event happened."); } } }
Store your event listener class in a directory in your source path. You can also store your ActionScript class in the same directory as your MXML file, although Adobe does not recommend this.
Defining multiple listeners for a single event
You can define multiple event handler functions for a single event in two ways. When defining events inside MXML tags, you separate each new handler function with a semicolon. The following example adds the
debugMessage() functions as handlers of the click event:
submitForm() and
71
<?xml version="1.0"?> <!-- events/MultipleEventHandlersInline.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ [Bindable] private var s:String = "";
private function submitForm(e:Event):void { // Handle event here. s += "The submitForm() method was called. "; } private function debugMessage(e:Event):void { // Handle event here. s += "The debugMessage() method was called. "; } ]]></fx:Script>
<s:Button id="b1" label="Do Both Actions" click='submitForm(event); debugMessage(event);' /> <s:Label id="l1" text="{s}"/>
<s:Button id="b2" label="Reset" click="s='';"/>
</s:Application>
Dernière mise à jour le 19/6/2011
Page 77
USING FLEX 4.5
Getting started
For events added with the addEventListener() method, you can add any number of handlers with additional calls
addEventListener() method. Each call adds a handler function that you want to register to the specified
to the object. The following example registers the
submitForm() and debugMessage() handler functions with b1’s click
event:
<?xml version="1.0"?> <!-- events/MultipleEventHandlersAS.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="createHandlers(event)"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ [Bindable] private var s:String = ""; public function createHandlers(e:Event):void { b1.addEventListener(MouseEvent.CLICK, submitForm); b1.addEventListener(MouseEvent.CLICK, debugMessage); } private function submitForm(e:Event):void { // Handle event here. s += "The submitForm() method was called. ";
} private function debugMessage(e:Event):void { // Handle event here. s += "The debugMessage() method was called. "; } ]]></fx:Script> <s:Button id="b1" label="Do Both Actions"/> <s:Label id="l1" text="{s}"/>
<s:Button id="b2" label="Reset" click="s='';"/> </s:Application>
72
You can mix the methods of adding event handlers to any component; alternatively, you can add handlers inline and with the control, which calls the
logAction() method, depending on the state of the CheckBox control.
addEventListener() method. The following example adds a click event handler inline for the Button
performAction() method. It then conditionally adds a second click handler to call the
Dernière mise à jour le 19/6/2011
Page 78
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/ConditionalHandlers.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="initApp(event)"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert; private function initApp(e:Event):void { cb1.addEventListener(MouseEvent.CLICK, handleCheckBoxChange); b1.addEventListener(MouseEvent.CLICK, logAction); } private function handleCheckBoxChange(e:Event):void { if (cb1.selected) { b1.addEventListener(MouseEvent.CLICK, logAction); ta1.text += "Added log listener." + "\n"; } else { b1.removeEventListener(MouseEvent.CLICK, logAction); ta1.text += "Removed log listener." + "\n"; } } private function performAction(e:Event):void { Alert.show("You performed the action."); } private function logAction(e:Event):void { ta1.text += "Action performed: " + e.type + ".\n"; } ]]> </fx:Script> <s:Button label="Perform Action" id="b1" click="performAction(event)"/> <s:CheckBox id="cb1" label="Log?" selected="true"/> <s:TextArea id="ta1" height="200" width="300"/> </s:Application>
73
You can set the order in which event listeners are called by using the priority parameter of the
addEventListener() method. You cannot set a priority for a listener function if you added the event listener using
MXML inline. For more information on setting priorities, see « Event priorities » à la page 88.
Registering a single listener with multiple components
You can register the same listener function with any number of events of the same component, or events of different components. The following example registers a single listener function,
Dernière mise à jour le 19/6/2011
submitForm(), with two different buttons:
Page 79
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/OneHandlerTwoComponentsInline.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert; private function submitForm(e:Event):void { // Handle event here. Alert.show("Current Target: " + e.currentTarget.id); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" click="submitForm(event)"/> <s:Button id="b2" label="Click Me, Too" click="submitForm(event)"/>
</s:Application>
74
When you use the addEventListener() method to register a single listener to handle the events of multiple components, you must use a separate call to the
addEventListener() method for each instance, as the following
example shows:
<?xml version="1.0"?> <!-- events/OneHandlerTwoComponentsAS.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="createHandlers(event)"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert; public function createHandlers(e:Event):void { b1.addEventListener(MouseEvent.CLICK, submitForm); b2.addEventListener(MouseEvent.CLICK, submitForm); } private function submitForm(e:Event):void { // Handle event here. Alert.show("Current Target: " + e.currentTarget.id); } ]]> </fx:Script> <s:Button id="b1" label="Click Me"/> <s:Button id="b2" label="Click Me, Too"/> </s:Application>
Dernière mise à jour le 19/6/2011
Page 80
USING FLEX 4.5
Getting started
When doing this, you should add logic to the event listener that processes the type of event. The event target (or object that dispatched the event) is added to the Event object for you. No matter what triggered the event, you can conditionalize the event processing based on the
target or type properties of the Event object. Flex adds these two
properties to all Event objects.
75
The following example registers a single listener function ( and the the
<?xml version="1.0"?> <!-- events/ConditionalTargetHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert;
public function initApp():void { button1.addEventListener(MouseEvent.CLICK, myEventHandler); cb1.addEventListener(MouseEvent.CLICK, myEventHandler); } public function myEventHandler(event:Event):void { switch (event.currentTarget.className) { case "Button": // Process Button click. Alert.show("You clicked the Button control."); break; case "CheckBox": // Process CheckBox click. Alert.show("You clicked the CheckBox control."); break; } } ]]> </fx:Script> <s:Button label="Click Me" id="button1"/> <s:CheckBox label="Select Me" id="cb1"/> </s:Application>
click event of a CheckBox control. To detect what type of object called the event listener, the listener checks
className property of the target in the Event object in a case statement.
myEventHandler()) to the click event of a Button control
Passing additional parameters to listener functions
You can pass additional parameters to listener functions depending on how you add the listeners. If you add a listener with the arbitrarily adding new parameters to the function signature. The default listener function can declare only a single argument, the Event object (or one of its subclasses).
For example, the following code throws an error because the
addEventListener() method, you cannot pass any additional parameters to the listener function by
clickListener() method expects two arguments:
Dernière mise à jour le 19/6/2011
Page 81
USING FLEX 4.5
Getting started
<fx:Script> public function addListeners():void { b1.addEventListener(MouseEvent.CLICK,clickListener); } public function clickListener(e:MouseEvent, a:String):void { ... } </fx:Script> <mx:Button id="b1"/>
Because the second parameter of the addEventListener() method is a function, you can define that function and pass the event object plus any additional parameters through to a different handler. The following example creates a new function in the all of the parameters in the
<?xml version="1.0" encoding="utf-8"?> <!-- events/CustomListenerFunction.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp(event)"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ private var specialParam1:String; private var specialParam2:String = "42"; private function initApp(e:Event):void { assignSpecialParam(e);
/* Change the value of specialParam whenever the user changes it in the TextInput and clicks the button. */ ti1.addEventListener("focusOut", assignSpecialParam);
/* Define the pass-through method in the addEventListener() method call. You can add any number of parameters, as long as teh target method's signature agrees. */ myButton.addEventListener(MouseEvent.CLICK, function (e:MouseEvent):void { myClickListener(e, specialParam1, specialParam2); } ); }
private function assignSpecialParam(e:Event):void { specialParam1 = ti1.text; }
/* This method acts as the event listener, and it has any number of parameters that we defined in the addEventListener() call. */ private function myClickListener(e:MouseEvent, s1:String, s2:String) : void { myButton.label = s1 + " " + s2; } ]]> </fx:Script> <s:Button id="myButton" label="Click Me"/> <s:TextInput id="ti1" text="Enter a custom String here." width="250"/> </s:Application>
addEventListener() method, add two parameters to the new handler’s call, and then handles
myClickListener() method.
76
Dernière mise à jour le 19/6/2011
Page 82
USING FLEX 4.5
Getting started
Another approach to passing additional parameters to the listener function is to define them in the listener function and then call the final method with those parameters. If you define an event listener inline (inside the MXML tag), you can add any number of parameters as long as the listener function’s signature agrees with that number of parameters.
77
The following example passes a string and the Event object to the
<?xml version="1.0"?> <!-- events/MultipleHandlerParametersInline.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ public function runMove(dir:String, e:Event):void { if (dir == "up") { moveableButton.y = moveableButton.y - 5; } else if (dir == "down") { moveableButton.y = moveableButton.y + 5; } else if (dir == "left") { moveableButton.x = moveableButton.x - 5; } else if (dir == "right") { moveableButton.x = moveableButton.x + 5; } } ]]> </fx:Script> <mx:Canvas height="100%" width="100%"> <s:Button id="moveableButton" label="{moveableButton.x.toString()},{moveableButton.y.toString()}" x="75" y="100" width="80" /> </mx:Canvas> <s:VGroup horizontalAlign="center">
runMove() method:
Dernière mise à jour le 19/6/2011
Page 83
USING FLEX 4.5
Getting started
<s:Button id="b1" label="Up" click='runMove("up",event);' width="75"/> <s:HGroup horizontalAlign="center"> <mx:Button id="b2" label="Left" click='runMove("left",event);' width="75"/> <s:Button id="b3" label="Right" click='runMove("right",event);' width="75"/> </s:HGroup> <s:Button id="b4" label="Down" click='runMove("down",event);' width="75"/> </s:VGroup> </s:Application>

Manually dispatching events

You can manually dispatch events using a component instance’s dispatchEvent() method. All components that extend UIComponent have this method. The method is inherited from the EventDispatcher class, which UIComponent extends.
78
The syntax for the
objectInstance.dispatchEvent(event:Event):Boolean
dispatchEvent() method is as follows:
When dispatching an event, you must create a new Event object. The syntax for the Event object constructor is as follows:
Event(event_type:String, bubbles:Boolean, cancelable:Boolean)
The event_type parameter is the type property of the Event object. The bubbles and cancelable parameters are optional and both default to
You can use the a Button control’s
false. For information on bubbling and capturing, see « Event propagation » à la page 81.
dispatchEvent() method to dispatch any event you want, not just a custom event. You can dispatch
click event, even though the user did not click a Button control, as in the following example:
Dernière mise à jour le 19/6/2011
Page 84
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/DispatchEventExample.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="createListener(event);">
<fx:Script><![CDATA[ import mx.controls.Alert; private function createListener(e:Event):void { b1.addEventListener(MouseEvent.MOUSE_OVER, myEventHandler); b1.addEventListener(MouseEvent.CLICK, myClickHandler); } private function myEventHandler(e:Event):void { var result:Boolean = b1.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false)); } private function myClickHandler(e:Event):void { Alert.show("The event dispatched by the MOUSE_OVER was of type '" + e.type + "'."); } ]]></fx:Script> <s:Button id="b1" label="Click Me"/> </s:Application>
79
You can also manually dispatch an event in an MXML tag. In the following example, moving the mouse pointer over the button triggers the button’s
<?xml version="1.0"?> <!-- events/DispatchEventExampleInline.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="createListener(event);"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function createListener(e:Event):void { b1.addEventListener(MouseEvent.CLICK, myClickHandler); } private function myClickHandler(e:Event):void { Alert.show("The event dispatched by the MOUSE_OVER was of type '" + e.type + "'."); } ]]> </fx:Script> <s:Button id="b1" label="Click Me" mouseOver="b1.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));" /> </s:Application>
click event:
Your application is not required to handle the newly dispatched event. If you trigger an event that has no listeners, Flex ignores the event.
Dernière mise à jour le 19/6/2011
Page 85
USING FLEX 4.5
Getting started
You can set properties of the Event object in ActionScript, but you cannot add new properties because the object is not dynamic. The following example intercepts a
doubleClick event. In addition, it sets the value of the shiftKey property of the MouseEvent object to true, to
as a
click event. It then creates a new MouseEvent object and dispatches it
simulate a Shift-click on the keyboard.
<?xml version="1.0"?> <!-- events/DispatchCustomizedEvent.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="addListeners()">
<s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ private function customLogEvent(e:MouseEvent):void { l1.text = String(e.currentTarget.id); l2.text = String(e.type); l3.text = String(e.shiftKey); // Remove current listener to avoid recursion. e.currentTarget.removeEventListener("doubleClick", customLogEvent); } private function handleEvent(e:MouseEvent):void { // Add new handler for custom event about to be dispatched. e.currentTarget.addEventListener("doubleClick", customLogEvent); // Create new event object. var mev:MouseEvent = new MouseEvent("doubleClick"); // Customize event object. mev.shiftKey = true; // Dispatch custom event. e.currentTarget.dispatchEvent(mev); } private function addListeners():void { b1.addEventListener("click",handleEvent); b2.addEventListener("click",handleEvent); } ]]></fx:Script> <s:Button id="b1" label="Click Me (b1)"/> <s:Button id="b2" label="Click Me (b2)"/>
<s:Form> <s:FormItem label="Current Target:"> <s:Label id="l1"/> </s:FormItem> <s:FormItem label="Event Type:"> <s:Label id="l2"/> </s:FormItem> <s:FormItem label="Shift Key Pressed:"> <s:Label id="l3"/> </s:FormItem> </s:Form> </s:Application>
80
Dernière mise à jour le 19/6/2011
Page 86
USING FLEX 4.5
Getting started
If you want to add custom properties to an Event object, you must extend the Event object and define the new properties in your own custom class. You can then manually dispatch your custom events with the
dispatchEvent()
method, as you would any event.
If you create a custom ActionScript class that dispatches its own events but does not extend UIComponent, you can extend the flash.events.EventDispatcher class to get access to the
dispatchEvent() methods.
and
addEventListener(), removeEventListener(),
For more information on creating custom classes, see Creating and Extending Adobe Flex3 Components .

Event propagation

When events are triggered, there are three phases in which Flex checks whether there are event listeners. These phases occur in the following order:
Capturing
Targeting
Bubbling
During each of these phases, the nodes have a chance to react to the event. For example, assume the user clicks a Button control that is inside a VBox container. During the capturing phase, Flex checks the Application object and the VBox for listeners to handle the event. Flex then triggers the Button’s listeners in the target phase. In the bubbling phase, the VBox and then the Application are again given a chance to handle the event but now in the reverse order from the order in which they were checked in the capturing phase.
81
In ActionScript 3.0, you can register event listeners on a target node and on any node along the event flow. Not all events, however, participate in all three phases of the event flow. Some types of events are dispatched directly to the target node and participate in neither the capturing nor the bubbling phases. All events can be captured unless they are dispatched from the top node.
Other events may target objects that are not on the display list, such as events dispatched to an instance of the Socket class. These event objects flow directly to the target node, without participating in the capturing or bubbling phases. You can also cancel an event as it flows through the event model so that even though it was supposed to continue to the other phases, you stopped it from doing so. You can do this only if the
cancelable property is set to true.
Capturing and bubbling happen as the Event object moves from node to node in the display list: parent-to-child for capturing and child-to-parent for bubbling. This process has nothing to do with the inheritance hierarchy. Only DisplayObject objects (visual objects such as containers and controls) can have a capturing phase and a bubbling phase in addition to the targeting phase.
Mouse events and keyboard events are among those that bubble. Any event can be captured, but no DisplayObject objects listen during the capturing phase unless you explicitly instruct them to do so. In other words, capturing is disabled by default.
When a faceless event dispatcher, such as a Validator, dispatches an event, there is only a targeting phase, because there is no visual display list for the Event object to capture or bubble through.
About the target and currentTarget properties
Every Event object has a target and a currentTarget property that help you to keep track of where it is in the process of propagation. The current node that is being examined for event listeners.
target property refers to the dispatcher of the event. The currentTarget property refers to the
Dernière mise à jour le 19/6/2011
Page 87
USING FLEX 4.5
Getting started
When you handle a mouse event such as MouseEvent.CLICK by writing a listener on some component, the
event.target property does not necessarily refer to that component; it is often a subcomponent, such as the Button
control’s UITextField, that defines the label.
When Flash Player or Adobe® AIR™ dispatches an event, it dispatches the event from the frontmost object under the mouse. Because children are in front of parents, that means the player or AIR might dispatch the event from an internal subcomponent, such as the UITextField of a Button.
event.target property is set to the object that dispatched the event (in this case, UITextField), not the object
The that is being listened to (in most cases, you have a Button control listen for a
click event).
MouseEvent events bubble up the parent chain, and can be handled on any ancestor. As the event bubbles, the value
event.target property stays the same (UITextField), but the value of the event.currentTarget property is
of the set at each level to be the ancestor that is handling the event. Eventually, the
currentTarget will be Button, at which
time the Button control’s event listener will handle the event. For this reason, you should use the
event.currentTarget property rather than the event.target property; for example:
<mx:Button label="OK" click="trace(event.currentTarget.label)"/>
In this case, in the Button event’s click event listener, the event.currentTarget property always refers to the Button,
event.target might be either the Button or its UITextField, depending on where on the Button control the
while user clicked.
82
Capturing phase
In the capturing phase, Flex examines an event target’s ancestors in the display list to see which ones are registered as a listener for the event. Flex starts with the root ancestor and continues down the display list to the direct ancestor of the target. In most cases, the root ancestors are the Stage, then the SystemManager, and then the Application object.
For example, if you have an application with a Panel container that contains a TitleWindow container, which in turn contains a Button control, the structure appears as follows:
Application Panel TitleWindow Button
If your listener is on the click event of the Button control, the following steps occur during the capturing phase if capturing is enabled:
1 Check the Application container for click event listeners.
2 Check the Panel container for click event listeners.
3 Check the TitleWindow container for click event listeners.
During the capturing phase, Flex changes the value of the current node whose listener is being called. The
target property continues to refer to the dispatcher of the event.
By default, no container listens during the capturing phase. The default value of the use_capture argument is The only way to add a listener during this phase is to pass
addEventListener() method, as the following example shows:
currentTarget property on the Event object to match the
false.
true for the use_capture argument when calling the
myPanel.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler, true);
If you add an event listener inline with MXML, Flex sets this argument to false; you cannot override it.
Dernière mise à jour le 19/6/2011
Page 88
USING FLEX 4.5
Getting started
If you set the use_capture argument to true—in other words, if an event is propagated through the capturing phase— the event can still bubble, but capture phase listeners will not react to it. If you want your event to traverse both the capturing and bubbling phases, you must call then again with use_capture set to
false.
addEventListener() twice: once with use_capture set to true, and
The capturing phase is very rarely used, and it can also be computationally intensive. By contrast, bubbling is much more common.
Targeting phase
In the targeting phase, Flex invokes the event dispatcher’s listeners. No other nodes on the display list are examined for event listeners. The values of the
currentTarget and the target properties on the Event object during the
targeting phase are the same.
Bubbling phase
In the bubbling phase, Flex examines an event’s ancestors for event listeners. Flex starts with the dispatcher’s immediate ancestor and continues up the display list to the root ancestor. This is the reverse of the capturing phase.
For example, if you have an application with a Panel container that contains a TitleWindow container that contains a Button control, the structure appears as follows:
Application Panel TitleWindow Button
83
If your listener is on the click event of the Button control, the following steps occur during the bubble phase if bubbling is enabled:
1 Check the TitleWindow container for click event listeners.
2 Check the Panel container for click event listeners.
3 Check the Application container for click event listeners.
An event only bubbles if its
bubbles property is set to true. Mouse events and keyboard events are among those that
bubble; it is less common for higher-level events that are dispatched by Flex to bubble. Events that can be bubbled include
change, click, doubleClick, keyDown, keyUp, mouseDown, and mouseUp. To determine whether an event
bubbles, see the event’s entry in the ActionScript 3.0 Reference for the Adobe Flash Platform.
During the bubbling phase, Flex changes the value of the current node whose listener is being called. The
target property continues to refer to the dispatcher of the event.
currentTarget property on the Event object to match the
When Flex invokes an event listener, the Event object might have actually been dispatched by an object deeper in the display list. The object that originally dispatched the event is the bubbling through is the
target property when referring to the current object in your event listeners.
If you set the
useCapture property to true—in other words, if an event is propagated through the capturing phase—
currentTarget. So, you should generally use the currentTarget property instead of the
target. The object that the event is currently
then it does not bubble, regardless of its default bubbling behavior. If you want your event to traverse both the capturing and bubbling phases, you must call then again with
useCapture set to false.
addEventListener() twice: once with useCapture set to true, and
An event only bubbles up the parent’s chain of ancestors in the display list. Siblings, such as two Button controls inside the same container, do not intercept each other’s events.
Dernière mise à jour le 19/6/2011
Page 89
USING FLEX 4.5
Getting started
Detecting the event phase
You can determine what phase you are in by using the Event object’s eventPhase property. This property contains an integer that represents one of the following constants:
1 — Capturing phase (CAPTURING_PHASE)
2 — Targeting phase (AT_TARGET)
3 — Bubbling phase (BUBBLING_PHASE)
The following example displays the current phase and information about the current target:
<?xml version="1.0"?> <!-- events/DisplayCurrentTargetInfo.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Script><![CDATA[ import mx.controls.Alert; private function showInfo(e:MouseEvent):void { Alert.show("Phase: " + e.eventPhase + "\n" + "ID: " + e.currentTarget.id + "\n" + "Label: " + e.currentTarget.label + "\n" + "Font Size: " + e.currentTarget.getStyle("fontSize"), "Current Target Info"); } ]]></fx:Script> <s:Button id="b1" label="Click Me" click="showInfo(event)"/> </s:Application>
84
Stopping propagation
During any phase, you can stop the traversal of the display list by calling one of the following methods on the Event object:
stopPropagation()
stopImmediatePropagation()
You can call either the event’s prevent an Event object from continuing on its way through the event flow. The two methods are nearly identical and differ only in whether the current node’s remaining event listeners are allowed to execute. The method prevents the Event object from moving on to the next node, but only after any other event listeners on the current node are allowed to execute.
stopImmediatePropagation() method also prevents the Event objects from moving on to the next node, but it
The does not allow any other event listeners on the current node to execute.
The following example creates a TitleWindow container inside a Panel container. Both containers are registered to listen for a
mouseDown event. As a result, if you click on the TitleWindow container, the showAlert() method is called
twice unless you add a call to the
stopPropagation() method or the stopImmediatePropagation() method to
stopPropagation()
stopImmediatePropagation() method, as the following example shows:
Dernière mise à jour le 19/6/2011
Page 90
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/StoppingPropagation.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="init(event);"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert; import flash.events.MouseEvent; import flash.events.Event; public function init(e:Event):void { p1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert); tw1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert); tw1.addEventListener(Event.CLOSE, closeWindow); p2.addEventListener(MouseEvent.MOUSE_DOWN, showAlertWithoutStoppingPropagation); tw2.addEventListener(MouseEvent.MOUSE_DOWN, showAlertWithoutStoppingPropagation); tw2.addEventListener(Event.CLOSE, closeWindow); } public function showAlert(e:Event):void { Alert.show("Alert!\n" + "Current Target: " + e.currentTarget + "\n" + "Phase: " + e.eventPhase); e.stopImmediatePropagation(); } public function showAlertWithoutStoppingPropagation(e:Event):void { Alert.show("Alert!\n" + "Current Target: " + e.currentTarget + "\n" + "Phase: " + e.eventPhase); } public function closeWindow(e:Event):void { p1.removeChild(tw1); } ]]> </fx:Script> <s:Panel id="p1" title="Stops Propagation">
85
Dernière mise à jour le 19/6/2011
Page 91
USING FLEX 4.5
Getting started
<mx:TitleWindow id="tw1" width="300" height="100" showCloseButton="true" title="Title Window 1"> <s:Button label="Click Me"/> <s:TextArea id="ta1"/> </mx:TitleWindow> </s:Panel> <s:Panel id="p2" title="Does Not Stop Propagation"> <mx:TitleWindow id="tw2" width="300" height="100" showCloseButton="true" title="Title Window 2"> <s:Button label="Click Me"/> <s:TextArea id="ta2"/> </mx:TitleWindow> </s:Panel> </s:Application>
Remarque : A call to either the Event.stopPropogation() or the Event.stopImmediatePropogation() methods does not prevent default behavior from occurring.
86
Event examples
In the following example, the parent container’s click handler disables the target control after the target handles the event. It shows that you can reuse the logic of a single listener (click the HGroup container) for multiple events (all the clicks).
Dernière mise à jour le 19/6/2011
Page 92
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/NestedHandlers.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ public function disableControl(event:MouseEvent):void { // Use this same logic for all events. event.currentTarget.enabled = false; } public function doSomething(event:MouseEvent):void { b1.label = "clicked"; ta1.text += "Something happened."; } public function doSomethingElse(event:MouseEvent):void { b2.label = "clicked"; ta1.text += "Something happened again."; } ]]></fx:Script> <s:HGroup id="hb1" height="200" click="disableControl(event)"> <s:Button id='b1' label="Click Me" click="doSomething(event)"/> <s:Button id='b2' label="Click Me" click="doSomethingElse(event)"/> <s:TextArea id="ta1"/> </s:HGroup> <s:Button id="resetButton" label="Reset" click="hb1.enabled=true;b1.enabled=true;b2.enabled=true;b1.label='Click Me';b2.label='Click Me';"/> </s:Application>
87
By having a single listener on a parent control instead of many listeners (one on each child control), you can reduce your code size and make your applications more efficient. Reducing the number of calls to the
addEventListener()
method potentially reduces application startup time and memory usage.
The following example registers an event handler for the Panel container, rather than registering a listener for each link. All children of the Panel container inherit this event handler. Since Flex invokes the handler on a bubbled event, you use the would refer to the Panel control, whereas the
target property rather than the currentTarget property. In this handler, the currentTarget property
target property refers to the LinkButton control, which has the label
that you want.
Dernière mise à jour le 19/6/2011
Page 93
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/SingleRegisterHandler.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="createLinkHandler();"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ private function linkHandler(event:MouseEvent):void { try { var url:URLRequest = new URLRequest("http://finance.google.com/finance?q=" + event.target.label); navigateToURL(url); } catch (e:Error) { /** * Do nothing; just want to catch the error that occurs when a user clicks on * the Panel and not one of the LinkButtons. **/ } } private function createLinkHandler():void { p1.addEventListener(MouseEvent.CLICK,linkHandler); } ]]> </fx:Script>
<s:Panel id="p1" title="Click on a stock ticker symbol"> <s:layout> <s:HorizontalLayout/> </s:layout> <mx:LinkButton label="ADBE"/> <mx:LinkButton label="GE"/> <mx:LinkButton label="IBM"/> <mx:LinkButton label="INTC"/> </s:Panel> </s:Application>
88

Event priorities

You can register any number of event listeners with a single event. Flex registers event listeners in the order in which the addEventListener() methods are called. Flex then calls the listener functions when the event occurs in the order in which they were registered. However, if you register some event listeners inline and some with the
addEventListener() method, the order in which the listeners are called for a single event can be unpredictable.
You can change the order in which Flex calls event listeners by using the priority parameter of the
addEventListener() method. It is the fourth argument of the addEventListener() method.
Flex calls event listeners in priority order, from highest to lowest. The highest priority event is called first. In the following example, Flex calls the
verifyInputData() method has the highest priority. The last method to be called is returnResult() because the
value of its
priority parameter is lowest.
verifyInputData() method before the saveInputData() function. The
Dernière mise à jour le 19/6/2011
Page 94
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/ShowEventPriorities.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ private function returnResult(e:Event):void { ta1.text += "returnResult() method called last (priority 1)\n"; } private function verifyInputData(e:Event):void { ta1.text += "verifyInputData() method called first (priority 3)\n"; } private function saveInputData(e:Event):void { ta1.text += "saveInputData() method called second (priority 2)\n"; } private function initApp():void { b1.addEventListener(MouseEvent.CLICK, returnResult, false, 1); b1.addEventListener(MouseEvent.CLICK, saveInputData, false, 2); b1.addEventListener(MouseEvent.CLICK, verifyInputData, false, 3); } ]]> </fx:Script> <s:Button id="b1" label="Click Me"/>
<s:TextArea id="ta1" height="200" width="300"/>
</s:Application>
89
You can set the event priority to any valid integer, positive or negative. The default value is 0. If multiple listeners have the same priority, Flex calls them in the order in which they were registered.
If you want to change the priority of an event listener once the event listener has already been defined, you must remove the listener by calling the
The priority parameter of the
removeEventListener() method. You add the event again with the new priority.
addEventListener() method is not an official part of the DOM Level 3 events model.
ActionScript 3.0 provides it so that programmers can be more flexible when organizing their event listeners.
If your listeners rely on a specific order of execution, you can call one listener function from within another, or dispatch a new event from within the first event listener. For more information on manually dispatching events, see « Manually dispatching events » à la page 78.

Using event subclasses

Depending on the event type, the Event object can have a wide range of properties. These properties are based on those defined in the W3C specification http://www.w3.org/TR/DOM-Level-3-Events/), but Flex does not implement all of these.
When you declare an Event object in a listener function, you can declare it of type Event, or you can specify a subclass of the Event object. In the following example, you specify the event object as type MouseEvent:
Dernière mise à jour le 19/6/2011
Page 95
USING FLEX 4.5
Getting started
public function performAction(e:MouseEvent):void { ... }
Most controls generate an object that is of a specific event type; for example, a mouse click generates an object of type MouseEvent. By specifying a more specific event type, you can access specific properties without having to cast the Event object to something else. In addition, some subclasses of the Event object have methods that are unique to them. For example, the LogEvent has a
getLevelString() method, which returns the log level as a String. The generic
Event object does not have this method.
An event object that you define at run time can be a subclass of the compile-time type. You can access the event-specific properties inside an event listener even if you did not declare the specific event type, as long as you cast the Event object to a specific type. In the following example, the function defines the object type as Event. However, inside the function, in order to access the
localX and localY properties, which are specific to the MouseEvent class, you must cast the
Event object to be of type MouseEvent.
<?xml version="1.0"?> <!-- events/AccessEventSpecificProperties.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="addListeners()"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert; private function customLogEvent(e:Event):void { var a:MouseEvent = MouseEvent(e); Alert.show("Y: " + a.localY + "\n" + "X: " + a.localX); } private function addListeners():void { b1.addEventListener(MouseEvent.CLICK, customLogEvent); } ]]> </fx:Script> <s:Button id="b1" label="Click Me"/> </s:Application>
90
If you declare the Event object as a specific type, you are not required to cast that object in the handler, as the following example shows:
private function customLogEvent(e:MouseEvent):void { ... }
In the previous example, you can also cast the Event object for only the property access, using the syntax shown in the following example:
Dernière mise à jour le 19/6/2011
Page 96
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/SinglePropertyAccess.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" initialize="addListeners()"> <fx:Script> <![CDATA[ import mx.controls.Alert; private function customLogEvent(e:Event):void { Alert.show("Y: " + MouseEvent(e).localY + "\n" + "X: " + MouseEvent(e).localX); } private function addListeners():void { b1.addEventListener(MouseEvent.CLICK, customLogEvent); } ]]> </fx:Script>
<s:Button id="b1" label="Click Me"/> </s:Application>
This approach can use less memory and system resources, but it is best to declare the event’s type as specifically as possible.
91
Each of the Event object’s subclasses provides additional properties and event types that are unique to that category of events. The MouseEvent class defines several event types related to that input device, including the
DOUBLE_CLICK, MOUSE_DOWN, and MOUSE_UP event types.
CLICK,
For a list of types for each Event subclass, see the subclass’s entry in ActionScript 3.0 Reference for the Adobe Flash
Platform.

About keyboard events

It is common for applications to respond to a key or series of keys and perform some action—for example, Control+q to quit the application. While Flash Player supports all the basic functionality of key combinations from the underlying operating system, it also lets you override or trap any key or combination of keys to perform a custom action.
Handling keyboard events
In some cases, you want to trap keys globally, meaning no matter where the user is in the application, their keystrokes are recognized by the application and the action is performed. Flex recognizes global keyboard events whether the user is hovering over a button or the focus is inside a TextInput control.
A common way to handle global key presses is to create a listener for the
KeyboardEvent.KEY_UP event on the application. Listeners on the application container are triggered every time a
key is pressed, regardless of where the focus is (as long as the focus is in the application on not in the browser controls or outside of the browser). Inside the handler, you can examine the key code or the character code using the
keyCode properties of the KeyboardEvent class, as the following example shows:
and
KeyboardEvent.KEY_DOWN or
charCode
Dernière mise à jour le 19/6/2011
Page 97
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/TrapAllKeys.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp();"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.core.FlexGlobals;
private function initApp():void { FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_UP, keyHandler); } private function keyHandler(event:KeyboardEvent):void { t1.text = event.keyCode + "/" + event.charCode; } ]]> </fx:Script> <s:TextInput id="myTextInput"/>
<s:Label id="t1"/> </s:Application>
92
To run this example, you must first set the focus to something inside the application, such as the TextInput control, by clicking on it.
Because any class that extends UIComponent dispatches the
keyUp and keyDown events, you can also trap keys pressed
when the focus is on an individual component.
Understanding the keyCode and charCode properties
You can access the keyCode and charCode properties to determine what key was pressed and trigger other actions as a result. The
charCode property is the numeric value of that key in the current character set (the default character set is UTF-8,
which supports ASCII). The primary difference between the key code and character values is that a key code value represents a particular key on the keyboard (the 1 on a keypad is different than the 1 in the top row, but the 1 on the keyboard and the key that generates the ! are the same key), and the character value represents a particular character (the R and r characters are different).
The mappings between keys and key codes are device and operating system dependent. ASCII values, on the other hand, are available in the ActionScript documentation.
The following example shows the character and key code values for the keys you press. When you run this example, you must be sure to put the focus in the application before beginning.
keyCode property is a numeric value that corresponds to the value of a key on the keyboard. The
Dernière mise à jour le 19/6/2011
Page 98
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- charts/ShowCharAndKeyCodes.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="init()" width="650"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ import flash.events.KeyboardEvent; private function init():void { ti1.setFocus(); this.addEventListener(KeyboardEvent.KEY_DOWN, trapKeys); }
private function trapKeys(e:KeyboardEvent):void { ta1.text = String(e.toString());
l1.text = numToChar(e.charCode) + " (" + String(e.charCode) + ")"; l2.text = numToChar(e.keyCode) + " (" + String(e.keyCode) + ")"; }
private function numToChar(num:int):String { if (num > 47 && num < 58) { var strNums:String = "0123456789"; return strNums.charAt(num - 48); } else if (num > 64 && num < 91) { var strCaps:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; return strCaps.charAt(num - 65); } else if (num > 96 && num < 123) { var strLow:String = "abcdefghijklmnopqrstuvwxyz"; return strLow.charAt(num - 97); } else { return num.toString(); } } ]]></fx:Script> <s:TextInput width="50%" id="ti1"/>
<s:Panel id="mainPanel" width="100%" height="100%"> <s:Form> <s:FormItem label="Char (Code)"> <s:Label id="l1"/> </s:FormItem> <s:FormItem label="Key (Code)"> <s:Label id="l2"/> </s:FormItem> <s:FormItem label="Key Event"> <s:TextArea id="ta1" width="500" height="200" editable="false"/> </s:FormItem> </s:Form> </s:Panel>
</s:Application>
93
Dernière mise à jour le 19/6/2011
Page 99
USING FLEX 4.5
Getting started
You can listen for specific keys or combinations of keys by using a conditional operator in the KeyboardEvent handler. The following example listens for the combination of the Shift key plus the q key and prompts the user to close the browser window if they press those keys at the same time:
<?xml version="1.0"?> <!-- events/TrapQKey.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp();"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.core.FlexGlobals;
private function initApp():void { FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_UP,keyHandler);
// Set the focus somewhere inside the application. ta1.setFocus(); } //This function quits the application if the user presses Shift+Q. private function keyHandler(event:KeyboardEvent):void { var bShiftPressed:Boolean = event.shiftKey; if (bShiftPressed) { var curKeyCode:int = event.keyCode; if (curKeyCode == 81) { // 81 is the keycode value for the Q key /* Quit the application by closing the browser using JavaScript. This may not work in all browsers. */ var url:URLRequest = new URLRequest("javascript:window.close()"); navigateToURL(url,"_self"); } } } ]]> </fx:Script> <s:TextArea id="ta1" text="Focus here so that Shift+Q will quit the browser."/> </s:Application>
94
Notice that this application must have focus when you run it in a browser so that the application can capture keyboard events.
Understanding KeyboardEvent precedence
If you define keyUp or keyDown event listeners for both a control and its parent, you will notice that the keyboard event is dispatched for each component because the event bubbles. The only difference is that the of the KeyboardEvent object is changed.
In the following example, the application, the events to the
keyHandler() event listener function:
my_vgroup container, and the my_textinput control all dispatch keyUp
Dernière mise à jour le 19/6/2011
currentTarget property
Page 100
USING FLEX 4.5
Getting started
<?xml version="1.0"?> <!-- events/KeyboardEventPrecedence.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp();" width="650"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Script><![CDATA[ import mx.core.FlexGlobals;
private function initApp():void { FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_UP, keyHandler); my_vgroup.addEventListener(KeyboardEvent.KEY_UP, keyHandler); my_textinput.addEventListener(KeyboardEvent.KEY_UP, keyHandler); // Set the focus somewhere inside the application. my_textinput.setFocus(); } private function keyHandler(event:KeyboardEvent):void { ta1.text += event.target + "(" + event.currentTarget + "): " + event.keyCode + "/" + event.charCode + "\n"; } ]]></fx:Script>
<s:VGroup id="my_vgroup"> <s:TextInput id="my_textinput"/> </s:VGroup> <s:TextArea id="ta1" height="300" width="550"/> </s:Application>
95
When you examine the output, you will notice that the target property of the KeyboardEvent object stays the same because it refers to the original dispatcher of the event (in this case, my_textinput). But the
currentTarget property
changes depending on what the current node is during the bubbling (in this case, it changes from my_textinput to my_vgroup to the application itself).
The order of calls to the event listener is determined by the object hierarchy and not the order in which the
addEventListener() methods were called. Child controls dispatch events before their parents. In this example, for
each key pressed, the TextInput control dispatches the event first, the VGroup container next, and finally the application.
When handling a key or key combination that the underlying operating system or browser recognizes, the operating system or browser generally processes the event first. For example, in Microsoft Internet Explorer, pressing Control+w closes the browser window. If you trap that combination in your application, Internet Explorer users never know it, because the browser closes before the ActiveX Flash Player has a chance to react to the event.
Handling keyboard-related mouse events
The MouseEvent class and all MouseEvent subclasses (such as ChartItemEvent, DragEvent, and LegendMouseEvent) have the following properties that you can use to determine if a specific key was held down when the event occurred:
Dernière mise à jour le 19/6/2011
Loading...