Download RMCS_FlashCS4Manual_r6.zip

In these lessons, you will learn how to create several multi-purpose applications:

  1. First, we will start by creating a simple Flash-based Website
    (which can be used instead of a PowerPoint presentation)
  2. Then, we will convert it into a Flash RSS Reader
    (which can also be used as a Resource Directory, etc.)
  3. Afterward, we will convert the RSS Reader into a Flash Photo Gallery.
    (which can be easily used as Product Catalog, Employee Directory, etc.)
  4. Then, we will convert the Flash Photo Gallery into a Flash Video Gallery

NOTE: If you understand in advance why you are doing a given step, you can skip the "why" explanation below it.

We will do the same or a similiar application using three different levels:

LEVEL 1: HARDWIRE COMPONENTS (Component-based Architecture)

Create new Flash file and set initial dimensions, etc.

  1. Create a new Flash ActionScript 3 file and save it as FlashWebSite.fla in the Lesson 3 folder.
  2. Set stage size to 750W x 500H in the Property Inspector by clicking on the document properties button -- the one with the current stage dimensions on it.
  3. Draw a rectangle with no fill and a 1-pixel solid black stroke of any size with Rectangle tool.
  4. Set rectangle x and y both to zero and width to 750 and height to 500 in the Property Inspector.

Lay out Flash web site interface (with components)

  1. Drag out the following components from the component panel (Window>Component) and lay them out as follow:

    UILoader for header (750Wx90H) & (x=0 and y=0)
    List for menu (100Wx340H) & (x=17 and y=107)
    TextArea for mainbody (590Wx300H) & (x=140 and y=107)
    TextArea for footer (710Wx22H) & (x=17 and y=460)

Note: A gap was intentionally left between the two TextArea components for the RSS Reader that will be created later.

  1. Give each component an instance name: (Note: Naming conventions are a blend between the purpose and the type of component)

    header_loader for UILoader
    menu_list  for List
    body_text for TextArea (larger of two)
    footer_text for TextArea

  2. Rename Layer 1 to components, etc. and create a new layer and name it ActionScript.

Populate UILoader with Company logo:

  1. Select UILoader and add source property in Property Inspector's parameters tab to "header.jpg"
    TIP: You can add a Flash *.swf file as a source instead of a *.jpg.
  2. Save and Test

Result Checkpoint: Company Logo should load into UILoader.

Populate TextArea in footer with static text:

  1. Add "Copyright {enter current year}.  {enter your companyname}.  All right reserved." in Property Inspector's parameters text (not htmlText) field.
  2. Save and Test

Result Checkpoint: Copyright notice should be displayed in footer's TextField.

Populate List with data from XML file

Create URLLoader (not UILoader) and XML object to hold data from an XML file:

  1. Select ActionScript layer and write the following code in the ActionScript panel.
    Why? To create URLLoader object and  add URLLoader load method to it and pass it a URLRequest object that will point to the actual index.xml file.

    var loader:URLLoader = new URLLoader();
    loader.load(new URLRequest("index.xml"))

    Caution: Note two ending parenthesis.

  2. Write the following code below current code.
    Why? To create a addEventListener for the loader object and an event Handler function (onDataLoad) to create an XML object and trace statement

loader.addEventListener (Event.COMPLETE, onDataLoad);

function onDataLoad (eventObject:Event):void
    {
      var applicationData:XML = new XML(eventObject);
      trace(applicationData)
    }

In this event handler, you created an XML object and passed it data from the URLLoader created earlier to provide data for the XML object and added a trace statement to see the result.

  1. Save and Test

    Result Checkpoint: You should be able to see some METADATA about the event that was dispatched or fired (i.e, its type, etc.) displayed in the Output panel.


  2. Add ".type" to the end of the eventObject.

       var applicationData:XML = new XML(eventObject.type);

  3. Save and Test

    Result Checkpoint: You should be able to see the type of event that was dispatched or fired displayed in the Output panel.

  4. Replace  ".type" with ".target" at the end of the eventObject.

    var applicationData:XML = new XML(eventObject.target);

  5. Save and Test

    Result Checkpoint: You should be able to see the target object that made the function called displayed in the Output panel.


  6. Add ".data" to the "eventObject.target" to "drill down" to get the the data in the loader object. (Do not delete the word target).

    var applicationData:XML = new XML(eventObject.target.data);

