Tutorial_ Reading in XML files_ reading in jpg files_ constructing

Document Sample
Tutorial_ Reading in XML files_ reading in jpg files_ constructing Powered By Docstoc
					Tutorial: Reading in XML files, reading in jpg files,
constructing radio buttons, combo box plus error
This tutorial/set of notes describes how to build a Flash application constructed
dynamically (during runtime) from data in XML files. There is a two step process: a
combo box is constructed using information from an XML file called albums.xml. When
the viewer makes a selection, it specifies a second xml file to be loaded. This file contains
titles and file names for image files. The program builds radio buttons so the viewer can
choose among the images.

The application uses the Snapshoterror.as described in another tutorial to create
Snapshoterror objects. The .fla application makes reference to what is termed a
Document class. In this case, the Document class is [defined in] the ReadXML.as file.

The application handles two types of errors: missing image files and ill-formed XML
files. The handling of the missing image files is described in the previous tutorial. It is an
asynchronous error, handled by addEventListener for the IO_ERROR event. The ill-
formed XML problem is what is termed a synchronous or immediate error. It is handled
using a try and catch construction.

Screen shots

The opening screen is
When the viewer clicks on the arrow, the dropdown selections appear:

If the viewer selects the Daniel's graduation (the one initially selected), the result is:
At this point, the viewer can use the radio buttons to select pictures to see or click on
Choose new album to return to the first screen. One of the album choices was made
intentionally to be a badly formed XML file. It produces this screen:
Similarly, the choice of Album with missing photo produces this screen:
If the viewer selects the radio button labeled non-existent picture, this screen appears:
The XML file that points to the other XML files is the following:

<?xml version="1.0" encoding="utf-8"?>
 <title>Daniel's graduation </title>
  <title>Bad xml file </title>
        <title>Obama campaign pictures
       <title>Album with missing photo

The album1.xml file is

<?xml version="1.0" encoding="utf-8"?>
       <title>Party in Ithaca</title>

       <title>Celebrating thesis defense</title>
       <title>Esther, Corey and the dog</title>

The badly formed xml file, album1e.xml, is

<?xml version="1.0" encoding="utf-8"?>
       <title>Party in Ithaca</title>

      <title>Celebrating thesis defense</title>

       <title>Esther, Corey and the dog</title>

This application consists of many files:
    a .fla file I gave the ungainly name xmlpicsxmlslidesdocument.fla
    Snapshoterror.as, described in a previous tutorial and tested using another .fla file
       not required here
    ReadXML.as, a file that serves as the Document class for the fla file, invoked
       when it is loaded
    xml files (albums.xml and all files named in albums.xml)
    jpg files (all files named in all the xml files)

The Snapshoterror.as file is located in a folder named familyscenes located in a folder
named as3. For the MAC, the as3 folder is in the same folder as the
xmlpicsmlslidesdocument.fla file. For the PC, the as3 folder is located at the top of the C
drive, that also contains, several folders down, the fla file. The xml and the jpg files are in
the same folder as the fla file. When this application is published, the results html and swf
files along with all the xml and jpg files must be uploaded together to the same folder on
the server. Note: it is possible to access xml files and jpg files elsewhere on the Web, but
the coding here assumes the xml files and the jpg files are in the same folder.

The xmlpicsxmlslidesdocument.fla file doesn't contain code. I did add a text field saying
View Photo Album. You also need to click on Window/Component and move Button,
Radio Button and ComboBox to the Library. You need to set the Document Class to
ReadXML. This is the name of the file with the code. Lastly, you need to do File/Publish
Settings Flash Settings and browse to as3. By the way, if you build this application by
modifying the getsnapshoterror.fla file, this will be set already.

I will give an overview of the ReadXML file, focusing on specific functions and then
describe the code line by line.

As a class definition pointed to as a Document Class, ReadXML is part of a package
without a name. The class must extend MovieClip since it defines behavior for the movie
clip that is the fla file. The import statements include the usual built-in Flash features
along with familyscenes, the package containing Snapshoterror.

The ReadXML class contains the constructor method along with methods invoked
through addEventListener calls. These are:

method                      invoked by/when
listxmlLoaded               … the first xml file is loaded
backtochoosing              … the button is clicked
getname                     … comboBox selection
xmlLoaded                   … the specified xml file with image data is loaded
changeslide                 … a radio button is clicked indicating a new picture
errorhandler                … error in loading XML file
The constructor method (ReadXML) must be public. All others are the default internal
since they are only invoked by code in the class, namely by action of the
addEventListener calls.

