Putting it All Together

In this section, well put together everything weve covered so far in the chapter and create a simple XML application. Well use the photoGallery.xml file that you created in Chapter 3. The application will load the content from the XML document and add the contents to create a photo gallery.

Well work through the following steps to create our application. These steps are likely to be the same ones you use each time you load an external XML document.

  1. Create the XML object.

  2. Set the ignoreWhite property to true.

  3. Specify the name of the function that will deal with the loaded XML document.

  4. Load the XML document.

  5. Within the load function, test whether the file has loaded successfully.

  6. Display the document tree with a trace action to check that youve loaded the contents correctly.

  7. Set a variable referring to the RootNode of the XML document.

  8. Work through the document tree, adding content to the Flash movie.

The completed file gallery_completed.fla is included with your resources for Chapter 4 in case you want to see how the finished application works. Note that Ive used ActionScript version 2.0 and version 2.0 components in the files, so youll need at least Flash MX 2004 to complete the exercise.

Exercise 3: Creating an XML photo gallery
image from book

In this exercise, well create a simple Flash photo gallery that loads external images. Well take the images from the photos folder included with the Chapter 4 resources. You can also use your own images if youd prefer. Just add them to the photos folder and the XML document.

Setting up the environment

  1. Move the photos folder, the starter file gallery.fla , and the photoGallery.xml file from the resources to the same directory on your computer.

  2. Open gallery.fla . Figure 4-11 shows the interface.

    image from book
    Figure 4-11: The gallery.fla interface

The interface includes a static text field containing the text Photo gallery . There are two dynamic text fields, one on the left for the caption and one on the right for the comments about the image. They have the instance names caption_txt and comment_txt , respectively.

There is an empty movie clip called empty_mc below the caption. Well use this to display the photos. The top right of the interface includes a ComboBox component, gallery_cb , and two buttons , back_btn and forward_btn . Users will choose the gallery from the ComboBox component and navigate through the photos with the two buttons.

The XML document

We created the XML document photoGallery.xml in Chapter 3. The following code shows a summary of the document structure:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <photoGallery>   <location locationName="galleryName">     <photo filename="filename.jpg" caption="caption content">       Text     </photo>     <photo filename="filename.jpg" caption="caption content">       text     </photo>   </location>   <location locationName="galleryName">     <photo filename="filename.jpg" caption="caption content">       Text     </photo>   </location> </photoGallery> 

The root element <photoGallery> contains one or more <location> elements. Each <location> has a single attribute locationName and contains one or more <photo> elements. The <photo> elements contain a filename and caption attribute as well as some descriptive text.

Feel free to update the XML document and photos folder with your own contents. The Flash movie is set up for landscape images with a width of up to 290 pixels, but you can change the movie if youre using differently sized images.

Loading the XML document into Flash

Well load the XML document into the gallery.fla movie.

  1. Create a new layer in the gallery.fla file and name it actions .

  2. Click the first frame of the actions layer and open the Actions panel with the F9 shortcut key.

  3. Add the code shown here. This code loads the document photoGallery.xml into the photoXML object. When the loading is completed, the loadPhotos function displays the contents of the XML object.

     var photoXML:XML = new XML(); photoXML.ignoreWhite = true; photoXML.onLoad=loadPhotos; photoXML.load("photoGallery.xml"); stop(); function loadPhotos(success:Boolean):Void{   if (success) {     trace (this);   }   else {     trace("Error in loading XML file");  }  } 
  1. Save the movie and test it with the CTRL-ENTER shortcut key ( CMD-RETURN on a Macintosh). You should see something similar to the image shown in Figure 4-12.

    image from book
    Figure 4-12: Testing that the XML document has been loaded into Flash

Youll notice that Flash has ignored the CDATA block from the XML document. Instead, the <b> tag has been converted to the HTML entities &lt; and &gt; . As we discovered earlier, Flash doesnt recognize CDATA.

Once the XML document has been loaded into the photoXML object, its time to start populating the interface.

Loading the ComboBox component