Result Checkpoint: You should be able to see the complete XML file.  Examine it to see the XML tree structure and take note of the repeating nodes (list_item).

Since the "list_item" nodes are repeating nodes, we will need to drill down deeper just like a file structure (directory/directory/file) to retrieve each node and add them to a XMLList.

  1. Comment out trace and add the following code in bold to the onDataLoad function.
    Why? To create an XMLList (similar to an Array) and to trace it.

function onDataLoad (eventObject:Event):void
    {
         var applicationData:XML = new XML(eventObject.target.data);
         //trace(applicationData)
         var MenuList:XMLList = applicationData.list_item
         trace(MenuList)

    }

  1. Save and Test

Result Checkpoint: Only the list_item REPEATING nodes should be returned and not the complete XML file as before.

  1. Comment out the trace and add the follow code in bold to the onDataLoad function
    Why? Since MenuList is similar to an array we can use a "for" loop to iterate through it to get the data we need.

function onDataLoad (eventObject:Event):void
    {
         var applicationData:XML = new XML(eventObject.target.data);
         //trace(applicationData)
         var MenuList:XMLList = applicationData.list_item
         //trace(MenuList);

         var menu_total:Number = MenuList.length()
        //trace(menu_total);

        for (var i:uint=0; i<menu_total; i++)
          {
         
 var MenuNames:String = MenuList.link_item_name[i];
           trace(MenuNames)

           }

    }

 Caution: Note parenthesis on the MenuList.  An XMLList has length as a method -- length() unlike a property -- length in an Array.   Also, watch out for cases, spaces, and braces.

Result CheckPoint: You should see a list (i.e., Home, Products, Services, Contact Us) from the index.xml file in the output panel.

  1. Comment out the two previous lines. (They were only used to show the data that will be used to populate the menu_list in the next step.) Add the follow code in bold to the onDataLoad function
    Why? Use a "for" loop to iterate through data to create generic objects with properties while at the same time populating the List component which will act as our menu.

function onDataLoad (eventObject:Event):void
    {
         var applicationData:XML = new XML(eventObject.target.data);
         //trace(applicationData)
         var MenuList:XMLList = applicationData.list_item
         //trace(MenuList)

         var menu_total:Number = MenuList.length()

        for (var i:uint=0; i<menu_total; i++)
          {

          // var MenuNames:String = MenuList.link_item_name[i];
           //trace(MenuNames)

               menu_list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i] });
          
}
    }

 Caution: Note parenthesis.  An XMLList has lenght as a method -- lenght() unlike a property -- length in an Array. Also, watch out for cases, spaces, and braces.

IMPORTANT NOTES:

Result CheckPoint: You should see List component populated with content from the "link_item_name" tags (i.e., Home, Products, Services, Contact Us) from the index.xml file.

Connect List to TextArea (mainbody) component

  1. Add following code to the bottom of current code.
    Why? Since we created a data property as one of our property of our generic object for each main_body tag in the XML file, we can listen for a change in the List component to dispaly the currently selected menu item.

       // Menu ====================================================
       menu_list.addEventListener (Event.CHANGE, onMenuChange);

       function onMenuChange (eventObject:Event):void
       {
          // trace("A list item was clicked")
           //trace("The " + eventObject.target.selectedItem.label + " button was clicked")
           //body_text.text = "The " + eventObject.target.selectedItem.label + " button was clicked"

           body_text.text = eventObject.target.selectedItem.data
      }

  1. Save and Test (by commenting or uncommenting only one line at a time.)

Result Checkpoint: By clicking on a "link" in the menu list (or using the up/down arrows) the body_text area change to reflect the content from the index.xml file.

Finishing touches