The errorhandler method will not be invoked as long as albums.xml and all the album
xml files cited in it are present. NOTE: the missing image error is handled in the
Snapshoterror code. Please note that I set up these files so that there IS a missing file to
demonstrate the working of the code. Similarly, I made one of the xml files be badly
formed (see above) to demonstrate another type of error handling. The badly formed
XML is handled in a try and catch construction to be described below.

The chooseagain button is created in the constructor method, but its visible property is set
to false and only set to visible in the getname method.

Radio buttons are set up to be part of one RadioButtonGroup. Flash implements radio
buttons using a RadioButtonGroup object and any number of RadioButton objects. One
RadioButtonGroup object is created as one of the object variables for the ReadXML
object. The individual RadioButton objects are created based on the data for each album,
that is, xml file. Notice that RadioButtons are removed from the display list and there is a
call to removeEventListener as part of the backtochoosing method, the handler for the
choosebutton being clicked. RadioButtons have labels and values. The label is what the
viewer sees next to the button. The value, in this case, is the index into a slides array that
has been filled with the names of the Snapshoterror objects, namely the loaded in jpg
images. All but one of these are set visible equal false.

ReadXML.as file:

package {                                                         package header. Note: no
                                                                  name since it is only
                                                                  holder for the Document
                                                                  class file
import familyscenes.*;                                            programmer package.
                                                                  Holds Snapshoterror
import fl.controls.*;
import flash.events.*;
import flash.display.*;
import flash.text.*;
import flash.net.*;
import flash.errors.*;
public class ReadXML extends MovieClip {                          class header. Must extend
                                                                  (be a subclass) of
                                                                  MovieClip since it is a
                                                                  Document class
var myXML:XML = new XML();                                        will hold the first XML
                                                                  document read it
var XML_URL:String ;                                     name of the file
var tf:TextField = new TextField();                      for XML parsing error
var myXMLURL:URLRequest;
var myLoader:URLLoader = new URLLoader();                for albums.xml
var myLoader2:URLLoader = new URLLoader();               for any of the album lists,
                                                         that is, the other .xml files
var slides:Array = [];                                   Used for manipulating
                                                         which image is shown
var fixedw:int = 300;                                    Fixed maximum width
var rbg:RadioButtonGroup = new RadioButtonGroup("gp");
var rbarray:Array = [];                                  Hold radio buttons so they
                                                         can be erased
var rbystart:int = 120;                                  vertical position of first
                                                         radio button
var xstart:int = 100;                                    horizontal position of
var ystart:int = 100;                                    vertical position of images
var hook:MovieClip;                                      Used for call to
var mycombo:ComboBox;                                    Drop down list of 'albums'
var chooseagain:Button = new Button();                   The button to go back to
                                                         choosing an album

public function ReadXML():void {                         Constructor method.
                                                         Invoked when movie is
     //create a combo box using albums.xml data
 XML_URL = "albums.xml";                                 File name for list of lists
 myXMLURL = new URLRequest(XML_URL);
                                                         Set up event when loading
myLoader.addEventListener(Event.COMPLETE,listxmlLoa      is complete
 myLoader.addEventListener(IOErrorEvent.IO_ERROR,        Set up event if any io
errorhandler);                                           error.
       chooseagain.label = "Choose new album";           Meanwhile, prepare the
                                                         chooseagain button
       chooseagain.y = 100;                              Position vertically
       chooseagain.x = 500;                              …. horizontally
       chooseagain.width = 200;                          set width
       chooseagain.addEventListener(MouseEvent.CLICK,    set up event handling
       this.addChild(chooseagain);                       Add to display list
       chooseagain.visible = false;                       (but) make not visible for
}                                                         End ReadXML method

function listxmlLoaded(ev:Event):void {                   Method to set up combo
       myXML = XML(myLoader.data);                        Extract data and parse to
                                                          create XML object
     mycombo = new ComboBox();
     for each(var prop:XML in myXML.album) {              for each album element
mycombo.addItem({label:prop.title, data:prop.address});   … add to mycombo,
                                                          setting label and data
                   }                                      End for each loop
     mycombo.width = 200;                                 Set width
     mycombo.x = 100;                                     Position horizontally
     mycombo.y = 200;                                     … and vertically
     this.addChild(mycombo);                              Add to display list
mycombo.addEventListener(Event.CHANGE,getname);           Set up event handling
     mycombo.addEventListener(Event.CLOSE,getname          … both events
}                                                         End method

function backtochoosing(ev:Event):void {                  Method for clicking on
                                                          button to go back to
                                                          choosing albums button
       chooseagain.visible = false;                       Set button (again) to not
                                                          be visible
       mycombo.visible = true;                            Make mycombo visible
       var i:int;                                         Remove pictures and radio
       var origsize:int = slides.length;                  Need this because code
                                                          pops arrays and need to
                                                          define how many times to

       for (i=0;i<origsize;i++) {                         slides loop

       for (i=0;i<origsize;i++) {                         radio button loop

       rbystart = 120;                                    Re-set the start of the
                                                          radio buttons
rbg.removeEventListener(Event.CHANGE,changeslide);        Remove event handler
}                                                        End method

function getname(ev:Event) {                             Method to load individual
                                                         album xml file
       XML_URL = mycombo.selectedItem.data;
       mycombo.visible = false;                      Make mycombo not
       tf.visible = false;                           Make the error message
                                                     not visible (if it ever was)
       chooseagain.visible = true;                   Make the chooseagain
                                                     button visible
       myXMLURL = new URLRequest(XML_URL);           Set up for the loading
       myLoader2.load(myXMLURL);                     Start the loading
myLoader2.addEventListener(Event.COMPLETE,           Set up event handling for
xmlLoaded);                                          successful load
myLoader2.addEventListener(IOErrorEvent.IO_ERROR,err Set up event handling for
orhandler);                                          error (only occurs if there
                                                     is a non-existent .xml file)
rbg.addEventListener(Event.CHANGE,changeslide);      Set up event handling for
                                                     the group
hook = this;                                         Set hook to be passed to
                                                     the Snapshoterror
 }                                                   End method

function xmlLoaded(event:Event):void {                   Method when the xml file
                                                         (that is, an individual
                                                         album file) is loaded
       myLoader2.removeEventListener(Event.COMPLET       Remove error handling
E, xmlLoaded);
myLoader2.removeEventListener(IOErrorEvent.IO_ERRO       ….
       try {                                             Since there may be a
                                                         badly formed xml file, set
                                                         this up in a try clause
              myXML = XML(myLoader2.data);               Parse the file as xml
                                                         (code only continues if the
                                                         parsing worked)
      for each (var prop:XML in myXML.item) {            for each item element
              var firstscene:Snapshoterror = new         invoke Snapshoterror,
Snapshoterror(prop.picname,hook,fixedw);                 which will load the picture
              firstscene.x = xstart;                     position (all) the images in
                                                         the same
              firstscene.y = ystart;                     … vertically
                    slides.push(firstscene);                  Add to array
                    firstscene.visible = false;               set to not be visible
                    var rb:RadioButton = new RadioButton();   Now, create
                                                              corresponding radio
                    rb.group = rbg;                           Make this rb part of the
                                                              rbg group
                    rb.x = xstart + fixedw+ 20;               position to the right of the
                    rb.y = rbystart;                          position vertically using
                                                              current value of rbystart
                    rbystart += 40;                           increment rbystart
                    rb.setSize(200,30);                       adjust the size and height
                    rbarray.push(rb);                         add radio button to array
                    rb.label = prop.title;                    set the label using the title
                    rb.value = slides.length-1;               set the value to point to
                                                              the image just added to
                    addChild(rb);                             make radio button visible
          }                                                   Close for each loop
              slides[0].visible = true;                       Make the first slide visible
          }                                                   Close the try clause
          catch (error:Error) {                               Catch clause invoked if
                                                              any problems in try
                                                              clause. The likely problem
                                                              is with the XML function

                    var tfformat:TextFormat = new             Create text format object
                    tfformat.size = 36;                       set up size
                    tfformat.underline = true;                set up underlin
                    tf.autoSize = TextFieldAutoSize.LEFT;     set up sizing and
                                                              alignment for text field
                    tf.border = true;                         give text field a border
                    tf.defaultTextFormat = tfformat;          link text field to the text
                    tf.text = "Error occurred reading album   Set text of the text field
                    tf.visible = true;                        Make the text field visible
                    tf.x = 200;                               Position horizontally
                    tf.y = 300;                               … and vertically
                    addChild(tf);                             Add to display list
          }                                                   end catch clause
}                                                             End method
function changeslide(ev:Event) {                               Method that handles
                                                               clicking on radio buttons
       var rg:RadioButtonGroup = ev.target as                  Set to be the radio group
  var s:int = Number(rg.selectedData);                         Set to be the data for the
                                                               radiobutton selected
        var i:int;
        for (i=0;i<slides.length;i++) {                        Loop through all slides
                                                               making just one visible
               if (i != s) {
                        slides[i].visible = false;
               else {
                        slides[i].visible = true;


function errorhandler(ev:Event):void {                         Method for handling io
       trace("io error");                                      Add to output page. THIS
                                                               COULD BE IMPROVED!
}                                                              End method
}                                                              End class
}                                                              End package

I was unable to figure out how to make a combo box that allowed EITHER selecting one
of the given choices or adding a new choice. I realize it involved the editable property,
but I could not get the events to work properly. If someone figures out how to do this,
please let me know.

Shared By: