What s New in Version 2 Components?

 < Day Day Up > 

What's New in Version 2 Components ?

The version 2 components are very different than the version 1 components available in Flash MX. As you will see, the application program interfaces (APIs) have been completely rewritten and the performance of the version 2 components has been greatly improved. In addition, all the new visual components have a new interface and a new look and feel; they also support data binding, which makes it possible to build applications without writing any ActionScript 2.0 code at all.

Of course, components do add a certain amount of file size to your Flash application because they use a component framework. Once this framework has been added to your application, however, there is very little additional file size cost for other components.

N OTE

Because version 2 components are so different than version 1 components, it is not recommended that version 1 components and version 2 components be combined in the same file. A great benefit of the version 2 component architecture is that they can be backward compatible with Flash Player 6.


Usability and Accessibility

In Flash, components are now accessible and screen readers can interpret their content. When a user tabs to a component, the Focus Manager enables the developer to set up logical behavior; in version 1 components, the user would just be stuck if he or she tried to tab to a component.

SWC Files

Components included with Flash are SWC files. SWC is the Macromedia file format for exported components. It is a compiled clip that has been exported for distribution. A compiled clip is basically just a compressed movie clip, very similar to an SWF file. When you add a component to the Stage from the Components panel, a compiled clip symbol is added to the Library, as shown in Figure 9.1:

Figure 9.1. A compiled clip symbol.

graphics/09fig01.jpg

The first step in creating an SWC file is to create a compiled clip. A compiled clip is an SWF file that resides in the Library of your application. Be sure your component is ready for production before you actually compile the clip, which is done through a menu setting in the Library. You cannot change a compiled clip; you must recompile it.

Note that SWCs are where components are stored and they are actually separate files. An SWC file is a compiled component in a separate file.

To create a compiled clip and publish it as an SWC file, do the following:

  1. Right-click the movie clip symbol in the Library.

  2. Choose Convert To Compiled Clip from the contextual menu.

  3. Right-click the compiled clip.

  4. Choose Export to SWC file from the contextual menu.

  5. Restart Flash and you will see the component in the Components panel.

The Visual Interface for Components

The visual component interface comprises many elements. Each is discussed in turn in the following subsections.

The Component Inspector

Like version 1 components and other assets, version 2 components still use the Property Inspector for basic functionality. However, a new panelthe Component Inspectorhas been created specifically for version 2 components and it gives us more options and control over a component visually.

The Component Inspector, as shown in Figure 9.2, is used to fill out component information properties manually. The Component Inspector is also used to set up bindings between the component and a data source, which enables the development of applications without typing any ActionScript 2.0 code at all.

Figure 9.2. The new Component Inspector gives us a lot more visual options in setting up components.

graphics/09fig02.jpg

The simplest way to use a component is to drag it on to the Stage from the Components panel and fill out the label and data information using the Component Inspector or the Property Inspector. Figure 9.3 is the interface that appears when the user clicks the label or data field of the Component Inspector.

Figure 9.3. Using the Component Inspector to populate a combo box manually.

graphics/09fig03.jpg

Visual Data Binding

Flash has made it easy to link components with data sources without writing any ActionScript 2.0 code. In the Component Inspector window, you can use the Bindings tab to access the Data Binding window. The add binding command shows all the bindable components, and it introspects the data associated with each component (which is also known as a schema). See Figure 9.4.

Figure 9.4. Adding a data binding to a component.

graphics/09fig04.gif

In Figure 9.5, the out field indicates the direction that the data is flowing . For example, in this case, the Component Inspector was accessed from the ComboBox component, and the combo box is passing a string (as a parameter) to the Babel Fish web service, so we indicate out . If the Component Inspector were accessed from the Web Service component, we would specify in for a parameter because the web service is receiving data from the combo box. If this combo box were receiving results from a web service call (instead of specifying a parameter for the web service), we would specify in if accessing it from the combo box.

Figure 9.5. The Data Bindings window linking a ComboBox component to a Web Service component with no ActionScript 2.0 code at all.

graphics/09fig05.gif

The bound to field indicates the component to which this combo box component is bound. In this case, it is bound to a component that calls a web service (see Chapter 13 for more information on the web service connector).

The Schema Tab

The Schema tab of the Component Inspector tells us exactly the type of data structure that this component is expecting. For example, if we look at the schema for a combo box, we can see that the component has a dataProvider . A dataProvider can be an array, or just a plain value that is a string as well as a selectedIndex and selectedItem . The Schema tab also works with non-UI components. For example, by looking at the Schema tab of a web service, we can see exactly the data structures that are returned.

Creating a Simple Application with Components and Visual Data Binding