Well start by adding the names of each location to the ComboBox component. The name comes from the locationName attribute in the <location> element.

  1. Create a new XMLNode variable called RootNode at the top of the actions layer. We create it outside of the loadPhotos function so that we can refer to the root node of the XML object anywhere within the Flash movie.

     var RootNode:XMLNode; 
  2. Modify the loadPhotos function as shown here. Ive indicated the new lines in bold. The function calls the loadCombo function after successfully loading the XML file.

     function loadPhotos(success:Boolean):Void{   if (success) {  RootNode = this.firstChild;   loadCombo();  }   else {     trace("Error in loading XML file");   } } 
  1. Add the loadCombo function below the loadPhotos function. Ive used the addItem method of the ComboBox component to add the locationName attribute values. Notice that Ive done this inside a loop so that I can process all child elements of the root node in the same way. I have also added an item -- Select -- at the beginning of the ComboBox.

     function loadCombo():Void {   var galleryName:String;   gallery_cb.addItem("-- Select --");   for (var i:Number=0; i< RootNode.childNodes.length; i++) {     galleryName = RootNode.childNodes[i].attributes.locationName;     gallery_cb.addItem(galleryName);   } } 
  2. Test the movie again. You should see the gallery names in the ComboBox component as shown in Figure 4-13.

    image from book
    Figure 4-13: Testing that the ComboBox component has been populated

At the moment, when we select a value from the ComboBox component, nothing happens. We actually want the first image from the selected gallery to be displayed on the Stage. To achieve that, well need to add an event listener to the ComboBox component.

Adding an event listener to the ComboBox

ActionScript is an event-driven language. We use it to respond to events that occur in a movie, for example, the click of a button or selecting a value from a ComboBox. Because we want something specific to happen when these events occur, we can use an event listener. Event listeners listen for specific events and respond by calling a function.

We want an image to display when the value of the item in the ComboBox changes. We can only do this with an event listener that listens for the change event of the ComboBox. When the listener detects that event, it will call a function to deal with the changed value in the ComboBox.

  1. Add the following code above the loadPhotos function. The code creates an object called CBOListener , which listens for the change event. When the event fires, the listener calls the loadGallery function.

     var CBOListener:Object = new Object(); CBOListener.change = loadGallery; gallery_cb.addEventListener("change", CBOListener); 
  2. Add the loadGallery function below the loadCombo function. The function receives the object that called it as a parameter, that is, the listener. It traces the label of the selected option using evtObj.target to locate the target of the event listener.

     function loadGallery(evtObj:Object):Void {   trace (evtObj.target.selectedItem.label); } 
  1. Test the movie. You should see something similar to Figure 4-14 when you make a selection in the ComboBox.

    image from book
    Figure 4-14: Testing the ComboBox listener

Once we have detected the selected gallery, we can move to that section of the document tree and load the first image.

Loading the photos

The first task is to move through the document tree and locate the selected gallery. Well create some variables to help out.

  1. Add new variables called selectedGallery , photoPosition , GalleryNode , and PhotoNode below the RootNode variable at the top of the Actions panel. Set the types to String , Number , and XMLNode , as shown here. These variables will have scope throughout the Flash movie because we havent created them within a function.

     var RootNode:XMLNode;  var selectedGallery:String;   var photoPosition:Number;   var GalleryNode:XMLNode;   var PhotoNode:XMLNode;  
  2. Modify the loadGallery function as shown here. The new lines appear in bold. The function finds if weve selected a gallery and sets the variable selectedGallery . It then finds the correct gallery and sets the position in the document tree within the variable GalleryNode . Finally, it calls the loadPhoto function, passing a value of to indicate that the first image should display. The break statement ends the loop.

     function loadGallery(evtObj:Object):Void {  var galleryName:String;   if (evtObj.target.selectedItem.label !=" Select ") {   selectedGallery = evtObj.target.selectedItem.label;   for (var i:Number=0; i< RootNode.childNodes.length; i++) {   galleryName = RootNode.childNodes[i].attributes.locationName;   if (galleryName ==  selectedGallery) {   GalleryNode =RootNode.childNodes [i ];   photoPosition=0;   loadPhoto(photoPosition);   break;   }   }   }  } 
  3. Add the function loadPhoto below the loadGallery function. This function traces the file name of the first image in the gallery.

     function loadPhoto(nodePos:Number):Void {   trace (GalleryNode.firstChild.attributes.filename); } 
  4. Test the movie. Select a gallery. You should see something similar to the image shown in Figure 4-15.

    image from book
    Figure 4-15: Testing the loadPhoto function

Now we need to use the file name to display the image from the photos folder in the empty movie clip. We also need to add text from the XML document to the caption and comment fields.

  1. Modify the loadPhoto function as shown here. The function sets the PhotoNode variable and finds the file name, caption, and comments from the document tree. The loadMovie action loads the image from the photos folder into empty_mc . The text and htmlText properties display the caption and comments. Notice that we set the html property of the comment_txt field to true so that it can render the HTML tags from the CDATA section of the XML document.

     function loadPhoto(nodePos:Number):Void {  PhotoNode = GalleryNode.childNodes[nodePos];   var filename:String = PhotoNode.attributes.filename;   var caption:String = PhotoNode.attributes.caption;   var comments:String = PhotoNode.firstChild.nodeValue;   empty_mc.loadMovie("photos/" + filename);   caption_txt.text = caption;   comment_txt.html =true;   comment_txt.htmlText =comments;  } 
  2. Test the movie again and select an image gallery. You should see something similar to Figure 4-16.

    image from book
    Figure 4-16: Testing that the first image loads

If you select the other galleries, the first image from each will load. A problem arises when we choose the -- Select -- option. The current image, caption, and comment remain . It would be better if this selection cleared the image and the text fields.

  1. Change the loadGallery function as shown here. If we choose the -- Select -- item, empty_mc is unloaded and the text fields are cleared.

     function loadGallery(evtObj:Object):Void {   var galleryName:String;   if (evtObj.target.selectedItem.label !="-- Select --") {     selectedGallery = evtObj.target.selectedItem.label;     for (var i:Number=0; i< RootNode.childNodes.length; i++) {       galleryName = RootNode.childNodes[i].attributes.locationName;       if (galleryName ==  selectedGallery) {         GalleryNode = RootNode.childNodes[i];         photoPosition=0;         loadPhoto(photoPosition);         break;       }     }   }  else {   empty_mc.unloadMovie();   caption_txt.text = "";   comment_txt.htmlText = "";   }  } 
  2. Test the movie again. Select an image gallery and then choose the first option in the ComboBox. The interface should clear.

So far, we can view the first image in each image gallery. The next step is to configure the buttons so we can navigate through all of the photos in each gallery.

Configuring the buttons

The gallery movie includes two buttons: back_btn and forward_btn . When the back button is pressed, we should move to the previous image, if one exists. Conversely, the forward button should move us to the next image. Well start by disabling the buttons so that we cant navigate until after weve selected an image gallery.

  1. Enter the following lines above the photoXML variable declaration at the top of the actions layer:

     back_btn.enabled = false; forward_btn.enabled = false; 
  2. Change the loadGallery function. Well need to enable the buttons after we have selected a gallery. Well also need to disable the buttons when the -- Select -- option is chosen and clear the selectedGallery variable.

     function loadGallery(evtObj:Object):Void {   var galleryName:String;   if (evtObj.target.selectedItem.label !="-- Select --") {     selectedGallery = evtObj.target.selectedItem.label;     for (var i:Number=0; i< RootNode.childNodes.length; i++) {       galleryName = RootNode.childNodes[i].attributes.locationName;       if (galleryName ==  selectedGallery) {         GalleryNode = RootNode.childNodes[i];         photoPosition=0;         loadPhoto(photoPosition);  back_btn.enabled = true;   forward_btn.enabled = true;  break;       }     }   }   else {     empty_mc.unloadMovie();     caption_txt.text = "";     comment_txt.htmlText = "";  selectedGallery = "";   back_btn.enabled = false;   forward_btn.enabled = false;  } } 
  3. Test the movie. Check that the buttons are enabled and disabled as you choose different gallery options.