Add first page (i.e., home page) to main body TextArea and make first menu item highlight on load:

  1. Add following code in bold at the bottom of "for" loop.
    Why? So that the first page content (i.e., home page) displays automatically on load without having to click on the first button (in this case, Home) and the first menu item get highlighted as well.

        for (var i:uint=0; i<menu_total; i++)
          {
               menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                   data:MenuList.main_body[i] });
           }
body_text.text = MenuList.main_body[0];
menu_list.selectedIndex = 0;

NOTES:

  1. Add the following code to the bottom of the existing code to set the editable property of the body_text and footer_text components to false.
    Why? To prevent the user from editing the dynamic text.Save and Test.

            for (var i:uint=0; i<menu_total; i++)
              {
                   menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i] });
               }
    body_text.text = MenuList.main_body[0];
    menu_list.selectedIndex = 0;
    body_text.editable = false
    footer_text.editable = false


    or you could "stack" the two line like this: body_text.editable = footer_text.editable = false.

  2. Save and Test

    Result Checkpoint: The first page should be loaded and the first menu should be highlighted automatically. Also, the text in the body and footer are not editable.

  3. Replace the property .text to .htmlText on both the body_text references in the code.

Result Checkpoint: The second page should rendered as standard HTML text (and image) and not just literal text.

Convert Flash Web Site to Flash RSS Reader

  1. Save the current file (FlashWebsite.fla) as FlashRSSReader.fla in the Lesson 4 folder.
  2. Add a button component to the Components layer and position it in the lower right corner of the body text field (x=630 and y=415)
  3. Give button an instance name of readFullPost_btn
  4. Add a label (More info... or something similiar) in Property Inspector's parameters panel
  5. Add following code to bottom of current code. Comment is optional.
    Why? To have be button listen for a change in the menu and open a seperate URL.

//Full Post Button ==============================================================

readFullPost_btn.addEventListener (MouseEvent.CLICK, onFullPost);

function onFullPost (eventObject:MouseEvent):void
       {
           navigateToURL(new URLRequest("http://" + menu_list.selectedItem.url))
      }

Note: selectedItem is used and not selectedIndex this time. The difference is that selectIndex is the index value or number; whereas the selectedItem is the literal name (not number) of the selected item as the name implies.

Caution: Note two ending parenthesis.

    1. Add following code in bold to generic object in "for" loop.
      Why? To accomodate the url tag in the index.xml file

              for (var i:uint=0; i<menu_total; i++)
                {
                     menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                         data:MenuList.main_body[i] ,
                                                         url:MenuList.url[i] });
                 }

      Caution: Note comma (,) at end of "data" property line.
      NOTE: While the data could be accessed directly from the  XML object, it is easier to "store" the data from the XML object into another component, in this case, a list component. Then, the component can be "talked" to get its properties instead.

  1. Save and Test

Result Checkpoint: Clicking on the More Info button will open a separate URL for each menu item.

Convert Flash RSS Reader to Flash Photo Gallery

  1. Save the current file (FlashRSSReader.fla) as FlashPhotoGallery.fla in the Lesson 5 folder.
  2. Open the component panel and drag and drop a TileList component to the Library panel.
  3. Select the List component (menu_list) on the stage and click the Swap... button in the Property Inspector and select the TileList component.
    Note: This saves from not having to:
  4. Save and Test

Result Checkpoint: You should see a two columns displayed in the TileList.  However, the application function the same.

  1. Change the TileList width to 160 and the TextArea x to 195 and the TextArea width to 540
  2. Change columnWidth to 160, rowHeight to 180 and direction to vertical in the Property Inspection's parameters tab.
    Note: The columnWidth is the same size as the width of the images that will be loaded. The columnHeight;however, was determine by the images widdth and a padding of 55 pixels to accomodate the names in the TileList.
  3. Save and Test

Result Checkpoint: You should only see a one column display.

  1. Add following code in bold to the generic object in the "for" loop.
    Why? To accomodate the source tag in the index.xml file

      for (var i:uint=0; i<menu_total; i++)
              {
                   menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i] ,
                                                       url:MenuList.url[i],
                                                       source:MenuList.thumbnail_img[i]});
               }

    Caution: Note comma (,) at end of "url" property line.
    NOTE: It is helpful to think of the List component as a set of drawers you can store whatever properties you want. Each drawer can have difference amount of data in it based on the XML file.

  2. Save and Test