We are going to build a simple application that will use data binding and components. This application will accept input from a user in English and translate that text to French by calling the Babel Fish web service.

  1. Open Flash and create a new FLA file.

  2. Open the Web Services panel (Window > Development Panels > Web Services) and enter the following URL: www.xmethods.net/sd/2001/BabelFishService.wsdl .

  3. Examine the data structures that the web service requires and returns. Notice that it expects two String parameters, the translation mode, and the actual text to be translated. Notice the web service is returning a string as well. This will work perfectly with the text components because they are built for dealing with simple strings.

  4. Find the BabelFish() method, right-click it, and choose Add Method Call, as shown in Figure 9.6.

    Figure 9.6. By choosing Add Method Call, an instance of the Web Services Connector component is automatically placed on the Stage from the Library.

    graphics/09fig06.gif

  5. Assign the Web Services Connector component an instance name of babelCall .

  6. Drag three Text Area components (from the Components panel) and a Button component and arrange them as shown in Figure 9.7.

    Figure 9.7. Dragging the needed components.

    graphics/09fig07.jpg

  7. Assign the top-right text component an instance name of language , and using the Component Inspector or Property Inspector, be sure the text reads en_fr . This will be the translation mode parameter sent to the web service, meaning the service will translate from English to French.

  8. Assign the top-left text area an instance name of babelInput . This will be the actual text the user can type in and send to the web service.

  9. Assign the bottom text area component an instance name of babelOutput . This will receive and display the translated text from the web service and display it to the user.

  10. Assign the button component a name of babelCall .

  11. Select the Web Services component and open the Bindings tab in the Component Inspector.

  12. Add a new binding to the translationmode parameter, as shown in Figure 9.8. This links the web service parameter to the language text box.

    Figure 9.8. Binding the translationmode parameter to the text area component.

    graphics/09fig08.gif

  13. Bind the translationmode parameter to the text area component you added earlier, as shown in Figure 9.9:

    Figure 9.9. Binding the translationmode parameter to the text field.

    graphics/09fig09.jpg

  14. Bind the sourcedata parameter of the Web Services component to the babelInput Text Area component. This will link the babelInput text field to the text that is to be the translated parameter of the web service.

  15. Bind the results of the Web Services component to the babelOutput Text Area component. This will display the string sent back from the web service in the babelOutput text field.

  16. Select the button and using the Component Inspector, change the label of the button to translate .

  17. With the button still selected, open the Behaviors panel and add a web service call to the button. It is located in the data behaviors of the Behaviors pane.

The Version 2 Component APIs

Visual data binding is powerful, but ultimately, there is no substitute for being able to delve into ActionScript to control components. APIs enable the developer to have complete control over components. For example, it would be difficult with visual data binding to apply conditional logic to components if we wanted a combo box to affect a list box component. However, with APIs, the developer can have complete control over the component at runtime.

Component Classes

Each component is its own class with its own set of properties and methods . The class is instantiated by dragging a component from the Components panel (really a separate external SWC file) and assigning it an instance name.

The component packages are located in the classes directory, in the mx folder. The UI components are in the controls folder and the data components are in the data folder. The classes that components can inherit from are in the core folder.

To use code hinting in the version 2 components, you must explicitly declare and type the component at the top of your ActionScript 2.0 code, as shown in the following code:

 var myCombo :mx.controls.ComboBox 

The suffixes required for code hinting in Flash MX (such as _cb, _lb, and so on) are no longer required in Flash MX 2004, but they will still work.

All the components inherit from the MovieClip class, which means that all movie clip properties and methods can be used with any component. For example, attachMovie() , _x , and _y can be used with any component. Figure 9.10 is a diagram that explains the inheritance chain of components in Flash.

Figure 9.10. Inheritance chain of components.

graphics/09fig10.gif

Flash MX 2004, like Flash MX, offers only single inheritance, so the actual ActionScript 2.0 code looks something like this:

 class UIObject extends MovieClip { //class code } class UIComponent extends UIObject { //class code } class List extends UIComponent TYPO- no space between ui and component { //class code } 

The base UIObject class offers common behavior among components and all components are descended from this class. The UIComponent class is the base class for all components that have some type of user interaction. The ActionScript developer should never need to use these classes except when building components. The main advantage is that after you learn how to use the API of one component, it becomes very easy to learn how to use all other components. The base classes, UIObject and UIComponent , provide common APIs among all components.

Implicit Getter and Setter Methods in Components

Many methods in the version 2 components now use implicit getters and setters and are referenced like properties. For example, in the version 1 components, the setDataProvider() method took a complex data structure and populated the component, as shown in the following code (in ActionScript 1.0):

 var myArray = new Array ('NewsWeek', 'The New Yorker', 'Time'); myCombo_cb.setDataProvider (myArray); 

The setDataProvider() method is now a property in the version 2.0 components (built behind the scenes with the implicit getter/setter method):

 var myCombo :mx.controls.ComboBox var myArray :Array = new Array('NewsWeek', 'The New Yorker', 'Time'); myCombo.dataProvider = myArray; 

Not all version 2 component methods are implicit getter/setters. The addItem() method remains pretty much in its original form, as does the getItemAt() method. The documentation that comes with Flash is the best source for figuring out what has and has not changed regarding component APIs.

The New Component Event Model

All components now generate and listen to different types of events that apply to that component. The developer can create one object and link the appropriate event to that object. This provides code reusability and scalability. It also enables us to handle events in a more object-oriented way, which will lead to easier and more effective class based development.

Examine the following code:

 var myCombo :mx.controls.ComboBox; var eventObj :Object = new Object(); eventObj.change = function () { trace ("called") } myCombo.addEventListener ("change", eventObj); 

The code is a version 2 replacement for the old setChangeHandler() method, which is no longer available. The function is called every time the user makes a change to the combo box. The combo box is now "listening" for the change event to occur. When the event occurs, it calls the method attached to the object specified in the addEventListener() method. The Flash documentation provides the most complete list of all available events, which vary by component and depend on functionality.

All UI components broadcast the following events, because these events are attached to the UIComponent class from which they all inherit:

  • Resize . The component has been resized.

  • Move . The component has been moved.

  • Load . The component is loading its subobjects.

  • UnLoad . The component is unloading its subobjects.

  • Focus . The component now has the input focus.

  • Blur . The component has lost the input focus.

Building a Simple Application with Version 2 Components

One of the most practical uses of Flash is to have two components link to each other. For instance, we are going to have a combo box with different types of magazines; the user will be able to select one magazine and have a list display only magazines that match that type. Doing this with any other technology is cumbersome at best. If we used a server-side solution, such as Macromedia Cold Fusion, a page refresh would be needed for every selection of the combo box. To use another client-side solution, such as Dynamic Hypertext Markup Language (DHTML) or JavaScript, would surely involve cross-browser issues and much more complicated code.

We are going to use the combo box, list box, and text components for our call center application. The user will be able to select a magazine type (such as news and technology) from a combo box, and a list box will populate based on that selection. The text components will then display the details of the selected magazine (the magazine id and the sales description). We are going to use static data in this case, but of course, in real life, this complex data would be obtained from a database through Web Services or XML.

  1. To begin the application, drag a ComboBox component onto the Stage and assign it an instance name of magTypes .

  2. Open the Actions panel and add the following code:

     var magTypesArray :Array = new Array (); magTypesArray[0] = "News"; magTypesArray[1] = "Technology"; magTypes.dataProvider = magTypesArray; 

    This populates the component labels with news and technology.

  3. Suppose we wanted to add a setting of "All" to the combo box but not the underlying data structure so that the rep would have the option of seeing all magazines available. The addItemAt() method would seem to be perfect because we could make "All" the first selection on the combo box. Toward this end, add the following code, which specifies that we want to add the string All to the first (0) element of the combo box array:

     magTypes.addItemAt(0, "All"); 
  4. At first glance, this appears to work perfectly. Test the movie. The combo box now contains the selection "All," just as we expected. However, the underlying array now also has the value of "All" at index 0 ( magTypes_array ). Enter the following code to verify this:

     trace (magTypesArray); 

    The data and component being linked is in stark contrast to the version 1 components where using addItem() did not affect the underlying data structure. This two-way communication enables us to easily divide our application into user interface and data layers. However, we can no longer store complex data structures inside a UI component; components are now only for visual displays, providing a much better separation between the presentation and data layers in Flash.

  5. Drag a List component onto the Stage and assign it an instance name of magList .

  6. Be sure the following class is in the same directory as your FLA file. Examine the class; the class is included with your files for this book.

     class Product {       var id:Number;       var prodType:String       var prodName:String;       var description:String;       function Product (id:Number, prodType:String, prodName:String, description:String)       {             idNo = id;             prodType = prodType;             productName = prodName;             productDescription = description;       }       public function get idNo() :Number {             return this.id; }       public function set idNo (id:Number) :Void {             this.id = id; }       public function get productType() :String {             return this.prodType; }       public function set productType(prodType:String) :Void {             this.prodType = prodType; }       public function get productName () :String {             return this.prodName; }       public function set productName (prodName:String) :Void {             this.prodName = prodName; }       public function get productDescription () :String {             return this.description; }       public function set productDescription (description:String) :Void {       this.description = description; } } 

    In most real-world scenarios, we deal with complex data structures, not just one-dimensional arrays. Our magazine application is no different. We have an array of magazines that includes important information about each magazine, such as the magazine id, the magazine name, the type of magazine it is, and a description of the magazine.

  7. Add the following code to build and array of objects using the Product class:

     var newsWeek :Product = new Product(); newsWeek.idNo =  1; newsWeek.productName = "Newsweek"; newsWeek.productType = "News"; newsWeek.productDescription = "America's source for current events and the latest in what's happening around the globe"; var time :Product = new Product(); time.idNo = 2; time.productName = "Time"; time.productType = "News"; time.productDescription = "Insightful commentary and the latest in- depth news articles"; var pcWorld = new Product(); pcWorld.idNo =3; pcWorld.productName = "PC World"; pcWorld.productType = "Technology"; pcWorld.productDescription = "Get up to date on the latest trends in the PC industry"; var macWorld = new Product(); macWorld.idNo = 4; macWorld.productName = "Mac World"; macWorld.productType = "Technology"; macWorld.productDescription = "Get up to data on the latest trends in the Macintosh World"; var magazine_array :Array = new Array(); magazine_array [0] = newsWeek; magazine_array [1] = time; magazine_array [2] = pcWorld; magazine_array [3] = macWorld; 

    The next step is to populate the list box with the information.

  8. Add this code to the Actions layer of the FLA:

     magList.dataProvider = magazine_array; 

    This populates the list box with all the information, including id, type, name, and description. Of course, this is not the desired result; we want only the name of the magazine displayed to the user. To do that, you would specify the field that you want to be used as the label for the list.

  9. Add the following code to the Actions layer after you set the dataProvider getter/setter method:

     magList.labelField = "productName"; 

    Now that we have both components populated with data, we need to link them together, which is not possible to do with visual data binding because we need to add if/else logic, which is possible only with ActionScript 2.0 code. When the user selects a magazine type such as news, we want Flash to filter the list to show only those magazines whose type is news.

  10. Add a change event listener to the combo box by using the following code:

     var myObject :Object = new Object(); myObject.change = function () {       trace ("called"); } magTypes.addEventListener("change", myObject); 
  11. Test the movie and you will see the change function is called each time you click the combo box component.

    Our next step is to figure out which item the user selected and populate the list box based on that selection.

  12. Add the following code within the change method, and delete the trace statement:

     myObject.change = function () { var selectedType = magTypes.selectedItem; if (selectedType == "All") {       magList.dataProvider = magazine_array; } 

    If the user selects "All," the dataProvider of the combo box will be the magazine_array . Now we need to add an else statement and test if the user has selected the type of news or technology. We need to build a new array with the appropriate magazines that meet the criteria. We then use that new array as the data provider for the combo box.

  13. Create a new array outside the if conditional logic, but still in the change function, as shown in the following code:

     myObject.change = function () { var result_array:Array = new Array(); if (selectedType == "All") {       magList.dataProvider = magazine_array; } } 

    The most efficient way to accomplish the comparison would be to loop through the existing array that is used as the data provider for the list component, which is the magazine array. We would then compare any of the product types in that list array to the items that the user has selected using if logic. For example, if the user selects the type of news, we want to show only those products that have the productType (tracked as an object property) of news.

  14. Add the following code within the else statement.

     if (selectedType == "All") { magList.dataProvider = magazine_array; }  else{   var len = magazine_array.length;  for (var i=0; i<len; i++) {              if (magazine_array[i].productType == selectedType)              {              //do something              }       } } } 

    If the magazine array product type is equal to the product type that the user has selected, we will push that object at that index of the magazine_array into the result_array . We then use the result_array as the dataProvider for the list.

  15. Be sure that your final change handler looks like the following:

     myObject.change = function () { var result_array:Array = new Array(); var selectedType = magTypes.selectedItem; if (selectedType == "All") { magList.dataProvider = magazine_array; }else{ var len = magazine_array.length; for (var i=0; i<len; i++) {              if (magazine_array[i].productType == selectedType)              {              result_array.push (magazine_array[i]);              magList.dataProvider = result_array;              }       } } } 
  16. Our combo box is almost finished, but there is one small problem: the combo box defaults to the "news" selection. We want the combo box to default to the "All" selection so that the rep immediately sees all the magazines available. To do that, we use the selectedIndex setter method; the "All" selection is located at index 0, so we can just add the following code:

     magTypes.selectedIndex = 0; 

    The preceding code will not work unless the data has already been loaded into the component. The component does not have an index until the data is loaded in.

  17. Add a load event to the magList component, and in the load event itself, set the selected index to 0, as shown in the following code:

     var loadObject :Object = new Object; loadObject.load = function () {       magTypes.selectedIndex = 0; } magList.addEventListener ("load", loadObject); 

You have now created a slick application that has no cross-browser issues and that saves on database calls by handling manipulation of the data on the client.

 < Day Day Up > 


Object-Oriented Programming with ActionScript 2.0
Object-Oriented Programming with ActionScript 2.0
ISBN: 0735713804
EAN: 2147483647
Year: 2004
Pages: 162

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net