BlackBerry Tablet OS SDK for Adobe AIR

Version: 1.1.1
Development Guide

Published: 2011-09-04 SWD-1840131-1005031135-001

Contents
1 Overview of the BlackBerry Tablet OS SDK for Adobe AIR............................................................................... Developing Adobe AIR applications for BlackBerry Tablet OS.......................................................................... BlackBerry Tablet OS security architecture...................................................................................................... Accessing restricted functionality.............................................................................................................. Folders accessible by an application................................................................................................................. 2 Managing your application through the application life cycle......................................................................... Understanding the application life cycle.......................................................................................................... Saving the application state.............................................................................................................................. Responding to application deactivation and activation.................................................................................... Respond to deactivation and activation.................................................................................................... Responding to application window state......................................................................................................... Listen for a change in application window state....................................................................................... Responding to low memory conditions............................................................................................................ Respond to low memory conditions.......................................................................................................... Respond to low battery notifications............................................................................................................... Respond to low battery notifications........................................................................................................ 3 ActionScript APIs............................................................................................................................................... 4 Updating Flash Builder...................................................................................................................................... Configure updates for Flash Builder in a Mac environment............................................................................. Configure updates for Flash Builder in a Windows environment..................................................................... Check for updates to the BlackBerry Tablet OS plug-in.................................................................................... 5 Organizing your UI with containers.................................................................................................................. Placing a child component within a container flow.......................................................................................... Aligning a child component within a container flow........................................................................................ Adjusting the size of a child parallel to the container flow............................................................................... Adjusting the size of a child perpendicular to the container flow.................................................................... Docking a child component.............................................................................................................................. Using containers to design a simple layout...................................................................................................... Create a container..................................................................................................................................... Create the orientation handler function................................................................................................... Create and add subcontainers................................................................................................................... Add UI controls.......................................................................................................................................... Adjust the opposite size of UI components............................................................................................... Use spacers to define child layout............................................................................................................. 7 7 7 8 9 12 12 13 13 14 14 15 15 16 16 17 19 20 20 20 20 22 22 23 24 24 25 25 26 27 28 30 31 32

................................................................................................................................ 32 37 38 39 41 42 42 43 44 45 46 47 48 49 51 52 54 56 56 58 59 59 59 60 61 62 63 64 66 67 68 69 70 71 74 74 ................... Create a label button.............................................................................................................................................................. Create a radio button group............................................................................................................................... 7 Displaying data in lists...................................................................................................................... Code sample: Creating a toggle switch....................................................................................................... Removing an item from a list................................. Code sample: Formating the label text for each button state.... Code sample: Creating a custom cell renderer........................................ Code sample: Creating a segmented control................................................ Create a check box................................ Apply a custom cell renderer to a list................................................................................................................................................................................................................................ Create a section tile list....................................................................................................................................................................................................................................................................... Create and populate a DataProvider object for a picker............................................................................. Create a toggle button............................................................................................................................................................................................................................................. Create a segmented control.................................................................................................................................................. Using the Toggleswitch class..............................................................................................................Code sample: Using containers to design a simple layout....................................................................................................................................................................................................... Code sample: Creating a check box............................................................................................................................................................ Code sample: Creating a radio button group.......................................................................................................................................................................................................................... Creating a custom list.............................................................................................. Format the label text for each button state.................... Creating a section tile list....................................................................................................................................................................................................................................................................................................................................................... 6 Choosing a button for your application......... Code sample: Creating a tile list...................................................................................................... Formatting the text on a label button................ Create a custom cell renderer...................... Create a List........ Code sample: Creating a section tile list calendar....................................................................................................................... Adding an item to a list...................................................................................................................................................................................................................... Updating an item in a list.. Create a toggle switch............................................ Code sample: Creating a list.............................................................. Remove an item from a section tile list............................................................................ Code sample: Creating an icon button........................................................................................................................................ Create a SectionDataProvider object........................................................................... Create a tile list.............................................................................................................................................................................................................................................................................................. 8 Using the picker to implement complex lists....................................................

......................................................................... Code sample: Detecting a multitouch gesture event.................................................................................................................................................................................. Code sample: Creating a volume slider.................................................................................... Creating a resource bundle.......................................................................... Code sample: Creating a custom button skin........................................................................... Load a resource bundle............................. Change the default skin of a UI component...................................................................................................................... Create a custom button skin class..................................................................................... 11 Skinning your UI components......................................... Create an activity indicator................................................................................................................................................................................................................. Code Sample: Creating an activity indicator................ 104 104 105 107 108 109 110 112 113 115 115 117 119 120 ........................................ Create a progress bar... Localize an application............................................................................... Code sample: Creating a picker clock.................................................................................................................... Code sample: Detecting a rotation gesture event.............................................................................. Create a volume slider......................... 76 78 79 81 85 85 86 87 88 89 91 91 92 94 94 96 97 98 12 Capturing text input.............................Create a picker...... Respond to an event........................................................................ 10 Capturing variable input with a slider......................................................................................... Update data in a picker............................................................................................................. Create a dialog box............................................................................................................................................................................................................... 102 13 Creating dialog boxes.......................................................................................................................................................................................................................................................................... Code sample: Creating a dialog box. 14 Responding to events and gestures..................................................................... Code sample: Detecting a swipe gesture event................................................................................................................................................... Apply a custom button skin............................ 102 Create a text input field............................................................................................. Customizing buttons in a dialog box......................................................................................................................................................................................................................................... Code sample: Creating a progress bar................................................................................ Code sample: Localizing an application..................................................................................................................................................................................................................................................................................................... Code sample: Creating a picker calendar......................................................................................... 15 Localizing your application and using resource bundles............................................................................................................................................ 9 Providing feedback and activity status to the user.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. Code sample: Creating a percentage bar........................................................................................................................................................................................................................

........ Creating an application that sells digital goods....................................................... Sign your application from the command line............... Code sample: Creating an application that sells digital goods..................................................................................................................................................................................... Sign your application in Flash Builder................................................ Code signing request failed because this file has been previously signed.................................... Configure application signing manually in Flash Builder.................................................................................................................................................................................... 122 16 In App Payments........................................................................................................................... Download an application before you make it available for distribution.................................................... 146 146 147 147 149 150 153 154 155 155 156 156 156 156 157 157 157 .................................................................................................. Initiate a purchase..... Code signing request failed because Application-Development-Mode in Manifest is present and is not set to false..................................................................................................................................................... License models. 124 124 125 125 126 127 128 130 133 135 140 140 140 141 141 141 17 The blackberry-tablet................................................................................................................................................. Testing your application.................................................................................................................... Check for existing purchases.............................................................................................................................................. Creating a sandbox account......................................................................... Code signing request failed because value of Package-Name in Manifest is not allowed......................................................................................................................................................................................................................... Using a proxy server from the command line.........xml file.... Code signing request failed because Package-Author in Manifest is not set to [value]......................Code sample: Loading a resource bundle.................. Application Signing Errors..... Package your application from the command line.............................................................................................................................................................................. Assigning a version number to your application................................................... Retrieve and display a list of digital goods.......................................................................... Distributing digital goods from a content server.................................... Live testing............................................. Registering digital goods with BlackBerry App World................................................................................................................................................................................................................................................................................... Configure application signing through a proxy server in Flash Builder............................................................................................................................................................................................. 143 18 Signing your application............ Configure application signing and create debug tokens using the setup wizard in Flash Builder.......................................................................................................................................................................... Create a class to store the properties for your digital goods........................................................................................................................................................................................................................................... Attempt to rename [value1] to [value2] failed............................ Code signing request failed because Common Name in developer certificate is not [value]...................... Distributing digital goods... Configure application signing from the command line........................................................................................................................................................................................................ Set up the UI.......................................................................................................

.....................................................................................................................................-cskpass and -csjpin must be specified if -register is specified.......................................................................... keytool error: java......................................................................... 175 23 Enable development mode........................... cskpass required................................................................................... Back up code signing keys using Flash Builder................................................................... No manifest...................................................................................................... Server is not responding......................... -register............................................................................................................................................................................................................................................................... 174 22 Retrieving the IP address of the BlackBerry PlayBook tablet................................................................................................................... Missing parameter for [option_name] option....... Restore code signing keys using Flash Builder...........................................io.................................................................................................................................................................................Exception: Key pair not generated.......................................... Create a debug token manually using Flash Builder............................................ alias <author> already exists........................................ Restore code signing keys manually................................ No key name specified........ Configure your application for use with a debug token from the command line............... 157 158 158 158 159 159 159 160 160 160 161 161 161 161 162 162 163 163 168 168 169 170 171 172 172 172 173 173 173 21 Retrieve the PIN of a BlackBerry tablet.....................................p12 <Access is denied>.........................IOException: Incorrect AVA Format..............................................................................................................io.............FileNotFoundException: certificate....... 176 24 Provide feedback.................................................................................................................................................................................................................................................................................................................................................................................. Developer certificate and private key not found in keystore or store password not supplied................. Unable to open BAR file.................... keytool error: java..................................... Only one of -setup............ Default location for code signing keys.......................................................................................................................... 19 Using debug tokens................................................................................................... Import a debug token using Flash Builder...................................... No BAR file or CSJ file specified..... Key associated with [value] not a private key......................................................................................................................... Install a debug token from the command line..................... 20 Backup and restore your code signing keys...................................................................................... Keystore load: store password incorrect......... 177 25 Document revision history............................................................................ Create a debug token from the command line.......................................... Install a debug token using Flash Builder...................................................................................................................................................................... Back up code signing keys manually....................................................................lang.................................... keytool error: java............................................................................................................................ 178 .................................................................................................................................................................................................................................................... Incomplete certificate chain........................................................................... or -verify can be specified..............

..............26 Legal notice....................................................................................... 180 ...................................................

5 mobile profile was developed to provide the critical improvements in performance and reduction in processor usage that were necessary to bring Adobe® Flash® based applications to mobile devices such as smartphones and tablets. These APIs provide some unique UI components and predefined skins and enable you to listen for events specific to the BlackBerry Tablet OS. the BlackBerry Tablet OS offers developers the opportunity to create new and compelling applications and games. Overview of the BlackBerry Tablet OS SDK for Adobe AIR 1 The BlackBerry® Tablet OS SDK for Adobe® AIR® lets you to create applications for the BlackBerry® PlayBook™ tablet. they function as standalone applications. allow your application to access to a richer set of functionality than browser-based applications.adobe. or to simply adapt existing ones to a tablet platform. Developing Adobe AIR applications for BlackBerry Tablet OS The BlackBerry® Tablet OS SDK for Adobe® AIR® allows you to optimize your Adobe AIR applications for the BlackBerry® Tablet OS.5 mobile device profile.Beta Customers Only. Additional ActionScript APIs.com/products/air/. APIs have been added to ActionScript 3. Content and software are subject to change. such as a swipe down event from the top bezel (the touch-sensitive frame around the display area of the screen). save for adjusting the application for the unique screen size of the tablet. Applications developed for this runtime should be fully functional on the BlackBerry PlayBook tablet with no additional development required.0 to allow Flash applications to access some of the functionality that is unique to mobile devices. The Adobe AIR 2. BlackBerry Tablet OS security architecture 7 . This SDK allows you to create Adobe AIR applications that leverage the Adobe AIR 2. Designed specifically to run applications developed using Adobe® Flash® and Adobe® ActionScript®. visit http://www.RIM Confidential and Proprietary Information .5 runtime environment that is built in to the BlackBerry Tablet OS.0 and allow you to develop applications that have the look and feel of native BlackBerry® PlayBook™ tablet applications and take advantage of some of the unique features of the OS. The BlackBerry PlayBook tablet includes the Adobe AIR 2. This SDK provides APIs that extend Adobe® ActionScript® 3. The BlackBerry Tablet OS supports the Adobe AIR 2. The BlackBerry Tablet OS is a multitasking operating system built upon the reliability and power of QNX® Neutrino® RTOS. for use only within the Adobe AIR runtime environment. because they run in the Adobe AIR runtime environment rather than in a plug-in to a web browser. such as access to accelerometer and geolocation information and support for touch and gesture events. For more information about Adobe AIR application development. Adobe AIR applications are built upon Flash and ActionScript technologies commonly associated with web content. which runs the BlackBerry® Tablet OS.5 runtime environment. However.

The kernel can restart a process without negatively affecting other processes. like the GPS receiver.FileStream flash. You should make sure you test your application's behavior for cases when a user denies the application access to a particular capability.xml file. The following table lists values for the action element. users must grant your application access to the functionality. Microkernel operating systems implement the minimum amount of software in the kernel space to manage access to basic computing functions such as CPU access. and the application does not request access to a device capability. By running higher-level services in the user space.Beta Customers Only. see Signing your application. The BlackBerry Tablet OS is designed to verify the authenticity of an application. the authorization manager displays a dialog box that specifies the capability requested. The kernel validates requests for system resources. The following APIs might require this permission if they try to access the shared directory: flash.RIM Confidential and Proprietary Information . and so on. You must specify the device capabilities required for your application by adding one action element per device capability to your blackberry-tablet. To help protect against potentially malicious code. the BlackBerry Tablet OS can manage processes in isolation from each other. the application fails.File 8 . memory management. All applications that run on a BlackBerry® tablet must be signed by the RIM® Signing Authority and a Developer Certificate. a microphone. the BlackBerry Tablet OS does not start. and gives the user the opportunity to grant or refuse access to that capability. All applications run in the user space. Higher-level system services. Accessing restricted functionality The BlackBerry® tablet has functionality that can capture rich information from its environment. when an application requests access to the camera. This helps prevent damage to the kernel and other applications.filesystem. For example. run in the user space. see The blackberry-tablet. Content and software are subject to change.xml file. and so on. If an application uses APIs that access restricted functionality. such as socket communication and device drivers. An authorization manager evaluates requests from applications to access the capabilities of the BlackBerry® tablet. For more information about creating a blackberry-tablet. • The BlackBerry Tablet OS is designed to be secure. • The BlackBerry Tablet OS is designed to be resilient. The kernel performs an integrity test when the OS starts. For more information about accessing the RIM Signing Authority. The microkernel architecture of the BlackBerry Tablet OS enables the following features: • The BlackBerry Tablet OS is designed to be tamper resistant. You can use these values to specify the capabilities and APIs that are that are required by your application: Value access_internet access_shared Capability Access remote resource by using a network connection Access the shared file system API Any API that accesses the Internet. If the integrity test reveals damage to the kernel.filesystem.xml file. The BlackBerry® Tablet OS is a microkernel operating system.

Sound qnx.png</image> </icon> <author>My Company</author> <authorId>gYAAgIqK0RLL5u4I9NanyxBUuCI</authorId> <category>core.xml file <qnx> <icon> <image>my_icon.MediaControl flash.jpg</splashscreen> <action>use_camera</action> <action>read_geolocation</action> <action>play_audio</action> <buildId>349</buildId> <platformVersion>1.Geolocation flash.media. The Adobe AIR API property File. Access the current location of the tablet Access the audio stream from the microphone Access the volume control Access data from one or more cameras Sample blackberry-tablet.media.0.serialNum ber flash.CameraUI qnx. Each application has access to its own working directory in the file system.pin qnx.games</category> <splashscreen>img/spalsh_landscape.system.0</platformVersion> </qnx> Folders accessible by an application The following table contains descriptions of the folders that an application can accesss.Device.Beta Customers Only. and might be able to access the shared folder.jpg:img/splash_portrait.media.media. Value Capability API flash.sensors.media. Content and software are subject to change.0.Microphone qnx.Device.system.CameraRoll flash. 9 .media.Camera flash.MediaControl flash.RIM Confidential and Proprietary Information .CameraUI play_audio read_device_identif ying_information read_geolocation record_audio set_audio_volume use_camera Access the audio controls Access the PIN and serial number of the tablet.media.media.userDirectory maps to the root of the working folder. All path references in your application are relative to the root of the working folder.

An application cannot write to this directory. This folder contains miscellaneous data that can be shared among applications. This folder contains eBook files that can be shared among applications. This folder contains web browser bookmarks that can be shared among applications. data tmp logs shared shared/bookmarks shared/books shared/clipboard shared/documents This folder contains the application's temporary working files. This folder contains system logs for an application. The BlackBerry® Tablet OS might remove these files any time the application is not running. This folder contains subfolders that contain shared data by type.Beta Customers Only. This folder contains documents that can be shared among applications. Folder app Description This folder contains the files that were installed with your application. The Adobe AIR API properties File. The Adobe® AIR® API property File. This folder contains the application's private data.RIM Confidential and Proprietary Information . Your application has readonly access to this folder. Stdin and stdout are redirected to this directory.applicationDirectory maps to the folder app/air. These files were packaged with you BAR file. Content and software are subject to change. This folder contains data copied or cut from another application.applicationStorageDirectory maps to this folder. shared/downloads shared/misc shared/music shared/photos shared/videos shared/voice 10 . This folder contains videos that can be shared among applications. This folder contains music files that can be shared among applications. This folder contains audio recordings that can be shared among applications. The application has full access to read and write files in this folder.documentsDirectory and File. The application should remove these files regularly.desktopDirectory map to this folder. This folder contains photos that can be shared among applications. The Adobe AIR API property File. This folder contains web browser downloads.

11 . Content and software are subject to change.Beta Customers Only.RIM Confidential and Proprietary Information .