Result Checkpoint: Thumbnails images appear along with their labels.

ALTERNATIVE: The text box can be replaced by a UILoader component and the code can be tweak to show larger versions of the thumbnail image when a list item is clicked.

  1. Create larger versions of the images in the Thumbnails folder (i.e. image_large.jpg) for each small image.
  2. Replace the text content in the <link_item_name> tags with a path (i.e., <link_item_name>Thumbnails/image_large.jpg</ link_item_name>) to the larger images for each repeating node in the xml file.
  3. Change the code body_text.text = eventObject.target.selectedItem.data to body_text.source = eventObject.target.selectedItem.data.
  4. Test movie.

Download version 2 (Createing a Flash PhotoGallery Version 2). It has an additional Loader component and the ListTile has been moved to the bottom. Use the (index.xml) file as the data source. Use Thumbnail file from the version 1.

Convert Flash Photo Gallery to Flash Video Gallery

  1. Save the file (FlashRSSReader.fla, NOT the FlashPhotoGallery.fla) as FlashVideoGallery.fla into the in the Lesson 6 folder.
  2. Delete the Text Area component (body_text) on the stage
  3. Drag and drop the FLVPlayBack component from the component panel under the video category and position it at x=285 and y=137 and give it and instance name of body_text.
    Notes
    :
    -- The instance name "body_text" may not be the most descriptive for this component but it is used so that we do not have to change the code.
    -- The FLVPlayBack will have default size of 320Wx240H so you don't have to set it.
    -- You can not swap a video componet like you did for the TileList so you had to, in this case, position the component
  4. With the FLVPlayBack component still selected, set the autoPlay property to false in the parameters tab and a skin type of your liking.
    NOTE: The skin is the VCR controller.
  5. Add following code that is in bold to generic object in "for" loop.
    Why? To accomodate the video tag in the index.xml file

      for (var i:uint=0; i<menu_total; i++)
              {
                   menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i],
                                                       url:MenuList.url[i],
                                                       source:MenuList.thumbnail_img[i],
                                                       video:MenuList.video[i] });
               }

    Caution: Note comma (,) at end of "url" property line.

  6. Replace the code: body_text.htmlText = MenuList.main_body[0]; with body_text.source = MenuList.video[0]; at the bottom of the "for" loop.
    Why? Since we are now working with a video component instead of a Text Area component, we need to change the property and its value accordingly from  text-and-data to source-and-video.
  7. Comment out the code: body_text.editable = false
    Why? Since this is a video component, we no longer need this line of code.
  8. Replace the code: body_text.htmlText = eventObject.target.selectedItem.data; with body_text.source = eventObject.target.selectedItem.video; in the onMenuChange event handler function.
    Why? Since we are now working with a video component instead of a Text Area component, we need to change the properties accordingly.
  9. Add the following code: body_text.play(); to the next line.
    Why? Not only do we need to provide a source property to "get" the video, but we also need to provide a play property to "play" the video.
    NOTE: You do not need this line of code if you select the autoPlay option in the Property Inspector or the Component panel.
  10. (Optional) Replace every instance of "body_text" in the complete code with "video_flv " manually or by using the Search and Replace icon at the top of the Action Panel.
    Why? Simply to make the code easiler to read when using the video component.
  11. Save and Test

    Result Checkpoint: If you "initially" select the first menu item (Home), the video will not play. The reason is no "change" has taken place because the menu is ALREADY selected.

  12. Comment out the following line of code in the onDataLoad function
    Why? So that no list item will be "initially" selected when the application loads.

    // menu_list.selectedIndex = 0

    Result Checkpoint: You can now selected any menu item and the corresponding video will play.

  13. (Optional) Swap the TileList component with a simple Tile component using the Property Panel.
    Why? To create a simple List with images
  14. (Optional) Delete the property value pair including the comma (source:MenuList.thumbnail_img[i],) from "for" loop
    Why? Not needed with a simply Tile component.

Finishing touches (need more work)

Add  a cell render *.as file, symbols and TileList to show picture, similar to PhotoGallery.

  1. Select File>Import>Open External Library... from menu and open the ThumbNailSymbols.fla file in the current lesson directory and drag and drop 3 symbols to "internal" Library.
    Why? These symbol will be used with an external class file (Thumbs.as) that will be attached to the current project.

  2. Close Exernal Library as it is no longer needs to be open since you drag the symbols into the current project library.

LEVEL 2: MAKE COMPONENTS DYNAMIC-- (Code-based Architecture)

Replace components with code

While the previous level did include some code, this level will create two of the four components in code and have their visual assets (i.e., Header/Footer) dynamically populate from the XML file.  Also,

Make UILoader dynamic:

  1. Re-open the FlashVideoGallery.fla  and save it as FlashVideoGallery_code.fla.
    Why? While any of the application could have been used, the FlashVideoGallery was chosen because it was the last one created.
  2. Delete UILoader component from stage
    Why? So that it can be replaced with code in the next step
  3. Add following code to top of code.  Comment is optional
    Why? Retrieving data for the header from an XML file allows you to update it without ever having to update any code in the Flash source file (*.fla) when it needs to be updated or replaced.
    Why? To create a code-based UILoader, add properties and display it.  Note, you must import the UILoader class first in order to use it.

    // Load Header dynamically =================================

  4. import fl.containers.UILoader;

    var ui_loader:UILoader = new UILoader();
    with (ui_loader)
    {
        autoLoad = true;
        scaleContent = true;
        width = 750;
        height = 100;
        move (0,0);
    }
    addChild (ui_loader);

    CAUTION: Because the move property has two values, notice there is no equal sign between the property and its values (i.e., move (0,0);).

    IMPORTANT NOTE: Since the loader depends on dynamic data, you can not access it from here, the code must be placed in the onDataLoad function (see next step) where the dynamic data is created. However, you could "test" the object here by adding "ui_loader.source = "header.jpg" to the bottom of the current code to test. Then, comment it out before continuing.

    NOTE: Because the UILoader is being created dynamically from code, as oppose to dragged and dropped from the component inspector, it class has to be import from the Flash class library and
       instantiated (i.e., var ui_loader:UILoader = new UILoader();)
       given properties (i.e., with {autoLoad = true;...})
      displayed (i.e., addChild(ui_loader);)
    Remember, a class is a blueprint or recipe of how to create an object.
    NOTE: The with {...} is a shorthand version that can be used when there are are many propeties that need to be assigned to an object. The longhand would have been written as:
        ui_loader.autoLoad = true;
        ui_loader.scaleContent = true;
        ui_loader.width = 750;
        ui_loader.height = 100;
        ui_loader.move (0,0);

  5. Add following code in bold below "for" loop.
    Why? To have header dynamically display in UILoader when the file first load.

for (var i:uint=0; i<menu_total; i++)
          {
               menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                   data:MenuList.main_body[i] ,
                                                  url:MenuList.url[i],
                                                  source:MenuList.thumbnail_img[i],
                                                  video:MenuList.video[i]});
           }
body_text.source = MenuList.video[0];
//menu_list.selectedIndex = 0
ui_loader.source = applicationData.@header

Note: We use applicationData because it represents the complete XML so that we could drill down to get to the header attribute.  We could not use the MenuList because it only returns the repeating nodes which is drilled down to far into the XML file.

  1. Save and Test

Result Checkpoint: Header image should load dynamcally into the UILoader from an attribute (header) in index.xml file

Make footer TextField dynamic:

  1. Delete footer TextField component
    Why? So that it too can be replaced with code in the next step
  2. Add a TextField object at bottom of current code.
    Why? Retrieving the data for the footer from an XML file allows you to update it without ever having to update any code in the Flash source file (*.fla) when it needs to be updated or replaced. (i.e., current year or company name)
    Why? To create a code-based TextField, add properties and display it.

//Load Footer dynamically ==================================
var footer:TextField = new TextField();
footer.border = true;
//border = true -- does not work in "with" function.
with (footer)
{
x = 20;
y = 460;
width = 700;
height = 20;
background = true;
}
addChild (footer);

Result Checkpoint: Footer's textfield should be displayed with a border around it.

  1. Add a Date object to the bottom of code. Trace is optional
    Why? So that it can be used within the footer TextField to create a complete copyright notice.

    //Create Date Object ==============================
    var currentYear:Date = new Date();
    var copyrightYear:String = String(currentYear.fullYear)
    trace ("What is current year? " + copyrightYear);

    NOTE: Date has been casted (or converted) from a date datatype into a string datatype using the String function (i.e., String(currentYear.fullYear)).

  2. Comment out the trace below the Date object

    //Create Date Object ==============================
    var currentYear:Date = new Date();
    var copyrightYear:String = String(currentYear.fullYear)
    //trace ("What is current year? " + copyrightYear);

  3. Add following code in bold below "for" loop.

    for (var i:uint=0; i<menu_total; i++)
              {
                   menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i] ,
                                                      url:MenuList.url[i],
                                                      source:MenuList.thumbnail_img[i],
                                                      video:MenuList.video[i]});
               }
    body_text.source = MenuList.video[0];
    //menu_list.selectedIndex = 0
    ui_loader.source = applicationData.@header
    footer.text = "Copyright  " + copyrightYear  + " " + applicationData.companyname + ".  All rigths reserved.";

    NOTE: There is a space after the word Copyright and before word All in the last string (i.e., ".  All rights reserved.")

  4. Save and Test

Result Checkpoint: Copyright notice should display the literal string "Copyright ", the current year and the company name from the index.xml file and  the literal text string: ". All Rights reserved."

Finishing touches

Add border to page using Flash drawing API

  1. Double-click on the border from around stage and press Delete key to delete it.
    Why? So that it can be replaced with code in the next step.
  2. Add following code to bottom of code.
    Why? To dynamically change border styles (i.e. color, size, etc.).

    //Draw border around application ================
    var border:Shape = new Shape();
    border.graphics.lineStyle (1,0x000000);
    //border.graphics.beginFill(0x000000)
    border.graphics.drawRect (0,0,750,500);
    //border.graphics.endFill()
    addChild (border);

    Note: border fill code has been purposely commented out just to show that a fill color could be added to a rectangle.

  3. Save and Test

Result Checkpoint: You should see a 1 pixel black border around application.

Make border color dynamic (optional)

  1. Add the following lines in bold to the code below the "for" loop. Trace is optional.
    Why? So that the border color value can be retrieved from the xml file using an attribute.

    for (var i:uint=0; i<menu_total; i++)
              {
                   menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i] ,
                                                      url:MenuList.url[i],
                                                      source:MenuList.thumbnail_img[i],
                                                      video:MenuList.video[i]});
               }
    body_text.source = MenuList.video[0];
    //menu_list.selectedIndex = 0
    ui_loader.source = applicationData.@header
    footer.text = "Copyright  " + copyrightYear  + " " + applicationData.companyname + ".  All rigths reserved.";
    var borderColor:uint = applicationData.@borderColor;
    trace("borderColor is " + borderColor);

    drawBorder(borderColor);

    IMPORTANT NOTE: It is important to remember that when retrieving external data, in this case an xml file, that the data is retreived before it can be used else where in the code.  One way is first retrieve the data (i.e, applicationData.@borderColor) and assign it to a variable (i.e., var borderColor:uint) and then create a function (i.e., drawBorder) and pass the variable as an argument of that function inside of the function that is retrieving the data (i.e., onDataLoad).

  2. Edit the following line of code in bold by wrapping a function block around the existing code and changing the literal argument 0x00000  to color

    //Draw border around application =======================================
    function drawBorder(color):void
    {

    var border:Shape = new Shape();
    border.graphics.lineStyle(1,color);
    border.graphics.drawRect(0,0,750,500);
    addChild(border);
    }

    CAUTION: Note the opening and closing curly braces (ie., {......}).

  3. Save and Test

    Result Checkpoint: You should see a 1 pixel red border (or whatever color is in the xml file) around the application based on the borderColor attribute in the xml file. You should also see the trace result in the output panel.

  4. Change the borderColor in xml file and save it and then  test the movie again.