Finally, well need to make the back and forward buttons work. We created the variable photoPosition earlier so we could keep track of the current photo number and the childNode within the selected gallery.

  1. Enter the following lines above the loadPhotos function at the top of the actions layer. The onRelease functions test whether there is a previousSibling or nextSibling of the current PhotoNode . If so, we either decrement or increment the photoPosition variable and call the loadPhoto function.

     back_btn.onRelease = function():Void {   if (PhotoNode.previousSibling.nodeName != undefined) {     photoPosition--;     loadPhoto(photoPosition);   } forward_btn.onRelease = function():Void {   if (PhotoNode.nextSibling.nodeName != undefined) {     photoPosition++;     loadPhoto(photoPosition);   } } 
  2. Test the movie for the last time and check that the gallery is functioning properly. Congratulations on completing the exercise. You can find the completed file saved as gallery_completed.fla in your resources for this chapter.

Points to note from exercise 3

  • Its important to define variables in the appropriate place. If youll only use a variable inside a function, you should define it inside that function using a var statement. When the function has finished running, the variable will cease to exist. This type of variable has local scope.

    If you want to use a variable in more than one function, youll need to define it outside the functions. The variable will then have timeline scope, and it will be available to every block of code on the current timeline. I normally list these variables at the top of a layer for convenience.

    You can set, retrieve, and change the values of timeline variables within functions. The RootNode variable is a perfect example of a timeline variable. We declare the variable at the top of the actions layer but its value isnt set until we call the loadPhotos function.

  • There is probably a more elegant way of dealing with the back and forward action of the buttons. For example, I could have disabled the back button if we were at the first photo and the forward button if we were at the last photo in the collection. Instead, I chose to use the previousSibling and nextSibling properties so you could see how they work.

  • If you followed the example, youll notice that, in each step, I wrote a little bit of code and then tested the movie. Its very important that you test your movie regularly. If you leave it too long before testing, it will be much harder to debug than if you have made only small changes each time. Sometimes, errors can compound and create strange results, making it hard to track down the cause of the problem.

  • You probably also noticed that I was fairly specific about where you should place the code on the actions layer. In fact, you could have put the code in just about any order and the gallery would still have worked. I wanted you to keep your code in a logical order so you could compare your content with the completed file. That way itll be easier for you to locate any errors in your code.

In the previous exercise, we created our first complete Flash XML application. We started by loading the XML document into Flash. We used it to populate a ComboBox component, and we added an event listener that responded when the user chose a gallery. The application displayed photos from the selected gallery, and we configured buttons so that the user could move to the next and previous photos. I broke the exercise into steps so you could see one approach that you could use to create the application.

If we didnt have a physical XML document with the photo information, we could have generated it from a database or by using a server-side file. These are examples of dynamic XML documents.

image from book
 

Loading dynamic XML documents

We refer to content stored in a physical document as static content. The content doesnt change each time we open the file, and we have to use a text or XML editor if we want to update the document. Its also possible to work with dynamic content. This type of content comes from a changing data source like a database.

In the previous example, we loaded information from a physical XML document into Flash. I saved the XML document with an .xml extension and stored it in the same folder as the Flash movie. You could view the file outside of Flash, in a text or XML editor.

As I mentioned earlier, its also possible to load XML content from a server-side file that creates an XML stream. This is a dynamic source of XML. You can use PHP, ColdFusion, ASP.NET, or any other server-side file that creates XML content. In this section, Ill show you an example using ASP.NET.

Installing IIS

Before you can work with server-side files, youll need to have a web server installed on your computer to process the files correctly. As Im running Windows XP Professional, I have IIS (Internet Information Services) installed. This allows me to run server-side files written in ASP or ASP.NET. I can also install an extension that allows me to run PHP files.

Windows XP Professional doesnt install IIS by default, so you may need to install it yourself using the Windows XP CD-ROM that came with your computer. You can check whether IIS is installed by looking at the folders in your C drive. IIS adds a folder called Inetpub to the C drive, and that folder should contain a subfolder called wwwroot . The wwwroot folder is the location for your websites . Youd normally create a set of folders within wwwroot one for each site or application.

If you dont have IIS installed, youll need to choose Start image from book Control Panel and select the Add or Remove Programs panel. Choose Add/Remove Windows Components on the left hand side and select the Internet Information Services (IIS) option. Click Next and follow the prompts to install IIS.

To work through the next exercise, youll also need to download and install the free .NET Framework from the Microsoft website. You can check if its installed by looking in the Add or Remove Programs Control Panel. If its there, you should see an entry for Microsoft.NET Framework . If its not, you can install it using Windows update at the Microsoft website. Make sure you install the .NET framework after youve installed IIS.

When you want to work with server-side files in Flash, the most important thing to remember is that the files must run through the web server first. This means that you have to use the full http:// path to the file. The web server will then process the server-side code before Flash receives the results. If you included the file name without the full path , Flash would read the server-side commands literally, without processing them first.

To work with server-side files in Flash, I have to copy them to the wwwroot subdirectory of the Inetpub folder. I usually create another folder in that area and copy all of my files there. For example, my files might live in the folder C:\Inetpub\wwwroot\FOE .

My web server has an address of http://localhost so I can open the files in a web browser by using the address http://localhost/foldername . When I use the full path, the web server processes the server-side code before sending the information to Flash.

Youll see an example of dynamic XML documents in the next exercise where well create an MP3 player. The movie uses ASP.NET to find out the names of MP3 files and folders. The server-side page converts the structure to XML before sending it to Flash. Ive used an ASP.NET page written in Visual Basic (VB) as I dont work with other server-side languages. You could also use a page written in another language. Youll find a PHP version of the page and Flash movie with your resources.

If you dont want to use a server-side file, you can still follow along with the exercise. However, youll need to create an XML file with the structure shown here. The root node <mp3s> contains a number of <folder> elements. Each <folder> has an attribute called foldername that indicates the name of the folder. The <folder> elements contain one or more <song> elements, and each <song> uses the attribute <filename> for the name of the MP3 file.

 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>   <mp3s>   <folder name="foldername">     <song filename="filename.mp3" />     <song filename="filename.mp3" />   </folder>   <folder name="foldername">     <song filename="filename.mp3" />     <song filename="filename.mp3" />   </folder> </mp3s> 

If you dont use a server-side file, youll need to replace the file name http://localhost/mp3s/MP3List.aspx with the name you choose for the XML file. Youll also need to change the file name if youre using a different server-side language.

Exercise 4: Creating an MP3 player
image from book

In this exercise, well use an ASP.NET page to create an XML representation of MP3 folders and files. Flash will load the content, and well create an application to play the files. After you complete the exercise, youll have a fully functioning MP3 player built in Flash. You can change the playlist by adding MP3 files to selected folders. If you want to see what youre building, you can see the finished product in the resource file MP3s_completed.fla . For those of you who prefer to work in PHP, the resource file MP3sPHP_completed.fla refers to the PHP version MP3List.php .

This is a long exercise, and well work through the following steps to complete the application:

  1. Setting up the environment

  2. Testing the server-side page

  3. Loading the XML content into Flash

  4. Testing that the XML content loaded correctly

  5. Loading the MP3 categories into a ComboBox component

  6. Adding a listener to the ComboBox component

  7. Loading the selected songs into a List component

  8. Adding a listener to the List

  9. Playing the selected song

  10. Configuring the controls

Lets get started by setting up the environment. For copyright reasons, youll need to use your own MP3 files for this exercise. Youll organize them into a set of subfolders to provide categories for the MP3 player.

Setting up the environment

  1. Create a new folder in your web server called MP3s . The path to mine is C:\Inetpub\ wwwroot\MP3s . You can find out more about web servers in the previous section.

  2. Copy the files MP3s.fla and MP3List.aspx from the Chapter 4 resources to the new folder.

  3. Create a set of subfolders for each song category in the MP3s folder. Copy MP3 files to each subfolder. Figure 4-17 shows how my folders are set up.

    image from book
    Figure 4-17: The folder structure for my MP3s

  1. Open the starter file MP3s.fla from the folder in the web server. You can see the interface in Figure 4-18.

    image from book
    Figure 4-18: The MP3s movie interface

The interface contains a ComboBox component called folder_cb that will list the folders in the MP3s folder. There is also a List component called songs_list . Well use this to display the songs in the selected folder. The interface also includes a sound volume slider and buttons to control the playback of songs.

Understanding the server-side page

Ive created a server-side page in ASP.NET called MP3List.aspx . The page looks inside c:\inetpub\wwwroot\mp3s , finds the subfolders and MP3 files, and creates an XML document. You can find the PHP version of the page in the resource file MP3List.php . Note that these pages dont create a physical document, but just a stream of XML information. This is similar to the stream of information that youd receive if you were consuming a web service. Youll find out more about web services in Chapter 9.

Ive included the code from Mp3List.aspx here, and Ill explain how it works. Note that Ive used ASP 1.1.

 <%@ Page Language="vb" %> <%@ import Namespace="System" %> <%@ import Namespace="System.IO" %> <%@ import Namespace="System.XML" %> <script runat="server">   Dim strDirectoryLocation as String = "c:\inetpub\wwwroot\mp3s"   Dim dirs As String(), fileInfos as String()   Dim i as Integer, j as Integer   sub Page_Load     Dim MP3Xml as XmlDocument = new XmlDocument()     Dim folderElement as XMLElement     Dim songElement as XMLElement 
 MP3Xml.AppendChild(MP3Xml.CreateXmlDeclaration("1.0", "UTF-8", _     "no"))     Dim RootNode As XmlElement = MP3Xml.CreateElement("mp3s")     MP3Xml.AppendChild(RootNode)     if Directory.Exists(strDirectoryLocation) then       dirs = Directory.GetDirectories(strDirectoryLocation)       for i = 0 to Ubound(dirs)         dirs(i) = replace(dirs(i), strDirectoryLocation, "")       next       Array.sort(dirs)       for i=0 to Ubound(dirs)         folderElement = MP3Xml.CreateElement("folder")         folderElement.SetAttribute("foldername", _         replace(dirs(i),"\",""))         RootNode.AppendChild(folderElement)         fileInfos = Directory.GetFiles(strDirectoryLocation _         & dirs(i) & "\", "*.mp3")         for j = 0 to Ubound(fileInfos)           fileInfos(j) = replace(fileInfos(j), strDirectoryLocation _           & dirs(i) & "\", "")         next         Array.sort(fileInfos)         for j = 0 to Ubound(fileInfos)           songElement = MP3xml.CreateElement("song")           songElement.SetAttribute("filename", fileInfos(j))           folderElement.AppendChild(songElement)         next       next     End If     dim strContents as String = MP3Xml.outerXML     response.write (strContents)   end sub </script> 

The first four lines of the code set up the language as Visual Basic and import the namespaces that the page will need to use. Next, Ive created some variables, including the variable strDirectoryLocation , which sets the location of the folder that contains the MP3s. You can change this folder reference to point to other folders on your computer. You dont have to include the MP3s folder within the web server folder. Ive also created two arrays: one for the directories in the folder and one for the files in each directory.

When the page loads, I create a new XMLDocument and some XMLElement variables. The page adds elements to the XMLDocument to create the XML page, and it starts by using the AppendChild and CreateXMLDeclaration methods to add the XML declaration. Then I create the RootNode element <mp3s> and append it to the document.

The page checks that the MP3s folder exists, and if so, it finds the directories inside and loops through them. The code removes the full path and adds the folder name to the dirs array. When the dirs array is completed, the page sorts it into alphabetical order.

Next, the page loops through the dirs array and creates the <folder> element, setting the folder name attribute. For each folder, we create an array of files called fileInfos , which is sorted into alphabetical order. The page loops through the fileInfos array and creates <song> elements with a filename attribute. At the end, the page writes the completed XMLDocument to the screen.

  1. Test the ASP.NET file in a web browser by loading the URL http://localhost/mp3s/MP3List.aspx. You should see something similar to Figure 4-19. Its a good idea to check that this page works before you start working on the Flash movie.

    image from book
    Figure 4-19: Displaying the page MP3List.aspx in a web browser

This is one example of how you could create an XML information stream from a server-side page.

Loading the XML information into Flash

Weve created the XML document that well use. Now its time to load the information into Flash.

  1. Create a new layer in the Flash file and name it actions . Click frame 1 in the Timeline.

  2. Open the Actions panel with the F9 shortcut key and add the code here. The code loads the XML information stream from the URL http://localhost/mp3s/MP3List.aspx into the SongsXML object. When the loading is completed, the loadSongs function displays the contents of the XML object in an Output window. This is the same approach that we used in the previous exercise.

     var SongsXML:XML = new XML(); SongsXML.ignoreWhite = true; SongsXML.onLoad = loadSongs; SongsXML.load("http://localhost/mp3s/MP3List.aspx"); stop(); function loadSongs(success:Boolean):Void {   if (success) {     trace (this);   }   else {     trace ("Error loading file");   } } 
  3. Save the movie and test it with the CTRL-ENTER shortcut key ( CMD-RETURN on a Macintosh). You should see something similar to the image shown in Figure 4-20.

    image from book
    Figure 4-20: Testing that the XML content has been loaded into Flash

We now have to add the content from the XML document tree to the Flash interface. Well start with the song categories.

Loading the ComboBox component

Well add the information from the folderName attribute to the ComboBox component. This will display a list of all of the MP3 subfolders so that the user can select a song category.

  1. Create a new XMLNode variable, RootNode , at the top of the actions layer. Because we create this variable outside of a function, well be able to use it anywhere within Flash. It has timeline scope.

     var RootNode:XMLNode; 
  2. Modify the loadSongs function as shown here so it calls the loadCombo function when the XML information has been successfully loaded. Ive indicated the new lines in bold.

     function loadSongs(success:Boolean):Void{   if (success) {  RootNode = this.firstChild;   loadCombo();  }   else {     trace("Error loading file");   } } 
  3. Add the loadCombo function to the actions layer. It uses the addItem method to add the foldername attribute to the ComboBox.

     function loadCombo():Void {   var folderName:String;   folder_cb.addItem("-- Select --");   for (var i:Number=0; i< RootNode.childNodes.length; i++) {     folderName = RootNode.childNodes[i].attributes.foldername;     folder_cb.addItem(folderName);   } } 
  4. Test the movie. Figure 4-21 shows how it should appear.

    image from book
    Figure 4-21: Testing the ComboBox component

When we select a folder from the ComboBox, well want to add the songs from that folder to the List component. If the user chooses the -- Select -- option, well want to clear the list so nothing displays. The movie will need to listen for a change in the ComboBox and respond to the event.

Adding a listener to the ComboBox

  1. Add the following code above the loadSongs function. The change event in the ComboBox will call the loadList function.

     var CBOListener:Object = new Object(); CBOListener.change = loadList; folder_cb.addEventListener("change", CBOListener); 
  2. Add the loadList function below the loadCombo function. The function traces the label of the selected option.

     function loadList(evtObj:Object):Void {   trace (evtObj.target.selectedItem.label); } 

The loadList function receives an event object as a parameter, and Ive referred to it using evtObj. The event object contains information about the event. To refer to the ComboBox component, I can use evtObj.target and any of the properties of the ComboBox component. In this case, Ive used selectedItem.label to find out which category the user selected.

  1. Test the movie and choose a value from the ComboBox. You should see something similar to Figure 4-22.

    image from book
    Figure 4-22: Testing the ComboBox listener

The next step is to load the songs from the selected category into the List component. The category comes from the <folder> element, so well start by creating a variable to refer to this element.

Loading the songs

  1. Add a new variable called FolderNode below the RootNode variable at the top of the Actions panel.

     var FolderNode:XMLNode; 
  1. Modify the loadList function as shown here. The new lines are in bold. If weve selected a folder, the function finds the node in the document tree and adds the child node songs within it to the List component. If weve chosen the -- Select -- option, we clear the List using the removeAll method. Ive also used the removeAll method before adding new songs so that we dont end up with a mix of new and old songs in the List.

     function loadList(evtObj:Object):Void {  var selectedFolderName:String;   var currentFolderName:String;   var songName:String;   selectedFolderName = evtObj.target.selectedItem.label;   if (selectedFolderName != "-- Select --") {   songs_list.removeAll();   for (var i:Number=0; i < RootNode.childNodes.length;i++){   currentFolderName = RootNode.childNodes[i].attributes.foldername;   if (selectedFolderName == currentFolderName) {   FolderNode = RootNode.childNodes[i];   for (var j:Number=0; j < FolderNode.childNodes.length; j++) {   songName = FolderNode.childNodes[j].attributes.filename;   songs_list.addItem(songName);   }   }   }   }   else {   songs_list.removeAll();   }  } 
  2. Test the movie. Choose a folder and check that the List component populates correctly. Figure 4-23 shows how the interface should look at this stage.

    image from book
    Figure 4-23: Testing that the List component is populated correctly

When we choose a song, well want it to play so we need to add an event listener to the List component. The event listener listens for the change event that occurs when the user makes a selection from the List. The listener then plays the selected song.

Adding a listener to the List

  1. Add the following code below the ComboBox listener. It creates a listener for the List component that calls the playSong function when the selection changes.

     var listListener:Object = new Object(); listListener.change = playSong; songs_list.addEventListener("change", listListener); 
  2. Add the playSong function at the bottom of the actions layer. This function traces the selected song name.

     function playSong(evtObj:Object):Void {   trace(evtObj.target.selectedItem.label); } 
  3. Test the movie, choosing a folder and a song. You should see something similar to Figure 4-24 when you select an MP3.

    image from book
    Figure 4-24: Tracing the song file name

Instead of displaying the song name, we want to start playing the selected MP3 file. We can do this using a Sound object.

Playing the song

  1. Create a new Sound object at the top of the actions layer.

     var MP3ToPlay:Sound = new Sound(); 
  2. Modify the playSong function as shown here. The changed code is shown in bold. The function creates a variable, selectedSong , which contains the path and file name for the MP3. It stops any song that is currently playing and loads the selected MP3. When the new MP3 has loaded successfully, it starts playing the song at a volume of 50 .

     function playSong(evtObj:Object):Void {  var selectedSong:String = evtObj.target.selectedItem.label;   selectedSong = folder_cb.selectedItem.label + "/" + selectedSong;   stopAllSounds();   MP3ToPlay.onLoad = function(success:Boolean):Void {   if (success) {   MP3ToPlay.setVolume(50);   MP3ToPlay.start();   }   else {   trace ("Error opening mp3");   }   };   MP3ToPlay.loadSound(selectedSong, false);  } 
  3. Test the movie and choose a song. Make sure your speakers are turned up so you can hear it playing. When you select a new song, the first song should stop before the second one starts.

At this point, you can play songs in the MP3 player but you cant use any of the other interface elements. To finish the application, well configure the volume slider and the Play, Stop, and Rewind buttons.

Configuring the buttons

  1. Create a variable at the top of the layer called songOffset . Well use this to store the position where a song stops when the Stop button is clicked.

     var songOffset:Number; 
  2. Configure the Stop button by adding the following code below the event listeners. We store the song position in the variable songOffset . This is a measurement in milliseconds , starting from the beginning of the song.

     stop_btn.onRelease = function():Void {   songOffset = MP3ToPlay.position;   MP3ToPlay.stop(); } 
  3. Add the following code for the Play button. The function stops any sounds that are currently playing and plays the selected song from the previously stopped position.

     play_btn.onRelease = function():Void {   stopAllSounds();   MP3ToPlay.start(songOffset/1000); } 
  4. Add the following code for the Rewind button. The function starts playing the song from the beginning.

     rewind_btn.onRelease = function():Void {   stopAllSounds();   MP3ToPlay.start(0); } 
  5. Test the movie. You should be able to select a song and use the Stop, Start, and Rewind buttons to control playback.

The last thing left to do is to set up the volume fader. If you look at the interface, youll see that the fader contains two parts : a scale and a fader knob. Dragging the fader knob should change the volume between the values of 0 and 100.

Configuring the slider

  1. Add the following code beneath the other button actions. When the fader button is clicked, the startDrag method allows you to drag it between the coordinates listed. When you release the button, the dragging stops and the function calculates the new volume based on the ending position of the button. Finally, it resets the volume of the song to the calculated value.

     fader_btn.onPress = function():Void {   this.startDrag(fader_mc, 406, 105, 406, 305); } fade_btn.onRelease = function():Void {   this.stopDrag();   var newVolume:Number = (200 - (this._y - 105))/2;   MP3ToPlay.setVolume(newVolume); } 

I passed five parameters to the startDrag method. The first parameter specifies the target movie clip. The numbers specify the left, top, right, and bottom measurements used to constrain the draggable area.

I calculated the new volume using (200 - (this._y - 105))/2 . The scale is exactly 200 pixels high and is placed at a y position of 105 pixels. I find the new y position relative to the scale this._y ˆ 105 and take it from the height of the scale 200 - (this._y - 105) . This gives me the position using the scale of 200 pixels so I have to divide by 2 to get a volume out of 100.

  1. Test the movie. You should be able to play a song and have full control of the volume. You should also be able to start, stop, and rewind the song. Congratulations, youve completed this exercise. You can find the completed file MP3s_completed.fla saved with your resources. You can also see the resource file MP3sPHP_completed.fla if youd rather work with PHP .

Points to note from exercise 4

  • The first few steps of exercise 4 were very similar to those in exercise 3. In fact, youll probably perform similar steps each time you load external XML content into a Flash movie. These steps usually involve

    1. Creating a new Flash movie.

    2. Making sure that the Flash movie and external XML document are stored in the same location. You should also save the Flash movie before you start doing any testing.

    3. Loading the XML document.

    4. Creating a function to test for successful loading and tracing the XML object in the Output window.

    5. Adding content from the XML object to user interface components and configuring event listeners.

    6. Configuring other instances in the movie.

  • Its a good idea to view dynamic XML documents within a web browser before you include them in a Flash movie. This is one way to test that a server-side file is creating the correct XML content. Dont forget to use the full path to the file in your browser, for example, http://localhost/FOE/MP3List.aspx.

  • If you forget to include the full path to the server-side file in Flash, you may not see an error when loading the XML content. Flash will try to load the page content into the XML tree. Youll only find a problem when you start to work with the elements in the document. Tracing elements will return null values, as shown in Figure 4-25. You can use the status property to find whether there are any errors in the document.

    image from book
    Figure 4-25: Tracing the root node when the full server path has been omitted

There are times when youll need to create XML content in Flash without loading it from an external document. For example, we might need to generate XML that queries or logs into another application. In the next section, well look at how to generate XML from within Flash.

image from book
 


Foundation XML for Flash
Foundation XML for Flash
ISBN: 1590595432
EAN: 2147483647
Year: 2003
Pages: 93
Authors: Sas Jacobs

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