when the battery drains. without ever becoming active again. multitasking platform so it can run multiple applications at the same time. When your application loses focus it is not terminated. Understanding the application life cycle The life cycle of an application refers to the stages that an application can move through.RIM Confidential and Proprietary Information . but it may be deactivated and pushed to the background. from the time it is invoked until it is terminated. it can be interrupted when another application opens and replaces yours as the active application. but it is no 12 . Lifecycle stage Application startup Foreground Background Exit Event Event. In its simplest form. The BlackBerry Tablet OS handles low memory conditions by closing idle background applications so it can reclaim memory resources. the application is still running. it could create a low memory situation. runs for a period of time. The events that an application receives can vary if a user changes the Application behavior setting on the tablet. the tablet shuts down and closes all open applications. Content and software are subject to change. the life cycle of your application has three stages: it starts. before the user has closed it).ACTIVATE Event. but is instead deactivated and pushed to the background. if a user has too many applications open. multitasking platform. the BlackBerry Tablet OS notifies the application using the Adobe® AIR® event system. or may be closed by the user. However. The following table lists the default events that the OS sends to an application to indicate a change in the application lifecycle. runs for a period of time.DEACTIVATE when another application receives the foreground Event.EXITING During the application life cycle. When your application loses focus it is not terminated. The life cycle of your application normally has three stages: it starts. and then ends. A background application can reactivated—returned to the foreground—at any time. it is active. when another application opens and replaces yours as the active application.ACTIVATE Event. from the time it is invoked until it is terminated. The BlackBerry® Tablet OS is a multithreaded. Alternatively. For example. It is important to understand the implications of the various states and transitions of the life cycle on your application so that you can respond to them appropriately in your code.Beta Customers Only. The BlackBerry® Tablet OS is a multithreaded. While your application is running and active. it is active. Managing your application through the application life cycle 2 The life cycle of an application refers to the stages that an application can move through. While the application is running in the foreground. When an application needs to move from one stage of the lifecycle to another. It is important to understand the implications of the various states and transitions of the life cycle on your application so that you can respond to them appropriately in your code. While your application is running in the foreground. The application may terminated by the system. it can be interrupted at any time. other events might cause your application to terminate prematurely (that is. and then ends.

it could create a low memory situation. change in application window state. A background application can be reactivated—that is. the application returns to the same condition it was in when it lost focus. the tablet shuts down and closes all open applications. any pertinent information about the current conditions of the application—for example. or any user-entered data—can be saved. or may be closed by the user. for example. You should not assume that the user appropriately saved their activity in your application before the application moves to the background. the screen element currently in focus. The type of information you should save about the application state depends upon the application. A mobile application can experience a number of interruptions during its life cycle—losing application focus. you must first determine what data is necessary for the user to continue when the application is reloaded. When the user returns to the application. a user may leave your application to open another application. you might save the state each time the user completes a level. you can reload the saved state. During the application life cycle. Content and software are subject to change. or occasionally terminated by the system. to decide what data to save and when to save it. In addition. When the OS deactivates your application. even if those changes were not saved manually. without ever becoming active again. It is important that your application listen for these events and respond by saving the application state. In an interactive game.Beta Customers Only. for example. the saved state can be reloaded and the user can then continue on as before. If. such as a driving game. For example. and restart any suspended processes. your application should stop any unnecessary processes (such as updating the UI in real-time) to preserve system resources. and upon the likely expectations of your user. when the battery drains. By default. the NativeApplication object dispatches one of the following events when your application changes its stage in the lifecycle: 13 . returned to the foreground—at any time. For example. in a game application. the user might expect that any text entered would still be available. a user has too many applications open. longer the top application on the stack. you might save much more data about the state of the application. there are memory considerations that your application should account for. The BlackBerry Tablet OS handles low memory conditions by closing idle background applications so it can reclaim the necessary memory resources. low memory events. Responding to application deactivation and activation The BlackBerry® Tablet OS can deactivate your application and move it to the background at any time. before the user has closed it). In addition. and low battery events—that must be managed. It is also wise to save the application state after other significant events. for an e-reader application. In a text editor application or on a settings page. other events might cause your application to terminate prematurely (that is. the user might simply expect to return to the same page of the same book they were reading. Saving the application state Saving the application state ensures that when the user returns to the application. When the OS activates your application again. For example.RIM Confidential and Proprietary Information . you should first save the application state. In each case.

Beta Customers Only. public function onDeactivate(event:Event):void { // Save state // Suspend processes } 4.addEventListener(Event.DEACTIVATE Event. 14 . saving the application state.addEventListener(Event. NativeApplication. Set up event listeners to listen for the Event.nativeApplication.*. NativeApplication. onActivate). Property Event. Define the callback function called when the application regains focus. The IowWindowEvent class defines events that are associated with the change in application window state.nativeApplication. a user may minimize an application to toggle to a new application or close it from the thumbnail view.ACTIVATE Description Dispatched when another application becomes the active application. In addition. public function onActivate(event:Event):void { // Reload state // Restart processes } Responding to application window state The BlackBerry® Tablet OS application window has three states that can be changed at any time. Your application should listen for these changes in application window state and respond accordingly by. 3.ACTIVATE events. 2. you can reload the saved state. Content and software are subject to change. for example. Dispatched when the application becomes the active application. your application should stop any unnecessary processes (such as updating the UI in real-time) to preserve system resources. For example.DEACTIVATE and Event.events. and restart any suspended processes. This function should save the state of the application and stop any unnecessary processes.DEACTIVATE.ACTIVATE. This function should save the reload the state of the application and restarted any processes that were stopped. Respond to deactivation and activation 1. When the OS activates your application again. onDeactivate). Property NORMAL Description The application window is full screen on the device and is active. Import the required classes and interfaces. import flash. Define the callback function called when the application loses focus.RIM Confidential and Proprietary Information .

applications might hold memory unnecessarily if they do not suspend processes when moved to the background. Content and software are subject to change. Set up an event listener to listen for a change in application window state. break. case IowWindowState.NORMAL: trace( "Application is full screen" ).events. This happens when another application is currently full screen. Listen for a change in application window state 1. Property THUMBNAIL HIDDEN Description The application window is a thumbnail on the device and is not active. win.THUMBNAIL: trace( "App is minimized" ). memory intensive applications open and running in the background.WINDOW_STATE_CHANGED.addEventListener(IowWindowEvent.state ) { case IowWindowState. 2. When the system runs low on memory. break. function stateChanged(event:IowWindowEvent):void { switch( win. } } Responding to low memory conditions Low memory conditions occur most often when the user has many. The OS attempts to close the application that been in the background the longest. 15 . The application window is not visible on the device. Import the required classes and interfaces. var win:IowWindow = IowWindow. 3.*. Define a callback function called when the application window state has changed. This happens when a user minimizes the application or is toggling between applications. break.getAirWindow(). the BlackBerry® Tablet OS attempts to reclaim resources by closing background applications.HIDDEN: trace( "App is hidden" ). case IowWindowState.Beta Customers Only. and continues to close applications until it reclaims enough memory for normal system operation. import flash. Alternatively. stateChanged ).RIM Confidential and Proprietary Information .

2.events. Your application should detect whether it was terminated due to low memory. However. public function onLowMemory(event:Event):void { // Save state // Release resources } Respond to low battery notifications 1.LOW_MEMORY.system. This way the user's application data should be preserved if your application is terminated.LOW_MEMORY event.Beta Customers Only. Content and software are subject to change. the QNXApplication class dispatches the QNXApplicationEvent. Set the deviceBatteryMonitoring property to true to access the values for the battery level and state and then initialize the values of the bLevel and bState variables. 3. import qnx.LOW_MEMORY event.RIM Confidential and Proprietary Information . Import the required packages. 16 . If your application receives focus again. From the user's perspective. QNXApplication. public static var bState:int. the application appears to be running in the background. import qnx.events. You should create a listener to process this event. When you receive a LOW_MEMORY event. the user expects to return to the application in the state it was in when it was pushed to the background. 2. Define variables for the battery level and battery state. onLowMemory). Define the callback function called when a low memory event occurs. release resources. it terminates the application's processes and destroys the associated NativeApplication instance. When the user returns the application to the foreground.system. the application window remains in the list of background applications.DeviceBatteryEvent. When the OS tries to terminate an application due to low memory. 3.addEventListener( QNXApplicationEvent. import qnx. the OS restarts the application and creates a new instance of NativeApplication.qnxApplication. public static var bLevel:int. Import the required packages. your application should immediately save state. destroy its objects. Set up an event listener to listen for the QNXApplicationEvent. then load the saved state if appropriate. Respond to low memory conditions 1. import qnx.Device. When the system runs low on memory.

UNPLUGGED || bLevel < 10) { // Save state displayWarning(). public static var bState:int. Device.STATE_CHANGE.system.device. import qnx. onStateChange). bLevel = Device. Define the callback methods for the event listeners. 2. onLevelChange).LEVEL_CHANGE and DeviceBatteryEvent. 3.batteryLevel. import qnx. 5. Device.device. evaluate(). bLevel = Device. Define variables for the battery level and battery state.events. Set up event listeners to listen for the DeviceBatteryEvent. In the following code sample. 17 .batteryState. evaluate().Beta Customers Only. } } Respond to low battery notifications 1.batteryMonitoringEnabled = true. Set the deviceBatteryMonitoring property to true to access the values for the battery level and state and then initialize the values of the bLevel and bState variables.RIM Confidential and Proprietary Information .addEventListener(DeviceBatteryEvent.batteryLevel.device.device.LEVEL_CHANGE.device. Content and software are subject to change. 4.STATE_CHANGE events. the appropriate variable is updated to reflect the new level or state of the battery.batteryState.Device. Import the required packages. } 6. Evaluate the new battery properties and respond as appropriate.device.DeviceBatteryEvent.device. Device. } public function onStateChange(evt:DeviceBatteryEvent):void { bState = evt. public function onLevelChange(evt:DeviceBatteryEvent):void { bLevel = evt.batteryLevel. Device.addEventListener(DeviceBatteryEvent.batteryState.batteryMonitoringEnabled = true.device. public function evaluate() { if( bState == DeviceBatteryState. bState = Device. public static var bLevel:int. bState = Device.

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

4.

Set up event listeners to listen for the DeviceBatteryEvent.LEVEL_CHANGE and DeviceBatteryEvent.STATE_CHANGE events.
Device.device.addEventListener(DeviceBatteryEvent.LEVEL_CHANGE, onLevelChange); Device.device.addEventListener(DeviceBatteryEvent.STATE_CHANGE, onStateChange);

5.

Define the callback methods for the event listeners. In the following code sample, the appropriate variable is updated to reflect the new level or state of the battery.
public function onLevelChange(evt:DeviceBatteryEvent):void { bLevel = evt.batteryLevel; evaluate(); } public function onStateChange(evt:DeviceBatteryEvent):void { bState = evt.batteryState; evaluate(); }

6.

Evaluate the new battery properties and respond as appropriate.
public function evaluate() { if( bState == DeviceBatteryState.UNPLUGGED || bLevel < 10) { // Save state displayWarning(); } }

18

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

ActionScript APIs

3

While the BlackBerry® Tablet OS SDK for Adobe® AIR® extends the Adobe® ActionScript® API in many important areas, you must use the ActionScript 3.0 APIs for data storage, networking, and device sensor functions. The following table lists some resources that you can use to learn more about ActionScript APIs. You must explicitly request permission from your user to use device sensors. For more information, see Accessing restricted functionality. Component Data storage Description The BlackBerry Tablet OS supports the following approaches to data storage • • Local shared object (in the flash.net.SharedObject package) Encrypted local store (in the flash.data.EncryptedLocalStore package) • File system (in the flash.filesystem package) • SQLite® (in the flash.data package) You can use the flash.net package to send and receive data over a network connection. You can use the flash.sensors.Accelerometer class to register an event listener for accelerometer events. The BlackBerry Tablet OS reports movement in three perpendicular planes relative to the device. You can use the flash.sensors.Geolocation class to register an event listener that processes changes in the geoposition of the device. For more information, see Detecting geolocation changes in the ActionScript 3.0 Developer's Guide.

Network communication Accelerometer

Geolocation

For more information, see the ActionScript 3.0 Reference for the Adobe Flash Platform.

19

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Updating Flash Builder

4

Configure updates for Flash Builder in a Mac environment
Before you can upgrade the BlackBerry® Tablet OS SDK plug-in on Mac OS, you need to change an Adobe® Flash Builder® configuration file. The upgrade process reverts the file to its original state when the update is complete. You only need to change the configuration file the first time you upgrade the plug-in. Subsequent upgrades work normally without this task. Before you begin: Close Adobe® Flash Builder® before you edit the config.ini file described in the steps below. 1. 2. In a text editor, open the config.ini file in <Flash Builder Installation Directory>/eclipse/configuration folder. The default location of this file is /Applications/Adobe Flash Builder 4.5/eclipse/configuration/config.ini Put a number sign (#) before the osgi.configuration.area parameter.
#osgi.configuration.area=@user.home/Documents/Adobe Flash Builder 4.5/cascaded/ 308971/configuration

3. 4. 5. 6. 7.

Save the file and exit the text editor. In Adobe Flash Builder, on the Flash Builder menu, click Preferences. In the list of preference categories, expand Install/Update > Available Software Sites. In the list of available software sites, select the BlackBerry Tablet OS update site check box. Click OK.

Configure updates for Flash Builder in a Windows environment
1. 2. 3. 4. In Adobe® Flash Builder®, on the Window menu, click Preferences. In the list of preference categories, expand Install/Update > Available Software Sites. In the list of available software sites, select the BlackBerry Tablet OS update site check box. Click OK.

Check for updates to the BlackBerry Tablet OS plug-in
After you enable the update site in Adobe® Flash Builder®, you should see it in the list of available software update sites. If it does not appear in the list of update sites, you should add it manually. The update site is located at http:// www.blackberry.com/go/eclipseupdate/flashbuilder4.5 Before you begin: Register for access to the BlackBerry Developer Zone. 1. 2. In Adobe® Flash Builder®, on the Help menu, click Install New Software. On the Available Software screen, in the Work with drop-down list, click BlackBerry Tablet OS update site.

20

9. On the Software Updates window. click Restart Now. Content and software are subject to change. enter your BlackBerry Developer Zone login information. On the Review Licenses screen. expand the BlackBerry Tablet OS Support item. click Next. Select the BlackBerry Tablet OS Plugin for Adobe Flash Builder item. 21 . Click Next. 4. On the Security Warning window. 7. On the Login required window. Click Next. 5.RIM Confidential and Proprietary Information . 8. accept or decline the license agreements. 3. click OK or Cancel. Click OK.Beta Customers Only. 6. If the list of available software is populated. On the Install Details screen.

you must understand the following concepts: • Placing a child component within a flow • Aligning a child within a flow • Adjusting the size of a child parallel to the container flow • Adjusting the size of a child perpendicular to the container flow • Docking a child component Placing a child component within a container flow Container flow is the layout orientation and direction of all child components relative to the near edge of the parent container. or side by side within the container. called subcontainers. In a container with a vertical flow. size.Beta Customers Only.The flow position is the position of a child component within the flow of a parent container. If a container uses a vertical flow (ContainerFlow. In a container with a horizontal flow.The mySub container is show below.RIM Confidential and Proprietary Information . To understand how child components are arranged and sized within a parent container. such as when the user switches from portrait to landscape mode. the near edge is the top edge of the container. A parent container refers to any container that contains one or more subcontainers. and layout of any UI component that it contains. A container can also Containers are also useful for resizing and laying out child components to respond to orientation changes. If a parent container's flow property is set to ContainerFlow. A container can define two flow directions: vertical and horizontal. 22 . An orientation change occurs when the user tilts the device. the container's children (which may also be containers) will appear horizontally opposed.VERTICAL) all subcomponents within this container will appear vertically-opposed. Content and software are subject to change. 5 You can use the Container class to create a container to organize the UI components of your application. the near edge is the left edge of the container.HORIZONTAL. or one on top of another. A child container refers to any container that is nested within a parent container. The Container class handles the positioning. Organizing your UI with containers contain other containers.

Beta Customers Only. relative to the left edge of the container. such that the top-most component in a container is the component that is first added to the container.FAR property to place a subcomponent furthest from the initial edge of the parent container. In a container with a horizontal flow. 23 . You can specify the ContainerAlign. The ContainerAlign. the align property specifies the vertical position (y coordinate) of the subcomponent relative to the top edge of the container.NEAR property to place a subcomponent closest to the initial edge of a parent container.MID value is the default. Content and software are subject to change. The following figure illustrates each align property in a single container.You can define the opposite position of a child by setting the align property of the parent container. The align property has the following values: • ContainerAlign.FAR Each value represents a position relative to the initial edge of the container. the align property specifies the horizontal position (x coordinate) of the subcomponent.MID • ContainerAlign.RIM Confidential and Proprietary Information . In a container with a vertical flow. The align property determines the alignment of each subcomponent in the direction opposite to the flow of the container. You can specify the ContainerAlign. Components appear in the order in which you add them to a container. You can use the container's padding property to set the amount of space (in pixels) between each subcomponent. This is always true unless a component is docked.NEAR • ContainerAlign. Aligning a child component within a container flow The opposite position refers to the position of a child in the direction opposite to the flow of the container.

For example. or the width of a button in a parent container with a vertical flow. Otherwise. Adjusting the size of a child perpendicular to the container flow Opposite size refers to the size of a child in the direction opposite to the flow of the parent container.Beta Customers Only. Adjusting the size of a child parallel to the container flow Flow size refers to the size of a child component in the direction of the flow of the parent container. or the width of a button in a container with a horizontal flow. the child component's flow size is not changed during layout operations. the height of a button in a container with a vertical flow.RIM Confidential and Proprietary Information . Content and software are subject to change.size property is not 0. The container sets the flow size for a child only if the child implements IContainable and the child's IContainable. the height of a button in the container with a horizontal flow. 24 . For example.

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

The parent container will only resize a child component in the opposite direction if the child implements IContainable and IContainable.sizeMod is set to SizeMode.BOTH. When SizeMode.BOTH is set, any container alignment settings are ignored, and the opposite size for a child is set to fill the available remaining container space in the opposite direction. For an example of a component that implements opposite size, see Adjust the opposite size of UI components The following illustration shows the opposite size and flow size of subcomponents as it relates to the flow direction of a parent container.

Docking a child component
You can dock a child component to anchor it adjacent to any edge of the parent container. If a component implements IContainment, you can set its containment property to dock it to any edge of the stage. When a resize event occurs, all docked components are laid out first, in the order in which they are added to the parent. The remaining child objects are placed in the remaining container space.

Using containers to design a simple layout
You can use a simple hierarchy of parent and child containers to design an effective layout for your application. Creating an application layout that uses multiple containers and basic UI controls involves the following tasks: • • • • • • Create a container Create the orientation handler function Create and add subcontainers Add UI components Adjust the opposite size of UI components Use spacers to define child layout
25

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

The complete application is shown below. The sample application uses four simple containers, and some basic UI controls to define a wizard-like application layout:

Refer to Code sample: Using containers to design a simple layout for the complete sample application.

Create a container
You can create a single main container to hold all other UI components. In this task, you define the main container and add it to the stage. 1. Import the required classes.
import import import import import import import import import import flash.display.Sprite; flash.events.Event; flash.text.TextFieldAutoSize; flash.text.TextFormat; qnx.ui.buttons.LabelButton; qnx.ui.core.* qnx.ui.data.DataProvider; qnx.ui.listClasses.List; qnx.ui.text.Label; qnx.ui.text.TextInput;

2.

Add the following statement to your class, directly before the class signature. This statement sets the stage width and height, the frrate, and the background color of your application.
[SWF(height="600", width="1024", frameRate="30", backgroundColor="#FFFFFF")]

3.

Create an application framework by extending Sprite.
class ContainerTest extends Sprite {

4.

Create the main container variable.
private var myMain:Container;

26

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

5.

Create a constructor for your class, and invoke initializeUI().
public function ContainerTest() { initializeUI(); }

6.

Create the function initializeUI. The initializeUI function sets up the UI components that are used by the application.
private function initializeUI():void {

7.

In the initializeUI function, instantiate the main container.
myMain = new Container();

8.

In the initializeUI function, set the debug color to a hexadecimal color value. The debugColor property is useful for visualizing the bounds of each container while you develop your application. Each container can use a different color value to allow you to tweak the details of the layout.
myMain.debugColor = 0xFFCC00;

9.

A component will only overlap a margin if the container runs out of space. The margin values are specified using literals, however, it's a good idea to use variables to allow you to change a container's margins at run time. The myMain container's flow property is set to ContainerFlow.HORIZONTAL to specify that the container's children (which may also be containers) will appear horizontally-opposed, or side-by-side within the container.
myMain.margins = Vector.<Number>([20,20,20,20]); myMain.flow = ContainerFlow.HORIZONTAL;

In the initializeUI function, set the margins and the flow for the container. The margins property takes a Vector of four numbers indicating, in order, margins for the left, top, right, and bottom edges of the container.

10. In the initializeUI function, add the container to the stage.
} addChild(myMain);

}

Create the orientation handler function
When the user re-orients the device by switching from landscape mode to portrait mode, the StageOrientationEvent.ORIENTATION_CHANGE system event is dispatched and the stage.width and stage.height device properties are swapped. You must set up an event listener to capture the StageOrientationEvent.ORIENTATION_CHANGE event in order to rotate and resize your application. In this task, you create an event listener and a function to handle device orientation changes. Before you begin: Create a container 1. Import the required classes

27

the onReorient function is called. onReorient(new StageOrientationEvent(StageOrientationEvent. create an event listener to handle stage events. The handleAddedToStage function creates an event listener to listen for reorientation events that occur whenever the user changes the orientation of the device. The handleAddedToStage function then explicitly calls the onReorient function. handleAddedToStage). Create the onReorient function and add the call to setSize.display.stageHeight). 28 .handleAddedToStage). This function is called by the event listener every time an item is added to the stage.stageWidth.StageOrientationEvent. stage. Call this method only after each container and each subcomponent is defined and added to the display list. addEventListener(Event. an event is dispatched whenever a UI component is added to the stage.display. private function onReorient(event:StageOrientationEvent):void { myContainer.true)). as shown in the diagram. import flash. The setSize method calls the layout function which adjusts the layout of the subcomponents according to the properties that are defined by each parent container. Otherwise. This task demonstrates how to add three subcontainers. stage. import flash. stage. Each subcontainer can use a distinct debug color. private function handleAddedToStage(e:Event):void { removeEventListener(Event.align = StageAlign. stage. onReorient).scaleMode = StageScaleMode. the call will have no effect. } Create and add subcontainers You can add multiple subcontainers to a parent container.ADDED_TO_STAGE.RIM Confidential and Proprietary Information . When an StageOrientationEvent.Beta Customers Only.events. 4.TOP_LEFT.StageAlign.ORIENTATION_CHANGE event is detected.ADDED_TO_STAGE.NO_SCALE. Create the handleAddedToStage. import flash.addEventListener(StageOrientationEvent. } 3. In the code sample below.StageScaleMode. 2. In the constructor for your class.ORIENTATION_CHANGE.ORIENTATION_CHANGE. Content and software are subject to change.true.setSize(stage.

mySubRight.padding = 10.<Number>([10. mySubRight. mySub.PIXELS. 29 .size = 50. create the first subcontainer: mySub. mySubRight = new Container(). In the initializeUI function.The mySubRight subcontainer takes up the right-side of the stage.NEAR.VERTICAL.debugColor = 0xFF3300.40]).align = ContainerAlign.10.VERTICAL.VERTICAL) meaning that all components within this container will appear vertically. mySub. and mySubBottom. In the body of the class. Before you begin: Create the orientation handler function 1.flow = ContainerFlow.size = 50.Beta Customers Only.10]). mySubRight. mySub. 2. Content and software are subject to change. private var mySub:Container.PERCENT.PERCENT indicating that mySub will take up 50% of the main container.sizeUnit = SizeUnit.align = ContainerAlign. add the variables for three subcontainers: mySub. mySubRight. In the initializeUI function.margins = Vector.sizeUnit = SizeUnit. mySubRight. size is set to 50 and sizeUnit is set to SizeUnit.debugColor = 0x0033FF. The size and sizeUnit properties determine the size of the subcontainer. mySub. mySub. mySub. mySubRight. private var mySubRight:Container.MID. private var mySubBottom:Container.20. mySub = new Container().PERCENT. mySubRight. The mySub container uses a vertical flow (ContainerFlow.padding = 10. create the second subcontainer: mySubRight. 3.40.margins = Vector. In the following code sample. mySubRight. mySub.RIM Confidential and Proprietary Information .<Number>([20.flow = ContainerFlow. The default value of sizeUnit is SizeUnit.10.

mySubBottom. mySubBottom.size = 12. mySubBottom. or you can specify that the component is not repositioned by the parent container (Containment.RIM Confidential and Proprietary Information . You can dock a subcomponent to any of the four edges of a container. private var leftButton:LabelButton.margins = Vector.5. In the initializeUI function.UNCONTAINED). firstLabel.DOCK_BOTTOM. firstLabel = new Label(). create the third subcontainer: mySubBottom. The third subcontainer.addChild(mySubBottom). myMain. private private private private var var var var firstLabel:Label. Set the containment property to Containment. In the initializeUI function.5]). create and add the UI components. In the body of the class.size = 22.<Number>([5. Docked children are handled first in layout operations. 4. mySubBottom. mySubBottom.debugColor = 0x33FF33.addChild(mySubRight). private var firstInput:TextInput.sizeUnit = SizeUnit. 30 . 2.DOCK_BOTTOM. In the initializeUI function.5. It is positioned first leaving the remainder of the stage for the other two subcontainers.containment = Containment. myMain.flow = ContainerFlow.addChild(mySub). myMain.Beta Customers Only. but not positioned. labelFormat. in the background of the stage (Containment. labelFormat = new TextFormat().format = labelFormat. 1.HORIZONTAL. mySubBottom. Before you begin: Create and add the subcontainers. thirdLabel:Label. The mySub and mySubRight containers are added to the stage first. private var rightButton:LabelButton. secondLabel:Label. Content and software are subject to change. add the UI control variables. mySubBottom = new Container(). 5. fourthLabel:Label.text = "First label". var labelFormat:TextFormat = new TextFormat(). firstLabel.align = ContainerAlign. Add UI controls You can add UI controls to each of the subcontainers. mySubBottom is added and docked to the bottom of the main container.BACKGROUND).PERCENT.FAR. add the subcontainers to the main container. mySubBottom.

size=35.LEFT.RIM Confidential and Proprietary Information .LEFT.PERCENT.BOTH for its SizeMode property.addChild(new Spacer(60)). thirdLabel = new Label(). mySub. secondLabel. Before you begin: Add UI controls 1. create and add the mySubRight subcontainer's UI components. In the initializeUI function. In the initializeUI function. secondLabel. thirdLabel. secondLabel.size=35. fourthLabel.Beta Customers Only.format = labelFormat.autoSize = TextFieldAutoSize.PERCENT.format = labelFormat.addChild(secondLabel). mySubRight. Content and software are subject to change. fourthLabel.PIXELS.addChild(firstLabel). thirdLabel. fourthLabel = new Label(). thirdLabel. mySubRight.sizeUnit = SizeUnit. firstLabel.size=35.autoSize = TextFieldAutoSize. secondLabel. the Back button will expand vertically (if the container uses a horizontal flow) to fill the space in the container. firstInput. fourthLabel. mySub. create a button.text = "Second label".addChild(thirdLabel). mySubRight.sizeUnit = SizeUnit. In the following code sample.width = 200. Adjust the opposite size of UI components You can adjust the opposite flow size of a UI control by setting the SizeMode property. 3.sizeUnit = SizeUnit. The spacer provides padding above the label. 31 .sizeUnit = SizeUnit. thirdLabel. After a layout call.format = labelFormat. firstLabel. the Back button specifies SizeMode. Add a spacer to the container before the first label is added.autoSize = TextFieldAutoSize.width = 200. fourthLabel.PERCENT.text = "Third label". secondLabel. firstLabel. firstInput = new TextInput.text = "Fourth label:".LEFT.size=30.addChild(firstInput). mySub. thirdLabel.addChild(fourthLabel). fourthLabel. secondLabel = new Label().

invisible component that adds space between components.size = 100. Use spacers to define child layout You can use spacers to position UI components in the direction of the flow of the parent container. In the initializeUI function. leftButton. The spacer. leftButton.PIXELS. rightButton = new LabelButton(). In the following example. the spacer's size property is set to 100. 3.Beta Customers Only. Add a button to the container.label = "Next". Add another button. rightButton. 4. 2.size = 100. the Next button does not specify the SizeMode property.SizeUnit. until another component is added. mySubBottom.addChild(rightButton). A spacer is a simple. Specify a size for the component (using the size property) to resize the component when a layout call occurs. mySubBottom.label = "Back". the spacer pushes all other components to the right-edge of the container. is set to three pixels in size.addChild(new Spacer()). rightButton. By default. Content and software are subject to change.RIM Confidential and Proprietary Information . Add another spacer to the container. add a spacer to a container. Before you begin: Adjust the opposite size of UI components 1. leftButton. 2.addChild(leftButton). In the following example. leftButton. mySubBottom. leftButton = new LabelButton().BOTH. mySubBottom.PIXELS)).sizeMode = SizeMode.sizeUnit = SizeUnit.PERCENT indicating that the spacer will take up the entire container flow.addChild(new Spacer(3. This button will not resize after a layout call. Code sample: Using containers to design a simple layout The following code listing builds the sample container layout application below: 32 . which is instantiated when it is added to the container. and the SizeUnit property is set to SizeUnit.

ui. backgroundColor="#FFFFFF")] // A simple container layout example public class ContainerTest extends Sprite { //containers private var myMain:Container.ui.core. qnx.Containment.SizeUnit.LabelButton.events.ui.ContainerFlow.events.Label. flash.RIM Confidential and Proprietary Information .text. width="1024".Event. qnx.Sprite.ui.StageOrientationEvent. qnx.ui.ui.display.ui.SizeMode. private var mySubBottom:Container. qnx. 33 . //Orientation Handler import flash. import flash. import flash. qnx.ContainerAlign.data.TextFormat.StageAlign. qnx.ui. qnx. qnx. Content and software are subject to change.StageScaleMode. frameRate="30".text.ui.listClasses. qnx. qnx.display.ui.display.text.core.Spacer.core.core.text.core.TextFieldAutoSize.Beta Customers Only.core.DataProvider. private var mySub:Container. qnx.Container. qnx. flash.ui. [SWF(height="600". private var mySubRight:Container.core.List.TextInput. package { import import import import import import import import import import import import import import import import flash.buttons.ui. flash.

onReorient).20. private var fourthLabel:Label.40. myMain. private var thirdLabel:Label.TOP_LEFT.ORIENTATION_CHANGE.VERTICAL. myMain.<Number>([20. mySub.Beta Customers Only.ORIENTATION_CHANGE.20.margins = Vector.margins = Vector.40]). private var secondLabel:Label. // create subcontainer on left side of the screen mySub = new Container().true.20]).scaleMode = StageScaleMode. //the left-side of the screen labels private var firstLabel:Label. //text input for second sub container private var firstInput:TextInput. // force a reorientation call onReorient(new StageOrientationEvent(StageOrientationEvent. private var myDP:DataProvider.debugColor = 0xFF3300. // back and next buttons private var leftButton:LabelButton.HORIZONTAL.true)).debugColor = 0xFFCC00. mySub.align = StageAlign.padding = 10.handleAddedToStage). mySub. // stage is available. private var myList:List.NO_SCALE. stage.addEventListener(StageOrientationEvent. Content and software are subject to change. 34 . myMain.20. we can now listen for events stage. private var rightButton:LabelButton. addChild(myMain). mySub.size = 50. initializeUI().handleAddedToStage). public function ContainerTest() { addEventListener(Event.RIM Confidential and Proprietary Information .flow = ContainerFlow.ADDED_TO_STAGE. mySub. } private function handleAddedToStage(e:Event):void { removeEventListener(Event.flow = ContainerFlow.ADDED_TO_STAGE. } private function initializeUI():void { // create main container myMain = new Container(). stage.<Number>([20.

PERCENT. secondLabel.<Number>([10. secondLabel.margins = Vector.addChild(mySubBottom).addChild(mySubRight).10.size=35. Content and software are subject to change.5. mySubRight.addChild(mySub).DOCK_BOTTOM.debugColor = 0x33FF33. secondLabel. secondLabel = new Label(). mySubRight. // add subcontainers to main container myMain.10.size=35.size = 12. mySub. mySub.PERCENT. mySub.sizeUnit = SizeUnit.addChild(secondLabel). mySubRight.margins = Vector.size = 22. mySubRight.align = ContainerAlign.padding = 10.sizeUnit = SizeUnit. secondLabel. mySubRight.5.sizeUnit = SizeUnit. // create second subcontainer on left side of the screen mySubRight = new Container().<Number>([5. firstLabel.LEFT. firstLabel. mySub. firstLabel.align = ContainerAlign.MID.sizeUnit = SizeUnit. thirdLabel. thirdLabel = new Label().FAR.PERCENT.sizeUnit = SizeUnit.format = labelFormat. mySubBottom. firstLabel.debugColor = 0x0033FF. myMain.format = labelFormat.PERCENT. // create and add UI components to the left container var labelFormat:TextFormat = new TextFormat().align = ContainerAlign.size=35.sizeUnit = SizeUnit.size = 50. thirdLabel. secondLabel.autoSize = TextFieldAutoSize.RIM Confidential and Proprietary Information . mySubRight. thirdLabel. 35 . mySubBottom.flow = ContainerFlow. mySubBottom.text = "First label".LEFT. firstLabel. myMain. firstLabel = new Label().autoSize = TextFieldAutoSize. labelFormat.NEAR. // create subcontainer as the bottom frame mySubBottom = new Container(). mySubBottom. mySubBottom.Beta Customers Only.format = labelFormat. mySubBottom.5]).PERCENT.10]).text = "Second label". mySubBottom.flow = ContainerFlow. thirdLabel. mySubRight.HORIZONTAL.containment = Containment.PERCENT.text = "Third label".addChild(firstLabel).VERTICAL.

format = labelFormat.stageHeight).addChild(thirdLabel).sizeMode = SizeMode. leftButton.size = 100. mySubRight.autoSize = TextFieldAutoSize. // create and add UI components for right side firstInput = new TextInput. stage.PIXELS. firstInput.label = "Back".addChild(new Spacer(3.addChild(firstInput).BOTH. mySubRight. leftButton.label = "Next". rightButton = new LabelButton().stageWidth. rightButton. fourthLabel. mySubBottom. fourthLabel.size=30. } 36 .PIXELS)).addChild(leftButton). fourthLabel.Beta Customers Only.LEFT.addChild(fourthLabel).RIM Confidential and Proprietary Information .SizeUnit.width = 200.sizeUnit = SizeUnit.setSize(stage. } } } private function onReorient(event:StageOrientationEvent):void { myMain. // add spacer then button then spacer then button mySubBottom. Content and software are subject to change.addChild(new Spacer()).addChild(new Spacer(60)).size = 100. // create and add back and next buttons leftButton = new LabelButton(). mySubBottom. fourthLabel.text = "Fourth label:". mySubRight. fourthLabel.sizeUnit = SizeUnit. fourthLabel = new Label(). mySubBottom. thirdLabel.width = 200. leftButton.PIXELS. rightButton.addChild(rightButton). mySub. leftButton.

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Choosing a button for your application
The BlackBerry Tablet OS SDK API provides the following button types: Class
Button

6

The BlackBerry® Tablet OS SDK API Reference contains a variety of button implementations. Each implementation is skinnable and customizable.

Image

Description The Button class is the most basic button type and the base class for all buttons. The BackButton class is a simple button that contains a back arrow. You can use this button to provide navigation in your application. The CheckBox class is a simple check box implementation. The IconButton class is a button that contains an icon. The LabelButton class is button that contains a String. The RadioButton class is a simple radio button implementation. The radio button remains in the selected state when pressed. The listener for the RadioButton runs when a button is selected.

BackButton

CheckBox IconButton

LabelButton

RadioButton

SegmentedControl

The SegmentedControl class is a group of interconnected radio buttons that force the user to select a single option from a group or related choices.

37

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Class
ToggleSwitch

Image

Description The ToggleSwitch class is a simple toggle switch implementation where the switch can be dragged along a track from one state to another.

Create a toggle button
You can use the toggle property to create a simple toggle button. When the toggle property is set to true, the button maintains the down state when pressed. When the button is pressed again, the button is released and returns to the up state. 1. Import the required classes.
import flash.display.Sprite; qnx.ui.Buttons.Button;

2.

Add the following statement to your class, directly before the class signature. This statement sets the stage width and height, the frame rate, and the background color of your application.
[SWF(height="600", width="1024", frameRate="30", backgroundColor="#FFFFFF")]

3.

Create an application framework by extending Sprite.
class MyToggle extends Sprite {

4. 5.

In the body of the class, create a variable.
var myButton:Button;

Create a constructor for your class and invoke initializeUI()
public function MyToggle() { initializeUI(); }

6.

Create a function called initializeUI to set up the toggle switch control.
private function initializeUI():void {

7.

In the initializeUI function, set the position and size of the button. The setPosition method takes the x and y position of the button, in pixels. The setSize method takes the width and height settings, in pixels.
myButton = new Button(); myButton.setPosition(200, 200); myButton.setSize(100, 50);

8.

In the initializeUI function, set the toggle property to true.
myButton.toggle = true;

38

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

9.

In the initializeUI function, add an event listener for the click event.
myButton.addEventListener(MouseEvent.CLICK, myButtonEvent);

10. In the initializeUI function, add the button to the stage.
} this.addChild(myButton);

11. Create the myButtonEvent function. In the following code sample, a trace is sent to the console indicating that the button has been pressed. The myButton.selected property is called to return the state of the button. When the button is in the down state (when it has been clicked) the selected property returns true.
function myButtonEvent(event:MouseEvent):void { trace ("myButton has been clicked, current toggle state is:" + myButton.selected); } }

Create a check box
1. Import the required classes.
import flash.display.Sprite; import flash.events.MouseEvent; import qnx.ui.buttons.CheckBox; import qnx.ui.buttons.LabelButton;

2.

Add the following statement to your class, directly before the class signature. This statement sets the stage width and height, the frame rate, and the background color of your application.
[SWF(height="600", width="1024", frameRate="30", backgroundColor="#FFFFFF")]

3.

Create an application framework by extending Sprite.
class CheckBoxSample extends Sprite {

4.

In the body of your class, create the instance variables.
private var myCheckBox:CheckBox; private var myButton:LabelButton; private var myText:TextInput;

5.

Create a constructor for your class and invoke initializeUI().
public function CheckBoxSample() { initializeUI(); }

6.

Create the initializeUI function to set up and initialize the UI controls.

39

addEventListener(MouseEvent. In the initializeUI function. In the initializeUI function. create the LabelButton and add it to the stage.addChild(myText). 10. add the check box to the stage. In the initializeUI function.setPosition(175. myCheckBox = new CheckBox(). this. this. 13. myText. } this. 11. myCheckBox. The event listener will call the disableButton function whenever the user clicks the check box. myCheckBox.label = "Disable login". myCheckBox.labelPlacement = LabelPlacement. create and position the check box. disableButton). myButton.Beta Customers Only. myCheckBox = new CheckBox(). the label is placed directly above the CheckBox instance. set the LabelPlacement property. myButton. private function initializeUI():void { 7. myCheckBox.label = "Login". 300).width = 150.width = 100.addChild(myCheckBox).addChild(myButton). create the text input field and add it to the stage. myCheckBox. Content and software are subject to change. 300). In the initializeUI function. 40 .TOP. You must specify a width value or the check box will not render. set the label for the check box. 250). myButton = new LabelButton(). In the code sample below.CLICK. myText = new TextInput(). 8. The label property takes a String. The labelPadding property takes an integer to specify the number of pixels between the check box and the label.width = 150. In the initializeUI function.setPosition(175. add an event listener to trap mouse click events. 12. The width property is mandatory. myCheckBox. In the initializeUI function. In the initializeUI function.RIM Confidential and Proprietary Information .setPosition(128. myText. This label button is disabled when the user selects the check box. myButton. myButton = new LabelButton(). 9.labelPadding = 5. For a check box. the width property sets the width for both the check box and the text label.

} private function initializeUI():void { myCheckBox = new CheckBox().setPosition(175.LabelButton. myButton.ui. myCheckBox. 41 . disableButton). the disableButton function is called and the enabled property for the myButton and myText buttons are toggled. myCheckBox.events. this. 14. function disableButton(event:MouseEvent):void { myButton. myText.enabled. myCheckBox. backgroundColor="#FFFFFF")] public class CheckBoxSample extends Sprite { private var myCheckBox:CheckBox. Create the disableButton function.addChild(myCheckBox). 350). private var myButton:LabelButton.label = "Login".setPosition(128.addEventListener(MouseEvent.label = "Disable login".ui. qnx. qnx.width = 200.TOP.width = 100.ui.CheckBox.Beta Customers Only. myButton.enabled. this.RIM Confidential and Proprietary Information .MouseEvent. myButton.labelPadding = 5. myCheckBox. width="1024".labelPlacement = LabelPlacement.LabelPlacement. package { import flash.CLICK. frameRate="30". myCheckBox. import import import import qnx. [SWF(height="600".display.addChild(myButton). 300). When the user clicks the check box. qnx. myCheckBox.Sprite.buttons. private var myText:TextInput.buttons.TextInput. public function CheckBoxSample() { initializeUI().ui.enabled = !myButton.text.enabled = !myText. import flash.buttons. Content and software are subject to change. } } Code sample: Creating a check box The following code sample uses a CheckBox object to disable a button and text input field. myButton = new LabelButton().

IconButton.buttons. myText. public function IconButtonTest() { initializeUI(). width="1024". backgroundColor="#FFFFFF")] public class IconButtonTest extends Sprite { private var myIconButton:IconButton. [SWF(height="600". } myText = new TextInput().enabled = !myButton. Content and software are subject to change.RIM Confidential and Proprietary Information . } private function initializeUI():void { var myIconButton:IconButton = new IconButton(). myIconButton.Beta Customers Only. 250).enabled = !myText. In the code sample below. private function disableButton(e:MouseEvent):void { myButton. } this. 42 Import the required classes.gif"). myIconButton.width = 150. myIconButton./assets/icon. } } } Code sample: Creating an icon button The following code sample describes how to create an icon button. The image asset is located in the src/assets folder in the project. import qnx. 30).addChild(myIconButton).setPosition(175.ui.setIcon(". .enabled..addChild(myText).width = 100. } } Create a label button 1. myText. myText.Sprite.setPosition(30.enabled. this. package { import flash. frameRate="30".display. the setIcon method is called to place an icon on a button.

and because button states typically supply unique skins for each state. You must set the width of the button according to the length of the text. Create a constructor for your class and invoke initializeUI(). the frame rate. width="1024". myButton. myButton = new LabelButton(). Add the following statement to your class. import flash.RIM Confidential and Proprietary Information . import qnx. } Formatting the text on a label button You can format the label text on a button by applying a TextFormat object to a button.addChild(myButton). create and set up the button. In the initializeUI function. [SWF(height="600". Create the initializeUI function to set up and initialize the UI controls. For more information about applying a format object to a label. public function LabelButtonSample() { initializeUI(). You can use a TextFormat object to apply formatting to the label text.Sprite.setPosition(175. You can accomplish this by calling the setTextFormatForState method and specifying a TextFormat object and a button state. } 5.display. Create an application framework by extending Sprite. This is the text that appears on the button. class LabelButtonSample extends Sprite { 4. Content and software are subject to change. 7. frameRate="30".label = "Login".Beta Customers Only. 43 .ui. myButton. var myButton:LabelButton. This statement sets the stage width and height.width = 100. add the button to the stage. otherwise the label will overrun the bounds of the button. The label property takes a String. 300). you must create and apply a TextFormat object to each button state. { private function initializeUI():void 6. directly before the class signature. Because a button has multiple states (one for each user-interaction). see Format the label text for each button state.LabelButton. and the background color of your application. In the initializeUI function. 2. } this.buttons. myButton. backgroundColor="#FFFFFF")] 3.

Content and software are subject to change. formatDown. In the initializeUI function. down.SkinStates. This statement sets the stage width and height. format.color = 0xcc0000.size = 16. frameRate="30". Add the following statement to your class. 44 . formatDown. class LabelButtonStatesSample extends Sprite { 4.size = 16.TextFormat.font = "Myriad Pro".skins. var formatDown:TextFormat = new TextFormat(). create an instance of the TextFormat object for the disabled button state. flash.font = "Myriad Pro". Create a constructor for your class and invoke initializeUI() public function LabelButtonStatesSample() { initializeUI(). Format the label text for each button state The following task demonstrates how to create a TextFormat object for the up. and disabled button states and how to use the setTextFormatForState method to apply the TextFormat object to each button state. create an instance of the TextFormat object for the down button state. and the background color of your application. width="1024". In the initializeUI function. import import import import import flash. [SWF(height="600".CENTER.display. Create the initializeUI function to set up and initialize the UI controls. In the following code sample. formatDown.text. The default skin color for the down state is blue. In the following code sample. } 5. qnx. Create an application framework by extending Sprite. 7. format. create an instance of the TextFormat object for the up button state.align = TextFormatAlign. the font color is set to white. the font color is set to red. In the initializeUI function.Sprite.buttons.color = 0xFFFFFF. 2. Import the required classes.TextFormatAlign.align = TextFormatAlign. 1. formatDown. flash. var format:TextFormat = new TextFormat().CENTER.ui. 8. the font color is set to dark grey.RIM Confidential and Proprietary Information . The default skin color for the down state is grey. format. private function initializeUI():void { 6. The default skin color for the up state is grey.ui. format. backgroundColor="#FFFFFF")] 3. In the following code sample.text.LabelButton. directly before the class signature. qnx.Beta Customers Only. the frame rate.

formatDisable. 12. frameRate="30". 9.setTextFormatForState(format. In the initializeUI function. The setTextFormatForState matches the TextFormat object with the button state.LabelButton. qnx. qnx.TextFormat. } this. call the setTextFormatForState for each button state. flash. add the button label and position the button on the stage.align = TextFormatAlign.DISABLED).SkinStates. } private function initializeUI():void { // create a text format for up. 10.color = 0xCCCCCC. flash.text.SkinStates.CENTER.addChild(myButton).buttons.font = "Myriad Pro".DOWN). myButton. down.display.Sprite.size = 16. formatDisable. formatDisable. myButton.UP). only the up.setTextFormatForState(formatDisable.ui. [SWF(height="600". formatDisable. 11. In the initializeUI function.TextFormatAlign. var myButton:LabelButton = new LabelButton().text. and disabled button states are assigned unique TextFormat objects. In the code sample.skins. selected.label = "OK".SkinStates. In the initializeUI function. var formatDisable:TextFormat = new TextFormat().ui. package { import import import import import flash. disabled. myButton. } Code sample: Formating the label text for each button state The following code sample describes how to apply a TextFormat object to each button state. myButton. // red label text 45 . Content and software are subject to change.setTextFormatForState(formatDown.Beta Customers Only. In the initializeUI function. The other button states are not implemented.RIM Confidential and Proprietary Information . add the button to the stage. myButton. create a LabelButton instance.x = 175.SkinStates. etc. width="1024". backgroundColor="#FFFFFF")] public class LabelButtonSample extends Sprite { public function LabelButtonStatesSample() { initializeUI().

font = "Myriad Pro".setTextFormatForState(format.color = 0xCCCCCC.SkinStates. formatDown.align = TextFormatAlign.font = "Myriad Pro". myButton. format.DISABLED). 46 .setTextFormatForState(formatDisable. // set the formats for each state you want to address myButton. var myButton:LabelButton = new LabelButton(). // create a text format for the down state // white label text var formatDown:TextFormat = new TextFormat().RIM Confidential and Proprietary Information .color = 0xFFFFFF. myButton.size = 16. format.SkinStates.CENTER.x = myButton. formatDisable. Content and software are subject to change.size = 16. In the following illustrations.size = 16. formatDisable.SkinStates.Beta Customers Only.color = 0xcc0000. a toggle switch is defined using Light and Dark states. } this. var format:TextFormat = new TextFormat().addChild(myButton). myButton. You can define your own states by setting the defaultLabel and selectedLabel properties. Internally. format.align = TextFormatAlign.label = "OK".CENTER.setTextFormatForState(formatDown.font = "Myriad Pro". it defines two states: default and selected. formatDisable.CENTER. // create a text format for the disabled state // grey label text var formatDisable:TextFormat = new TextFormat(). myButton.y = 175. formatDown.DOWN). formatDisable.align = TextFormatAlign. format.UP). formatDown. The toggle switch is a sliding button that the user can drag from one state to another. formatDown. } } Using the Toggleswitch class The ToggleSwitch class allows you to create a simple toggle switch.

[SWF(height="600". the frame rate.RoundedButtonSkinWhite. Import the required classes.display. qnx.RIM Confidential and Proprietary Information . add the LabelButton object.RoundedButtonSkinBlack. public function ToggleSample() { initializeUI(). import flash. Create a constructor for your class and invoke initializeUI(). create a new ToggleSwitch instance and set the position on the stage.buttons. 200). myButton. Create a toggle switch 1.skins. qnx.buttons. this.Sprite. import flash. Content and software are subject to change. directly before the class signature. In the initializeUI function. myButton.ui.Event. Create an application framework by extending Sprite. import import import import qnx.addChild(myButton). In the initializeUI function.ui. width="1024".ToggleSwitch. class ToggleSample extends Sprite { 4. var myToggle:ToggleSwitch = new ToggleSwitch(). Add the following statement to your class. Create the initializeUI function to set up and initialize the UI controls. 5.buttons. frameRate="30".LabelButton. } 6.events.label = "myButton".setPosition(200. private var myToggle:ToggleSwitch. the LabelButton class named myLabel.buttons. and the background color of your application. Create the variables for the myToggle toggle switch and the myButton label button.skins.ui. backgroundColor="#FFFFFF")] 3. myToggle. private function initializeUI():void { 7. 47 .ui.Beta Customers Only. 8. var myButton:LabelButton = new LabelButton(). In the following code sample. private var myButton:LabelButton. qnx. This statement sets the stage width and height. 2.setPosition(200. 150).

qnx. qnx.SELECT. You also set the selected property to false. } this.skins. indicating that the toggle will be set to the default label on initialization.addChild(myToggle).ui. The themeChange function sets the skin for the button myButton based on the current state. In the initializeUI function. 10.setSkin(RoundedButtonSkinBlack).buttons. Add the themeChange function that is called by the event listener. import flash.ui. myToggle. } else { } } myButton.defaultLabel = "Light". define the toggle states.Beta Customers Only.backgroundColor="#FFFFFF")] public class ToggleSample extends Sprite { private var myToggle:ToggleSwitch. 9.buttons. 12. Content and software are subject to change.selected = false. In the initializeUI function.ui.RoundedButtonSkinBlack.events. } Code sample: Creating a toggle switch The following code sample uses a ToggleSwitch object to change a button theme from dark to light. You can define the toggle states by assigning a String to the defaultLabel and selectedLabel properties. package { import flash. myToggle. [SWF(height="600". add an event listener for the toggle switch. themeChange).display. width="1024".ToggleSwitch. the Light and Dark states represent the light and dark color themes. myToggle. In the initializeUI function.Sprite. qnx.buttons.addEventListener(Event. add the ToggleSwitch to the stage. function themeChange(event:Event):void { if (myToggle. myToggle. 11.skins.setSkin(RoundedButtonSkinWhite). import import import import qnx.ui. 48 .LabelButton. In the following code sample.RIM Confidential and Proprietary Information .buttons. private var myButton:LabelButton.selected == true) { myButton.RoundedButtonSkinWhite. frameRate="30".selectedLabel = "Dark".Event.

setSkin(RoundedButtonSkinBlack). 150).label = "myButton". } else { } } myButton.setSkin(RoundedButtonSkinWhite).RIM Confidential and Proprietary Information . // listen the select event the toggle switch dispatches myToggle.Event. themeChange). } } Create a segmented control 1.display.events. qnx.data. myButton.addChild(myToggle). myToggle.selected = false. myButton.DataProvider.setPosition(200. myButton = new LabelButton(). Import the required classes. 49 . myToggle. else white if ( myToggle. import import import import flash. /** @private **/ private function themeChange( e:Event ):void { // if the toggle is selected. public function ToggleSample() { initializeUI().SELECT.selected == true ) { myButton. myToggle. flash.addEventListener(Event. Content and software are subject to change. } this.Beta Customers Only. 200). qnx.SegmentedControl.ui.addChild(myButton).buttons.setPosition(200. this. set the button skin to black.defaultLabel = "Light". } private function initializeUI():void { myToggle = new ToggleSwitch(). myToggle.Sprite.selectedLabel = "Dark".ui.

and the background color of your application. buttonArray. Each object must contain a label property.dataProvider = new DataProvider(buttonArray). frameRate="30". Content and software are subject to change. var buttonArray:Array=[]. You can use the addItemAt method to add a button to the segmented control at a given index. The remaining day names will be added later. In the following code sample. the frame rate.push({label:"Thursday"}). private function initializeUI():void { 6. buttonArray. Add the following statement to your class. mySegment. Create a constructor for your class and invoke initializeUI(). Create an application framework by extending Sprite. } 5.RIM Confidential and Proprietary Information .width = 500.length -1) 10.push({label:"Tuesday"}). 7. mySegment.addItem({label: "Friday" }). 8. mySegment. In the initializeUI function. 9.y = 200. var mySegment:SegmentedControl = new SegmentedControl(). width="1024". In the initializeUI function. You can use the addItem method to append a button to the segmented control.push({label:"Monday"}). Create the initializeUI function to set up and initialize the UI controls. Add an entry in the DataProvider for Wednesday. create and populate the array.Beta Customers Only. [SWF(height="600". Add an entry in the DataProvider for Friday. The label property "Wednesday" is added in the second last index within the segmented control. 2. public function SegmentedControlExample() { initializeUI(). mySegment. the array contains the names of only three days. mySegment. In the initializeUI function. The array contains the objects that define the text that appears on each button in the segmented control. create and configure the segmented control. mySegment. buttonArray.addItemAt({label: "Wednesday" }.height = 50. backgroundColor="#FFFFFF")] 3. This statement sets the stage width and height.dataProvider. mySegment. instantiate the DataProvider class and associate it with the segmented control that you just created. mySegment. 50 . class SegmentedControlExample extends Sprite { 4. directly before the class signature.x = 200.

} Code sample: Creating a segmented control This code sample provides an example of a SegmentedControl object that contains a button for each day of the week. frameRate="30". 12.Sprite. Content and software are subject to change.buttons.selectedIndex = 2.ui.RIM Confidential and Proprietary Information . mySegment. qnx.display. width="1024". package { import flash.skins.ui. add the segmented control to the stage. set the button that is initially selected. qnx. mySegment.SegmentedControlSkinBlack.addChild(mySegment). // set the selected index to be the 3 item in the dataProvider mySegment. // set the data provider mySegment. } private function initializeUI():void { // create an array for the segmented control with objects //that have label properties var buttonArray:Array=[]. buttonArray.SegmentedControl.buttons. 11.push({label:"Monday"}). backgroundColor="#FFFFFF")] public class SegmentedControlExample extends Sprite { public function SegmentedControlExample() { initializeUI(). mySegment. 51 .skins.push({label:"Thursday"}). mySegment. buttonArray. import import import import qnx.x = 200.width = 500. In the initializeUI function.ui.DataProvider.Beta Customers Only.dataProvider = new DataProvider(buttonArray). In the initializeUI function.RoundedButtonSkinBlack.buttons. [SWF(height="600". // create a segemented control var mySegment:SegmentedControl = new SegmentedControl().selectedIndex = 2.height = 50. qnx. } this. buttonArray. mySegment.y = 200.data.push({label:"Tuesday"}).ui.

public function RadioButtonSample() { initializeUI().display. Import the required classes.ui.buttons.Beta Customers Only. the groupname property is set to rbg1_meals13.addItem({label: "Friday" }) -1) } } } Create a radio button group 1. backgroundColor="#FFFFFF")] 3. In the initializeUI function. } 5. Create an application framework by extending Sprite. In the following code sample. private function initializeUI():void { 6.Sprite. These buttons will become the first radio button group. directly before the class signature. mySegment.RadioButtonGroup.length // add an item to the end mySegment. all radio buttons on the screen will be part of the same array. Content and software are subject to change. This is the name of the RadioButtonGroup object that will contain the radio buttons.addItemAt({label: "Wednesday" }. and the background color of your application. [SWF(height="600". Create a constructor for your class and invoke initializeUI(). Add the following statement to your class. This statement sets the stage width and height. // add the control to the disply list this.buttons. width="1024". create three radio buttons.dataProvider.RadioButton.addChild(mySegment). the frame rate. 52 . import qnx. import flash. Create the initializeUI function to set up and initialize the UI controls. You must specify the name of the RadioButtonGroup for each button to associate the button with a parent group.RIM Confidential and Proprietary Information . // add an item at the index mySegment. class RadioButtonSample extends Sprite { 4. You will create the RadioButtonGroup in a later step. Otherwise.MouseEvent. 2. frameRate="30". import qnx. import flash.ui.events.

rb5. var rbg2:RadioButtonGroup. Call the setSelectedRadioButton method to set the initial selection. addChild( rb3 ).x.setPosition(rb4. These buttons will become the second radio button group: rbg1_meals46. rbg2. rb4. var rb5:RadioButton = new RadioButton().setPosition(300. rb4.groupname = "rbg1_meals13". In the initializeUI function.groupname = "rbg1_meals46". create the first radio button group. rbg2Change). rbg2 = RadioButtonGroup. rb5. rbg1Change). rb6. 100) rb1. Use the getGroup method to instantiate the radio button group by specifying a unique name for the radio button group. var rb3:RadioButton = new RadioButton().RIM Confidential and Proprietary Information .CLICK. In the initializeUI function. rb2. rb3. var rb6:RadioButton = new RadioButton(). 100) rb4.setPosition(100. the radio button rb2 will be selected.groupname = "rbg1_meals46".setPosition(rb1. rb2.groupname = "rbg1_meals46". In the initializeUI function.setSelectedRadioButton(rb2). addChild( rb4 ). rbg1.x. rb3.label = "Meal option 3".x. addChild( rb1 ).label = "Meal option 2". addChild( rb2 ). 8.y + 40).label = "Meal option 5".label = "Meal option 4". rb5.y + 40). rb5. rb4.CLICK.label = "Meal option 1". create the second radio button group. rb3.groupname = "rbg1_meals13". var rbg1:RadioButtonGroup. rb1. } 53 .getGroup("rbg1_meals46").setPosition(rb1.getGroup("rbg1_meals13"). rbg1. Content and software are subject to change. It's important to use a unique name for each radio button group.y + 40). 9. rb2. var rb1:RadioButton = new RadioButton(). var rb4:RadioButton = new RadioButton(). addChild( rb5 ). rb6. rb1. addChild( rb6 ). rb1.Beta Customers Only. 7. rb2. When the application loads. create the second set of radio buttons.label = "Meal option 6".addEventListener(MouseEvent.y + 40).x. var rb2:RadioButton = new RadioButton(). rbg1.groupname = "rbg1_meals13". rbg1 = RadioButtonGroup.setPosition(rb4. rb6.addEventListener(MouseEvent.

rb2. 100) rb1.groupname = "rbg1_meals13". width="1024". rb2.setPosition( rb1.RIM Confidential and Proprietary Information .label = "Meal option 2". function rbg1Change(event:MouseEvent):void { trace("rb1 change event"). } } Code sample: Creating a radio button group package { import flash.x.groupname = "rbg1_meals13".ui.RadioButtonGroup. rb2.display. rb3. import flash. The functions trap mouse-click events for each radio button group. 100 ) 54 .label = "Meal option 1". [SWF(height="600".setPosition( 300.MouseEvent. } function rbg2Change(event:MouseEvent):void{ trace("rb2 change event").groupname = "rbg1_meals13".setPosition(100. addChild( rb1 ). import qnx.Beta Customers Only. Content and software are subject to change. rb1.y + 40 ). import qnx. var rb4:RadioButton = new RadioButton(). 10. addChild( rb2 ). backgroundColor="#FFFFFF")] public class RadioButtonSample extends Sprite { public function RadioButtonSample() { initializeUI().Sprite. rb1. var rb2:RadioButton = new RadioButton().buttons. frameRate="30".RadioButton. rb3. create the event listener functions.label = "Meal option 3".x. rb1. In the initializeUI function.y + 40 ).events. rb2.ui. } private function initializeUI():void { var rb1:RadioButton = new RadioButton().buttons.setPosition( rb1. rb4. var rb3:RadioButton = new RadioButton(). rb3. addChild( rb3 ).

getGroup( "rbg1_meals46" ). rbg2Change ). var rb5:RadioButton = new RadioButton(). rbg2 = RadioButtonGroup. rbg1.CLICK. } } } 55 . } private function rbg2Change( event:MouseEvent ):void { trace("rb2 change event").getGroup( "rbg1_meals13" ). rb5.CLICK. rbg1.y + 40 ).setSelectedRadioButton( rb2 ). rb4. rb5. rb6.Beta Customers Only. rbg1Change ).addEventListener( MouseEvent.groupname = "rbg1_meals46". Content and software are subject to change.RIM Confidential and Proprietary Information . rb5.label = "Meal option 4". rbg2. var rb6:RadioButton = new RadioButton(). addChild( rb6 ). addChild( rb5 ). rbg1 = RadioButtonGroup. addChild( rb4 ). var rbg2:RadioButtonGroup. rb6.addEventListener( MouseEvent. rb4.setPosition( rb4.x. rbg2. rb4.label = "Meal option 5".label = "Meal option 6".y + 40 ).setSelectedRadioButton( rb5 ). rb5. } private function rbg1Change( event:MouseEvent ):void { trace("rb1 change event").groupname = "rbg1_meals46".x.groupname = "rbg1_meals46". rb6. var rbg1:RadioButtonGroup.setPosition( rb4.

The SectionList class is a list implementation that contains sections.listClasses package contains classes that you can use to create a number of different list types. Class List RoundList SectionList TileList SectionTileList DropDown Description The List class is the base list class that provides simple list functionality. where each section contains zero or more list items. Create a List 1. Create a constructor for your class and invoke initializeUI().listClasses. The SectionTileList class is a variation of the SectionList that uses tiles instead of list items. This statement sets the stage width and height. qnx.ui.ui. The TileList displays list items laid out in a grid format. width="1024".Beta Customers Only.ScrollDirection.ui. Add the following statement to your class. import flash. Content and software are subject to change. The RoundList class is a simple list class that has no scroll bar. directly before the class signature. backgroundColor="#FFFFFF")] 3.Sprite.data.DataProvider. You can use the ListSelectionMode class to define how the user interacts with the list. 2. The DropDown class is a simple drop-down list implementation. The qnx. and the background color of your application.listClasses.ui.List. Import the required classes. [SWF(height="600". and the ScrollDirection class to define how the list scrolls. import import import import qnx. Create an application framework by extending Sprite. qnx.RIM Confidential and Proprietary Information . frameRate="30".ui. qnx. and continues to scroll from the beginning after the final cell is reached.display.listClasses. class ListSample extends Sprite { 4. 56 . with each list inheriting from the base List class. Displaying data in lists 7 The BlackBerry® Tablet OS SDK contains convenient and flexible list implementations that you can use to display data and to provide the user with a selectable. scrollable list of input choices. the frame rate.ListSelectionMode.

columnWidth = 100. "June"}). 57 .MULTIPLE. myList. "April"}). public function ListSample() { initializeUI(). assign a DataProvider to the list. myList. myList. "November"}).push({label: "January"}). In the initializeUI function. a new DataProvider instance is created using the array of objects that you created in step 5.HORIZONTAL to allow the list to scroll horizontally.push({label: arrMonth.Beta Customers Only. 11.push({label: arrMonth. 10.setPosition(100. create the array of objects. instantiate the List class and position it on the stage. var arrMonth:Array=[]. "August"}). private function initializeUI():void { 6. Create the initializeUI function to set up and initialize the UI controls.width = 300.HORIZONTAL. "September"}).height = 100.push({label: arrMonth. the List object looks for the label property within the List object data. "July"}). set the scrollDirection property to ScrollDirection. Content and software are subject to change. 8.push({label: arrMonth. the array is populated with an object for each month of the year. myList.scrollDirection = ScrollDirection. "December"}). 200). In the following code sample. myList.push({label: arrMonth. In the initializeUI function. myList. You must provide a height and width for the list. where each object contains a label property.push({label: arrMonth.selectionMode = ListSelectionMode. By default. 9. In the initializeUI function. 7.push({label: arrMonth.RIM Confidential and Proprietary Information .push({label: arrMonth. In the initializeUI function. add the List object to the stage. In the initializeUI function.push({label: arrMonth. arrMonth.push({label: arrMonth. "October"}).dataProvider = new DataProvider(arrMonth). In the following code sample. In the initializeUI function. myList. The label property contains the String that will appear inside each list cell. var myList:List = new List(). } 5. set the selectionMode property to allow multiple selections.push({label: arrMonth. "March"}). "February"}). "May"}). otherwise it will not render.

// add objects with a arrMonth.RIM Confidential and Proprietary Information .ScrollDirection.setPosition(100. // set the height myList. // set the position of x and y myList.height = 100.push({label: arrMonth. frameRate="30".addChild(myList). [SWF(height="600". "December"}).listClasses. "November"}).display. qnx.data.listClasses.push({label: arrMonth.push({label: label property "January"}).Sprite.ui.push({label: arrMonth.push({label: arrMonth.push({label: arrMonth. qnx.ui.columnWidth = 100. qnx. 200). "July"}).ui.List. "February"}).push({label: arrMonth. "May"}). width="1024". backgroundColor="#FFFFFF")] public class ListSample extends Sprite { public function ListSample() { initializeUI(). "September"}). "April"}). qnx.push({label: arrMonth. "June"}).push({label: arrMonth.push({label: arrMonth. "March"}). 58 .width = 400.ListSelectionMode. //create a new list var myList:List = new List(). } } this. Code sample: Creating a list package { import import import import import flash. Content and software are subject to change.Beta Customers Only. // set the width myList.listClasses. "August"}).ui. } private function initializeUI():void { // create an array for objects var arrMonth:Array=[]. "October"}).push({label: arrMonth.push({label: arrMonth. myList.DataProvider.

an object with the label property "January" is removed from the list. a new array of data is added at the second index. myList. myList.addItemsAt(myNewArray. The addItemAt method takes the object data to add and the index location to place the new data. myList. a new item is added to the list at the second index. The addItemsAt method takes an array of object data and the index location to place the new data. In the following code sample.removeItemAt(2) To remove all items in the list.addItemAt({label: "Q1 FY11"}.removeItem({label: "January"}). Updating an item in a list You can update the data in a list at runtime. In the following code sample. } } } Adding an item to a list Call the addItemAt method to add an item to a list at a given index. myList. You can append a child to the list by calling the addItem method.Beta Customers Only. To remove an item at a given index. To update an item with a given item use the updateItem method.addChild(myList). In the following code sample.RIM Confidential and Proprietary Information .scrollDirection = ScrollDirection. 4) Removing an item from a list You can remove data from a list at runtime. myList. myList. use the removeAll method.HORIZONTAL. {label: "Q1 FY11"} ). 59 . an object with the label property "January" is updated with a new object that contains the label property "Q1 FY11".selectionMode = ListSelectionMode. You can add multiple children to a given item by calling the addItemsAt method. Call the removeItem method and specify a valid object to remove the object from a list. //add the list to the display list this. myList. Content and software are subject to change.MULTIPLE.updateItem({label: "January"}. 2).dataProvider = new DataProvider(arrMonth). The array data is inserted into the existing data array. use the removeItemAt method. myList. In the following code sample.

private function initializeUI():void { 6.push({label: "January"}). the frame rate. Create an application framework by extending Sprite.push({label: arrMonth. "February"}). directly before the class signature. The array data is inserted into the existing data array.display.updateItemAt({label: "Q1 FY11"}. using a new array of data.RIM Confidential and Proprietary Information .data.push({label: arrMonth. var arrMonth:Array=[]. Create the initializeUI function to set up and initialize the UI controls. The updateItemsAt method takes an array of object data and the index location at which to update the new data.push({label: arrMonth. arrMonth.TileList. myList. create the array. myList.push({label: arrMonth. "July"}). Create a constructor for your class and invoke initializeUI().updateItemsAt(myNewArray. The following code sample creates an array of month names named arrMonth. Import the required classes. class TileListSample extends Sprite { 4. "May"}). import qnx.DataProvider. and the background color of your application. 60 . "March"}).ui.listClasses. import flash. public function TileListSample() { initializeUI().Beta Customers Only. [SWF(height="600". This statement sets the stage width and height. } 5. import qnx.push({label: arrMonth. 4) Create a tile list 1.ui. Add the following statement to your class.frameRate="30". backgroundColor="#FFFFFF")] 3. 1) You can call the updateItemsAt method to update the data in the array starting at the fourth index. width="1024". 2.Sprite. "August"}). You can use the updateItemAt method to update an item at a given index. Content and software are subject to change.push({label: arrMonth.push({label: arrMonth. "April"}). "June"}). In the initializeUI function.

endFill(). var myTileList:TileList = new TileList().push({label: arrMonth.data. myTileList. In the initializeUI function. You must set a height and width for the list. import qnx. In the initializeUI function. create a background for the TileList instance. } this. specify the data provider for the TileList.graphics. bg.x = 90. bg. myTileList.listClasses. The cell padding specifies the amount of pixels between each TileList cell.graphics.graphics.push({label: arrMonth. bg.beginFill(0x333333.Beta Customers Only. myTileList. "October"}).0xCCCCCC).ui. In the initializeUI function. Content and software are subject to change. "December"}).push({label: "September"}). import qnx.DataProvider.display. 8.In the code sample below. By default. 200). In the initializeUI function.420. 7.TileList.setPosition(100.columnCount = 3.height = 300.width = 400. each tile is 100 pixels wide.Sprite.push({label: arrMonth. bg. add the TileList instance to the stage.ui. create the TileList instance and position it on the stage.graphics. myTileList.RIM Confidential and Proprietary Information . myTileList.y = 190. set the number of columns and the cell padding for the TileList. bg. myTileList. 9. "November"}). 11.lineStyle(2. In the initializeUI function. var bg:Sprite = new Sprite(). 10.addChild(myTileList). bg.dataProvider = new DataProvider(arrMonth). addChild(bg).1). you create a new DataProvider instance by passing in the arrMonth array that you created in step 3.drawRect(0.cellPadding = 5.0. arrMonth.320). { package import flash. } Code sample: Creating a tile list The following code sample provides an example of a TileList object that contains the names of all months of the year. 61 .

Beta Customers Only.addChild(myTileList).drawRect(0. "September"}).push({label: arrMonth.0xCCCCCC). myTileList. "June"}). "December"}). myTileList.graphics.columnCount = 3.graphics. and each item contains children. bg.push({label: arrMonth.RIM Confidential and Proprietary Information . this.x = 90. Conceptually.1). 62 . and in the context of the API. Content and software are subject to change. backgroundColor="#FFFFFF")] public class TileListSample extends Sprite { public function TileListSample() { initializeUI().push({label: arrMonth.dataProvider = new DataProvider(arrMonth). bg.push({label: arrMonth. "March"}).0. myTileList. frameRate="30". } private function initializeUI():void { var arrMonth:Array=[]. [SWF(height="600". bg.push({label: "January"}). where each section contains one or more list items. a section is called an item. bg.graphics.endFill(). myTileList. When you add a child to a SectionList. "May"}).push({label: arrMonth.320).420. myTileList. arrMonth. you must first determine which item to add the child to. "October"}). width="1024".cellPadding = 5.beginFill(0x333333.push({label: arrMonth. } } } Creating a section tile list The SectionTileList list contains one or more sections. "February"}). this.push({label: arrMonth. bg. myTileList.push({label: arrMonth.width = 400. "April"}).push({label: arrMonth. bg.addChild(bg). var myTileList:TileList = new TileList(). "November"}). "July"}).push({label: arrMonth.graphics.y = 190.push({label: arrMonth. "August"}). var bg:Sprite = new Sprite(). 200).height = 300.lineStyle(2.setPosition(100.

the frame rate. the SectionTileList class uses the SectionDataProvider data structure to store data.push({label: arrMonth. This statement sets the stage width and height. Create the createDataProvider function to create a SectionDataProvider object instance. directly before the class signature. The SectionDataProvider class contains the structure and functionality that is required to create and maintain a list structure with multiple sections. "March"}).push({label: "January"}). Creat the constructor. 7. "September"}). { private function createDataProvider():SectionDataProvider 6. In the following code sample. and the background color of your application. Add the following statement to your class. "October"}). "June"}). class SectionTileSample extends Sprite { 4. arrMonth. import qnx. the arrMonth array is a simple array of objects. frameRate="30". 2. "November"}). "April"}). create a SectionDataProvider object.Sprite. backgroundColor="#FFFFFF")] 3.SectionDataProvider. In the createDataProvider function. Content and software are subject to change. width="1024". import flash. "August"}). "July"}). "December"}).push({label: arrMonth.push({label: arrMonth.push({label: arrMonth.push({label: arrMonth. "February"}). Create an application framework by extending Sprite.data.ui. Create a SectionDataProvider object This task demonstrates how to create a SectionDataProvider object to contain month and day data for a calendar.push({label: arrMonth.Beta Customers Only. [SWF(height="600". 63 . create an array.push({label: arrMonth. To accomodate both item and child data.push({label: arrMonth. var arrMonth:Array=[]. public function SectionTileSample() { } 5.display.RIM Confidential and Proprietary Information .push({label: arrMonth. Import the required classes. 1. "May"}).push({label: arrMonth.push({label: arrMonth. In the createDataProvider function.

2. j++ ) { mySDP. Create the initializeUI function to set up and initialize the UI controls. mySDP. This statement sets the stage width and height. Add the following statement to your class. i++ ) { var section:Object = new Object(). directly before the class signature. section. } } } } Create a section tile list 1. The label property of each object is set using the array of month names that you created in a previous step. Create an application framework by extending Sprite.SectionDataProvider. var mySDP:SectionDataProvider = new SectionDataProvider(). frameRate="30".Sprite. i < arrMonth. [SWF(height="600". for( var j:int = 1.listClasses. Create a constructor for your class and invoke initializeUI().ui. width="1024". import flash.RIM Confidential and Proprietary Information . Each object is added to the SectionDataProvider object by calling the addItem method. and the background color of your application. private function initializeUI():void { 64 . In the createDataProvider function.label = arrMonth[i]. The second for loop adds 31 children to each item by calling the addChildToItem method. class SectionTileSample extends Sprite { 4. public function SectionTileSample() { initializeUI(). the frame rate.ui. backgroundColor="#FFFFFF")] 3. a for loop is used to create an object for each month of the year.Beta Customers Only.addChildToItem( {label: j}. j<32. section ).SectionTileList.data. } 5. for( var i:int = 0.display. Content and software are subject to change. populate the SectionDataProvider object. In the following code sample. Import the required classes. import qnx.addItem( section ).label.length. import qnx. 8.

The cell padding is set to 5 pixels.columnCount = 5. var mySDP:SectionDataProvider = new SectionDataProvider(). mySectionTileList. In the initializeUI function. Content and software are subject to change.length. the section tile list contains 5 columns. section ). 9. mySectionTileList.push({label: arrMonth. i < arrMonth. section. "September"}).label. j++ ) { mySDP. for( var i:int = 0. "June"}). mySectionTileList.push({label: arrMonth.push({label: arrMonth. } } 7. mySectionTileList.push({label: arrMonth. j<32. set the number of columns and the cell padding.push({label: arrMonth. "March"}). In the initializeUI function. var mySectionTileList:SectionTileList = new SectionTileList(). "August"}). mySDP.addItem( section ).push({label: arrMonth. var arrMonth:Array=[]. "October"}). "November"}).width = 520.addChildToItem( {label: j}.push({label: arrMonth. "February"}).label = arrMonth[i].cellPadding = 5. mySectionTileList. 6. "December"}).push({label: arrMonth. add the SectionTileList instance to the stage. "May"}). In the initializeUI function.push({label: "January"}).Beta Customers Only.height = 300. for( var j:int = 1. specify the SectionDataProvider instance for the section tile list.dataProvider = createDataProvider(). create the SectionTileList instance and position it on the stage. In the initializeUI function. 10. create and populate a SectionDataProvider instance. In the initializeUI function. The width of the list is set to 520 pixels to accomodate the tiles and the padding. In the following code sample. "April"}). Each tile is 100 pixels wide by default.setPosition(100.push({label: arrMonth.RIM Confidential and Proprietary Information .push({label: arrMonth. 65 . arrMonth. "July"}). i++ ) { var section:Object = new Object(). 200). mySectionTileList.push({label: arrMonth. 8.

2. In the normalizeDays function. call removeChildFromIndexAt to remove extra days from months that contain fewer than 31 days.removeChildFromIndexAt(5. mySectionTileList. 30). mySectionTileList. Before you begin: This task builds on the application that you created in the previous task.ui. and mySectionTileList object that you created when you created and populated the list. 30th.RIM Confidential and Proprietary Information . Add the following statement to your class. the removeChildFromIndexAt method is called to remove the 31st.SectionDataProvider. mySectionTileList.listClasses.removeChildFromIndexAt(10. } } this. Remove an item from a section tile list The following code sample demonstrates how to create a function to remove extra day children from month items that contains less than 31 days. normalizeDays().Sprite. 28).SectionTileList. call the normalizeDays function.removeChildFromIndexAt(1. 6. 4. mySectionTileList. directly before the class signature. In the constructor of your application.removeChildFromIndexAt(1. Content and software are subject to change. import flash. In the following code sample.display. Add the remaining code to the normalizeDays function to remove excess days from each remaining month. mySectionTileList. frameRate="30". } 5. 30).ui. This statement sets the stage width and height. 30). 1. Import the required classes. In the SectionTileSample class. the frame rate.Beta Customers Only. [SWF(height="600". import qnx. 29). 66 .removeChildFromIndexAt(1.removeChildFromIndexAt(8. 30). 30). Create the arrMonth SectionDataProvider instance. width="1024".addChild(mySectionTileList). create a function called normalizeDays.data. backgroundColor="#FFFFFF")] 3.removeChildFromIndexAt(3. function normalizeDays():void{ mySectionTileList. import qnx. mySectionTileList. and the background color of your application. and 29th days (remember that the array is zero-based) from the month object in the first index position of the array.

display. 67 .SectionTileList. public function SectionTileSample() { initializeUI().push({label: arrMonth. mySectionTileList. mySectionTileList. "June"}).listClasses. [SWF(height="600". "February"}). "May"}).push({label: arrMonth. "April"}). Content and software are subject to change. mySectionTileList.ui.Beta Customers Only.Sprite. mySectionTileList.columnCount = 5.RIM Confidential and Proprietary Information . Code sample: Creating a section tile list calendar The following code sample provides an example of a calendar that was implemented using the SectionTileList class. mySectionTileList. "November"}).push({label: arrMonth.push({label: arrMonth. private function createDataProvider():SectionDataProvider { var arrMonth:Array=[]. mySectionTileList. "July"}). normalizeDays().setPosition(100. frameRate="30".push({label: arrMonth. 200).addChild(mySectionTileList). "December"}).dataProvider = createDataProvider().push({label: "January"}).height = 300. backgroundColor="#FFFFFF")] public class SectionTileSample extends Sprite { private var mySectionTileList:SectionTileList. } private function initializeUI():void { //create and setup section list mySectionTileList = new SectionTileList(). "October"}).push({label: arrMonth. "March"}). import qnx. } this. width="1024". "September"}). "August"}).data.width = 520.ui. import qnx.push({label: arrMonth.push({label: arrMonth.push({label: arrMonth.SectionDataProvider.push({label: arrMonth. arrMonth. package { import flash.push({label: arrMonth.cellPadding = 5.

68 . j<32. section.removeChildFromIndexAt(10.RIM Confidential and Proprietary Information . 30). } } mySectionTileList.length.removeChildFromIndexAt(1. i++ ) { //add month names var section:Object = new Object(). mySectionTileList. 30).removeChildFromIndexAt(5. j++ ) { mySDP. var mySDP:SectionDataProvider = new SectionDataProvider().Beta Customers Only.removeChildFromIndexAt(1.addItem( section ). i < arrMonth. 30).label = arrMonth[i]. 29).removeChildFromIndexAt(8. } } Creating a custom list You can extend the CellRenderer or AlternatingCellRenderer classes in order to create a custom look and feel for your list. add a check box control to each cell. The CellRenderer class is used to draw the table cells that make up a list. 28). for( var i:int = 0. mySectionTileList. 30). and create a List object that uses the setSkin method to set the new class as the skin for the list. //add day numbers. mySectionTileList.removeChildFromIndexAt(3. mySectionTileList. section ). 30). The AlternatingCellRenderer class extends the CellRenderer class to provide alternating colors for the cells in a list. add an event listener and logic to define how each cell behaves when the user clicks the check box. mySDP. Content and software are subject to change. The following code sample demonstrates how to create a custom list class that extends the AlternatingCellRenderer class. mySectionTileList. all 31 for now for( var j:int = 1. } private function normalizeDays():void { //TODO: account for leap years mySectionTileList.label. } return(mySDP).addChildToItem( {label: j}.removeChildFromIndexAt(1.

private var myCB:CheckBox. In the init function. Import the required classes. Add the onClick function. In the init function. backgroundColor="#FFFFFF")] 3. Create the constructor.RIM Confidential and Proprietary Information .ui.Beta Customers Only. myCB. myCB.listClasses.DataProvider.ui. Add the following statement to your class.y = 10. myCB. } 9.x = 250.MOUSE_DOWN. call the init function of the super class (AlternatingCellRenderer). In your application signature. onClick). The init function is called when the list is instantiated.List. The x and y coordinates are relative to the edge of the cell.ui. The CheckBox appears in every cell in the list. myCB = new CheckBox().Sprite. 69 . myCB. width="1024". [SWF(height="600".addEventListener( MouseEvent.addChild(myCB) 8. super.init(). public function MyCustomCellRenderer() { } 5. This statement sets the stage width and height. add an event listeners to capture mouse click events and mouse down events. The onClick function dispatches a new event that bubbles up whenever the check box control is selected.addEventListener(MouseEvent. the frame rate. 2. directly before the class signature. Create the MyCustomCellRenderer class.ListSelectionMode. Override the init function. this. frameRate="30". and the background color of your application. extend the AlternatingCellRenderer class. qnx. public class MyCustomCellRenderer extends AlternatingCellRenderer { 4. 7. create a CheckBox object. Content and software are subject to change. qnx. override protected function init():void { 6. qnx. Create a custom cell renderer 1. onMouseDown).CLICK.data. You can add custom logic inside this function to customize each cell in the list.listClasses. import import import import flash.display. In the init function.

} 10. Add the onMouseDown function. the cell. Create a constructor for your class and invoke initializeUI(). var arrItems:Array=[].stopImmediatePropagation(). public class CustomListSample extends Sprite { 4. true. arrItems. private function onClick(event:MouseEvent):void { dispatchEvent( new Event( Event. private function onMouseDown(event:MouseEvent):void { event. } 5. Add the following statement to your class.RIM Confidential and Proprietary Information . The following code sample creates an array of grocery items. [SWF(height="600". The onMouseDown function calls the stopImmediatePropagation method which stops the event from propagating to the parent container. } } Apply a custom cell renderer to a list Before you begin: The following code sample demonstrates how to apply a custom AlternatingCellRenderer class to a list.ListSelectionMode.ui. import flash.data.listClasses.SELECT. 1.push({label: "Apples"}). 70 . Create an application framework by extending Sprite.List. This code sample assumes that the MyCustomCellRenderer class exists in the same project. true ) ). import qnx. private function initializeUI():void { 6. width="1024". Content and software are subject to change.DataProvider.Sprite.display. This statement sets the stage width and height. frameRate="30". public function CustomListSample() { initializeUI(). Create the initializeUI function to set up and initialize the UI controls. Create and populate the array. backgroundColor="#FFFFFF")] 3. the frame rate. 2. and the background color of your application. or in this case.ui.ui.Beta Customers Only. Import the required classes. This allows the user to select the check box control without selecting the cell. directly before the class signature. import qnx. import qnx.listClasses.

package { import flash.push({label: arrItems.push({label: arrItems. arrItems. "Eggplant"}). public function MyCustomCellRenderer() { } override protected function init():void { 71 .Event.ui. myList.Beta Customers Only. public class MyCustomCellRenderer extends AlternatingCellRenderer { private var myCB:CheckBox.selectionMode = ListSelectionMode.buttons. "Cheese"}).dataProvider = new DataProvider(arrItems). myList.push({label: "Potatoes"}). The following code sample shows a custom cell renderer that places a check box control inside of each list cell.MouseEvent. myList.push({label: arrItems. import flash. Create and set up the List object. var myList:List = new List().RIM Confidential and Proprietary Information . Content and software are subject to change.push({label: arrItems.push({label: arrItems. Add the List object to the stage. myList.CheckBox. "Celery"}). myList.height = 300. "Oranges"}). Apply the AlternatingCellRenderer class to the List.push({label: arrItems. myList. "Bacon"}).MULTIPLE.setSkin(MyCustomCellRenderer). In the following code sample. } Code sample: Creating a custom cell renderer You can apply a custom CellRenderer to a List object by calling the setSkin method.listClasses.push({label: arrItems. import qnx. "Ham"}). 7.width = 300.events. 9. "Carrots"}).events.addChild(myList). "Milk"}).AlternatingCellRenderer. "Tomatoes"}). the selectionMode property is set to ListSelectionMode.ui.setPosition(100. 200). } this. 8.MULTIPLE to allow the user to select multiple items in the list at one time.push({label: arrItems. import qnx.push({label: arrItems.

y = 10.CLICK. "Tomatoes"}). onMouseDown). "Carrots"}). } private function initializeUI():void { var arrItems:Array=[].addEventListener( MouseEvent.List.SELECT. myCB. myCB. arrItems. myCB. true. "Oranges"}). true ) ). } } } The following code listing creates a simple grocery list.push({label: 72 "Apples"}). package { import flash. width="1024".addChild(myCB).listClasses. myCB = new CheckBox().addEventListener( MouseEvent.DataProvider.MOUSE_DOWN. } private function onClick(event:MouseEvent):void { dispatchEvent( new Event( Event. "Potatoes"}).stopImmediatePropagation(). super.init(). onClick ).ListSelectionMode.Sprite.ui.RIM Confidential and Proprietary Information .display.push({label: arrItems.listClasses.push({label: arrItems. this.ui. Content and software are subject to change.x = 250.push({label: arrItems. import qnx. backgroundColor="#FFFFFF")] public class CustomListSample extends Sprite { public function CustomListSample() { initializeUI().ui. import qnx.push({label: arrItems. } //this will prevent the cell from being selected private function onMouseDown(event:MouseEvent):void { event. The list calls the custom cell renderer above to place a check box on each list cell.data. import qnx. . //add this listener in order to block the mouse // down event from the list myCB.Beta Customers Only. [SWF(height="600". frameRate="30".

var myList:List = new List(). myList.push({label: arrItems. } this. "Bacon"}).push({label: arrItems. myList. myList. myList.push({label: arrItems.RIM Confidential and Proprietary Information .selectionMode = ListSelectionMode. "Cheese"}). myList.width = 300.MULTIPLE.addChild(myList).Beta Customers Only.setSkin(MyCustomCellRenderer).dataProvider = new DataProvider(arrItems). 200).push({label: arrItems. } } 73 .push({label: "Eggplant"}). arrItems. "Milk"}).push({label: arrItems. "Ham"}).setPosition(100. myList. Content and software are subject to change.height = 300. "Celery"}).

data. Create and populate a DataProvider object for a picker You can create a DataProvider object that contains the day.display. Import the required classes.Picker. class PickerSample extends Sprite { 4. the frame rate. backgroundColor="#FFFFFF")] 3. 74 .Beta Customers Only.Sprite. Create an application framework by extending Sprite. Create the array variables. 2. qnx. import import import import import flash. Content and software are subject to change.ui.events.ui. then swiping up or down to scroll a list to the desired value. Using the picker to implement complex lists 8 The Picker class provides a scrollable. Users can select a value from a Picker object by first clicking on the Picker to open it.text.picker. Add the following statement to your class. selectable list that you can use to display complex data in multiple columns. frameRate="30". and the background color of your application.RIM Confidential and Proprietary Information . Create a constructor for your class and invoke createDataProvider() public function PickerSample() { createDataProvider().Event. qnx. [SWF(height="600". In the createDataProvider function. private function createDataProvider():DataProvider { 6. qnx. width="1024". This statement sets the stage width and height. flash. Create the createDataProvider function to set up and initialize the UI controls. } 5.ui.Label. directly before the class signature. 1. and year data for the Picker object. month.DataProvider.

arrMonth.push({label: arrMonth.push({label: arrMonth.Beta Customers Only. populate the arrDay array with the day data and use it to create the dayDP DataProvider. "March"}).RIM Confidential and Proprietary Information . dpp.push(monthDP).push({label: arrMonth. var returnDataProvider:DataProvider = new DataProvider(dpp).push({label: arrMonth. In the createDataProvider function. 75 . var arrYear:Array=[]. l<2011. dpp. var dpp:Array = new Array(). month. using the day. This code sample assumes a simple month data model. "May"}). dpp. 10. "September"}). } var yearDP:DataProvider=new DataProvider(arrYear). "August"}).push({label: arrMonth.toString()}).push({label: l.push(yearDP). var arrDay:Array=[].push({label: arrMonth. var monthDP:DataProvider=new DataProvider(arrMonth). 8. "November"}). var arrMonth:Array=[]. create the main calendar array.push({label: arrMonth. In the createDataProvider function. "April"}). "October"}). and year data that you created in the previous steps. "June"}). number of days in a month is not provided.push({label: arrMonth. The dpp array is an array of arrays.toString()}). l++) { arrYear. } var dayDP:DataProvider=new DataProvider(arrDay). dpp. In the createDataProvider function. "December"}).push({label: arrMonth. var monthDP:DataProvider=new DataProvider(arrMonth). i++) { arrDay. i<32. for (var l:int=1900. "February"}). Content and software are subject to change. 7. 9. "July"}).push({label: i. populate the arrMonth array with the month data and use it to create the monthDP DataProvider instance. The logic used to determine the for (var i:int=1.push({label: arrMonth.push({label: arrMonth.push(dayDP). In the createDataProvider function. populate the arrYear array with the year data and use it to create the yearDP DataProvider.push({label: "January"}).

toString()}).Picker. 76 .push({label: "January"}). width="1024". "June"}).Event. arrMonth.push({label: arrMonth. the frame rate. qnx. qnx. Create a constructor for your class. for (var i:int=1. "May"}). i<32. Add the following statement to your class.push({label: arrMonth. "February"}). Create an application framework by extending Sprite.Sprite. backgroundColor="#FFFFFF")] 3. [SWF(height="600". directly before the class signature. "March"}). } } return(returnDataProvider).text. import import import import import flash. Create the createDataProvider function to create and populate the DataProvider object. flash.push({label: arrMonth.RIM Confidential and Proprietary Information . "April"}).ui. i++) { arrDay.ui. } var dayDP:DataProvider=new DataProvider(arrDay).data. var arrYear:Array=[]. This statement sets the stage width and height.Label.push({label: arrMonth.picker. Invoke the initializeUI() function. and the background color of your application. var arrMonth:Array=[].ui.display. } 5. qnx.Beta Customers Only. frameRate="30".events. 2. public function PickerSample() { initializeUI(). private function createDataProvider():DataProvider { var arrDay:Array=[].push({label: i.DataProvider. Content and software are subject to change.push({label: arrMonth. class PickerSample extends Sprite { 4. refer to Create and populate a DataProvider object for a picker. "July"}). Import the required classes. For more information about creating the following DataProvider instance. Create a picker 1.push({label: arrMonth.

push({label: arrMonth. return(returnDataProvider).width=400. private function initializeUI():void { 7. 9.25). create and configure the Picker object. addChild(calPicker). The second argument represents the width of the list. calPicker. dpp. calPicker.setListWidth(0. This array is zero-based.push({label: "August"}). l++) { arrYear. add the event listeners for the open. dpp. "October"}). "November"}). 10. for (var l:int=1900. } 6.push({label: arrMonth.dataProvider=createDataProvider().setListWidth(1. var returnDataProvider:DataProvider = new DataProvider(dpp). l<2011. In the initializeUI function. calPicker.x=calPicker.push(dayDP). "September"}). var dpp:Array = new Array(). In the initializeUI function. calPicker. var monthDP:DataProvider=new DataProvider(arrMonth). calPicker. var calPicker:Picker = new Picker(). Create the initializeUI function to set up and initialize the UI controls. } var yearDP:DataProvider=new DataProvider(arrYear).50). "December"}). The first argument in the setListWidth method is the index value of the list. arrMonth.toString()}). calPicker. calPicker. 77 . close.push({label: arrMonth.setListWidth(2.push({label: l.push(yearDP).25).y=300. set the width of each list in the picker.push(monthDP).RIM Confidential and Proprietary Information .push({label: arrMonth. and select events.height=50. In the initializeUI function. 8. dpp.Beta Customers Only. Content and software are subject to change. and the value 0 represents the first list in the picker. In the initializeUI function. add the DataProvider to the Picker by calling the createDataProvider function.

handleSelect).CLOSE. You can call this method at any time to set the current index of the picker.addEventListener(Event. 12.handleOpen). function handleOpen(e:Event):void { trace("Picker. Before you begin: Create a Picker object.handleClose).Beta Customers Only.RIM Confidential and Proprietary Information .selectedIndices=[0. calPicker.selectedIndices "+calPicker. It uses the selectedIndices method to capture the current index value. j++) { trace("calPicker.0. then use the updateItemAt method to replace the English month name array.selectedItems " +calPicker. } 13.label. . Content and software are subject to change. } calPicker.selectedItems.close event captured").selectedItems "+calPicker. function handleSelect(e:Event):void { for (var j:int = 0.selectedItems[j].length.selectedIndices). Create the handleOpen and handleClose functions to handle open and close events. In the code sample below.label). calPicker.selectedItems[j]. } function handleClose(e:Event):void { trace("Picker. } trace("calPicker. In the initializeUI function. selIndex = calPicker. The handleSelect function uses the selectedItems method to capture the currently selected item in each of the three arrays. selItem = calPicker. trace("calPicker. calPicker. For example.open event captured").selectedItems). you can create a DataProvider object that contains French month names. 78 Create the new array and DataProvider.selectedItems. The selectedIndices method takes an array of index values. the values represent 1 January 2010. } } Update data in a picker You can create a new DataProvider instance and apply it to a Picker at run time.selectedIndices.addEventListener(Event. j <calPicker. 1. Create the handleSelect function to print the selected items to the console. selObj = calPicker.OPEN. 11.addEventListener(Event.110].SELECT. set the initial index values of the picker.

push({label: arrMonth_fr.push({label: "Janvier"}). "Juillet"}). width="1024". "Fevrier"}). calPicker.display.push({label: arrMonth_fr.dataProvider=createDataProvider().Picker. import qnx.push({label: arrMonth_fr. calPicker. 2. 1). package { import flash.push({label: arrMonth_fr. var month_frDP:DataProvider=new DataProvider(arrMonth_fr). import qnx.RIM Confidential and Proprietary Information .push({label: arrMonth_fr. calPicker.text.events. calPicker.updateItemAt(month_frDP.ui.Label.y=300. "Aout"}).Beta Customers Only. Code sample: Creating a picker calendar The following code sample demonstrates how to create a Picker that contains calendar data.push({label: arrMonth_fr.ui.picker.Sprite. "Mai"}). "Decembre"}). calPicker.data. backgroundColor="#BBBBBB")] public class PickerSample extends Sprite { private var calPicker:Picker. "Juin"}). "Avril"}).x=calPicker.push({label: arrMonth_fr.height=50. Content and software are subject to change.Event. public function PickerSample() { initializeUI().push({label: arrMonth_fr.ui.width=400. import qnx. "Mars"}). [SWF(height="600". } private function initializeUI():void { calPicker = new Picker().push({label: arrMonth_fr. import flash. 79 . arrMonth_fr. "Septembre"}). "Novembre"}). frameRate="30". var arrMonth_fr:Array = new Array().push({label: arrMonth_fr. Call the updateItemAt method to update the second column of the picker with the new array of month names.DataProvider. "Octobre"}).push({label: arrMonth_fr.

"September"}). i++) { arrDay.50). arrMonth:Array=[].push({label: i.OPEN.addEventListener(Event.push({label: l.push({label: arrMonth.0.toString()}).push({label: arrMonth. 80 .addEventListener(Event.push({label: arrMonth.handleOpen). private { var var var for (var i:int=1. calPicker.25).push({label: arrMonth. calPicker.push(dayDP). Content and software are subject to change. "August"}).push({label: arrMonth.110].addEventListener(Event.push({label: arrMonth. l++) { arrYear.push({label: arrMonth. calPicker. } var dayDP:DataProvider=new DataProvider(arrDay).Beta Customers Only. "October"}). "February"}). var dpp:Array = new Array(). "December"}). "May"}).push(monthDP).push({label: arrMonth. "June"}). arrYear:Array=[].setListWidth(0.push({label: arrMonth. i<32. function createDataProvider():DataProvider arrDay:Array=[].handleSelect). addChild(calPicker). calPicker. } var yearDP:DataProvider=new DataProvider(arrYear). for (var l:int=1900.toString()}).push({label: arrMonth.CLOSE.push({label: "January"}).SELECT.push({label: arrMonth. calPicker. var monthDP:DataProvider=new DataProvider(arrMonth). } traceItems(). arrMonth.selectedIndices=[0. "November"}).handleClose). dpp. "April"}).setListWidth(1.RIM Confidential and Proprietary Information . calPicker. calPicker. "March"}).setListWidth(2. "July"}). l<2011.push(yearDP).25). dpp. dpp.

selectedItems " +calPicker. trace("Picker.selectedIndices "+calPicker. The user can interact with the picker by scrolling through the lists. [SWF(height="600".selectedItems). however the picker always resets to the system time after a period of time. backgroundColor="#FFFFFF")] public class PickerClock extends Sprite { 81 .picker. } var returnDataProvider:DataProvider = new DataProvider(dpp).Event. flash. frameRate="30". } } } Code sample: Creating a picker clock The following code listing provides an example of a clock.ui.utils.data. The picker is updated using the system time.ui.utils. return(returnDataProvider).selectedItems "+calPicker. } private function handleOpen(e:Event):void { trace("Picker.events. flash.RIM Confidential and Proprietary Information . j <calPicker. private function traceItems():void { for (var j:int = 0.display.Sprite.label). implemented using the picker.selectedItems[j].DataProvider.Beta Customers Only.setInterval. } trace("Picker. flash. import qnx. package { import import import import import flash.Picker. import qnx.selectedItems.open event captured").length. width="1024".Timer. } private function handleClose(e:Event):void { trace("Picker. } private function handleSelect(e:Event):void { traceItems(). j++) { trace("Picker.close event captured").selectedIndices). flash.TimerEvent. Content and software are subject to change.events.

setListWidth(0.25).handleSelect).SELECT. addChild(picker).PickerListBgBlack). picker.addEventListener(TimerEvent. // create a timer to run every 6 seconds timer = new Timer(60000).width = 200. picker. updatePicker(). private function handleTimerTick(e:TimerEvent):void { updatePicker(). picker. timer. mins. timer. // To customize column widths. picker.handleOpen).y = 175.setListWidth(1. picker.start(). picker.addEventListener(Event. picker. // simple function that outputs the selected items traceItems().RIM Confidential and Proprietary Information . private var timer:Timer. //hours 82 .TIMER. public function PickerClock() { initializeUI(). var arrAmPm:Array=[]. AM PM var arrHour:Array=[]. picker. private var picker:Picker. picker.dataProvider = createDataProvider().CLOSE.isOpen = true. } picker.25).25).setListBackgroundSkin(SkinAssets. } private function initializeUI():void { // Create the picker and add the main DataProvider picker = new Picker().addEventListener(Event.Beta Customers Only. Content and software are subject to change. picker. } private function createDataProvider():DataProvider { // Create three arrays to handle hours. picker.handleClose).OPEN.height=50.handleTimerTick).addEventListener(Event. var arrMin:Array=[].x = 300. // all widths are added up and then used for // a ratio against the component set width picker.setListWidth(2.

//mins arrMin. i++) { arrHour. "03"}). i<13. "01"}). "05"}).push({label: k. for (var k:int=10.push(AmPmDP). // Populate the main array var dpp:Array = new Array().Beta Customers Only. "06"}).open event captured").push(HourDP).push({label: i. k<60. dpp.push({label: arrMin.push(MinDP).push({label: arrMin. var AmPmDP:DataProvider=new DataProvider(arrAmPm). } var MinDP:DataProvider=new DataProvider(arrMin).push({label: arrMin. return(returnDataProvider). var returnDataProvider:DataProvider = new DataProvider(dpp). } private function traceItems():void 83 . arrAmPm.push({label: arrMin. } private function handleSelect(e:Event):void { traceItems().push({label: "AM"}). } private function handleOpen(e:Event):void { trace("Picker. "08"}). "09"}). "04"}). "07"}).toString()}). Content and software are subject to change. } private function handleClose(e:Event):void { trace("Picker.push({label: "00"}). } var HourDP:DataProvider=new DataProvider(arrHour). "02"}). arrAmPm. k++) { arrMin.push({label: arrMin.toString()}).push({label: "PM"}).close event captured"). for (var i:int=1.RIM Confidential and Proprietary Information . dpp. dpp.push({label: arrMin.push({label: arrMin.push({label: arrMin.push({label: arrMin.

ampm].Beta Customers Only.hours. { for (var j:int = 0.1. ampm].selectedIndices=[0. //add 1 if hour is 1 am if (hours == 0) { picker. trace("Picker.selectedIndices=[hours . ampm].selectedIndices).selectedItems[j]. hours = hours . var ampm:Number = 0. } } 84 . j++) { trace("Picker. mins. mins. mins.selectedIndices "+picker.1.selectedItems " +picker. } trace("Picker. var mins:Number = new Date(). } private function updatePicker():void { trace("PickerClock. mins.data). Content and software are subject to change.selectedItems. } else { } } picker.label).minutes. var hours:Number = new Date().selectedIndices=[hours .length. picker.12.selectedIndices=[11. } else if (hours > 12) { ampm = 1.updatepicker"). } else if (hours == 1) { picker. ampm].data "+picker.RIM Confidential and Proprietary Information . j <picker.

the track fill changes to represent the current status of the operation. and the background color of your application. 2.progress. A PercentageBar object is shown in the following illustration: The ActivityIndicator class is an animation that you can enable or disable to indicate to the user that an activity is currently in progress. width="1024". the frame rate. import qnx.RIM Confidential and Proprietary Information . The PercentageBar class contains a label that displays the current percentage value of the track. Add the following statement to your class.Sprite. backgroundColor="#FFFFFF")] 3. Content and software are subject to change. frameRate="30". class ProgressSample extends Sprite { 4. you could create an ActivityIndicator instance to display during timeconsuming or processor-intensive operations. Providing feedback and activity status to the user 9 You can provide temporal feedback and pending activity status indications to the user by using the ProgressBar class. When you set the progress property. Create a constructor for your class and invoke initalizeUI(). directly before the class signature. [SWF(height="600". 85 .Beta Customers Only. For example. PercentageBar class. import flash. } 5. Create the initializeUI function to set up and initialize the UI controls.ProgressBar. This statement sets the stage width and height. Create a progress bar 1. Import the required classes. public function ProgressSample() { initializeUI(). and the ActivityIndicator class. Create an application framework by extending Sprite.display.ui. An ActivityIndicator instance is shown in the following illustration. The ProgressBar class is a horizontal track that takes a percentage value to represent the current progress of an ongoing operation.

5.Beta Customers Only. private function initializeUI():void { 6. 7.progress = .progress = . add the ProgressBar instance to the stage. myPercentage.addChild(myProgress).width = 200. 0. this. } myProgress. import qnx. var myProgress:ProgressBar. backgroundColor="#FFFFFF")] public class ProgressSample extends Sprite { private var myPercentage:PercentageBar.display.RIM Confidential and Proprietary Information .IconButton. width="1024". myProgress = new ProgressBar(). 86 .ui. import qnx.PercentageBar.You can use the progress property to update the fill position of the progress bar.addChild(myPercentage). 300). create and position the ProgressBar object instance. For example. Content and software are subject to change. public function ProgressSample() { initializeUI(). 8.buttons. 300).ui. In the initializeUI function. The progress property takes a percentage value as a decimal. myPercentage. You should write a function that periodically sets the progress property to reflect the current state of your operation. myProgress. this.progress. set the progress value.width = 200. frameRate="30". In the initializeUI function.setPosition(400. } private function initializeUI():void { myPercentage = new PercentageBar().Sprite.setPosition(400.5. myPercentage. } Code sample: Creating a progress bar package { import flash. [SWF(height="600". myProgress.5 indicates 50% and 1 indicates 100%. In the initializeUI function.

Beta Customers Only. onClick). create the ActivityIndicator instance and add it to the stage.setPosition(260.RIM Confidential and Proprietary Information .Sprite. This statement sets the stage width and height.CLICK. the LabelButton instance is used to enable and disable the activity indicator. class ActivityIndicatorSample extends Sprite { 4. private function initializeUI():void { 6. In the following code sample. 225).LabelButton.events.width = 150. this. create a LabelButton instance and add it to the stage. } } } Create an activity indicator 1. import qnx. In the initializeUI function. myAnimate.addChild(myActivity). backgroundColor="#FFFFFF")] 3. var myAnimate:LabelButton = new LabelButton(). 300). frameRate="30". 8. Add the following statement to your class. 87 . Create an application framework by extending Sprite. Create the initializeUI function to set up and initialize the UI controls.label = "Animate". 2. directly before the class signature. the frame rate.setPosition(200.buttons. public function ActivityIndicatorSample() { initializeUI(). this. add an event listener to capture button click events. Create a constructor for your class. import flash.display. 7. and the background color of your application. Content and software are subject to change. } 5. width="1024". import qnx. var myActivity:ActivityIndicator = new ActivityIndicator().ActivityIndicator. myActivity.MouseEvent.addEventListener(MouseEvent. [SWF(height="600". In the initializeUI function. myAnimate. import flash.addChild(myAnimate).ui. myAnimate.progress. Import the required classes. } myAnimate. In the initializeUI function. and invoke initializeUI().ui.

function onClick():void { if (!myActivity.ui.MouseEvent. import qnx.animate(true).label = "Animate". If the activity indicator is currently animating.label = "Stop". myActivity.Beta Customers Only. 9.ui. import flash.animate(false). myActivity. 88 . } } } Code Sample: Creating an activity indicator package { import flash.progress. Create the onClick function. import flash.setPosition(200. Content and software are subject to change. width="1024".events.addChild(myActivity).events. } else { myAnimate.buttons.Sprite. myActivity. myAnimate.ActivityIndicator. The onClick function uses the isAnimating property of the ActivityIndicator to determine if the activity indicator is currently animating. public function ActivityIndicatorSample() { initializeUI(). myAnimate= new LabelButton(). then the button label text is toggled and the animation is turned off by calling the animate method with a Boolean argument.display.setPosition(260. 300).LabelButton. } private function initializeUI():void { myActivity = new ActivityIndicator(). frameRate="30". private var myAnimate:LabelButton.Event. import qnx. backgroundColor="#FFFFFF")] public class ActivityIndicatorSample extends Sprite { private var myActivity:ActivityIndicator.RIM Confidential and Proprietary Information .isAnimating()) { myAnimate. [SWF(height="600". 225). this.

animate(false).Beta Customers Only. import qnx. onClick). this.addChild(myPercentage).width = 200.progress. public function myPercentageSample() { initializeUI(). myActivity.PercentageBar.setPosition(400.display.width = 150. myPercentage.isAnimating()) { myAnimate. import flash.Sprite. myAnimate. Content and software are subject to change. this. backgroundColor="#FFFFFF")] public class myPercentageSample extends Sprite { private var myPercentage:PercentageBar.events. myActivity. [SWF(height="600".Timer.utils.progress = 0.animate(true) } else { myAnimate.CLICK. myAnimate. } myAnimate. myPercentage. private var counter:int.TimerEvent.addEventListener(MouseEvent.label = "Animate". myPercentage. width="1024".RIM Confidential and Proprietary Information . } } private function onClick(e:MouseEvent):void { if (!myActivity.label = "Animate". } } Code sample: Creating a percentage bar package { import flash. private var timer:Timer.addChild(myAnimate). // counter to keep track of how many times the timer has ticked 89 .ui. frameRate="30". import flash. 300).label = "Stop". } private function initializeUI():void { myPercentage = new PercentageBar().

TIMER.RIM Confidential and Proprietary Information . timer.100). counter = 0.addEventListener(TimerEvent.TIMER_COMPLETE. Content and software are subject to change.handleTimerTick). timer.TIMER_COMPLETE.Beta Customers Only.progress = counter/100.TIMER. timer = new Timer(100. } } } 90 .start(). } private function handleTimerTick(e:TimerEvent):void { counter++.removeEventListener(TimerEvent. myPercentage.handleTimerTick).removeEventListener(TimerEvent. timer. } private function handleTimerComplete(e:TimerEvent):void { timer. counter = 0. timer.addEventListener(TimerEvent.handleTimerComplete).handleTimerComplete).

class SliderSample extends Sprite { 4.slider.backgroundColor="#FFFFFF")] 3.SliderEvent. myVSlider. Content and software are subject to change. the frame rate.events. frameRate="30". directly before the class signature. [SWF(height="600". } 6. In the initializeUI function. and slider stop events. 5. Create an application framework by extending Sprite. Create the initializeUI function to set up and initialize the UI controls. Add the following statement to your class.RIM Confidential and Proprietary Information . public function SliderSample() { initializeUI(). The event listeners use event types that are defined in the SliderEvent class to capture slider movement. Import the required classes. In the initializeUI function. var myVSlider:VolumeSlider = new VolumeSlider(). 91 . Create a constructor for your class and invoke initializeUI().VolumeSlider. This statement sets the stage width and height. myVSlider. import qnx.y = 50. width="1024". slider start.display. 2. add the event listeners. Create the VolumeSlider variable.ui.Beta Customers Only. create the VolumeSlider object and position it on the stage. private function initializeUI():void { 7. 8. The VolumeSlider class is used to adjust volume levels for media playback. Capturing variable input with a slider 10 The Slider class enables the user to input variable data by dragging a thumb across a track.x = 50. A volume slider control is shown in the illustration below: Create a volume slider 1. import flash. set the initial value of the slider control.ui.Sprite. myVSlider. private var myVSlider:VolumeSlider. import qnx. 9. In the initializeUI function.value = 50. and the background color of your application.

frameRate="30".display.MOVE.Sprite. trace( "stopped moving at: ".ui. backgroundColor="#FFFFFF")] public class SliderSample extends Sprite { /** @private **/ private var myVSlider:VolumeSlider.SliderEvent. The functions in the following code sample are used to output the current slider value and thumb state to the console.value ). sliderStart ).Beta Customers Only.round( event.value ). In the initializeUI function.addEventListener( SliderEvent. function sliderChange( event:SliderEvent ) : void { var newlevel:int = Math. } function sliderStop( event:SliderEvent ) : void { var newlevel:int = Math. public function SliderSample() { initializeUI(). } private function initializeUI():void 92 .round( event. newlevel ). newlevel ). [SWF(height="600". add the VolumeSlider object to the stage. myVSlider.addEventListener( SliderEvent.START. myVSlider. 10.round( event.value ). myVSlider.events.ui. import qnx. Content and software are subject to change. } function sliderStart( event:SliderEvent ) : void { var newlevel:int = Math. trace( "started moving at: ". sliderStop ).RIM Confidential and Proprietary Information . sliderChange ). width="1024". 11.END. The values change as the user drags the slider. trace( "slider value: ".target. Create the event functions.target. The thumb skin icon changes as the user drags the thumb from the left edge of the track to the right edge of the track.target. } } Code sample: Creating a volume slider package { import flash. newlevel ).VolumeSlider.slider.addEventListener( SliderEvent. } this.addChild( myVSlider ). import qnx.

addChild( myVSlider ). sliderStart ). myVSlider.MOVE.value = 50. // listen to the end of the slider event myVSlider.addEventListener( SliderEvent. 300). myVSlider. newlevel ).round( event.Beta Customers Only. sliderChange ).value ).round( event.target. trace( "stopped moving at: ". } private function sliderStop( event:SliderEvent ) : void { var newlevel:int = Math.minimum = 0. myVSlider.setPosition(300.target.addEventListener( SliderEvent. { myVSlider = new VolumeSlider(). myVSlider.RIM Confidential and Proprietary Information .value ). Content and software are subject to change.value ). trace( "slider value: ". } private function sliderStart( event:SliderEvent ) : void { var newlevel:int = Math.START.maximum = 100.round( event. newlevel ). } private function sliderChange( event:SliderEvent ) : void { var newlevel:int = Math.addEventListener( SliderEvent.END. // listen to the when the slider moves myVSlider. this. myVSlider. sliderStop ). } } } 93 .target. newlevel ). trace( "started moving at: ".

Beta Customers Only. Skinning your UI components 11 The BlackBerry® Tablet OS contains a set of skin classes that provide a customizable and consistent. both of which are comprised of many parts.ISkin.Sprite.ui. Content and software are subject to change. import qnx. you must create a skin class that implements the qnx. For example. Change the default skin of a UI component You can change the color scheme of a segmented control from light (default) to dark by changing the component's skin. Each asset must be registered with the skin. In order to create your own custom skin. The ISkin class is the default skin for all components such as buttons and thumbs.skins. For example. down.ui. For example. All skinnable UI component parts in the SDK use one of the following skin types: Skin type ICellRenderer ISkin Description The ICellRenderer class is used to render the cells in all list types. your skin must implement ICellRenderer interface.RIM Confidential and Proprietary Information . import flash.ui. You can then register each skin asset by associating an asset with the intended UI component state.SegmentedControl.buttons. The qnx.skins. most UI components differ from one another in the way that they implement skinning.ISkin interface. This gives your skin class a functional base for handling state changes and for associating skins with states. The user can expand the picker component in order to scroll through a set of vertical scrolling lists. look and feel for your application.ui. The quickest way to create a custom skin is to extend qnx. These component states are defined in the qnx. 1. a button skin should contain assets to define the up. Each skin object consists of one or more graphic assets. selected.ui.UISkin class registers skins for certain states and handles the state changes so that the appropriate skin is associated with the current state. When you create a skin for the list class. To register assets. An asset uses 9 slice scaling which allows it to be resized with little or no distortion. The OS defines two distinct color themes: light and dark. 94 .UISkin class. you must override the protected functioninitializeStates() in your skin class.SkinStates class.skins.skins.ui. and disabled states that appear when the user interacts with the button. Each UI component in the OS was designed to enable a specific user-interaction. where a graphic asset provides the bitmap or vector data that is used to render each state of the skin.display. Import the required classes. your skin must implement ISkin interface. When you create a skin for a button class. Because UI components vary in their complexity. The tablet uses the light themed component skins by default.skins. Most skins in the SDK derive from the qnx. the picker is useful for inputting complex numbers such as dates or IP addresses. a basic button component is simple to skin when compared to a section tile list or a picker.

height = 50.RIM Confidential and Proprietary Information . buttonArray. backgroundColor="#FFFFFF")] 3.ui. Add the following statement to your class. call the setBackgroundSkin method. import qnx. buttonArray.ui. mySegment.buttons.push({label:"Wednesday"}). import qnx. buttonArray. the frame rate. Create the initializeUI function to set up and initialize the UI controls.setBackgroundSkin(SegmentedControlSkinBlack). class SkinSample extends Sprite { 4. import qnx. This statement sets the stage width and height.skins.dataProvider = new DataProvider(buttonArray). passing in the SegmentedControlSkinBlack skin asset class.SegmentedControlSkinBlack. this.selectedIndex = 2.y = 200. Content and software are subject to change. mySegment.data. passing in the RoundedButtonSkinBlack skin asset class.ui. var mySegment:SegmentedControl = new SegmentedControl(). mySegment.push({label:"Monday"}). } 5. private function initializeUI():void { 6.push({label:"Friday"}). 95 . buttonArray. In the initializeUI function. 7. mySegment. [SWF(height="600". directly before the class signature.RoundedButtonSkinBlack.push({label:"Thursday"}). Create a constructor for the class and invoke initializeUI(). and the background color of your application. This changes the background skin of the SegmentedControl instance to the dark color scheme asset. create a SegmentedControl object instance.push({label:"Tuesday"}).addChild(mySegment). 2. mySegment. frameRate="30". 8. Create an application framework by extending Sprite.width = 500.buttons. public function SkinSample() { initializeUI(). This changes the skin of each button in the SegmentedControl instance to use the asset from the dark color scheme.skins. In the initializeUI function. width="1024". mySegment. mySegment. call the setButtonSkin method. var buttonArray:Array=[]. buttonArray. In the initializeUI function.x = 200.Beta Customers Only.DataProvider.

and the background color of your application. public class CustomButtonSkin extends UISkin { 4. In your class signature. In the initializeStates function. In the following code sample. backgroundColor="#FFFFFF")] 3.ISkin interface and provides the base functionality required for loading and registering your skin assets. import qnx.UISkin.ui. Import the required classes. selectedSkin:Sprite. Content and software are subject to change. width="1024". Each skin is filled using a different hexadecimal color code to create a unique look for each button state. Each skin is instantiated as a Sprite object. 7. } } mySegment.skins.The initializeStates function is used to register your skin assets to associate them with UI component states. 2.skins package.skins. frameRate="30". 1. protected protected protected protected var var var var upSkin:Sprite. create the skin assets. } 5. disabledSkin:Sprite. down.ui. Create the constructor. you create skin assets for the up. extend the UISkin class. see the SkinAssets class in the qnx.Beta Customers Only. The drawRoundRect method is used and each button skin will have a rounded edge.ui.ui. After you finish: For more information about the light and dark color scheme assets. and disabled skin states. Create a custom button skin class In the following task you create a custom button skin and apply it to a set of buttons. import qnx. The UISkin class implements the qnx.setButtonSkin(RoundedButtonSkinBlack).skins. directly before the class signature. import qnx.SkinAssets. Create variables for the skin assets.RIM Confidential and Proprietary Information . 96 . This statement sets the stage width and height. selected.skins. Add the following statement to your class.ui. [SWF(height="600". public function CustomButtonSkin() { super(). override protected function initializeStates():void { 6.SkinStates. downSkin:Sprite. Override the initializeStates method. the frame rate.

2.endFill(). each skin asset is associated with the proper state.drawRoundRect(0.graphics. upSkin = new Sprite().graphics.50. disabledSkin. selectedSkin.graphics.buttons.ui.0.beginFill(0xCC0000).50.0.drawRoundRect(0.graphics. This statement sets the stage width and height. 8. the frame rate.RIM Confidential and Proprietary Information .0. 10. upSkin. Otherwise. } Apply a custom button skin Before you begin: Create a custom button skin. register your skin assets by calling the setSkinState method for each skin asset.drawRoundRect(0.50.Button.selectedSkin). downSkin = new Sprite().10). 97 . import qnx.beginFill(0x000000).DISABLED.10).50. selectedSkin. Add the following statement to your class.beginFill(0x333333).50. 1. downSkin). Import the required classes. upSkin. downSkin. selectedSkin = new Sprite().50.graphics. In the initializeStates function.graphics. 10. } showSkin(upSkin).0.endFill().graphics. It associates the skin asset with the UI component state. the appropriate skin asset is displayed. setSkinState(SkinStates. selectedSkin. directly before the class signature.graphics.endFill(). downSkin. In the initializeStates function. setSkinState(SkinStates.UP.beginFill(0xFF6600).drawRoundRect(0. disabledSkin.DOWN. In the code sample below.graphics. 10.ui. upSkin. downSkin. disabledSkin.endFill(). The setSkinState method takes a skin state constant and a skin asset.SELECTED. set the default skin state by calling the showSkin method.50. setSkinState(SkinStates. 9. or a list is rendered. This example assumes that you created the custom button skin class CustomButtonSkin in the same project as the following sample application.50. Content and software are subject to change.graphics.graphics. setSkinState(SkinStates. disabledSkin = new Sprite(). 10. disabledSkin). you'd need to import the class into your sample application.10). import qnx. upSkin).Beta Customers Only. such that when a button is pressed. and the background color of your application.buttons.LabelButton.graphics.10).

Code sample: Creating a custom button skin This code sample contains a small sample application that uses a custom button skin class.label = "My Label Button". myToggleButton. } addChild(myLabelButton). 50).setPosition(200. create a label button that calls the setSkin method. [SWF(height="600". you must import the CustomButtonSkin class into your sample application. public function ButtonSample() { initializeUI(). class ButtonSample extends Sprite { 4. private function initializeUI():void { 6. In the initializeUI function. When you click the buttons. 7. frameRate="30". myLabelButton. width="1024". 200).setSkin(CustomButtonSkin).In the following code sample.setSize(150. myToggleButton. create a toggle button that calls the setSkin method. } 5. myLabelButton. myToggleButton = new Button(). Create an application framework by extending Sprite. myToggleButton. 300). Create a constructor for the class and invoke initializeUI(). myLabelButton = new LabelButton(). backgroundColor="#FFFFFF")] 3.setPosition(200. Build and run the application. Content and software are subject to change. var myLabelButton:LabelButton.setSize(100. } 8.setSkin(CustomButtonSkin). myLabelButton. myLabelButton. var myToggleButton:Button.RIM Confidential and Proprietary Information . you must make sure that both the ButtonSample class and the CustomButtonSkin class are located in the same source project. The buttons are rounded and the colours appears as you defined them the custom skin class.Beta Customers Only. addChild(myToggleButton). Otherwise. In the initializeUI function. 50). the setSkin method takes the name of the custom skin class. Create the initializeUI function to set up and initialize the UI controls. When you build and run this sample application. 98 . myToggleButton.toggle = true. notice that each button state is also skinned.

SkinAssets. public function ButtonSample() { initializeUI(). The sample application ButtonSample creates two buttons and adds them to the stage.setSkin(CustomButtonSkin). myToggleButton. import qnx. import qnx.Sprite. addChild(myLabelButton). } private function initializeUI():void { myToggleButton = new Button(). myToggleButton.display.ui.setSize(150. myLabelButton. } } } The CustomButtonSkin class is listed below. package { import flash.MouseEvent. backgroundColor="#FFFFFF")] public class ButtonSample extends Sprite { private var myToggleButton:Button. 50). Each button calls the setSkin method to set the custom skin CustomButtonSkin class as the button skin. 99 . import flash.Button.setSkin(CustomButtonSkin).label = "My Label Button". myLabelButton. myLabelButton = new LabelButton().setPosition(200.skins.Beta Customers Only. addChild(myToggleButton).buttons.setSize(100.display.RIM Confidential and Proprietary Information . frameRate="30". package { import flash. myToggleButton.buttons.setPosition(200. import flash.ui. import qnx.Rectangle. myLabelButton.LabelButton.Sprite.toggle = true. width="1024". private var myLabelButton:LabelButton.events. 200). 300).geom. Content and software are subject to change. 50). myLabelButton. myToggleButton. [SWF(height="600".ui.

50. setSkinState(SkinStates.drawRoundRect(0.DOWN.10).beginFill(0xFF6600).beginFill(0x333333).10).ui. downSkin. selectedSkin.graphics. setSkinState(SkinStates. setSkinState(SkinStates.50.50.graphics.graphics.endFill(). disabledSkin = new Sprite().SELECTED.graphics. disabledSkin.drawRoundRect(0.endFill().50.scale9Grid = gridRect.endFill().10).selectedSkin). Content and software are subject to change.graphics. selectedSkin.0. /** @private **/ protected var selectedSkin:Sprite. upSkin.endFill().30).graphics.graphics. 10. downSkin.drawRoundRect(0. public function CustomButtonSkin() { super().skins.graphics. selectedSkin = new Sprite().50. import qnx.10). import qnx.scale9Grid = gridRect. /** @private **/ protected var downSkin:Sprite. /** @private **/ protected var gridRect:Rectangle. downSkin.Beta Customers Only. selectedSkin.RIM Confidential and Proprietary Information . public class CustomButtonSkin extends UISkin { /** @private **/ protected var upSkin:Sprite.DISABLED. upSkin).beginFill(0x000000). disabledSkin.0.50.50. disabledSkin. upSkin.scale9Grid = gridRect.scale9Grid = gridRect. downSkin = new Sprite().drawRoundRect(0.8.graphics. 100 .graphics.UISkin.0.skins. downSkin). 10. selectedSkin.30.beginFill(0xCC0000). /** @private **/ protected var disabledSkin:Sprite.ui. downSkin.graphics. upSkin = new Sprite(). disabledSkin).50. 10. upSkin. 10. disabledSkin. setSkinState(SkinStates. } override protected function initializeStates():void { gridRect = new Rectangle(8. upSkin.0.SkinStates.graphics.UP.

Beta Customers Only. } } } 101 . showSkin(upSkin).RIM Confidential and Proprietary Information . Content and software are subject to change.

[SWF(height="600". 2. frameRate="30". 102 . 1.ReturnKeyType. The following task demonstrates how to create a text input field that enables the following keyboard.text package contains the classes required for displaying text on the screen and for gathering text input from the user.text. the virtual keyboard appears. Add the following statement to your class. directly before the class signature.ui.ui. qnx.ui.ui. qnx.Beta Customers Only.display. The TextInput class enables you to create a text input field that the user can use to enter text. and the Return key type. the frame rate.TextInputIconMode. the virtual keyboard automatically appears enabling the user to enter text into the field. import import import import import flash. Create an application framework by extending Sprite. width="1024".ui.text. When a TextInput instance gains focus. qnx.RIM Confidential and Proprietary Information . including the types of keys.TextInput. You can define the type of keyboard for each text input field. Capturing text input 12 The qnx.Sprite.text. The keyboard type defines the layout of the keyboard.text. and the background color of your application. backgroundColor="#FFFFFF")] 3. class TextInputSample extends Sprite { 4. Create a constructor for your class and invoke initializeUI(). depending on the context of the current application. Import the required classes. The Label class cannot be used to gather text input. The Label class enables you to display formatted text within your application. qnx. and it cannot get input focus. Content and software are subject to change. You can define the type of keyboard that appears. This statement sets the stage width and height.KeyboardType. Create a text input field When the user clicks in a text input field.

the text input field is used to type a URL to connect to a remote server. var myInput:TextInput = new TextInput(). and the Enter key is set to use the Connect key.width = 300. By default.returnKeyType = ReturnKeyType. myInput.URL constant). set the clearIconMode property. Content and software are subject to change. In the following code sample.keyboardType = KeyboardType. private function initializeUI():void { 6. public function TextInputSample() { initializeUI().RIM Confidential and Proprietary Information .addChild(myInput). 8.CONNECT. In the initializeUI function. } 103 . instantiate the TextInput class and position the control on the stage.Beta Customers Only. 7. set the keyboard type and keyboard Enter key type.clearIconMode = TextInputIconMode. Create the initializeUI function to set up and initialize the UI controls. 9. The URL keyboard is specified (by specifying the KeyboardType. The icon is enabled by default. 200). In the initializeUI function. myInput. myInput. } this.URL. myInput. In the initializeUI function. however you can define when the icon will be available to the user. the text input field contains a clear icon that the user can click to clear the text input field. In the initializeUI function.setPosition(200. add the text input field to the stage. } 5.UNLESS_EDITING. myInput.

104 . This dialog box presents two text input boxes. your dialog will lock the user interface for the tablet until your user dismissis it. you must pass a boolean value in this parameter. if you specify the SKIN property. you can customize the appearance and behaviour of buttons in a dialog box by invoking Dialog.Beta Customers Only.getAirWindow(). Customizing buttons in a dialog box The appearance of a dialog box is controlled by the BlackBerry® Tablet OS. Content and software are subject to change. Provide an object that is appropriate to the type of property you want to apply. This dialog box presents three text input boxes and a series of buttons. You can set the values for size. However.RIM Confidential and Proprietary Information . if a user is one of the top scoring players in a game application. myDialog. Similarly.getAirWindow(). When you want to display your dialog. For example. position. you can prompt them to add their name to the leaderboard.dialog package.show(IowWindow. ensure that you pass IowWindow.group as a parameter when you invoke the show() method. you can control the size. To optimize visibility for a dialog box in the context of your application. Dialog box AlertDialog LoginDialog PasswordChangeDialog PopupList PromptDialog Description This dialog box presents a message and a series of buttons.setButtonPropertyAt() specifying the following parameters: Parameter Property name Value Value Provide one of the constants found in the DialogButtonProperty class. see the API Reference for the BlackBerry® Tablet OS SDK for Adobe® AIR®. If you do not specify the window group using the IowWindow class. This restricts the dialog box to lock your application only. Creating dialog boxes 13 Your application can prompt users when your application state changes. and alignnment of a dialog box on the screen. This dialog box presents a list of and a series of buttons. For example.group) For more information about setting properties of the dialog box. This dialog box presents a text input box and a series of buttons. and alignment by using the contstant values provided in the other classes in the qnx. you must pass an object that implements the ISkin interface. and a series of buttons. You can use one of the pre-defined dialog boxes in the qnx. position. if you specify the ENABLED property in the first parameter.dialog package to communicate with your user. a check box.

stageWidth .stageHeight . 105 .dialog.addEventListener(MouseEvent.btnShowDialog.Sprite. btnShowDialog.width)/2.events. btnShowDialog.ui. Add this statement to your application framework. Invoke the ButtonClicked() method when the BlackBerry® Tablet OS SDK reports a click event. 2. Content and software are subject to change.ui. var btnShowDialog:LabelButton = new LabelButton(). [SWF(width="1024".display.MouseEvent.height)/2. This statement sets the width. btnShowDialog.y = (stage. flash.CLICK. height. frame rate. 5.Beta Customers Only. backgroundColor="#cccccc". Parameter Index Value Provide the index of the button to which you want to apply the property that you specified in the first parameter. public class DialogDemo extends Sprite { public function DialogDemo() { } } 4. Create the initializeUI() method to setup and initialize the UI components.LabelButton. Create an instance variable that refers to a Label object. btnShowDialog. and center the button on the screen.events.x = (stage. Create a dialog box 1. add a button to invoke your dialog box. private var lblWhichButton:Label = new Label(). private function initializeUI():void { } 6.Event. Add an event listener to your button to capture click events. and background color of the Stage.text. Create an application framework by extending the Sprite class. qnx. qnx. import import import import import import flash. In initializeUI().RIM Confidential and Proprietary Information .*.buttons. 7. before your constructor.label = "Click here". height="600". Add the following statement to your class before the class declaration. Import the required classes and interfaces. qnx. The Adobe® AIR® runtime assigns an index of 0 to your first button.*. buttonClicked).btnShowDialog. frameRate="30")] 3. flash. This label reports which button on the dialog the user presses.

Display the dialog box for the user. 10.btnShowDialog.getAirWindow(). 9. After you finish: For a complete code sample.addButton("Cancel"). myDialog. Create the ButtonClicked() method to respond to click events on your button. 8.target.RIM Confidential and Proprietary Information . Content and software are subject to change. 106 . Add an event listener to the button in the dialog box to capture click events. initializeUI(). lblWhichButton.getAirWindow().SIZE_SMALL. lblWhichButton.dialogSize = DialogSize. Create the alertButtonClicked() method to respond to click events in the dialog. In ButtonClicked().show(IowWindow.show(IowWindow. myDialog. 15. invoke initializeUI(). myDialog. see "Code sample: Create a dialog box". In alertButtonClicked().addButton("OK"). myDialog.text = "Index of button Clicked: " + e. 11.x = (stage. add the button and label to the Stage.Beta Customers Only. 14. alertButtonClicked). update the value of the label on the Stage when the user clicks on a button in the dialog. lblWhichButton.addEventListener(Event. 13.text = "". In the constructor for your class. public function ButtonClicked(event:Object):void { } 12.width = 600.group). var myDialog:AlertDialog = new AlertDialog().height. addChild(btnShowDialog). public function alertButtonClicked(event:Object):void { } 16.y + btnShowDialog. myDialog. In initializeUI().selectedIndex. myDialog. lblWhichButton.message = "This is a small alert dialog".SELECT. Center the label on the Stage below the button. configure the label object you created in step 4.y = btnShowDialog. myDialog.title = "Dialog".group) myDialog.width)/2. In initializeUI(). Invoke the alertButtonClicked() method when the BlackBerry® Tablet OS SDK reports a click event. create an AlertDialog object.stageWidth . lblWhichButton. addChild(lblWhichButton).

LabelButton. myDialog. frameRate="30")] public class Dialogs extends Sprite { private var lblWhichButton:Label = new Label().addEventListener(Event. import qnx. myDialog. lblWhichButton.width)/2.addButton("OK"). btnShowDialog. myDialog. } } } 107 .addEventListener(MouseEvent.btnShowDialog. addChild(btnShowDialog). import qnx.IowWindow.height)/2.CLICK.buttons.show(IowWindow.ui. myDialog. myDialog. import qnx. } public function ButtonClicked(event:Object):void { var myDialog:AlertDialog = new AlertDialog().stageWidth .ui. [SWF(width="1024".*.x = (stage.label = "Click here". myDialog. Content and software are subject to change.display.SELECT. import flash. btnShowDialog. lblWhichButton. myDialog.group).y = btnShowDialog.btnShowDialog.btnShowDialog.dialog.message = "This is a small alert dialog".display. height="600". } public function alertButtonClicked(event:Object):void { lblWhichButton.text = "Button index reported here. addChild(lblWhichButton).*.MouseEvent.text.events.events. public function Dialogs() { var btnShowDialog:LabelButton = new LabelButton().stageWidth .". lblWhichButton.text = "Button Clicked Index: " + event.title = "Dialog". import flash.target. lblWhichButton.RIM Confidential and Proprietary Information .width = 600.x = (stage. btnShowDialog. alertButtonClicked). ButtonClicked).width)/2.dialogSize = DialogSize. import qnx.height.selectedIndex.SIZE_SMALL.Event. btnShowDialog.stageHeight .Sprite. Code sample: Creating a dialog box package { import flash. backgroundColor="#cccccc".y + btnShowDialog.addButton("Cancel").getAirWindow().Beta Customers Only.y = (stage.

events flash. If the event is not processed.0 Reference for the Adobe Flash Platform. when you create a button you can add an event handler: myButton. This package contains event classes that you can use to capture events that are generated by the Adobe® AIR® runtime. Responding to events and gestures 14 The most common events are those generated by a user.ui.events Description This package contains event classes that you can use to capture BlackBerry Tablet OS specific events (for example. if the battery power level is low. events related to application state (foreground. method) When the event specified by the event parameter occurs. and foreground status events. the BlackBerry Tablet OS notifies the next object in the object hierarchy until the event is processed. background). low battery power level. low available memory. geolocation. You can use this package to detect the following gestures: • • • • • • Pan Rotate Swipe Zoom Hold and press Two finger tap 108 . the BlackBerry Tablet OS invokes the method specified by the method parameter Most applications should listen for low battery power level. In the Flash event model. and requests to release the media service connection). For more information. This package contains event classes that you can use to capture events related to BlackBerry Tablet OS UI components. the BlackBerry Tablet OS attempts to notify an object about an event. For example. Content and software are subject to change.events qnx. When a user touches the screen or tilts the BlackBerry® PlayBook™ tablet. You can add an event handler to any object by invoking addEventListener(). and the accelerometer.RIM Confidential and Proprietary Information . BlackBerry® Tablet OS sends your application a notification of the event. see the API reference for BlackBerry Tablet OS or the Adobe® ActionScript® 3.Beta Customers Only. Other events are generated by the BlackBerry Tablet OS. For more information about those events.addEventListener(event. The following table describes some of the API packages related to events. the BlackBerry Tablet OS attempts to notify all applications. For example. see Managing your application through the application life cycle. API package qnx. The BlackBerry Tablet OS passes event information to your application by using the Adobe® Flash® event model.

In initializeUI(). flash. height.height)/2. import import import import flash.inputMode = MultitouchInputMode. lblStatus.y = (stage. frameRate="30")] 3. public class SwipeDemo extends Sprite { public function SwipeDemo() { } } 4. private var _lblStatus:Label = new Label(). lblStatus. 2. lblStatus. lblStatus. frame rate. addChild(lblStatus).MultitouchInputMode.TransformGestureEvent. This label reports the direction that the user swipes.addEventListener(TransformGestureEvent.ui.Center the label on the screen and add it to the Stage.text. configure the label object you created in step 5. In initializeUI().Multitouch. Respond to an event The following steps demonstrate how to respond to a swipe gesture.x = (stage. This statement sets the width. backgroundColor="#cccccc". 1.ui.GESTURE_SWIPE.GESTURE. Content and software are subject to change.stageWidth .width = stage. private function initializeUI():void { } 6.stageWidth.stageHeight . and background color of the Stage. Add this statement to your application framework.lblStatus.Beta Customers Only. add an event listener for swipe gestures. flash. 7. onSwipe).display.text = "Drag your finger across the screen". In initializeUI(). 109 . Create an instance variable that refers to a Label object.Sprite. Create the initializeUI() method to setup and initialize the UI components. set the input mode to GESTURE. 5. Create an application framework by extending the Sprite class. import qnx. before your constructor.ui. height="600". Import the required classes and interfaces. [SWF(width="1024".lblStatus. 8. stage. Multitouch.events.RIM Confidential and Proprietary Information . Invoke the onSwipe() method when the BlackBerry® Tablet OS SDK reports a swipe gesture. Add the following statement to your class before the class declaration.width)/2. flash.Label.

import qnx. if ( event. initializeUI(). create a String variable to hold the interpretation of the swipe event. Create tests to detect swipes in other directions. After you finish: For a complete code sample.ui.offsetY == -1 ) strSwipe = "Swipe direction: Up". public function onSwipe(event:TransformGestureEvent):void { } 11.ui.Sprite. var strSwipe:String = "". In onSwipe().offsetY == 1 ) strSwipe = "Swipe direction: Down". invoke initializeUI(). lblStatus.offsetX == -1 ) strSwipe = "Swipe direction: Left".events. see "Code Sample: Detect a swipe gesture event".Beta Customers Only.text = strSwipe. 9. 10. 14. Content and software are subject to change.ui. Code sample: Detecting a swipe gesture event package { import import import import flash. 12. if ( event. 13. if ( event.offsetX == 1 ) strSwipe = "Swipe direction: Right". test the event's offsetX property to determine if the user swiped left.text. flash. Set the text property of the Label on the Stage to display the interpretation of the swipe event. flash.Multitouch. 110 . In onSwipe().Label.RIM Confidential and Proprietary Information .TransformGestureEvent.display. In the constructor for your class. Create the onSwipe() method to process the event.MultitouchInputMode. flash. if ( event.

[SWF(width="1024". } public function onSwipe(event:TransformGestureEvent):void { var strSwipe:String = "".width = stage.offsetX event. frameRate="30")] public class SwipeDemo extends Sprite { private var lblStatus:Label = new Label().addEventListener(TransformGestureEvent.RIM Confidential and Proprietary Information . -1 ) strSwipe = "Swipe direction: Up".Beta Customers Only.GESTURE_SWIPE.offsetY event. lblStatus. lblStatus.lblStatus.text = "Drag your finger across the screen".text = strSwipe. if if if if } ( ( ( ( event.stageWidth .x = (stage.offsetX event.inputMode = MultitouchInputMode.y = (stage. Multitouch. stage.width)/2.stageHeight .lblStatus. public function SwipeDemo() { lblStatus. height="600". 1 ) strSwipe = "Swipe direction: Right". onSwipe). lblStatus. lblStatus.GESTURE. } } 111 . backgroundColor="#cccccc". Content and software are subject to change.height)/2. addChild(lblStatus). 1 ) strSwipe = "Swipe direction: Down".stageWidth.offsetY == == == == -1 ) strSwipe = "Swipe direction: Left".

TOUCH_MOVE.addEventListener(TouchEvent. height="600". stage. flash.Graphics.TouchEvent.RIM Confidential and Proprietary Information . flash. public function MultiTouchDemo() { Multitouch.TOUCH_BEGIN. stage. frameRate="30")] public class MultiTouchDemo extends Sprite { private var lineColors:Array = [0x731931.TOUCH_END.addEventListener(TouchEvent.Dictionary.addEventListener(TouchEvent.events. 0x401323. flash. flash. onTouchBegin).ui. stage. onTouchMove).inputMode = MultitouchInputMode.utils.TOUCH_POINT. private var lines:Dictionary = new Dictionary().ui. 0x262226. onTouchEnd).Multitouch. 0x54594C.MultitouchInputMode.events. Content and software are subject to change. flash.Beta Customers Only.display. Code sample: Detecting a multitouch gesture event package { import import import import import import import flash. backgroundColor="#cccccc". } public function onTouchBegin(event:TouchEvent):void 112 . private var touchPointCount:int = 0. 0x888C65]. [SWF(width="1024".display.TransformGestureEvent. flash.Sprite.

TransformGestureEvent.x = (stage. { var tPoint:Sprite = new Sprite().y = (stage.events.endFill().100. _rotateMe. public function RotateDemo() { Multitouch.Beta Customers Only. 113 . tPoint. tPoint.Sprite. lines[event. this. _rotateMe.0x83A603). _rotateMe.removeChild(tPoint).beginFill(0xE9D303). height="600".moveTo( event. _rotateMe. } public function onTouchEnd(event:TouchEvent):void { var tPoint:Sprite = lines[event.stageWidth .0.20).inputMode = MultitouchInputMode.graphics. Content and software are subject to change.localX. _rotateMe. event.graphics. flash.localY).graphics.display.touchPointID].lineTo(event.rotateMe. tPoint.graphics.drawRoundRect(0. touchPointCount--.lineStyle(5.touchPointID] as Sprite.rotateMe.graphics. delete lines[event.ui. _rotateMe.localX .localY). addChild(tPoint). backgroundColor="#cccccc". } public function onTouchMove(event:TouchEvent):void { var tPoint:Sprite = lines[event. flash.touchPointID] as Sprite.graphics. flash.width) /2.100. touchPointCount++.MultitouchInputMode [SWF(width="1024". frameRate="30")] public class RotateDemo extends Sprite { private var _rotateMe:Sprite = new Sprite(). event.height) /2. lineColors[touchPointCount]).Multitouch.stageHeight .touchPointID] = tPoint.ui.RIM Confidential and Proprietary Information .graphics. } } } Code sample: Detecting a rotation gesture event package { import import import import flash.GESTURE.lineStyle(1.

rotation += event. Content and software are subject to change.rotation. addChild(rotateMe). } 114 .addEventListener( TransformGestureEvent.GESTURE_ROTATE. onRotate ).Beta Customers Only.RIM Confidential and Proprietary Information . } } public function onRotate(event:TransformGestureEvent):void { _rotateMe. } rotateMe.

In your application source code. list-tomato=Tomato list-potato=Potato list-asparagus=Asparagus list-bacon=Bacon list-celery=Celery list-corn=Corn label-title=Grocery List 115 . The following table provides a brief description of the qnx. The LocaleResourceBundle class represents the files that contain the resource strings that you can create to provide locale-specific text for your application.Beta Customers Only. or load a resource bundle to provide flexibility to a control. Your application can listen for locale changes. You can use the classes in the qnx. You can also include graphic assets in your application's locale folders to load specific images for a given locale. listen for locale change events. you can use a resource bundle to change the context of a given control. You can create a resource bundle for each locale that contains a set of key-value pairs for each locale-specific string in your application. Class Locale LocaleManager LocaleResourceBundle Description You can use the Locale class to represent the locale of the device. you can reference a key in a resource bundle to return a String value. set the locale of your application. the keyboard uses resource bundles to load a unique set of key characters depending on the context of the keyboard. then load locale-specific resources to reflect the user's current locale.RIM Confidential and Proprietary Information . The BlackBerry® PlayBook™ tablet sets and maintains a locale value at run time.locale package. Each line of the list follows the form key=value. and set and return the path to the locale-specific reource bundle. You can translate the text in the foreign language resource bundles to localize the text in your application.CHANGE event is dispatched only after the reource bundles have loaded. The Event. The following code sample shows an English language resource bundle for an application. For example. Resource bundles are loaded asynchronously and your application can only load a resource string after a resource bundle has finished loading. load locale-specific images.locale package to localize your application. thus decreasing the likelihood that your application will reference a missing resource. In addition to providing locale support. You can use the LocaleManager class to interact with the device locale. Creating a resource bundle A resource bundle is a text file that contains key-value pairs. Localizing your application and using resource bundles 15 The BlackBerry® Tablet OS SDK provides support for localization. regardless of the locale of the device or application. Content and software are subject to change. The locale value represents the language of the current user.

text = LocaleManager. 116 . Each subfolder must be a valid locale code. myLabel. You can include a resource bundle in your application by creating a locale folder structure in the source folder of your application. There are no naming restrictions for the bundle. By default. You can modify the settings in the File Exclusions preferences.getResource("label-title"). Flash Builder does not copy your . you should place the locale folder in the bin-debug folder of your application source directory. The following code sample demonstrates how an application would use a resource bundle.getResource method and passing in the label-title key. The path to the locale folder is relative to your application's . Within the locale folder. The code statement sets a button label by calling the localeManager. you must create a subfolder for each locale that your application supports.localeManager. or you can use a build script to copy your locale folder into the root directory of your application at build time. Content and software are subject to change. The following screen capture shows an application that contains resources for the US English (en_US) and France French (fr_FR) locales. If you use Adobe® Flash Builder® as your IDE.swf file.properties file to your output folder.RIM Confidential and Proprietary Information .Beta Customers Only.

see Load a resource bundle. For more information about loading and using resource bundles.ui. import qnx.locale.display. Content and software are subject to change.Sprite.DataProvider. import flash.LocaleManager.Event. import flash. 117 . Localize an application 1. import qnx.RIM Confidential and Proprietary Information .Beta Customers Only. Import the required classes and interfaces.events.data.

stage. private function initializeUI():void { //Listen for locale changes. lm. myList.addChild(myList).Beta Customers Only. 2. Content and software are subject to change. frame rate.ui. a Label object. var lm:LocaleManager = LocaleManager. Create initializeUI() and instantiate a LocaleManager object. Create a label and a list. import qnx. myLabel = new Label().ListSelectionMode. 200). myList.Label. Also.ui. and a data provider.RIM Confidential and Proprietary Information .selectionMode = ListSelectionMode. Create an application framework by extending the Sprite class. private var myList:List. Create the onLocaleChange() method. The event listener calls onLocaleChange() function when the device locale changes. and background color of the Stage.text. import qnx. private function onLocaleChange(event:Event):void { 118 . The Label and List instances will reference Strings in the resource bundle. myList. In the following code sample. 150). height="600". frameRate="30")] 3.addChild(myLabel). myLabel. backgroundColor="#cccccc". public class MyLocaleChangeSample extends Sprite { 4.MULTIPLE. [SWF(width="1024".setPosition(100.List. initialize your data provider.localeManager. myDP = new DataProvier(). This statement sets the width. stage. onLocaleChange).width = 400. myList = new List(). Create a constructor for your class and invoke the initializeUI() method. 5.addEventListener(Event.ui. public function MyLocaleChangeSample() { initializeUI().listClasses. private var myLabel:Label. } 6. height.setPosition(100. myList.height = 500. Create instance variables to store a List object.CHANGE. an event listener is added to listen for locale change events. } 8. private var myDP:DataProvider. Add the following statement to your class before the class declaration.listClasses. 7. import qnx.

setItems([{label: {label: {label: {label: {label: {label: LocaleManager.events.localeManager. Add items to your data provider and set the text property of the LabelButton. myLabel = new Label(). private var myDP:DataProvider. frameRate="30".getResource("list-celery")}.CHANGE.ui.getResource("list-corn")}]). var lm:LocaleManager = LocaleManager. } myList.addEventListener(Event. qnx. 9. the getResource() method is called to return the string that is associated with the specified resource key.setPosition(100.listClasses.Beta Customers Only.localeManager. LocaleManager.localeManager.DataProvider. qnx.getResource("list-tomato")}.getResource("label-title").Sprite.display. myDP. The localeManager class returns the resources that are defined for the current locale. LocaleManager. 10. Set the dataProvider property of your list to the DataProvider object you populated in step 9.localeManager. width="1024". [SWF(height="600". private var myLabel:Label.ui. myLabel.Label. import import import import import qnx. public function MyLocaleChangeSample() { initializeUI(). //Create a label.text = LocaleManager.ui.getResource("list-potato")}.ui.localeManager.getResource("list-asparagus")}.dataProvider = myDP.Event. LocaleManager.text. import flash.LocaleManager.locale.data.localeManager. package { import flash.RIM Confidential and Proprietary Information . lm.localeManager. myDP = new DataProvider().listClasses. } private function initializeUI():void { //Listen for locale changes. } } Code sample: Localizing an application The following code sample demonstrates how to build localization support into an application. LocaleManager. qnx. onLocaleChange). myLabel. 150). In this step.getResource("list-bacon")}. This code sample assumes that the resource bundles are present at runtime.ListSelectionMode.localeManager. qnx. Content and software are subject to change. LocaleManager.List. 119 . backgroundColor="#FFFFFF")] public class MyLocaleChangeSample extends Sprite { private var myList:List.

RIM Confidential and Proprietary Information .getResource("list-tomato")}.display. myList. {label: LocaleManager. Content and software are subject to change. {label: LocaleManager. and background color of the Stage. import import import import qnx.addChild(myLabel).SegmentedControl. 5.getResource("list-celery")}.events.dataProvider = myDP. } //This function is called when the locale of the device changes.localeManager. backgroundColor="#cccccc".Event. myList.getResource("list-corn")}]). //Create a list. import flash. myList = new List().locale.getResource("list-potato")}. {label: LocaleManager. Create an application framework by extending the Sprite class.Beta Customers Only. public class MyLocaleSample extends Sprite { 4.LocaleManager. Import the required classes and interfaces. Create an instance variable that refers to a SegmentedControl and a DataProvider. private function onLocaleChange(event:Event):void { myDP. private var myDP:DataProvider.addChild(myList).localeManager. qnx. myList.locale.height = 500. myLabel. import flash.getResource("list-asparagus")}.ui. This statement sets the width.text = LocaleManager. qnx.width = 400. myList.getResource("label-title"). frameRate="30")] 3.buttons. qnx. } } } Load a resource bundle 1. {label: LocaleManager. {label: LocaleManager.selectionMode = ListSelectionMode. height="600".x = 100 myList.y = 100.setItems([{label: LocaleManager.localeManager.getResource("list-bacon")}. Add the following statement to your class before the class declaration. stage. 120 .data.Sprite.LocaleResourceBundle. frame rate.ui. private var mySegmented:SegmentedControl.localeManager.localeManager.DataProvider. Create a constructor for your class and invoke the initializeUI() method and initialize your data provider. 2. stage. This SegmentedControl object uses resource strings to create button labels.localeManager. height.localeManager. myList.MULTIPLE. [SWF(width="1024".

8. 9. so you can only reference a resource string after your application finishes loading a resource bundle. stage. the current device locale.getLocalePath() + "/resource. Create the onResourceLoad() function. onResourceLoad ). onResourceLoad() stores the event as a LocaleResourceBundle object named bundle.getResource("day-saturday")}]).getResource("day-wednesday")}. {label: bundle. {label: bundle. Your application must listen for bundle load completion events. myDP = new DataProvider(). The BlackBerry® Tablet OS calls onResourceLoad() when it finishes loading the resource bundle.addEventListener( Event.height = 50.dataProvider property. 200).properties" ). myDP. Resource bundles are loaded asynchronously.COMPLETE.setItems([{label: bundle. {label: bundle. {label: bundle. mySegmented. an event listener is added to listen for resource bundle load complete events.getResource("day-thursday")}. In the following code sample. The Event.dataProvider = myDP.getResource("day-monday")}. In the following code sample. Content and software are subject to change.Beta Customers Only. In the following code sample. and the file name of the resource bundle. private function initializeUI():void { mySegmented = new SegmentedControl().getResource("day-friday")}. Create a LocaleResourceBundle instance and add an event listener. mySegmented. Load the resource bundle for the current locale. The strings are passed into the function by calling the getResource() method. } 6. var MyBundle:LocaleResourceBundle = new LocaleResourceBundle(). 121 . MyBundle. {label: bundle.getResource("day-sunday")}.width = 700. 10. private function onResourceLoad(event:Event):void { trace(LocaleManager. The getCurrentLocale() method returns the current locale.getCurrentLocale()).COMPLETE event is dispatched only after a resource bundle has loaded. Assign your data provider to the SegmentedControl.RIM Confidential and Proprietary Information . Add items to your data provider by passing in resource strings from the current resource bundle. {label: bundle. mySegmented. MyBundle. the load() method is called by passing in a compound string that comprises the directory name. mySegmented. Create initializeUI() and instantiate the SegmentedControl object.target as LocaleResourceBundle.load(LocaleManager.getResource("day-tuesday")}. 7.addChild(mySegmented).localeManager.setPosition(100. var bundle:LocaleResourceBundle = event. public function MyLocaleSample() { initializeUI().

getResource("day-tuesday")}. [SWF(height="600".SegmentedControl.DataProvider.getResource("day-saturday")}]).getCurrentLocale()). mySegmented.localeManager. import import import import qnx. 200).width = 700. MyBundle. {label: bundle.locale. //Create a segmented control mySegmented = new SegmentedControl(). qnx. {label: bundle.load( "locale/" + LocaleManager. stage.getResource("day-friday")}. } } } Code sample: Loading a resource bundle package { import flash.LocaleManager. mySegmented.setItems([{label: bundle. mySegmented.locale.properties" ). backgroundColor="#FFFFFF")] public class MyLocaleSample extends Sprite { private var mySegmented:SegmentedControl. } //This function is called when the resource bundle is loaded. private function onResourceLoad(event:Event):void { trace(LocaleManager. width="1024". frameRate="30". //Update the buttons in the segmented control with the bundle resources myDP.addChild(mySegmented). qnx.RIM Confidential and Proprietary Information .getResource("day-thursday")}. {label: bundle.localeManager.getCurrentLocale() + "/resource. qnx. Content and software are subject to change.ui.events.Sprite.target as LocaleResourceBundle. var bundle:LocaleResourceBundle = event.addEventListener( Event. onResourceLoad ). public function MyLocaleSample() { initializeUI(). {label: bundle.getResource("day-monday")}.buttons. import flash. {label: bundle. 122 .data.display.height = 50.COMPLETE.setPosition(100.LocaleResourceBundle. //Store the incoming event target as a bundle.getResource("day-wednesday")}.Event.getResource("day-sunday")}. } private function initializeUI():void { //Load the resource bundle var MyBundle:LocaleResourceBundle = new LocaleResourceBundle().Beta Customers Only. {label: bundle. myDP = new DataProvider(). private var myDP:DataProvider.ui. MyBundle.

dataProvider = myDP.Beta Customers Only. } } } mySegmented. 123 .RIM Confidential and Proprietary Information . Content and software are subject to change.

The net. The Payment Service server blocks subsequent purchases by the user. To view the required minimum time period in the Research In Motion® SDK License agreement. you must ensure that the digital goods are available through your application for a specific period of time after the user downloads the application. Depending on the license models that your application uses.RIM Confidential and Proprietary Information . By invoking the PaymentSystem.events package contains events that allow your application to listen for successful or unsuccessful purchases. The Payment Service server does not set any controls on the number of times that a user can purchase these goods. Users can purchase digital goods using any of the payment types supported by BlackBerry App World. Consumable Digital goods that are registered as consumable must be purchased by a user for each use. One-time payment Digital goods that are registered as one-time payment are purchased only once by a user.getExistingPurchases function. you could sell tickets to a virtual attraction or feed for a virtual animal. In App Payments 16 The BlackBerry® Tablet OS SDK enables you to use the same Payment Service that processes all purchases that users make in the BlackBerry App World™ storefront. In this scenario.rim. Content and software are subject to change. When you offer a single-instance digital good. You must also make sure that digital goods are still available if the user reinstalls the application or switches devices.payment package to create a highly secure and consistent purchase experience that allows users to buy digital goods without leaving your application. For example. visit http://us.blackberry. To sign up as a vendor.com/ isvportal.blackberry. Digital goods aren't automatically restored.blackberry.blackberry. in a virtual world simulation. you might want to customize the way you present purchase options to reflect that digital goods were purchased already.Beta Customers Only. or PayPal®.com/developers/legal. Digital goods go through a vetting process along with your applications. you might want to provide a way for users to see their purchase history. Payment types can include billing to the wireless service provider (if available). credit card.rim.jsp. To sell digital goods from your application you must be a registered vendor with BlackBerry App World and your application containing digital goods must be distributed exclusively through BlackBerry App World. visit appworld. you can retrieve a record of a user's past purchases. License models You can distribute digital goods in your application by using a number of different license models (some of which are supported by the Payment Service). Subscription 124 . You can use the classes in the net. so it's up to you to make sure that users can download these digital goods again.

0. see the BlackBerry App World vendor documentation at www. To purchase subscription-based digital goods in your application. Content and software are subject to change. You must provide the name. Set up a UI Create a class to store the properties for your digital goods Retrieve and display a list of digital goods Initiate a purchase Check for past purchases 125 . you can use the same name and SKU for multiple digital goods. you can pass a metadata argument that allows you to differentiate between digital goods that reference the same SKU.blackberry. If it is impractical to create a separate name and SKU for each of your digital goods. Users are then charged the renewal fee each time the usage period elapses so that they can continue to use the digital goods.purchase() function. 2. 3. This way you can update the purchase options without submitting a new version of your application. the SKU (the unique identifier for the digital goods). Users are charged the initial fee when they purchase the digital goods and can use the digital goods for the initial period of time. Registering digital goods with BlackBerry App World When you submit an application for review in the BlackBerry App World™ vendor portal. as well as a renewal fee and usage period. When you register subscription-based digital goods. When you invoke the PaymentSystem. In this scenario. 4. and the user is charged at regular intervals for continued use of the goods.RIM Confidential and Proprietary Information . you might register digital goods with the name "Video $4. if you sell streaming video through your application.99" and use the same SKU for every streaming video that you sell at the $4. and a description of the digital goods in each language that your application is available. For more information about submitting applications and digital goods. For example. users must be running BlackBerry App World™ storefront 3. the license model (consumable or one-time payment). Creating an application that sells digital goods Creating an application that sells digtal goods involves the following tasks: 1. the pricing tier. but you cannot use the Payment Service to process transactions for goods with no monetary value. you must also add the details about the digital goods that your application offers. 5. Free The Payment Service doesn't provide support for free digital goods.Beta Customers Only. you could use one name and SKU for the digital goods that you sell at a particular price tier. Digital goods that are registered as a subscription are purchased initially by a user.99 pricing tier. Your application can distribute free digital goods.com/go/appworld/vendordocs/. You can implement a trial period for your subscription-based digital goods by not specifying an initial fee. you must specify an initial fee and usage period. Users can download your digital goods and use them free of charge for the trial period and are charged after the trial period ends.

Sprite. instantiate PaymentSystem and set the connection mode to local. net. 2.ui.CONNECTION_MODE_LOCAL). Create an application framework by extending Sprite. } initializeUI(). invoke initializeUI(). Set an event listener on each button to listen for click events.rim. see Code sample: Creating an application that sells digital goods. buyButton:LabelButton. qnx. 1. For a complete sample application.PaymentSystem.RIM Confidential and Proprietary Information . 6.ui. [SWF(height="600".setConnectionMode(PaymentSystem. instantiate the UI components. a Buy button. private function initializeUI():void { 7. All purchases are simulated within the application. This statement sets the stage width and height. the frame rate. width="1024". backgroundColor="#FFFFFF")] 3. You initiate a purchase of one of the digital goods by clicking the Buy button. public function PaymentServiceDemo() { paymentSystem = new PaymentSystem(). frameRate="30". paymentSystem. Set up the UI This task demonstrates how create a simple UI that allows users to purchase digital goods from your application.events. refreshButton:LabelButton. In the constructor.Beta Customers Only. Declare a variable for PaymentSystem. Add the following statement to your class. You can retrieve an array of past successful purchases by clicking the Refresh button. qnx. In the constructor. 126 . Create a constructor for your class. class PaymentServiceDemo extends Sprite { 4.List.LabelButton. Content and software are subject to change. private private private private var var var var paymentSystem:PaymentSystem. buyList:List.blackberry.MouseEvent. 5.display. and add the components to the stage.listClasses. and the background color of your application. Declare variables for the list and buttons that you need to use to build your UI. import import import import import flash. Setting the connection mode to local prevents your application from processing purchases with the Payment Service server. Import the required classes. Create the initializeUI function to setup and initialize the UI controls. and a Refresh button.buttons. Set the selection mode on the list to permit single selections. set the appropriate properties. The sample application displays a list of goods.payment. directly before the class signature. which is the class that is required for invoking purchases. In the initializeUI function. flash.

305). only the buttons appear on the screen.width = 400. Create the purchaseHandler function. buyList.width = 150.scrollable = true.addChild(buyList).CLICK. buyButton. buyButton. you must specify a data provider for the list and populate the list with data. 305). 1. This function runs whens the Refresh button dispatches a click event.addChild(refreshButton). buyList. buyButton. Create a new ActionScript class named DigitalGoodsInfo.addEventListener(MouseEvent.addChild(buyButton). buyList. refreshButton.width = 150. refreshButton. buyButton.setPosition(180. refreshButton = new LabelButton(). private function refreshHandler(event:MouseEvent):void { } 10. it can help you manage the data more efficiently.allowDeselect = false. refreshButton. This function runs whens the Buy button dispatches a click event. buyList. Content and software are subject to change. } this.columnWidth = 400. 8. refreshButton.selectionMode = ListSelectionMode.height = 250. Run the application.25). this.CLICK. 127 . but when you're dealing with large numbers of digital goods that you want to update dynamically. buyList. private function purchaseHandler(event:MouseEvent):void { } 9.label = "Refresh". refreshHandler). purchaseHandler).Beta Customers Only. you create a class that is designed to store the properties for the digital goods that your application offers.setPosition(25.SINGLE. Create the refreshHandler function.RIM Confidential and Proprietary Information . Before the list can appear. buyList.setPosition(25. When you run the application. In this task. this. buyButton = new LabelButton().label = "Buy". Create a class to store the properties for your digital goods Creating a separate class to store the properties for your digital goods isn't a requirement.addEventListener(MouseEvent. buyList. buyList = new List().

In this task. Create public variables for each of the properties for your digital goods. appName = "PaymentServiceDemo".ui.com/products/appworld_3col. public function DigitalGoodsInfo( name:String. this.RIM Confidential and Proprietary Information . 3.collections.rpc. icon:String.http. mx. Set the values of the icon and appName properties to default values.sku = sku. By maintaining a list of digital goods outside of your application. 1. mx. 128 . Create the constructor for DigitalGoodsInfo. metadata:String ) { 4.DigitalGoodInfo. icon = "http://www. import import import import import import mx. and metadata of the digital goods as parameters. you: • Retrieve data from a remote server by using an HTTPService call.Beta Customers Only.HTTPService. • Create an ArrayCollection of DigitalGoodsInfo objects. The constructor accepts strings for the name. metadata:String.metadata = metadata.events. sku. sku:String.rpc.name = name. this. set the values for the properties of the class to the values of the parameters that the constructor receives.rim. In PaymentServiceDemo. you might want to dynamically update the list of digital goods that your application offers. • Populate the List object that you previously created using the names of the digital goods. package valueObjects { public class DigitalGoodsInfo { 2. Content and software are subject to change.data. this. In the constructor. } } } Retrieve and display a list of digital goods Depending on your application. mx. you can make updates without having to release a new version of your application.ArrayCollection. import the required classes.events.ResultEvent. qnx. Make sure that you import the DigitalGoodsInfo class that you created. appName:String.rpc. valueObjects.DataProvider. public public public public public var var var var var name:String.jpg". sku:String.FaultEvent.

remoteData = event.xml". private var digitalGoods:ArrayCollection. create an instance of the HTTPService class. var remoteData:ArrayCollection.xml.addEventListener(FaultEvent.blackberry. This function runs when HTTPService broadcasts a result event.com/digitalgoods. populate the remoteData variable that you declared with the .url = "http://docs. The result of the following code sample is that each index in the array collection is populated with an object that contains a digitalgood element and all of its children elements. The array collection is required for storing the value objects that contain data about the digital goods that your application offers.FAULT. In the resultHandler function. 129 . var dgObject:DigitalGoodsInfo. httpService. For the complete contents of the digitalgoods. private function resultHandler(event:ResultEvent):void { 5. digitalgoods. add declarations for ArrayCollection and HTTPService variables.xml file is named <digitalgoods>. private var httpService:HTTPService.xml data retrieved during the HTTPService call. 3. the class that you created to store the properties of digital goods. and set event listeners to listen for ResultEvent. instantiate the data provider. Invoke send() to send the HTTPService call. resultHandler). 6.blackberry. faultHandler). this. In the following code sample. Instantiate the array collection that you created to contain the DigitalGoodsInfo objects. Content and software are subject to change. Specify the URL for the location of the .xml file. httpService.digitalgood.result. and set the data provider on the list that you created when you set up the UI. In the resultHandler function. HTTPService broadcasts one of these two events depending on whether the HTTPService call is successful or not. The parent element in the . which contains the .com/digitalgoods. The <digitalgood> elements contain the individual properties for each of the digital goods.result property contains. In the body of the PaymentServiceDemo class. var data:DataProvider.FAULT. httpService. } 4. 2. In the resultHandler function. httpService.digitalgoods. 7.RESULT. Declare a variable for DigitalGoodsInfo. and it contains a series of children named <digitalgood>.xml file.send().digitalgood represents the hierarchy of the elements in the . In the initializeUI function. visit http://docs.RIM Confidential and Proprietary Information . declare variables for an ArrayCollection and a DataProvider.xml data that the event.addChild(refreshButton). The ResultEvent object that this function receives has a result property.addEventListener(ResultEvent.RESULT and FaultEvent.xml file. httpService = new HTTPService().Beta Customers Only. Create the function resultHandler.

xml file. data = new DataProvider(). set the current selection in the list to the first item. Pass in the name. and so on. Content and software are subject to change.RIM Confidential and Proprietary Information . In the resultHandler function.sku. create a for each loop that iterates over each object in the array collection."). buyList. The list that you created is now populated with the names of the digital goods.addItem(dgObject). import the required classes. obj.name. } buyList. for each(var obj:Object in remoteData) { 9. 1. call the PaymentSystem. 130 .metadata). Initiate a purchase When you're ready to charge your user's account for a purchase. • Set event listeners to listen for successful and unsuccessful purchases.Beta Customers Only.dataProvider. 8. This function runs when HTTPService broadcasts a fault event. sku. informatino about the digitals goods being purchased. PaymentSystem. Add the new instance of DigitalGoodsinfo to the digitalGoods array collection.selectedIndex = 0.purchase takes a variety of arguments that include things like authentication with the Payment Service server. In this task.addItem({label: obj. you: • Define the functionality for the purchaseHandler function. Create the function faultHandler. see Arguments for purchases. Run the application. dgObject = new DigitalGoodsInfo(obj. After the for each loop has executed. • Define the functionality for when the purchase routine completes. create a new instance of DigitalGoodsinfo. obj. buyList. } 12. Add the name of the digital goods to the data provider for the list that you previously created. } 11. digitalGoods. In PaymentServiceDemo.dataProvider = data.name}). digitalGoods = new ArrayCollection(). In the faultHandler function. 10. To see a description of all the arguments. In the for each loop.purchase function. and metadata from the current index of the array collection to the constructor. private function faultHandler(event:FaultEvent):void { trace("Unable to retrieve digital goods from the server. which runs when the user presses the Buy button. create a trace statement that notifies you if the application is unable to retrieve the data from the . and the names of the digital goods are all added to the list.

Beta Customers Only.icon). Set the value of index to the index of the row in the list that is currently selected.addEventListener(PaymentSuccessEvent. In the purchaseHandler function. declare a variable for Purchase. var purchase:Purchase = event.digitalGoodID + " : " + purchase. digitalGoods. paymentSystem.purchase property.events. 6.payment.PaymentSuccessEvent. purchaseErrorHandler). add some event listeners to listen for successful and unsuccessful purchase attempts. This function runs when PaymentSystem dispatches PaymentSuccessEvent.sku.name.PURCHASE_SUCCESS.digitalGoodSKU + 131 .RIM Confidential and Proprietary Information .selectedIndex. private function purchaseSuccessHandler(event:PaymentSuccessEvent):void { The PaymentSuccessEvent object that this function receives has a purchase property. declare a variable called index. digitalGoods.purchase(null.PURCHASE_ERROR.getItemAt(index). From the array collection of DigitalGoodsInfo objects.rim. In the purchaseHandler function.PURCHASE_SUCCESS. Pass in the properties as arguments to purchase().appName.purchase(). paymentSystem.CONNECTION_MODE_LOCAL).blackberry. import net. trace("Purchase Success . which contains details about the successful purchase.getItemAt(index).blackberry. get the properties of the object that is at the position in the array collection equivalent to the position of the list item that is currently selected.getItemAt(index). Create a trace statement to display all of the details of the successful purchase. digitalGoods.purchase. Create the purchaseSuccessHandler function." + purchase.rim. invoke PaymentSystem.addEventListener(PaymentErrorEvent.setConnectionMode(PaymentSystem.getItemAt(index). index = buyList. and set the value to the event.getItemAt(index).PaymentErrorEvent. In the purchaseSuccessHandler function. import net. 5. paymentSystem. paymentSystem.blackberry.metadata. digitalGoods. digitalGoods.Purchase.rim. import net. } initializeUI(). In the constructor. } 4.date + " : " + purchase.events. private function purchaseHandler(event:MouseEvent):void { var index:int. Content and software are subject to change. 2. purchaseSuccessHandler). 3.

you might want to handle some errors differently from others. 10. } trace("Purchase Error . digitalGoodID 132 .RIM Confidential and Proprietary Information . Argument digitalGoodSKU Description • • • • • • • Required argument (can be substituted with the ID). and is 5 to 100 characters in length. which contains an integer representing the type of error. This enables you test the responses you can expect from the Payment Service so that you can test whether your application handles the responses the way you intend. The PaymentErrorEvent object that this function receives has an errorID property.CONNECTION_MODE_LOCAL.metaData + " : " + purchase. Required argument (can be substituted with the SKU).PURCHASE_ERROR.errorID + " : " + event. the dialog displays a drop-down list that allows you specify the result that you want for the test purchase. If specified along with the SKU. An identifier that you assign to digital goods when you register the digital goods in the BlackBerry App World™ vendor portal.transactionID). Arguments for purchases The following table describes the arguments that you can pass to PaymentEngine. Content and software are subject to change. if the purchase fails because the user cancels the purchase. the SKU is ignored.Beta Customers Only. If the connection mode for the application is set to PaymentSystem. This function runs when PaymentSystem dispatches PaymentErrorEvent. must not contain only numbers. and a text property. If the application is configured for testing. while if the purchase fails because of an error with the server. Run the application. you might want to display an alert to the user indicating that the purchase is a success. In production." + event. private function purchaseErrorHandler(event:PaymentErrorEvent):void { 8. In production. which contains a human-readable error message. the confirmation dialog that you see is different from the dialog that users see when the application is in production. 7. you might want to display an alert that indicates that. the SKU is ignored.licenseKey + " : " + purchase. In the purchaseErrorHandler function. If specified along with the ID. } " : " + purchase. Create the purchaseErrorHandler function. For example. 9. After the application starts. An identifier that the vendor portal assigns to your digital goods after you register the digital goods in the vendor portal. create a trace statement to display the error ID and the error message. An alphanumeric string that can contain hyphens (-) and underscores (_).purchase(). you might not want to do anything. select one of the digital goods and press Buy.text).

as it appears on the Home screen of the device. Appears on the purchase confirmation dialogs in your application to provide users with context for what they are purchasing. • metadata • • • purchaseAppName • • • • purchaseAppIcon • • • • Check for existing purchases Records of a user's past purchases are stored in a file on the device. Argument digitalGoodName Description • • Optional argument.Beta Customers Only. If you specify true for allowRefresh. 133 .getExistingPurchases function accepts a Boolean argument named allowRefresh. can change dynamically (for example. Appears on the purchase confirmation dialogs in your application to provide users with context for what they are purchasing. Identifying a user's past purchases is necessary if you need to perform any of the following tasks: • Modify the UI of your application to reflect past purchases. the function tries to retrieve the purchase history from the Payment Service server. A name that overrides the name that you specified for the digital goods when you registered the digital goods in the vendor portal (the registered name might be a generic name that describes an entire batch of digital goods). Content and software are subject to change. • Implement a subscription model for your digital goods. Returned with each Purchase object when you make a getExistingPurchases() call. if the application name changes when the icon for the application receives focus). • Redistribute digital goods to users that switch devices. Should always be specified if the name of the application. Optional argument.RIM Confidential and Proprietary Information . and on the Payment Service server. as it appears on the Home screen of the device. if your application sells eBooks. The PaymentSystem. Optional argument Overrides the icon for the application that the purchase request originates from Should always be specified if the icon for the application. if the icon changes when new content is available in the application). Appears on the purchase confirmation dialogs in your application to provide users with context for what they are purchasing. Overrides the application name retrieved from the application descriptor. the identifier could be an ISBN number). A unique identifier that is required if you need to differentiate between the digital goods that reference the same SKU (for example. can change dynamically (for example. Optional argument.

If your application is configured for local testing. getPurchasesSuccessHandler). In the for loop. The purchases history on the device could be out of date for a variety reasons.GET_EXISTING_PURCHASES_ERROR. If the user has switched devices. } initializeUI(). Create a trace statement to display all of the details of the successful purchase. invoke getExistingPurchases(). Create a for loop that iterates through each position in the array of purchases. In this task. you can use the updated array of purchases to make sure that all of the user's past purchases are made available. you should invoke getExistingPurchases(true) each time your application starts. add event listeners to listen for successful and unsuccessful attempts at retrieving the array of existing purchases. Declare a variable for an array. In the getPurchasesSuccessHandler function. i++) { 5. declare a variable for Purchase.Beta Customers Only. private function purchaseHandler(event:MouseEvent):void { paymentSystem. Create the getPurchasesSuccessHandler function. and set the value to the event. The PaymentSuccessEvent object has an existingPurchases property that contains an array of Purchase objects. you invoke getExistingPurchases(false) to retrieve the array of existing purchases from the device. getPurchasesErrorHandler). var pastPurchases:Array = event. } 2. 1.addEventListener( PaymentErrorEvent. Content and software are subject to change. In the constructor. This function runs when PaymentSystem dispatches PaymentSuccessEvent.RIM Confidential and Proprietary Information .length. private function getPurchasesSuccessHandler(event:PaymentSuccessEvent):void { 4. Each of those objects represent a successful purchase. In the refreshHandler function. paymentSystem.addEventListener( PaymentSuccessEvent.existingPurchases.GET_EXISTING_PURCHASES_SUCCESS. for (var i:int = 0. get the Purchase object from the current position in the array.existingPurchases property. 134 . var purchase:Purchase. Pass in false as an argument so that the application doesn't attempt to refresh the array of past purchases with the server.GET_EXISTING_PURCHASES_SUCCESS. i < pastPurchases. As a best practice. including a device switch. and you attempt to refresh the array of existing purchases with the server. 3. getExistingPurchases throws an error. paymentSystem.getExistingPurchases(false).

FaultEvent. qnx.ArrayCollection.rpc. initiate a series of successful purchases. Debug the application.rim. backgroundColor="#FFFFFF")] // A simple application that offers digital goods 135 .licenseKey + " : " + purchase.rim.digitalGoodSKU + " : " + purchase. This function runs when PaymentSystem dispatches PaymentSuccessEvent.Beta Customers Only. Create a trace statement to display the error ID and error message associated with the event.HTTPService.PaymentErrorEvent.payment.listClasses. net. import valueObjects.MouseEvent.digitalGoodID + " : " + purchase. qnx. 9.rpc.errorID + " : " + event.text). [SWF(height="600".events.GET_EXISTING_PURCHASES_SUCCESS. } } 6.rpc. import import import import import import import import import import import import mx.blackberry.DataProvider.PaymentSuccessEvent. 8. mx. net. net. private function getPurchasesErrorHandler(event:PaymentErrorEvent):void { trace("Get Existing Purchases Error . frameRate="30". mx.ui. Content and software are subject to change.Sprite. Code sample: Creating an application that sells digital goods PaymentServiceDemo." + purchase.blackberry. Press the Refresh button. net.data. Create the getPurchasesErrorHandler function. mx.transactionID).events.as package { import flash.LabelButton.Purchase. qnx.DigitalGoodsInfo.RIM Confidential and Proprietary Information . The console displays information for each of the previous successful purchases. import flash.listClasses.blackberry. width="1024".events. trace("Get Existing Purchases Success .PaymentSystem.date + " : " + purchase.ui. After the application starts.blackberry.List.collections.ResultEvent.payment.metaData + " : " + purchase.events.ui.ui.events." + event. } 7. purchase = pastPurchases[i].rim.rim.ListSelectionMode. qnx.display.http.buttons.

private var digitalGoods:ArrayCollection. this. buyList.setConnectionMode(PaymentSystem.PURCHASE_SUCCESS.addChild(buyList). paymentSystem. 305). paymentSystem. getPurchasesErrorHandler). private var httpService:HTTPService. purchaseHandler).columnWidth = 400.setPosition(180.GET_EXISTING_PURCHASES_ERROR.width = 400.PURCHASE_ERROR. public class PaymentServiceDemo extends Sprite { private var paymentSystem:PaymentSystem. // creates the Buy button buyButton = new LabelButton(). // listeners for successful and unsuccessful payment events paymentSystem.addEventListener( PaymentErrorEvent. public function PaymentServiceDemo() { // configures the application for testing paymentSystem = new PaymentSystem(). buyList. purchaseSuccessHandler). refreshButton. } initializeUI().SINGLE.selectionMode = ListSelectionMode. getPurchasesSuccessHandler).setPosition(25. buyList.addEventListener( PaymentSuccessEvent.CLICK. private var refreshButton:LabelButton. private function initializeUI():void { // creates the list that displays purchase options buyList = new List(). buyButton. // creates the Refresh button refreshButton = new LabelButton().allowDeselect = false.scrollable = true.GET_EXISTING_PURCHASES_SUCCESS.width = 150.addEventListener(PaymentErrorEvent. private var buyList:List. paymentSystem.addEventListener(MouseEvent.CONNECTION_MODE_LOCAL). buyList.RIM Confidential and Proprietary Information . Content and software are subject to change. 305).width = 150. buyList.label = "Buy".addEventListener(PaymentSuccessEvent.height = 250. refreshButton. purchaseErrorHandler). paymentSystem.setPosition(25. private var buyButton:LabelButton.addChild(buyButton). 136 . buyButton. buyList. buyButton.25). this. buyList. buyButton.Beta Customers Only.

name. refreshHandler). // sends an HTTPService request to retrieve a list of digital goods httpService = new HTTPService(). resultHandler).addItem(dgObject). Content and software are subject to change. digitalGoods. obj. } private { var var var // creates an array of raw xml data remoteData = event. } buyList. refreshButton.blackberry. and displays the names of the // digital goods in the list for each(var obj:Object in remoteData) { dgObject = new DigitalGoodsInfo(obj.result. faultHandler). } private function purchaseHandler(event:MouseEvent):void { var index:int. obj.xml".FAULT.getItemAt(index). refreshButton.CLICK.Beta Customers Only. function resultHandler(event:ResultEvent):void remoteData:ArrayCollection.url = "http://docs.selectedIndex.metadata). creates // DigitalGoodsInfo objects.name.addChild(refreshButton).dataProvider.RESULT. digitalGoods.sku.send(). index = buyList. httpService. buyList.com/digitalgoods. httpService. httpService. data:DataProvider. } private function faultHandler(event:FaultEvent):void { trace("Unable to retrieve digital goods from the server. // sets a data provider for the list data = new DataProvider(). httpService.addEventListener(MouseEvent. buyList.purchase(null. digitalGoods = new ArrayCollection().label = "Refresh".addItem({label: obj.digitalgoods.addEventListener(FaultEvent.RIM Confidential and Proprietary Information . dgObject:DigitalGoodsInfo.selectedIndex = 0.").addEventListener(ResultEvent.digitalgood.name}).getItemAt(index). this.dataProvider = data.sku. // initiates a purchase using the properties of the digital good // that is at the equivalent position in the array as the position // in the list that is currently selected paymentSystem. digitalGoods. 137 . // loops through each object in the array of xml data.

} else { // iterates through the list of existing purchases and prints the data for (var i:int = 0.length == 0) { trace("No existing purchases"). var pastPurchases:Array = event.appName. i < pastPurchases. private function refreshHandler(event:MouseEvent):void { // initiates a local request for a list of existing purchases paymentSystem. if (pastPurchases.purchase. 138 .RIM Confidential and Proprietary Information .metadata. Content and software are subject to change.transactionID).licenseKey + " : " + purchase.getItemAt(index). trace("Get Existing Purchases Success .digitalGoodID + " : " + purchase. trace("Purchase Success .getItemAt(index)." + purchase. digitalGoods. } digitalGoods. i++) { purchase = pastPurchases[i]. } } } private function getPurchasesErrorHandler(event:PaymentErrorEvent):void { trace("Get Existing Purchases Error .digitalGoodSKU + " : " + purchase. } private function getPurchasesSuccessHandler(event:PaymentSuccessEvent):void { var purchase:Purchase.date + " : " + purchase." + event.getItemAt(index).metaData + " : " + purchase." + event.digitalGoodSKU + " : " + purchase.text).metaData + " : " + purchase.date + " : " + purchase.errorID + " : " + event.icon)." + purchase.Beta Customers Only.existingPurchases.errorID + " : " + event.text).length. } private function purchaseSuccessHandler(event:PaymentSuccessEvent):void { var purchase:Purchase = event.transactionID).licenseKey + " : " + purchase. } private function purchaseErrorHandler(event:PaymentErrorEvent):void { trace("Purchase Error .getExistingPurchases(false). digitalGoods.digitalGoodID + " : " + purchase.

xml <?xml version="1. public var metadata:String.Beta Customers Only. } } } DigitalGoodsInfo. public var appName:String. Content and software are subject to change. appName = "PaymentServiceDemo". icon = "http://www.rim. sku:String.RIM Confidential and Proprietary Information . metadata:String ) { this. this. public var sku:String.jpg".0" encoding="utf-8"?> <digitalgoods> <digitalgood> <name>Developing for BlackBerry</name> <sku>123456abc123</sku> <metadata>1234-56-7890</metadata> </digitalgood> <digitalgood> <name>Intro to the BlackBerry Tablet OS</name> <sku>123456abc123</sku> <metadata>09-4567-1243</metadata> </digitalgood> <digitalgood> <name>Tutorial: Selling Digital Goods</name> <sku>123456abc123</sku> <metadata>654-34-29304</metadata> </digitalgood> <digitalgood> <name>Feature and Technical Overview</name> <sku>123456abc123</sku> <metadata>7399-29-0940</metadata> </digitalgood> <digitalgood> <name>Development Guide</name> <sku>123456abc123</sku> 139 .com/products/appworld_3col. public function DigitalGoodsInfo( name:String.sku = sku. this.as package valueObjects { public class DigitalGoodsInfo { public var name:String. public var icon:String.metadata = metadata.name = name. } } } digitalgoods.

To request notifications from the Payment Service. After each successful purchase. you must set up a dynamic license model when you register the digital goods in the BlackBerry App World™ vendor portal. or you can request a notification from the Payment Service. You can design your application to send notifications. you can update and add to your offering of digital goods without having to submit a new release of your application to the BlackBerry App World™ storefront. Your game logic can control access to those levels based on the purchase logic. you must have the BlackBerry App World™ storefront 1. 140 . If the digital goods for your application don't require dynamic updates.RIM Confidential and Proprietary Information . if you sell a game that has a predetermined selection of additional levels. Testing your application The Payment Service supports live testing with the Payment Service server. Distributing digital goods from a content server If you host your digital goods on a content server. When you set up a dynamic license model for your digital goods.0 or later installed on the BlackBerry® PlayBook™ tablet. as well as the following parameters that describe the successful purchase: • • • • • • • pin: the device PIN email: the email address associated with the user's BlackBerry® ID account product: the name of the application that the digital goods are purchased from version: the version of the application that the digital goods are purchased from transactionid: a unique identifier for the successful purchase sku: the SKU test: true or false depending on whether the purchase is initiated using a BlackBerry ID account that is configured for testing After your content server receives the notification. the Payment Service server sends your content server a request for a license key. you can notify your content server about successful purchases in two different ways. include the functionality of those goods in the source code. To test an application. If you host your digital goods on a content server and deliver them to BlackBerry® devices over the wireless network. For example. Content and software are subject to change. those levels should be included in your application.Beta Customers Only. <metadata>34-90390-124</metadata> </digitalgood> </digitalgoods> Distributing digital goods You can distribute digital goods either by sending data files over the wireless network from your own server. it's up to you to make sure that your users receive the digital goods that they purchase. provide an HTTPS URL for your content server. or by unlocking existing functionality from within the application's code.

When you create a sandbox account. Content and software are subject to change. you can test the purchase of your products and any digital goods that you sell within your products by creating a sandbox account. Click Add New User. otherwise you won't be able to locate your application in the BlackBerry App World™ storefront. type a description for the sandbox account.com/id/. click Sandbox. Register for a BlackBerry® ID account at na. type the email address associated with a BlackBerry® ID. 5. Creating a sandbox account Before you make products available to BlackBerry® device and BlackBerry® PlayBook™ tablet users. Create a sandbox account 1.RIM Confidential and Proprietary Information . Download an application before you make it available for distribution If your application has any distribution restrictions (such as the BlackBerry® device models or BlackBerry® Device Software versions that it supports). You then use the BlackBerry ID to test the purchase of your products without being charged for the purchases. 2. Create a sandbox account by registering your BlackBerry ID in the vendor portal. When you initiate a purchase. Live testing Live testing permits you to test the purchase of digital goods against the live Payment Service server without being charged real money. Click Create. as well as digital goods within your applications.blackberry. you specify the email address that is associated with a BlackBerry ID. By registering the BlackBerry ID with the vendor portal. In the Email field. For more information about submitting applications and creating sandbox accounts. you can download your application from BlackBerry App World and start testing the purchase process against the live Payment Service server. After you add your application and digital goods. you must perform the following actions: • • • • Add your application to the vendor portal for the BlackBerry App World™ storefront (the application can remain in the Draft state). make sure that the BlackBerry device that you download the application to is compatible with your application. you can use the BlackBerry ID to perform test purchases of applications. and log in using the BlackBerry ID that you registered with the vendor portal. 4. The BlackBerry ID that you register with the vendor portal can be used only to purchase digital goods from the applications associated with your BlackBerry App World vendor account.Beta Customers Only. you can simulate a real purchase without any charges to your account.com/go/appworld/vendordocs/. 3.blackberry. To test your applications live. Add digital goods and a release bundle to your application in the vendor portal. In the Description field. On the vendor portal for the BlackBerry App World™ storefront. 141 . see the BlackBerry App World vendor documentation at www.

you can type http:// appworld. Before you begin: • Add your application. Open the browser on the tablet. 142 . 3. 4. On the home screen of the BlackBerry® PlayBook™ tablet. 5. You can simulate only the purchases of your own applications and digital goods.Beta Customers Only. Type tst. Content and software are subject to change. Tap Return. • Create a sandbox account in the vendor portal using a BlackBerry ID. Swipe your finger from the bottom left corner of the screen toward the center of the screen to display the keyboard.blackberry. 2.com/webstore/content/xxxxx. Complete the instructions on the screen to download the application. In the address bar. tap the BlackBerry App World icon.RIM Confidential and Proprietary Information . and your account is charged. type the location of the application that you want to test (for example. a release bundle. where xxxxx is the ID of the application). 6. 1. the transaction is real. not simulated. and digital goods in the vendor portal for the BlackBerry App World (the application status can remain as Draft). If you purchase another vendor's application or digital goods using your BlackBerry® ID account that is configured for testing.

The following table describes the elements of the configuration file: XML element action Description Specifies the device capability to which your application requires access. Specifies the BlackBerry Tablet OS Home screen category in which your application should appear. All applications appear in the All category by default. For more information about how to use this element. see Using debug tokens. If you create an XML configuration file in your Adobe® Flash® Builder project.xml configuration file. author authorId buildId category icon 143 .media This element is optional.RIM Confidential and Proprietary Information . it is automatically included in your BAR file.xml file. Specify a value for this element when you intend to run your application on a device using a debug token. For more information about how to use this element. The blackberry-tablet. For more information about version numbers. see Accessing restricted functionality. For a list of device capabilities. be sure to specify the blackberry-tablet. see Using debug tokens. Specifies the fourth segment of the version number for an application. This must be a value from 0 to 65535. The value must be one of: • core. For example. Your icon should be 86-by-86 pixels. The BlackBerry Tablet OS prompts the user to allow your application to use any device capability you specify in this element. You can only specify one element of this type in your blackberry-tablet.xml file 17 You can configure the appearance and behavior of your application in the BlackBerry® Tablet OS by specifying XML elements and values in the blackberry-tablet.xml file when you run the blackberry-airpackager tool. see Assigning a version number to your application. You can specify one action element per capability. Your application appears in the category you specified using this element and the All category. the user must grant your application permission to use the GPS or the microphone. This value should match the Author Id value from your debug token. An icon that is larger than 86-by-86 pixels will not display on the screen. Specifies the icon to display in the BlackBerry Tablet OS Home screen. If you package your application from the command line.games • core.Beta Customers Only. This value should match the Author value from your debug token. Specify a value for this element when you intend to run your application on a device using a debug token. Content and software are subject to change.

Specifies a BlackBerry Tablet OS configuration file.jpg:img/splash_portrait. the first file is used when the tablet is in an landscape orientation.xml and <myApplication>-app. Sample blackberry-tablet. see the BlackBerry PlayBook Tablet UI Guidelines. the BlackBerry Tablet OS displays the file in a landscape orientation. landscape orientation. XML element Description The icon must be included in your BAR file and can be a PNG file or JPG file. Your splash screen should be this size to fill the screen.png</image> </icon> <author>My Company</author> <authorId>gYAAgIqK0RLL5u4I9NanyxBUuCI</authorId> <category>core. <icon> <image>my_icon_image_file.png</image> </icon> platformVersion qnx splashscreen For more information about designing application icons.xml. The following attributes can be localized.jpg</splashscreen> <action>use_camera</action> <action>read_geolocation</action> <action>play_audio</action> <buildId>349</buildId> <platformVersion>1.0. This is the root XML element in blackberry-tablet. Specifies the minimum version of the BlackBerry Tablet OS required to run the application. Nest all other elements in this table within this element. and the second file is used when the tablet is in a portrait orientation.Beta Customers Only. Specifies the images to display while the BlackBerry Tablet OS loads your application.0.xml file <qnx> <icon> <image>my_icon. You specify the file name for the icon within an XML element named image. If you specify one file.games</category> <splashscreen>img/spalsh_landscape. The screen resolution of the BlackBerry® PlayBook™ tablet is 1024 by 600 pixels in default. Content and software are subject to change. You can specify up to two files separated by a colon (":"). The image for your splash screen must be included in your BAR file and can be a PNG file or JPG file.0</platformVersion> </qnx> Localization You can manage multiple regions and languages by localizing attributes in the blackberry-tablet.xml files.RIM Confidential and Proprietary Information .0.0. 144 . If you specify two files. The default is 1.0.

xml file: • • image splashscreen For a list of available language codes.xml <name> <text xml:lang="en-US">localization</text> <text xml:lang="fr-FR">localisation</text> <text xml:lang="de-DE">lokalisation</text> </name> 145 . Content and software are subject to change. In the <myApplication>-app.Beta Customers Only. Sample localization syntax in <myApplication>-app. see <Link to Language Codes>.xml file: • • name description In the blackberry-tablet.RIM Confidential and Proprietary Information .

bar file) during the signing process. When you sign an application. You must increment the version number of your application each time you sign it. You can change the build number by updating the buildId element in your blackberry-tablet. This wizard runs when you create a new Adobe® ActionScript® Mobile Project and guides you through the configuration process to sign your applications or test them on a BlackBerry® PlayBook™ tablet.xml and using the blackberry-airpackager tool. 146 . The hash files help verify the authorship of your application to users and the BlackBerry® Tablet OS. Alternatively.(Build) Each time you sign your application. The version number for a BlackBerry® Tablet OS application comprises a series of four numbers separated by decimals (for example 1.xml file. 2. you must sign your application. Signing your application 18 Before you can distribute your application for use on a BlackBerry® tablet.xml file. The signing tool included with the BlackBerry® Tablet OS SDK adds cryptographic hash values to your application package (. Content and software are subject to change.bar file signature from the RIM® Signing Authority. If you do not specify a build number.(Revision). After you sign your application. you can manually configure your environment for application signing.0. you receive two . Request permission to sign BlackBerry Tablet OS applications by completing the web form at https:// www.(Minor). you can create and install a debug token on the device.blackberry. see Using debug tokens.357). you must change at least one segment of the version number. you can specify the build ID using the buildId command line option when you package your application using the blackberry-airpackager tool. you can publish it to the BlackBerry App World™ storefront. The buildId option accepts a number from 0 to 65535. After your request is accepted.Beta Customers Only.com/SignedKeys.5. Sign your application by requesting a .RIM Confidential and Proprietary Information . minor. (Major). The RDK file allows you to configure your keystore to sign applications and the PBDT file allows you to create debug tokens.csj registration files by email. the default build segment of your version number is 0. If necessary. you perform the following actions: 1. If you specify a build number in both the blackberry-tablet. You can change the major. and revision numbers by updating the versionNumber element in the your_project_nameapp. 3. For more information about debug tokens. Assigning a version number to your application You must change the version number of your application before you package it for signing and installation on BlackBerry® tablets. Complete the BlackBerry Tablet OS deployment setup wizard. If you want to test your application on a device without signing it. the value given to the blackberryairpackager tool is used. Each file arrives in a separate email with information about the purpose of the file attached.

On the Register with RIM Signing Authority screen. in the preferences list. Configure application signing manually in Flash Builder The following steps help you manually configure your computer to sign applications. complete the following steps: a. 3. In the CSJ Pin field. expand Flash Builder > Target Platforms > BlackBerry Tablet OS.Beta Customers Only. 147 . 5. c. On the Preferences screen.blackberry. click Preferences. in the RIM Signing Authority section. After your application is accepted. click Preferences. Content and software are subject to change. After your application is accepted. e. expand Flash Builder > Target Platforms > BlackBerry Tablet OS.com/SignedKeys. On the Preferences screen. Click Signing. In the PBDT CSJ Path field. 5. You should only perform these steps once. Before you begin: Request permission to sign BlackBerry® Tablet OS applications by completing the web form at https://www. b. 3. click Register. you receive two CSJ registration files by email. provide the PIN you entered on the web form to request permission to sign applications. provide the location of the PBDT CSJ registration file you received from the RIM Signing Authority. 4. In the CSK Password field. in the preferences list. d. Click OK. 2. provide the location of the RDK CSJ registration file you received from the RIM® Signing Authority. On the Window menu. Configure application signing and create debug tokens using the setup wizard in Flash Builder The following steps help you configure your computer to sign applications and create debug tokens using the setup wizard. 2. On the Window menu. On the Preferences screen.com/SignedKeys. In the RDK CSJ Path field. Click BlackBerry Tablet OS Deployment Setup Wizard. 1. f. You should only perform these steps once. you receive two CSJ registration files by email. Follow the setup wizard to configure your computer to sign applications and create debug tokens. repeat the password you provided in the previous step. 4.blackberry. 1.RIM Confidential and Proprietary Information . Click Signing. In the Confirm CSK Password field. Before you begin: Request permission to sign BlackBerry® Tablet OS applications by completing the web form at https://www.

xml file. see Default file location for code signing keys. click Create certificate. in the Certificate Path field. e. For more information about the default location for signing keys and developer certificates. provide a password. provide a location where you want to store your developer certificate.RIM Confidential and Proprietary Information .Beta Customers Only. Click OK. In the Confirm Keystore Password field. d. f. For more information about the blackberry-tablet. see The blackberrytablet. In the Author field. Content and software are subject to change. 148 . Ensure that this value matches the author element in your blackberry-tablet.xml file. In the Keystore Password field. In the Developer Certificate section. b. On the Create Developer Certificate screen. c. 6. type your company name. repeat the password you provided in the previous step.xml file. Create a developer certificate by completing the following steps: a.

expand General. 149 . Content and software are subject to change. you must configure Adobe® Flash Builder® to use your proxy server. 2. If your computer uses a proxy server to connect to the Internet. 3. Configure application signing through a proxy server in Flash Builder During the signing process. in the preferences list. On the Window menu. Click Network Connections. On the Preferences screen.Beta Customers Only. 1. Click OK.RIM Confidential and Proprietary Information . In the Active Provider drop-down list. click Preferences. 7. your computer connects to the RIM® Signing Authority. click Manual.

specify the host address for your proxy server. Sign your application in Flash Builder Before you begin: 150 . specify the host port number for your proxy server. b. select the HTTP schema. In the Port field. In the Proxy entries section. c. Click Edit. a.RIM Confidential and Proprietary Information .Beta Customers Only. Content and software are subject to change. 5. Click OK. Click OK. In the Host field. 4.

On the Export Release Build window. On the File menu. see Assigning a version number to your application. select the BlackBerry Tablet OS check box. For more information about version numbers. Configure your computer to sign applications. Make sure that your computer is connected to the Internet.RIM Confidential and Proprietary Information . in the export destination list. Make sure that you increment the version number of your application. • • • 1. Select the Signed packages for each target platform option. in the Target platforms section. Click Release Build. In the Export section. b. Click Next. On the Export screen. 4. If you do not specify a path. Content and software are subject to change.Beta Customers Only. For more information about configuring your computer to sign applications. Click Browse to specify an export location for your application. see Configure application signing and create debug tokens using the setup wizard in Flash Builder. expand Flash Builder. 2. specify the export settings. click Export. a. Click Next. the application is exported to the project directory. 151 . 3. c.

On the Digital Signature tab. 152 .Beta Customers Only. Content and software are subject to change.RIM Confidential and Proprietary Information . Click Finish. select the Enable digital signing check box. 6. 5.

In the -storepass parameter.Beta Customers Only. For more information about distributing your applications through BlackBerry App World. Before you begin: • Request permission to sign BlackBerry® Tablet OS applications by completing the web form at https:// www. see Using a proxy server from the command line. The . You can find the blackberry-signer and blackberry-keytool tools in the bin subfolder where you installed the BlackBerry® Tablet OS SDK.bar file in the folder that you specified on the Export Release Build screen contains your signed application. you must specify the registration PIN you enter in the PIN field on the web form when you requested permission to sign applications. You can also configure your computer to create debug tokens at the same time by including the debug token CSJ file in the blackberry-signer command. Use the blackberry-signer tool to register with the RIM Signing Authority using your CSJ registration file for application signing.blackberry. you must specify additional command line options to contact the RIM® Signing Authority. You should only perform this step once. You can publish the . Configure application signing from the command line The command below helps you configure your computer to sign applications.RIM Confidential and Proprietary Information . you must specify the keystore password. • If you connect to the Internet through a proxy server. For more information about using a proxy server from the command line.bar file to BlackBerry App World™ storefront for distribution. Content and software are subject to change. In the -csjpin parameter. 153 .com/SignedKeys. see the Vendor Portal Administration Guide.

xml file.RIM Confidential and Proprietary Information . This options allows you to provide your password if your proxy server requires authentication. The command below creates a developer certificate.xml file. you should append the options in the table below to your blackberry-signer and blackberry-debugtokenrequest commands.xml file.Beta Customers Only. This option specifies the port number on your proxy server through which blackberry-signer or blackberry-debugtokenrequest should communicate with the RIM Signing Authority. you must create a developer certificate manually by using the blackberry-keytool tool. see The blackberry-tablet. The host parameter can be an IP address or a fully qualified domain name. 2011.168. For more information about the blackberry-tablet. Content and software are subject to change. If your computer connects to the Internet through a proxy server. blackberry-signer -register -csjpin <PIN> -storepass <KeystorePassword> <AppSigningCSJFile> <DebugTokenCSJFile> After you finish: If you received your signing keys before August 9.1. Example: blackberry-signer command line blackberry-signer -proxyhost 192. and the password that you specify in the -storepass parameter allows you to use the . This option allows you to provide your user name if your proxy server requires authentication. Option -proxyhost <host> -proxyport <port> -proxyusername <user name> -proxypassword <password> Description This option specifies the network host that provides the proxy service. You should protect the . Make sure that the common name (company name) parameter matches the author element in your blackberry-tablet.p12 file and its password.1 -proxyport 80 -register -csjpin <PIN> -storepass <KeystorePassword> <AppSigningCSJFile> <DebugTokenCSJFile> 154 . blackberry-keytool -genkeypair -storepass <storepass> -author <company_name> Using a proxy server from the command line During the signing process. your computer connects to the RIM® Signing Authority.p12 file to sign BAR files.

You must sign your application before you can publish it. Navigate to the folder where your SWF application and XML configuration files are stored.Beta Customers Only. For more information about using a proxy server from the command line.bar file to BlackBerry App World™ storefront for distribution. 155 . see Configure application signing from the command line. see Assigning a version number to your application. Alternatively. 1.bar file contains your signed application. In the -storepass parameter. you must specify additional command line options to contact the RIM® Signing Authority. For more information about packaging your application. see the Vendor Portal Administration Guide. Sign your application by with the blackberry-signer tool.RIM Confidential and Proprietary Information . You can find the blackberry-signer tool in bin subfolder where you installed the BlackBerry® Tablet OS SDK.bar> Your . Package your application from the command line Before you begin: Add the path to the bin subfolder where you installed the BlackBerry® Tablet OS SDK to the PATH environment variable for your operating system.bar file . Content and software are subject to change. For more information about distributing your applications through BlackBerry App World. see Using a proxy server from the command line. Type the following command to package your application.bar file. • Configure your computer to sign applications. 2. you can package and sign your application using separate commands. For more information about version numbers. The command below demonstrates how you can sign your application after you package it into a .xml project_name.swf any_other_project_files For more information about command line options. Before you begin: • Package your application into a . • If you connect to the Internet through a proxy server. Open a command prompt. For more information about configuring you computer to sign applications. 3. blackberry-airpackager -package output_filename project_name-app. you must specify the keystore password that you created when you configured application signing in the -storepass parameter. • Make sure you increment the version number of your application. run blackberry-airpackager from the command line with no options. blackberry-signer -storepass <KeystorePassword> <BAR_file. You can publish the . Sign your application from the command line You can sign your application during the packaging process using the blackberry-airpackager tool. see Package your application from the command line.

blackberry. the copy is renamed to the original input file name and the original file is deleted.bar file. Possible solution Obtain a Developer Certificate that matches the name you provided when you requested permission to sign applications. in the Company field. provide the name that appears in your Developer Certificate.com/ SignedKeys. On the web form. Possible solution Make sure that you have permissions to modify files in the folder where your .Beta Customers Only. Code signing request failed because Application-Development-Mode in Manifest is present and is not set to false Description This message appears when you try to sign a . This error indicates that one of these rename operations failed. do not include the debug option in your command line. Code signing request failed because Common Name in developer certificate is not [value] Description The Common Name (CN) property in your Developer Certificate does not match the value you provided in the Company field when you requested permission to sign applications by using the RIM® Signing Authority.bar file is stored. Content and software are subject to change.RIM Confidential and Proprietary Information . Application Signing Errors Attempt to rename [value1] to [value2] failed Description During the signing process. that has a CN property that matches the name you provided when you requested permission to sign applications.bar file successfully. 156 . or another command line tool. Possible solution Create a self-signed Developer Certificate using the blackberry-keytool tool. If you use blackberry-packager. Possible solution Repackage the . Possible solution Reapply for permission to sign applications with the RIM Signing Authority at https://www.bar file that was packaged in Development mode.bar file. the signing tool makes a copy of the input . After the tool signs the copy of the .

xml file does not match the value you provided in the Company field when you requested permission to sign applications by using the RIM® Signing Authority.xml file. Possible solution 1. 3. Code signing request failed because this file has been previously signed Description You can sign an application only once per version number. Recompile your project.blackberry. Code signing request failed because Package-Author in Manifest is not set to [value] Description The publisher element in your blackberry-tablet. Change the name of your project. provide the name that appears in your publisher element. In the your_project_name-app.RIM Confidential and Proprietary Information . Possible solution Change the value of the publisher element in your blackberry-tablet. 2. Content and software are subject to change.Beta Customers Only. in the Company field. On the web form. Possible solution 1.xml file. Repackage your project. 2. Code signing request failed because value of Package-Name in Manifest is not allowed Description Your application has a name that is restricted. Repackage your application. -cskpass and -csjpin must be specified if -register is specified Description This message appears when you try to run the blackberry-signer tool with the register option. but you did not include both the cskpass and csjpin options.com/ SignedKeys. increment the value in the versionNumber element.\ Possible solution Reapply for permission to sign applications with the RIM Signing Authority at https://www. 157 .

Content and software are subject to change. Possible solution Include the cskpass parameter and the password in your command line. Make sure that you provide the literal value "author" (not your name) for the alias option. cskpass required Description You requested a signature from the RIM® Signing Authority. To contact the RIM Signing Authority. Possible solution Recreate your Developer Certificate. but you did not provide a value for the storepass option. but did not include the cskpass option.csk file using the password you provide using the cskpass option. Make sure you provide appropriate values for each option.RIM Confidential and Proprietary Information . The blackberry-signer tool tries to encrypt communication between your computer and the RIM® Signing Authority. The tool stores the encryption keys an encrypted file that is designed to be unlocked by using the password your provide in the cskpass option. The CSJ Pin is a 6 to 10 digit number you selected when you requested permission to sign applications. the blackberry-signer tool must decrypt the barsigner. or your Developer Certificate has no private key named author. Incomplete certificate chain Description 158 . and specifies the correct password. You can use the blackberry-keytool tool. Possible solution Add the cskpass and csjpin options to your command line.Beta Customers Only. Developer certificate and private key not found in keystore or store password not supplied Description You attempted to sign an application using the blackberry-signer tool. Possible solution Verify that your command line includes the storepass option. The number is designed to verify that the CSJ registraion file is only used by the person who requested it.

Possible solution Add the certificate chain to the keystore. 159 .p12 parameter. To sign your BAR file using your Developer Certificate. Possible solution Acquire read-write permissions for the folder to which you want to write the P12 file. The tool does not have permission to write to the location you provided for the output_file. Content and software are subject to change. Possible solution Choose another location for your P12 file.FileNotFoundException: certificate.Beta Customers Only.io. the series of signatures (from a root authority to your certificate) that establish the authenticity of your certificate was not found in your keystore along with your Certificate. However. make sure you specify author for the keyname parameter. Possible solution Run blackberry-keytool with superuser permissions.p12 <Access is denied> Description You tried to use the blackberry-keytool tool to create a self-signed Developer Certificate. make sure you specify RDK for the keyname parameter. However. the key found is inappropriate for application signing.RIM Confidential and Proprietary Information . Possible solution Provide the correct password for your keystore. Keystore load: store password incorrect Description The value you specified for the storepass option is incorrect. keytool error: java. Key associated with [value] not a private key Description The blackberry-signer tool found a application signing key using the keyname parameter you specified on the command line. Possible solution • • To request a signature from the RIM® Signing Authority. The blackberry-signer tool cannot decrypt the keystore for your Developer Certificate. The Developer Certificate that you provided to the blackberry-signer tool was issued by a Certificate Authority.

three" . option_name.. -dname "cn=One\. alias <author> already exists Description You tried to use the blackberry-keytool tool to create a self-signed Developer Certificate. The special character set includes: • Commas (. Missing parameter for [option_name] option Description You specified a command line option.RIM Confidential and Proprietary Information . The following shows an excerpt from an incorrect command line: .) Add a back-slash in front of the special character in your command line.Exception: Key pair not generated. 160 .) • Additon symbol (+) • Quotation mark (") • Back-slash (\) • Angled brackets(< and >) • Semi-colon (. Possible solution Delete your existing P12 file. Possible solution The following corrects the excerpt above: .. you did not supply a value for the parameter.p12 parameter already exists..lang. Content and software are subject to change. The cn value for the dname parameter contains a special character. three" .IOException: Incorrect AVA Format Description You tried to use the blackberry-keytool tool to create a self-signed Developer Certificate. Possible solution Change the file name so that blackberry-keytool creates the output file using a different name or location.. Then run blackberry-keytool again. two.io.. two\. -dname "cn="One. However..Beta Customers Only.. Possible solution Provide a value for the parameter. keytool error: java. keytool error: java. that takes a parameter.. The file name you provided for the output_file.

type author to the end of your command line.bar file. Possible solution Repackage your project using the blackberry-packager tool. register. Possible solution Perform these functions separately.Beta Customers Only. but no . No BAR file or CSJ file specified Description This error appears when you try to use the blackberry-signer tool to sign or verify a . -register. Possible solution To request a signature from the RIM Signing Authority. Possible solution To sign your BAR file using your Developer Certificate. Possible solution Specify the appropriate file.bar file. Content and software are subject to change.bar file must be signed twice: first by the RIM® Signing Authority. Your .bar file because you did not specify a signing key. 161 . No key name specified Description You cannot sign your . and verify.bar file was specified on the command line. or -verify can be specified Description You cannot execute any of the following functions concurrently: setup. No manifest Description The BAR file is corrupt. They are mutually exclusive operations. This error can also appear when you try to use the blackberry-signer tool to register with the RIM® Signing Authority. then by your Developer Certificate. but no CSJ file was specified on the command line.RIM Confidential and Proprietary Information . The final parameter of the blackberry-signer tool specifies the key with which to sign your . Only one of -setup. type RDK to the end of your command line.

then try repackaging your project using the blackberry-packager tool. Possible solution Verify that you have permission to access the file and that it exists at the location you provided on the command line. 162 . or the file may be missing or corrupt. Content and software are subject to change.Beta Customers Only. Possible solution Check your computer's network connection. Unable to open BAR file Description The blackberry-signer tool cannot read the BAR file you specified on the command line.RIM Confidential and Proprietary Information . A problem with the network connection prevents the blackberry-signer tool from contacting the RIM Signing Authority. Server is not responding Description The signing tool cannot contact the RIM® Signing Authority. The signing tool cannot sign your BAR file until it contacts RIM Signing Authority. You may not have permission to access this file. If the file exists and you have access to it.

On the Preferences screen. You are limited to 100 tablet PINs across all of your debug tokens that are currently active. then deliver the application to a supervisor or a client for signing and publication. Create a debug token manually using Flash Builder If you have physical access to the BlackBerry® tablet. When you create a debug token. The RDK file allows you to configure your keystore to sign applications and the PBDT file allows you to create debug tokens. 2. or you can install the debug tokens yourself. the BlackBerry Tablet OS no longer allows unsigned applications that rely on that token to run. they must configure the application to use the same author and authorID values that are defined in the debug token. the BlackBerry Tablet OS deployment setup wizard guides you through the configuration process to test your applications on a BlackBerry PlayBook tablet. you must wait for some of your debug tokens to expire before you create more. you can configure your computer to create debug tokens. If necessary. click Preferences. Debug tokens are valid for 30 days. You can create and test an application using a debug token. When you create a new Adobe® ActionScript® Mobile Project. Using debug tokens When you run an unsigned application using a debug token. You can create a debug token if you have permission to sign BlackBerry® Tablet OS applications. 163 .blackberry. Click Signing. you can create and configure debug tokens manually.RIM Confidential and Proprietary Information . you can avoid: • Changing the version number of your application • Accessing the Internet • Exporting a release build of your application 19 You can run an unsigned application on a BlackBerry® PlayBook™ tablet by using a debug token. expand Flash Builder > Target Platforms > BlackBerry Tablet OS. To request permission to sign applications. In the Debug Tokens section. click Create. After you receive your CSJ registration files. 4. After your request is approved. On the Windows menu. you can create and install a debug token when you configure the tablet as a test device in Adobe® Flash Builder® . 3. you specify the PIN for each tablet on which the token can be used. use the following steps to create a debug token.Beta Customers Only. Debug tokens allow you to separate the process of application creation and publication.com/SignedKeys. If you create debug tokens that address 100 PINs. 1. you must complete the web form at https://www. When a developer is ready to load an unsigned application on a tablet. Each file arrives in a separate email with information about the purpose of the file attached. You can distribute the debug tokens that you create to developers who can install them on the specified tablets. Otherwise. When a debug token expires. Content and software are subject to change. in the preferences list. you receive two CSJ registration files by email.

b. Content and software are subject to change. Choose one of the following options: • If you did not configure your computer for signing applications. In the RDK CSJ Path field. continue to step 8. • If you configured your computer for signing applications and creating debug tokens. provide the CSK password that you defined when you configured your computer for signing applications.RIM Confidential and Proprietary Information . If you did not configure your computer for signing applications. c. e. but did not configure your computer for creating debug tokens. continue to step 7. In the CSJ Pin field. f. provide the location of the CSJ registration file that you received for signing applications. • If you configured your computer for signing applications. specify or create a developer certificate. For more information about developer certificates. provide the PIN that you entered on the web form to request permission for signing applications. 6. a. In the PBDT CSJ Path field. On the Register with RIM Signing Authority screen. 5. you must register both CSJ registration files that you received for signing applications and creating debug tokens. Click OK. d.Beta Customers Only. see Configure application signing manually in Flash Builder. continue to to step 9. 164 . In the CSK Password field. provide the location of the CSJ registration file that you received for creating debug tokens.

Content and software are subject to change. a. If you already configured your computer for signing. d. but this is the first debug token you are creating on your computer. e. b. Click OK. In the CSK Password field. enter the CSK password you defined when you configured your computer to sign applications.RIM Confidential and Proprietary Information . In the CSJ Pin field. In the PBDT CSJ Path field. continue to step 9. 7. enter the location of the CSJ registration file that you received for creating debug tokens. On the Register with RIM Signing Authority screen. create or specify a developer certificate. For more information about developer certificates.Beta Customers Only. you must register the CSJ registration file that you received for creating debug tokens. enter the PIN that you entered on the web form to request permission to sign applications. 165 . Now that you configured your computer for signing applications and for creating debug tokens. see Configure application signing manually in Flash Builder. c.

in the Location field. 8. 9. The debug token file must have a .RIM Confidential and Proprietary Information . click Add. Now that you configured your computer for creating debug tokens. Content and software are subject to change. go to step 9. On the Create Debug Token screen. If you specify the name of an existing file. enter the location and file name of the debug token you want to create. 166 .bar extension. that file is deleted before your debug token is created.Beta Customers Only. In the Device PINs section.

10.RIM Confidential and Proprietary Information .Beta Customers Only. provide a comma-delimited list that includes the PIN for each tablet that you want to load this debug token on. see Retrieve the PIN of a BlackBerry tablet. On the Add Devices screen. Click OK. in the Device PINs field. Content and software are subject to change. For more information about finding the PIN of a tablet. 167 .

In the upper-right corner of the Home screen on your BlackBerry tablet. 3. 5. In the list of security options. you should see the token you imported. 2. 5. In the Debug Tokens section. On the Preferences screen. 6. 1. 9. • Configure your BlackBerry® tablet as a test device. You can distribute or install the debug token you created. you should see the token you created. touch Development Mode. in the list of debug tokens. Install a debug token using Flash Builder Before you begin: • Create or import a debug token. On the Preferences screen. click Preferences. Click Signing. 168 . in the preferences list. 8.Beta Customers Only. expand Flash Builder > Target Platforms > BlackBerry Tablet OS. enter the location of the debug token you were assigned (a . you must import it into Adobe® Flash Builder® first. Touch Upload Debug Token. 2. In Adobe® Flash Builder®. On the Create Debug Token screen. 4. On the Import screen. On the Preferences window. 11. Import a debug token using Flash Builder If you receive a debug token that you want to install on a BlackBerry® PlayBook™ tablet. On the Preferences screen.RIM Confidential and Proprietary Information . expand Flash Builder > Target Platforms > BlackBerry Tablet OS. 7. click OK. Click Open. Click Signing. In the list of options. touch the gear icon to open the BlackBerry tablet options. click Import. in the Debug Tokens section. select the debug token that you want to install on the tablet. 3. touch Security. in the preferences list. Content and software are subject to change. 4.bar file). 1. In the Debug Tokens section. on the Window menu. in the File name field. Click Upload. On the Window menu. click Preferences. in the Debug Tokens section.

you must specify the keystore password. Before you begin: • Request permission to sign BlackBerry® Tablet OS applications by completing the web form at https:// www. On the Upload Debug Tokens to Devices screen. go to step 2. see Using a proxy server from the command line.com/SignedKeys.blackberry. In the -csjpin parameter.csj registration file for creating debug tokens. In the -storepass parameter. • If you connect to the Internet through a proxy server. You should only perform this command once. Otherwise. Click OK. you must specify the registration PIN you enter in the PIN field on the web form when you requested permission to sign applications. 169 . 1. use the blackberry-debugtokenrequest tool to register with the RIM® Signing Authority using your PDBT . you must specify additional command line options to contact the RIM® Signing Authority. Create a debug token from the command line You can find the blackberry-debugtokenrequest tool in the bin subfolder where you installed the BlackBerry® Tablet OS SDK. Content and software are subject to change. Note: You can also configure your environment for signing by including the RDK . select the tablet on which you want to install the debug token.Beta Customers Only. Create a debug token for your tablet. Provide the following values for the command line options: Option storepass Value The keystore password that you specified when you registered with the RIM Signing Authority. blackberry-debugtokenrequest -register -csjpin <PIN> -storepass <KeystorePassword> <DebugTokenCSJFile> blackberry-signer command.csj registration file in the 2. 10. You can now run unsigned applications on your BlackBerry tablet. If you already configured your computer for creating debug tokens when you configured application signing.RIM Confidential and Proprietary Information . For more information about using a proxy server from the command line.

In the list of options. the blackberry-debugtokenrequest tool deletes the file before the tool creates the debug token. Option devicepin Value The PIN of the BlackBerry tablet on which you want to install this debug token. Open the BlackBerry tablet options. see Retrieve the PIN of a BlackBerry tablet. see Configuring your application for use with a debug token from the command line. 3. see Retrieving the IP address of the BlackBerry tablet. 4. 2.bar. debug_token_file_name.RIM Confidential and Proprietary Information . 1. For example.bar Example: blackberry-debugtokenrequest command line blackberry-debugtokenrequest -storepass <KeystorePassword> -devicepin<PIN tablet 1> -devicepin <PIN tablet 2> -devicepin <PIN tablet n> <debug_token_file_name. In the list of security options. enter the following command: blackberry-deploy -installDebugToken <path to debug token> -device <IP address of tablet> -password <tablet password> The tablet is now ready to accept unsigned applications. The file name of the debug token you want to create. For more information about configuring your application for use on a tablet with a debug token.-devicepin12A34B56C . touch the gear icon. At a command prompt.bar> Install a debug token from the command line Before you begin: Retrieve the IP address of your BlackBerry® tablet. touch Development Mode. If you specify the name of an existing file. For more information about retrieving the IP address of your tablet. Content and software are subject to change. In the upper-right corner of the Home screen on your BlackBerry tablet. touch Security. The debug token file must end with . 5. 170 .Beta Customers Only. Touch Upload Debug Token. For more information about finding the PIN of a tablet.

RIM Confidential and Proprietary Information . you must configure the application's author and authorId properties match those of specified by the debug token. You can find the blackberry-airpackager tool in bin subfolder where you installed the BlackBerry® Tablet OS SDK.bar> <MyApplication.. Configure your application for use with a debug token from the command line You can use the BlackBerry® Tablet OS to run an unsigned application on a BlackBerry tablet that has a debug token installed. include -debugToken to extract author and authorId from <token> and apply it to your application.Beta Customers Only. blackberry-airpackager -devMode -debugToken <token> -package <MyApplication.xml> <others files.bar> <MyApplication.> Example: blackberry-airpackager command line blackberry-airpackager -devMode -debugToken <token> -package <MyApplication.xml> <others files. When you package your application.xml> <blackberry-tablet. To load an unsigned application. Content and software are subject to change...> 171 .xml> <blackberry-tablet..

5. click Preferences. 4. 2. On the Save As screen. Click Open. In the Backup and Restore section. not an upgrade. you must register with the RIM Signing Authority again to receive new code signing keys. they can use your code signing credentials to sign an application. you can: • Restore the code signing keys to the original computer • Install the code signing keys on another computer • Share the code signing keys within an organization or between developers It is important that you protect your backup files. click Unregister to remove any existing signing keys. click Preferences. Click Save. click Restore. expand Flash Builder > Target Platforms > BlackBerry Tablet OS. On the Window menu. Content and software are subject to change. specify a name and location for your backup file. If you sign your application with a new code signing key and deploy it to a BlackBerry® PlayBook™ tablet. Because you can only register your CSJ registration files with the RIM® Signing Authority once. if you do not back up your code signing keys and you forget your password or lose your code signing keys. In the RIM Signing Authority section. in the preferences list. expand Flash Builder > Target Platforms > BlackBerry Tablet OS. specify a name and location for your backup file. 172 . 2. 3. Using your backup files. Restore code signing keys using Flash Builder Before you begin: • Before restoring your code signing keys and developer certificates. If someone obtains your backup files. On the Window menu. and cannot access shared data from the previous version. make sure you back up and remove any existing code signing keys and developer certificates. On the Preferences screen. 1. 5. Click Signing.Beta Customers Only. 6. On the Preferences screen. in the preferences list. 4. Click Signing. Backup and restore your code signing keys 20 You should back up your code signing keys to protect your code signing credentials and developer certificate. code signing keys and developer certificate. click Backup. your application appears as a new application. On the Open screen. In the Backup and Restore section. Back up code signing keys using Flash Builder To back up your code signing keys and developer certificate as a ZIP file: 1.RIM Confidential and Proprietary Information . 3.

p12 Note: The default filename for the developer certificate is author.p12 Restore code signing keys manually Before you begin: • Before restoring your code signing keys and developer certificates.p12 Note: The default file name for the developer certificate is author. In a Windows Vista® and Windows® 7 environment. see Default location for code signing keys. the default %HOMEPATH% is C:\Users###BOT_TEXT###lt;username>. 2. For more information about the default location for signing keys.p12 Default location for code signing keys By default. Copy the following files from your backup file location to the default file location: • barsigner. Operating System Windows XP Windows Vista and Windows 7 Mac OS UNIX® and Linux® Default location %HOMEPATH%\Local Settings\Application Data\Research In Motion %HOMEPATH%\AppData\Local\Research In Motion ~/Library/Research In Motion ~/. see Default location for code signing keys.rim 173 . Content and software are subject to change.RIM Confidential and Proprietary Information .db • <yourkeyname>. Navigate to the directory that contains your code signing keys. The default locations of these files vary based on operating system and are outlined in the table below. Navigate to the current file location for your code signing keys and developer certificates. make sure you back up and remove any existing code signing keys and developer certificates. Copy the following files to a backup file location: • barsigner. code signing keys are stored in a central location in your profile directory and are used by all BlackBerry® Tablet OS development tools. 2.Beta Customers Only.csk • barsigner. For more information about the default location for code signing keys. Back up code signing keys manually 1.csk • barsigner. 1. Note: In a Windows® XP environment.db • <yourkeyname>. the default %HOMEPATH% is C:\Documents and Settings###BOT_TEXT###lt;username>.

174 . In the View information about your tablet field. 3.RIM Confidential and Proprietary Information . Retrieve the PIN of a BlackBerry tablet 1.Beta Customers Only. select Hardware. Record the value from the PIN field. press the gear icon to open the BlackBerry tablet options. 21 In the upper-right corner of the Home screen on your BlackBerrytablet. Content and software are subject to change. 2.

Beta Customers Only.RIM Confidential and Proprietary Information . Development mode is enabled by default. see Enable development mode. the tablet must be in development mode. To display the IP address. 175 . To learn how to enable development mode manually. Content and software are subject to change. Retrieving the IP address of the BlackBerry PlayBook tablet You can view the tablet's IP address by tapping the icon to the right of the clock on the status bar. 22 You must provide the IP address of the BlackBerry® PlayBook™ tablet to the deployment tool of your choice to load your application on the tablet.

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Enable development mode
Development mode must be enabled before you can load and run your application on the BlackBerry® Tablet Simulator, or if you want to view the IP address of the simulator. Development mode is enabled by default. 1.

23

In the virtual machine for the BlackBerry Tablet Simulator, in the upper-right corner of the simulator screen, click the icon.

2. 3.

On the Security screen, click Development mode. Next to the Use Development Mode label, set the Development Mode setting to ON.

4. 5.

In the Device password field, type the password for your device. Click Back.

176

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Provide feedback
To provide feedback on this deliverable, visit www.blackberry.com/docsfeedback.

24

177

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Document revision history
Date 13 September 2011 Description Added the following topics: • • • • • • • • • • • • • • •

25

Responding to application window state Listen for a chance in application window state Configure updates for Flash Builder in a Windows environment Configure updates forFlash Builder in a Mac environment Check for updates to the BlackBerry Tablet OS plug-in Configure application signing and create debug tokens using the setup wizard in Flash Builder Configure application signing manually in Flash Builder Using debug tokens Create a debug token manually using Flash Builder Backup and restore your code signing keys Back up code signing keys using Flash Builder Restore code signing keys using Flash Builder Back up code signing keys manually Restore code signing keys manually Default location for code signing keys

Changed the following topics: Folders accessible by an application Understanding the application life cycle Saving the application state Signing your application Configure application signing through a proxy server in Flash Builder Sign your application in Flash Builder Configure application signing from the command line Using a proxy server from the command line Sign your application from the command line Create a debug token from the command line Configure your application for use with a debug token from the command line Changed the following topics: • • •
178

• • • • • • • • • • •

23 March 2011

Configure application signing from Adobe Flash Builder 4.0.1 Configure application signing from Adobe Flash Builder 4.5 Configure application signing from the command line

Date Description • Sign an application from Adobe Flash Builder 4.Beta Customers Only.RIM Confidential and Proprietary Information .1 Configure application signing from Adobe Flash Builder 4. 17 February 2011 13 January 2011 179 .1 • Sign an application from Adobe Flash Builder 4.0.0.1 Sign an application from Adobe Flash Builder 4. Content and software are subject to change.5 Configure signing through a proxy server Creating a resource bundle Localizing your application using resource bundles Localizing an application Load a resource bundle Sign an application from Adobe Flash Builder 4.0.5 • Sign your application from the command line Added the following topics: • • • • • • • • • • • • • Accessing restricted functionality Application signing errors Configuring your application Configure application signing from Adobe Flash Builder 4.5 Using a proxy server from the command line 10 March 2011 Changed the following topics: • Configure application signing from the command line • Signing your application • Sign your application from the command line • Configure application signing from the command line • Signing your application • Sign your application from the command line First draft released.

OR PERFORMANCE OR NON-PERFORMANCE OF ANY SOFTWARE. and is not responsible for. SERVICE. hardware or software. MERCHANTABLE QUALITY. without limitation the content. names.RIM Confidential and Proprietary Information . RIM does not control. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW IN YOUR JURISDICTION.blackberry.Beta Customers Only. SOME JURISDICTIONS MAY NOT ALLOW THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES AND CONDITIONS. IN NO EVENT SHALL RIM BE LIABLE FOR ANY TYPE OF DAMAGES RELATED TO THIS DOCUMENTATION OR ITS USE. and related trademarks. Adobe. trustworthiness. guarantee. OR ANY THIRD PARTY PRODUCTS AND SERVICES 180 . products or services including components and content such as content protected by copyright and/or third-party web sites (collectively the "Third Party Products and Services"). or omissions in this documentation. endorsement. The inclusion of a reference to Third Party Products and Services in this documentation does not imply endorsement by RIM of the Third Party Products and Services or the third party in any way. updates. however. decency.AIR. GUARANTEES. enhancements. Wyrick & Company.S. EXPRESS OR IMPLIED. RIM®. Inc. INCLUDING WITHOUT LIMITATION. MERCHANTABILITY. EXCEPT TO THE EXTENT SPECIFICALLY PROHIBITED BY APPLICABLE LAW IN YOUR JURISDICTION. OR TITLE. or any other aspect of Third Party Products and Services. performance. and logos are the property of Research In Motion Limited and are registered and/or used in the U. any Third Party Products and Services including. RIM reserves the right to periodically change information that is contained in this documentation. SATISFACTORY QUALITY. technical.com/go/docs is provided or made accessible "AS IS" and "AS AVAILABLE" and without condition. compatibility. All other trademarks are the property of their respective owners. copyright compliance. BUT CAN BE LIMITED. links. HARDWARE. SERVICE. YOU MAY ALSO HAVE OTHER RIGHTS THAT VARY BY STATE OR PROVINCE. ANY IMPLIED WARRANTIES OR CONDITIONS RELATING TO THE DOCUMENTATION TO THE EXTENT THEY CANNOT BE EXCLUDED AS SET OUT ABOVE. NON-INFRINGEMENT. OR WARRANTIES OF ANY KIND. errors. All rights reserved. this documentation may describe some aspects of RIM technology in generalized terms. REPRESENTATIONS OR WARRANTIES OF DURABILITY. and ActionScript are trademarks of Adobe Systems Incorporated. and countries around the world. legality. In order to protect RIM proprietary and confidential information and/or trade secrets. or other inaccuracies. Flash. ARE HEREBY LIMITED TO NINETY (90) DAYS FROM THE DATE YOU FIRST ACQUIRED THE DOCUMENTATION OR THE ITEM THAT IS THE SUBJECT OF THE CLAIM. ALL CONDITIONS. OR ARISING FROM A STATUTE OR CUSTOM OR A COURSE OF DEALING OR USAGE OF TRADE. OR PERFORMANCE OR NONPERFORMANCE OF ANY SOFTWARE. KG. REPRESENTATIONS. ENDORSEMENTS. Content and software are subject to change. ANY CONDITIONS. SQLite is a trademark of Hipp. QNX is a trademark of QNX Software Systems GmbH & Co. FITNESS FOR A PARTICULAR PURPOSE OR USE. RIM makes no commitment to provide any such changes. TO THE EXTENT PERMITTED BY LAW. representation. GUARANTEES. or other additions to this documentation to you in a timely manner or at all. ENDORSEMENTS. or warranty of any kind by Research In Motion Limited and its affiliated companies ("RIM") and RIM assumes no responsibility for any typographical. accuracy. OR ANY THIRD PARTY PRODUCTS AND SERVICES REFERENCED HEREIN. Legal notice 26 ©2011 Research In Motion Limited. Research In Motion®. OR RELATED TO THE DOCUMENTATION OR ITS USE. BlackBerry®. HARDWARE. This documentation including all documentation incorporated by reference herein such as documentation provided or made available at www. ARE HEREBY EXCLUDED. This documentation might contain references to third-party sources of information.

BUSINESS INTERRUPTION. copyright. DAMAGES FOR LOSS OF PROFITS OR REVENUES. DOWNTIME COSTS. DEMAND. COST OF SUBSTITUTE GOODS. OR LIABILITY WHATSOEVER IN CONTRACT. You are solely responsible for determining whether to use Third Party Products and Services and if any third party licenses are required to do so. THE LIMITATIONS. 181 . trademark. PUNITIVE. and/or BlackBerry® Device Software. LOSS OF BUSINESS OPPORTUNITY. AUTHORIZED RIM DISTRIBUTORS (ALSO INCLUDING AIRTIME SERVICE PROVIDERS) AND THEIR RESPECTIVE DIRECTORS. BlackBerry® Desktop Software. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW IN YOUR JURISDICTION. AND (B) TO RIM AND ITS AFFILIATED COMPANIES. service plans and features. INDIRECT. DISTRIBUTOR. Check with your service provider for availability. AGENTS. THEIR SUCCESSORS. Prior to subscribing for. AND DISCLAIMERS HEREIN SHALL APPLY: (A) IRRESPECTIVE OF THE NATURE OF THE CAUSE OF ACTION. OR OTHERWISE TO YOU INCLUDING ANY LIABILITY FOR NEGLIGENCE OR STRICT LIABILITY.RIM Confidential and Proprietary Information . roaming arrangements. LOSS OF BUSINESS INFORMATION. LOSS OF THE USE OF RIM PRODUCTS OR SERVICES OR ANY PORTION THEREOF OR OF ANY AIRTIME SERVICES. representations. COSTS OF COVER.Beta Customers Only. IN NO EVENT SHALL ANY DIRECTOR. Your use of Third Party Products and Services shall be governed by and subject to you agreeing to the terms of separate licenses and other agreements applicable thereto with third parties. INDEPENDENT CONTRACTOR OF RIM OR ANY AFFILIATES OF RIM HAVE ANY LIABILITY ARISING FROM OR RELATED TO THE DOCUMENTATION. NEGLIGENCE. TORT. OR AGGRAVATED DAMAGES. in relation thereto. OR OTHER SIMILAR PECUNIARY LOSSES. COST OF CAPITAL. OR ACTION BY YOU INCLUDING BUT NOT LIMITED TO BREACH OF CONTRACT. SUPPLIER. guarantees. AND EVEN IF RIM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. EMPLOYEE. SUPPLIERS (INCLUDING AIRTIME SERVICE PROVIDERS). IN ADDITION TO THE LIMITATIONS AND EXCLUSIONS SET OUT ABOVE. Some airtime service providers might not offer Internet browsing functionality with a subscription to the BlackBerry® Internet Service. If required you are responsible for acquiring them. ASSIGNS. or other licenses in order to avoid infringement or violation of third party rights. DUTY. or using any Third Party Products and Services. FACILITIES OR SERVICES. AND INDEPENDENT CONTRACTORS. it is your responsibility to ensure that your airtime service provider has agreed to support all of their features. PROBLEMS ASSOCIATED WITH ANY APPLICATIONS USED IN CONJUNCTION WITH RIM PRODUCTS OR SERVICES. RIM SHALL HAVE NO OTHER OBLIGATION. except to the extent expressly covered by a license or other agreement with RIM. or warranties of any kind by RIM and RIM assumes no liability whatsoever. FAILURES TO TRANSMIT OR RECEIVE ANY DATA. AGENT. WHETHER OR NOT SUCH DAMAGES WERE FORESEEN OR UNFORESEEN. Installation or use of Third Party Products and Services with RIM's products and services may require one or more patent. FAILURE TO REALIZE ANY EXPECTED SAVINGS. REFERENCED HEREIN INCLUDING WITHOUT LIMITATION ANY OF THE FOLLOWING DAMAGES: DIRECT. Certain features outlined in this documentation require a minimum version of BlackBerry® Enterprise Server. Any Third Party Products and Services that are provided with RIM's products and services are provided as a convenience to you and are provided "AS IS" with no express or implied conditions. OR CORRUPTION OR LOSS OF DATA. You should not install or use Third Party Products and Services until all necessary licenses have been acquired. STRICT LIABILITY OR ANY OTHER LEGAL THEORY AND SHALL SURVIVE A FUNDAMENTAL BREACH OR BREACHES OR THE FAILURE OF THE ESSENTIAL PURPOSE OF THIS AGREEMENT OR OF ANY REMEDY CONTAINED HEREIN. INCIDENTAL. EXCLUSIONS. Content and software are subject to change. installing. EXEMPLARY. CONSEQUENTIAL. SPECIAL. endorsements. TORT. EMPLOYEES.

The terms of use of any RIM product or service are set out in a separate license or other agreement with RIM applicable thereto. Surrey TW20 9LF United Kingdom Published in Canada 182 . ON N2L 3W8 Canada Research In Motion UK Limited Centrum House 36 Station Road Egham.RIM Confidential and Proprietary Information .Beta Customers Only. Content and software are subject to change. NOTHING IN THIS DOCUMENTATION IS INTENDED TO SUPERSEDE ANY EXPRESS WRITTEN AGREEMENTS OR WARRANTIES PROVIDED BY RIM FOR PORTIONS OF ANY RIM PRODUCT OR SERVICE OTHER THAN THIS DOCUMENTATION. Research In Motion Limited 295 Phillip Street Waterloo.