Result Checkpoint: You should see a 1 pixel border of whatever color that was set in the xml file around the application.

Make border thickness dynamic (optional)

  1. Add and edit the following lines in bold to the code below the "for" loop. Trace is optional
    Why? So that the border color value can be retrieved from the xml file using a tag (instead of an attribute).

    for (var i:uint=0; i<menu_total; i++)
              {
                   menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i] ,
                                                      url:MenuList.url[i],
                                                      source:MenuList.thumbnail_img[i],
                                                      video:MenuList.video[i]});
               }
    body_text.source = MenuList.video[0];
    //menu_list.selectedIndex = 0
    ui_loader.source = applicationData.@header
    footer.text = "Copyright  " + copyrightYear  + " " + applicationData.companyname + ".  All rigths reserved.";
    var borderColor:uint = applicationData.@borderColor;
    trace("borderColor is " + borderColor);
    var borderThickness:uint = applicationData.borderThickness;
    trace("borderThickness is " + borderThickness);

    drawBorder(borderThickness, borderColor );

    NOTE: There is no "@" on the borderThickness because data from a tag and not a tag attribute is being retrieved. Also, note a additional argument was added to the drawBorder function (borderThickness).

  2. Edit the following line of code in bold by changing the literal argument 1  to thickness in two places

    //Draw border around application =======================================
    function drawBorder(thickness, color):void
    {
    var border:Shape = new Shape();
    border.graphics.lineStyle(thickness,color);
    border.graphics.drawRect(0,0,750,500);
    addChild(border);
    }

  3. Save and Test

    Result Checkpoint: You should see a 1 pixel red border (or whatever color is in the xml file) around the application based on the borderColor attribute in the xml file. You should also see the trace results in the output panel.

  4. Change the borderThickness in xml file and save it and then test the movie again.

Result Checkpoint: You should see the border thickness changed based on the setting in the xml file.

Add TextFormat to TextField (footer)

  1. Add following code to below the footer.text statement in the onDataLoad function.
    Why? One way to format text is to create a TextFormat object (similar to CSS) and then apply it to an existing textfield.

    //Create a TextFormat object with properties ================================================================
    var footerTextFormat:TextFormat = new TextFormat();
    with (footerTextFormat)
    {
         font = "Arial";
         color = 0x0000FF;
         size = 10;
    }

  2. Add the following code in bold below the "for" loop:

    for (var i:uint=0; i<menu_total; i++)
              {
                   menu_ list.addItem ({label:MenuList.link_item_name[i],
                                                       data:MenuList.main_body[i] ,
                                                      url:MenuList.url[i],
                                                      source:MenuList.thumbnail_img[i],
                                                      video:MenuList.video[i]});
               }
    body_text.source = MenuList.video[0];
    //menu_list.selectedIndex = 0
    ui_loader.source = applicationData.@header
    footer.text = "Copyright  " + copyrightYear  + " " + applicationData.companyname + ".  All rigths reserved.";
    var borderColor:uint = applicationData.@borderColor;
    trace("borderColor is " + borderColor);
    var borderThickness:uint = applicationData.borderThickness;
    trace("borderThickness is " + borderThickness);
    drawBorder(borderThickness, borderColor );
    footer.setTextFormat (footerTextFormat);

  3. Save and Test

Result Checkpoint: Text in footer should be Arial, 10 points and blue.

Add CSS to TextField (mainbody) Add later.....

  1. Comment out the TextFormat code block using a block level comment (/* ........ */). Also, comment out the last line added to the bottom of the footer using a single line comment (i.e., //footer.setTextFormat(fotterTextFormat);.
  2. Add following code to bottom of existing code.
    Why? Another way to add text format is to create a CSS file and attach it to the flash movie.

    Add code here.....

LEVEL 3: MAKE COMPONENTS DYNAMIC-- (Class-based Architecture)

Replace components with classes

  1. Re-open FlashVideoGallery.fla and save it as as FlashVideoGallery_class.fla.
    Why? While any of the applications (i.e., web site, RSS, PhotoGallery) could have been used, the FlashVideoGallery was chosen because it was the last application created.
  2. Open ThumbnailsAsset.fla as an external library and copy and paste 3 symbols into library.
    Note: Three assets that are need for this class has already been created (ThumbCellBg,ThumbCellBgOver, and ThumbCellBgSelected). See library
  3. Add following code in bold to top of current code.
    Why? To add an already created class (Thumb.as) to the TileList component to format its cells.

    // Format the tileList,
    menu_list.setSize (300, 279);
    menu_list.columnWidth = 280;
    menu_list.rowHeight = 100;
    // Specify cellRenderer class.

    menu_list.setStyle ("cellRenderer", Thumb);


  4. Comment out the three properties for the menu_list:
    Why? We will add these properties in a custom class file.
    // Format the tileList,
    //menu_list.setSize (300, 279);
    //menu_list.columnWidth = 280;
    //menu_list.rowHeight = 100;

    // Specify cellRenderer class.

    menu_list.setStyle ("cellRenderer", Thumb);

  5. Create a new ActionScript (*.as) and name it playList.as in the same folder as the other files.
  6. Write the following code
    Why? To import the required classes that are needed for this class:

    package
    {
    import flash.display.MovieClip;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import fl.controls.listClasses.CellRenderer;
    import fl.controls.ScrollBarDirection;

  7. Write the following code below the previous code:
    Why? To set up class constructor and main Playlist method.

public class Playlist extends MovieClip
{
private var loader:URLLoader;

public function Playlist ():void
{
// Load the playlist file, then initialize the media player.
loader = new URLLoader();
loader.load (new URLRequest("index2.xml"));
loader.addEventListener (Event.COMPLETE, onDataLoad);

// Format the tileList, specify its cellRenderer class.
menu_list.setSize (300, 279);
menu_list.columnWidth = 280;
menu_list.rowHeight = 100;
menu_list.direction = ScrollBarDirection.VERTICAL;
menu_list.setStyle ("cellRenderer", Thumb);
}

  1. Write the following code below the previous code:
    Why? To create the onDataLoad event handler and close out the other code blocks with curly braces.

public function onDataLoad (eventObject:Event):void
{
var applicationData:XML = new XML(eventObject.target.data);
//trace(eventObject.target.data)
var MenuList:XMLList = applicationData.list_item;
//trace(MenuList)
var menu_total:uint = MenuList.length();
for (var i:uint=0; i<menu_total; i++)
{
menu_list.addItem ({label:MenuList.link_item_name[i],
data:MenuList.main_body[i],
url:MenuList.url[i],
source:MenuList.thumbnail_img[i],
video:MenuList.video[i]});
}
//Load first page ===============================================================
main_body.source = MenuList.video[0];
menu_list.selectedIndex = 0;
// Menu =========================================================================
menu_list.addEventListener (Event.CHANGE, onMenuChange);

function onMenuChange (eventObject:Event):void
{
main_body.source = menu_list.selectedItem.video;
main_body.play (menu_list.selectedItem.video);
//trace ("Selected menu item? " + menu_list.selectedItem.label);
//trace ("Selected page in output panel? " + menu_list.selectedItem.data);
}
//Full Post Button ==============================================================
readFullPost_btn.addEventListener (MouseEvent.CLICK, onFullPost);

function onFullPost (eventObject:MouseEvent):void
{

//navigateToURL (new URLRequest("http://" + menu_list.selectedItem.url));
trace ("hello");
}
}
}
}

  1. Save this file and return to multi-purpose_app_FlashVideoGallery_class.fla
  2. Type Playlist into the Document Class textfield in the Property Inspector.
  3. Save and Test

Result Checkpoint: The movie should work the same as before;however, it is class-based instead of internal code-based or component-based.