Learning Flex 4 | O'Reilly Media

Archive for the ‘Flex 4’ Category

Google Search Application in Flex 4

with one comment

Unfortunately, the Yahoo! web services, which we consumed using the ASTRA Flex library and introduced near pages 232-233, are deprecated and discontinued, devaluing the book I realize many of you bought with hard-earned money. In light of this reversal, I applied myself to replacing the YahooSearch example with something comparable.

This alternative arrangement consumes the Google Search API, which is simplified into callable methods exposed through googleas3api.swc—an ActionScript library package created by Joris Timmerman (my apologies if I am incorrect about the creator and maintainer). Because googleas3api is an ActionScript library and not a Flex library, we can’t instantiate  the service component in MXML like we did with the Yahoo! search component (but to be honest, I didn’t even try so maybe I am wrong about that), so this alternate example uses more ActionScript and looks a little different. On the bright side, I believe that is good for you; on the other hand, it will require more of your intuition at timesto understand the similarities and differences between the original YahooSearch code illustrated in the book, which will fail at runtime (i.e. when you perform a search), and this GoogleSearch variation, which looksdifferent in code, but performs as you would expect.

Application: GoogleSearch.mxml

The application requires two supporting libraries—as3corelib.swc and googleas3api.swc. Make sure to download these, unzip if necessary, and copy their SWC files into the “libs” folder of your Flex 4 project.

<?xml version="1.0" encoding="utf-8"?>
<s:Application
 xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:s="library://ns.adobe.com/flex/spark"
 xmlns:mx="library://ns.adobe.com/flex/mx"
 creationComplete="onComplete();"
 defaultButton="{searchButton}">
 
 <fx:Script>
  <![CDATA[
   /**
    * This project requires two reference libraries.
    * 
    * as3corelib.swc:
    *   https://github.com/mikechambers/as3corelib
    *   (Downloads > Download Packages > as3corelib-93.zip)
    *   Find the .swc file in the extracted "lib" folder.
    *
    * googleas3api.swc:
    *   http://code.google.com/p/googleas3api
    *   (Downloads > googleas3api.swc)
    *
    * Copy/paste or drag/drop these into the "libs" folder
    * for this Flex 4 project.
    */
   import be.boulevart.google.ajaxapi.search.GoogleSearchResult;
   import be.boulevart.google.ajaxapi.search.web.GoogleWebSearch;
   import be.boulevart.google.events.GoogleAPIErrorEvent;
   import be.boulevart.google.events.GoogleApiEvent;
   
   import mx.collections.ArrayCollection;
   
   
   private var googleSearch:GoogleWebSearch;
   
   private var searchResultAC:ArrayCollection;
   
   
   
   private function onComplete():void
   {
    googleSearch = new GoogleWebSearch();
    googleSearch.addEventListener(
       GoogleApiEvent.WEB_SEARCH_RESULT, searchResult);
    googleSearch.addEventListener(
       GoogleAPIErrorEvent.API_ERROR, searchFault);
   }
   
   private function onSearch():void
   {
    // See the API library example here..
    // http://code.google.com/p/googleas3api
    // "en" means English
    // ..try "de", which is Danish, etc..
    googleSearch.search(queryTI.text, 0, "en");
    
    // you can also leave the string out, which may
    // allow Google to introspect by IP and "guess"
    // the correct language (I am supposing this):
    //  googleSearch.search(queryTI.text, 0);
   }
   
   private function searchResult(event:GoogleApiEvent):void
   {
    // Cast the event.data response as GoogleSearchResult
    // to enable code completion and compile-time error checking.
    var searchResult:GoogleSearchResult;
    searchResult = event.data as GoogleSearchResult;
    
    // searchResult.results is an Array, so we can pass it
    // into a new ArrayCollection and use it as a dataprovider.
    searchResultAC = new ArrayCollection(searchResult.results);
    resultsList.dataProvider = searchResultAC;
   }
   
   private function searchFault(event:GoogleAPIErrorEvent):void
   {
    // Catch search faults and trace to the console.
    trace(String(event.responseDetails));
   }
  ]]>
 </fx:Script>
 
 <s:VGroup left="10" right="10" top="10" bottom="10">
  <s:Label text="Google Search:" fontWeight="bold"/>
  <s:HGroup>
   <mx:FormItem label="Query:" fontWeight="bold">
    <s:TextInput id="queryTI" width="350"/>
   </mx:FormItem>
   <mx:FormItem>
    <s:Button id="searchButton" label="Search"
        click="onSearch();"/>
   </mx:FormItem>
  </s:HGroup>
  <s:List id="resultsList" width="100%" height="100%"
     itemRenderer="SearchItemRenderer"/>
 </s:VGroup>
 
</s:Application>

SearchItemRenderer.mxml

The ItemRenderer used in the application is created using the same approach described in pages 235-238. However, note the use of the Ternary Operator to create a shorthand if..then conditional statement; this is described on page 354 as an inline if..then for use in MXML code, but here I’m demonstrating its use in an ActionScript-only context.

Note: To work with the application code, above, this custom ItemRenderer needs to be created in the default package (i.e. the local package), the same folder as GoogleSearch.mxml.

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    autoDrawBackground="true"
    creationComplete="onComplete();">
 <fx:Script>
  <![CDATA[
   import be.boulevart.google.ajaxapi.search.web.data.GoogleWebItem;
   import flashx.textLayout.conversion.TextConverter;
   
   private function onComplete():void
   {
    // Cast the data record as GoogleWebItem to expose
    // code commpletion and enjoy tighter compile-time
    // error-checking. We could use object notation
    // on the data variable like this..
    //   urlLabel.text = "From: " + data.url;
    // but casting the object is preferred.
    var item:GoogleWebItem = data as GoogleWebItem;
    
    urlLabel.text = "From: " + item.url;
    
    // Create "content teaser" with no more than 100 chars..
    var teaserString:String=item.title + " | " + item.content;
    
    // Shorthand if..then using the ternary operator..
    // See pg. 354 for background on this syntax.
    teaserString = (teaserString.length>99)
        ? teaserString.substr(0,99)+"..[more].."
        : teaserString ;
    
    contentTA.textFlow = TextConverter.importToFlow(teaserString,
          TextConverter.TEXT_FIELD_HTML_FORMAT);
    
    callLater(invalidateDisplayList);
    callLater(validateNow);
         
   }
   
   private function onClick(event:MouseEvent, url:String):void
   {
    var urlRequest:URLRequest = new URLRequest(url);
    navigateToURL(urlRequest, "_blank");
   }
  ]]>
 </fx:Script>
 <s:VGroup width="100%" gap="2" paddingTop="2" paddingBottom="2">
  
  <s:Label id="urlLabel" fontWeight="bold" buttonMode="true"
     click="onClick(event, data.url);"/>
  
  <s:TextArea id="contentTA" width="100%" heightInLines="1"
     verticalScrollPolicy="off"
     editable="false" selectable="false"
     contentBackgroundAlpha="0"
     borderVisible="false"/>
 </s:VGroup>
</s:ItemRenderer>

Advertisements

Written by elrobis

29 September 2011 at 10:06 am

Posted in AIR, Flex 4

Load PDF Content into an AIR Application

with 6 comments

It’s deceptively simple to load a PDF file into an AIR appliction. Basically, point an HTMLLoader at a URLRequest—which can take a local file path—add the HTMLLoader to a UIComponent, then add the UIComponent to a container.

In this case, I added the UIComponent directly to the application, but it stands to reason you could put it in any container.

Flex 4 / AIR Application Code

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication title="PDF Viewer"
      xmlns:fx="http://ns.adobe.com/mxml/2009"
      xmlns:s="library://ns.adobe.com/flex/spark"
      xmlns:mx="library://ns.adobe.com/flex/mx"
      height="600" width="525"
      backgroundColor="#000000">

<s:Button label="Load The PDF" click="loadPdf(path)" top="4" left="4"/>

<s:Button label="Close The PDF" click="closePdf()" top="4" right="4"/>

<fx:Script>
<![CDATA[
  import mx.core.FlexGlobals;
  import mx.core.UIComponent;

  private var pdfUIC:UIComponent;

  // double forward-slashes necessary for win file paths..
  private var path:String = "C:\\pdf_files\\original\\filename.pdf";

  private function loadPdf(fullPathToPDF:String):void
  {
    var pdfRequest:URLRequest = new URLRequest(fullPathToPDF);
    var pdfHTMLLoader:HTMLLoader = new HTMLLoader();

    // 1) load the PDF into an HTMLLoader (Air-only)
    pdfHTMLLoader.height = FlexGlobals.topLevelApplication.height-70;
    pdfHTMLLoader.width = FlexGlobals.topLevelApplication.width-60;
    pdfHTMLLoader.load(pdfRequest);

    // 2) add the HTMLLoader to a UIComponent
    pdfUIC = new UIComponent();
    pdfUIC.addChild(pdfHTMLLoader);
    pdfUIC.name = "pdfPrintPreview";

    // 3) add the UIComponent to the application
    pdfUIC.y = 33;
    pdfUIC.x = (FlexGlobals.topLevelApplication.width - pdfHTMLLoader.width) / 2;
    this.addElement(pdfUIC);
  }

  // destroy the PDF, call garbage collector..
  private function closePdf():void
  {
    if(pdfUIC)
    {
      this.removeElement(pdfUIC);
      
      // make the object a candidate for garbage collection..
      pdfUIC = null;
      
      flash.system.System.gc();
    }
  }

]]>
</fx:Script>

</s:WindowedApplication>

Lo! The sample application running in Debug mode..

Load a PDF into Adobe AIR Using Flex 4

Load a PDF into Adobe AIR Using Flex 4

Written by elrobis

2 July 2011 at 6:41 am

Posted in ActionScript 3, AIR, Flex 4

Debugging in FlashDevelop: Stepping Through Code

with 7 comments

This post discusses debugging with breakpoints in FlashDevelop 4 as well as FlashDevelop 3.3.4. My original tutorial covered FlashDevelop 3.3.4 RTM, but it fell out of date with the release of FlashDevelop 4, so I added details to accomodate that release.

Debugging in FlashDevelop 4 (FlashDevelop 4 Beta2)

If you want to debug your ActionScript code in FlashDevelop 4 (FD4) and you’re wondering why your breakpoints won’t catch, you probably just need to impose a simple two-step fix:

1) Install the 32-bit Java Development Kit
2) create a JAVA_HOME environment variable.

I’ll walk you through it, but first, I’m making the following assumptions about your FlashDevelop installation:

— FD4 (I used Beta2 at the time) recognizes your Flex 4 SDK, and you can build/launch Flex 4 applications.
— FlashDevelop properly launches the Flash debug player, and trace statements appear in the output pane.

While experimenting withFlashDevelop 4 Beta2, I was vexed once again by the task of configuring the debugger. At a glance, there several obvious improvements over FD3, but none of my breakpoints were catching, and the steps I used to setup debugging in FD3 were no longer applicable. So I started poking around, and I eventually identified the problem by enabling Verbose Output (FD4 > Tools > Program Settings > FlashDebugger > Verbose Output = True). The Verbose Output setting pushes additional notifications to the FD4 output pane that revealed a sly, behind-the-scenes exception I wasn’t seeing previously. Basically the debugger wanted the JAVA_HOME environment variable, and it couldn’t find it. Googling the exception statement led me here:

http://www.flashdevelop.org/community/viewtopic.php?f=6&t=8435

To fix the problem, I downloaded JDK 7 for Windows (use the 32-bit, x86 variant, even if you have a 64-bit OS), installed it, then created a new environment variable called JAVA_HOME and set it’s value to the JDK install path (C:\Program Files (x86)\Java\jdk1.7.0).

If you’ve never created an environment variable, do this: open the Windows Start menu (lower-left), right-click on “Computer” and select “Properties”. In the new window, select “Advanced system settings” from the choices at left, and when the System Properties dialog opens, select “Environment Variables” at the bottom. The bottom-half of the Environment Variables dialog is devoted to your System variables.. select “New” and for Variable name use JAVA_HOME. For Variable value use C:\Program Files (x86)\Java\jdk1.7.0 (note that your install path may be different). Now Ok/Save your way out of the dialogs and restart Windows.

I was surprised I needed to restart Windows 7 for a new system variable to go into effect, but it was in fact necessary. [EDIT] While restarting Windows is one way to refresh the environment variables, you may find it smoother to kill and reload the explorer.exe process. For more info, see the comment provided by joebain, appearing below. –Thanks joebain.

When Windows reloads, you should be able to set a breakpoint in FlashDevelop 4 and walk through your code using the F10 key. Conveniently, FD4 provides a ready-set-go “Step Into” shortcut (among others—see the Debug menu) that just works once your system environment is properly tweaked.

Thanks to lutfihilfan (see comments) for informing me that my original tutorial discussing debugging in FlashDevelop 3 fell out of date. This has been my most popular blog post, so hopefully these updates will continue to prove useful for Flex developers wanting to use FlashDevelop. —Thanks lutfihilfan.

Debugging in FlashDevelop 3 (FlashDevelop 3.3.4 RTM)

FlashDevelop 3 [I used 3.3.4 RTM] provides some native support for debugging, but walking through your code line-by-line isn’t exposed in the menu options. Moreover, the options that are exposed do not have default keyboard shortcuts. Here’s how you fix that:

1) Open the Tools Menu and select Program Settings
–> This view gives you access to a variety of customizations

2) Select “FlashDebugger” from the categories on the left
–> This is where you configure special keyboard shortcuts

3) Left-click to the right of “Next Shortcut” to set values
–> I ultimately used Ctrl+L

Ok, step 3 proved to be tedious. First I tried good ol’ F6 so I could stay in-sync with Flash Builder. But that doesn’t work. Neither did Ctrl+F6 (which isn’t convenient anyway). In short, I tried several different key combos before I finally found Ctrl+L. Most e left-hand combos I tried already had default functionality, for instance saving the application or trying to open a new file, etc. You may come up with a better combo than Ctrl+L if you poke around–certainly a left-hand combo is better than a right-hand combo, which requires repositioning the mouse hand a lot while debugging. Basically, I’m tired so I settled.

4) If you don’t already have a project lined up to debug, here’s a simple app you can write just to demonstrate the stepping:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx">
 
 <fx:Script>
  <![CDATA[
  [Bindable] private var i:int = 0;
  
  private function onClick():void
  {
   do {
    i++;
    trace("now i = " + i.toString());
   } while (i <= 31)
  }
  ]]>
 </fx:Script>
 
 <s:VGroup verticalCenter="0" horizontalCenter="0">
  <s:Button id="button" label="Start Debugging!"
   click="onClick();"/>
  <s:Label id="label" text="New Count: {i}"/>
 </s:VGroup>

</s:Application>

 5) With an app ready to go, set a breakpoint by left-clicking in the gutter, just to the left of the line you want to intercept; in this case I’m at the trace() statement inside the do..Loop at line #14.

In my example, you have to click the Button in the app to trigger the function with the breakpoint, but assuming your app compiled and you launched the Debug version, it should hit your breakpoint as expected. At this point, do your thing and walk through the code using Ctrl+L.

Cheers, Elijah

Written by elrobis

19 June 2011 at 12:07 am

Create an AIR Application to Write Your XML

with 6 comments

I keep finding myself wishing we spent more time in the book discussing Adobe AIR, so I decided to add some extra content here.  Of course, if you run into any questions or concerns, feel free to post them here.

The following application demonstrates a few key uses for AIR’s File() class, particularly:

1) Open a dialog for browsing the file system
2) Create a new file in the file system
3) Use the FileStream() class to write content into a file

Background

The application presented below builds upon various topics covered in Learning Flex 4.  I’m assuming you’ve become comfortable with XML basics. If you need some extra info, chapters 4, 11, 12, and 16 discuss using XML data in Flex applications.  Appendix C (PHP Basics) presents a solution for first concatenating XML as a text string on the server, then receiving that text later in the Flex application as an XML object.  This exercise builds upon these concepts.

The use case for the following application is a scenario where you require fairly dynamic XML data, but you’ve decided it’s impractical to handle XML generation on the web server.  To support the book, I considered the case of the PhotoGallery application (Chapt 12), which relies on some ready-made XML to reference the image content.  While manually typing the XML for about a dozen photos isn’t a big problem, this would quickly become tedious if you were working with a hundred images.  Similarly, the task would consume a lot of time if you frequently recreate or revise the XML.  With this use case in mind, it may be desirable to write a program that automates the XML writing for you.  And hey, if nothing else, writing a 100-line AIR program to handle a programming scenario is generally more fun than writing a couple hundred lines of XML.  :)

Here’s the gist:   When you browse to a folder in your local file system, the AIR app will inspect the files in that directory and build an XML file required for the PhotoGallery application (i.e. photos.xml).  While likely you’d only want to run this utility on a folder of images intended for the PhotoGallery, the app will ensure you’re only adding references to PNG, JPG, and GIF files–this could be helpful in case there was an unassuming LOG file looming about, marooned in the otherwise clean and purposed images folder.

What to Look For

Selecting a directory in the file system:

The function getDirectory()  shows how to use the browseForDirectory() method on a File() object to select and access file objects as directories via the Flex UI.

Creating a New (XML) File and Writing its Content:

The function saveXmlFile() demonstrates how to create a new File() object and use the FileStream() class to write data into the new File(). 

Notice how we use the nativePath property of the selected directory (file.nativePath), followed by the operating system’s separator symbol (File.separator, as a static property), followed by a file name provided by the user, followed by the desired file extension (.xml)–all concatenated together–to establish where to save the new XML file (newXMLFile).

Notice also that the FileStream() object must open() the new file (newXMLFile) in FileMode.WRITE in order to access it for modification purposes.  The FileStream() method writeUTFBytes() is called to pass the concatenated XML string into the new file.  When finished, the close() method is called on the FileStream() to finalize the data input.

The Try..Catch Block!

The Try..Catch block (see the saveXMLFile() function) is good stuff.  It works like this:  First, in the Try section, you try some code that you suspect capable of throwing unanticipated errors; this section should be programmed to handle the task completely, as you’re assuming it will work more often than not.  Next, you follow the Try with a Catch section that allows your program to gracefully catch any “surprise!”, unanticipated errors that might happen when attempting to process the function.  In this case, our Try section ends with an Alert box that notifies us if the XML file is created sucessfully.  Alternatively, our Catch section creates an Alert box notifying the user of the exact error message (er.message) in hopes that it may be detailed enough for the user to consider what caused the error then followup with a successful attempt.

Caveat:  It is too easy to abuse the Try..Catch system as an all-purpose error handling tactic.  Good practice dictates using Try..Catch only when you want to account for unknowns that may throw a wrench, or a chainsaw, or some other mess-making boobalatosomitch into your function.  The Try..Catch system is fairly “expensive” as far as system resources go; plus, it’s just wise to think about your code and handle your use case with a true understanding instead of an attitude that could be epitomized by the phrase “well, I really hope this works, but just in case it doesn’t I’ll Try it and Catch it.”  ….please, just don’t do that.

The String class’s split() method–someString.split(“.”)

The split() method, which is available to String objects, is ultra-useful.  If you have a text String–in this case fileNameAndExt, which is the filename, followed by a dot (.), followed by the file’s extension (.png, .jpg, .gif, .xml, etc..)–you can call the String’s split() method to divide that text string into an Array of String objects as pieces separated by a delimiter.  For this example, the dot (.) is the delimiter. 

This code:
var fileNameArray:Array = new Array();
var fileNameAndExt:String = fileObj.name;      // “photo.jpg”
fileNameArray = fileNameAndExt.split(“.”);

Would create the following index values in the Array:
fileNameArray[0] = “photo”
fileNameArray[1] = “jpg”

Breaking apart the filename into its component portions helps us later when we’re concatenating together our XML text.

The Application Code

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication
 xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:s="library://ns.adobe.com/flex/spark"
 xmlns:mx="library://ns.adobe.com/flex/mx"
 minWidth="600" minHeight="400">

 <fx:Script>
  <![CDATA[
   import mx.controls.Alert;

   private var file:File = new File();
   private var xmlString:String;

   private function getDirectory():void{
    file.browseForDirectory("Select Image Directory");
    file.addEventListener(Event.SELECT, directorySelected);
   }

   private function directorySelected(event:Event):void{
    var filesArray:Array = new Array();
    filesArray = file.getDirectoryListing();

    // create the XML..
    xmlString = '';
    xmlString += '<?xml version="1.0" encoding="utf-8"?>\n';
    xmlString += '<photos>\n';

    // loop through file objects and add XML nodes..
    for each(var fileObj:File in filesArray){
     // make sure the file is not a directory, etc.,
     // or an image format not supported in Flash Player..
     if(((fileObj.isDirectory == false) &&
      (fileObj.isHidden == false) &&
      (fileObj.isPackage == false) &&
      (fileObj.isSymbolicLink == false)) &&
      ((fileObj.extension.toUpperCase() == "PNG") ||
      (fileObj.extension.toUpperCase() == "JPG") ||
      (fileObj.extension.toUpperCase() == "GIF"))){

      // separate "name" into filename AND extension..
      var fileNameAndExt:String = fileObj.name;
      var fileNameArray:Array = new Array();
      var fileName:String;
      var ext:String;
      var path:String;
      var thumbPathNameAndExt:String;
      var imagePathNameAndExt:String;

      fileNameArray = fileNameAndExt.split(".");
      fileName = fileNameArray[0].toString();
      ext = fileNameArray[1].toString();
      // of course, use your own URL here..
      path = "http://www.learningflex4.com/photos/";
      thumbPathNameAndExt = path + fileName + '_th.' + ext;
      imagePathNameAndExt = path + fileNameAndExt;

      xmlString += 
       '<photo credit=""\n' +
        '  title="' + fileName + '"\n' +
        '  thumb="' + thumbPathNameAndExt + '"\n' +
        '  image="' + imagePathNameAndExt + '"/>\n';
     }
    }

    // close the XML and show content in the TextArea..
    xmlString += '</photos>';
    textArea.text = xmlString;
   }

   private function saveXmlFile():void{
    try{
     var newXMLFile:File = new File();
     var fileStream:FileStream = new FileStream();
     var sep:String = File.separator;
     var xmlFilePath:String =
      file.nativePath + sep + fileNameTI.text + ".xml";

     newXMLFile.nativePath = xmlFilePath;
     fileStream.open(newXMLFile, FileMode.WRITE);
     fileStream.writeUTFBytes(xmlString);
     fileStream.close();
     Alert.show("XML Data File Created..", "XML-Builder");
    }

    catch(er:Error){
     trace(er.message);
     Alert.show("XML Data File FAILURE!!" + "\n\n" +
      er.message, "XML-Builder");
    }
   }
  ]]>
 </fx:Script>

 <s:layout>
  <s:VerticalLayout paddingTop="14" horizontalAlign="center"/>
 </s:layout>

 <s:Label text="XML-Builder for the PhotoGallery Application"/>
 <s:Button label="Select Folder to Parse" click="getDirectory()"/>
 <s:TextArea id="textArea" width="90%" height="75%"/>
 <s:HGroup verticalAlign="middle">
  <s:Label text="(provide filename WITHOUT extension)" fontStyle="italic"/>
  <s:TextInput id="fileNameTI"/>
  <s:Button label="Save File" click="saveXmlFile()"/>
 </s:HGroup>

</s:WindowedApplication>

Written by elrobis

7 December 2010 at 8:06 pm

Posted in AIR, Flex 4

Flex Audio Player code available

leave a comment »

If you want to create a Flex 4 Audio Player, feel free to get started using the code on my homepage (opens in a new window).  I’ve enabled “View Source” on the release build, so you only have to load the site, right-click on the audio player, select “View Source”, and then in the lower-left, choose “Download source (ZIP)”.   The player takes content references using an xml file (opens in a new window).  To serve your own  audio content, I assume you’ll need to review the structure in my XML file in order to adopt/hack it to suit your own purposes.

Elijah

Written by elrobis

21 August 2010 at 4:08 pm

Posted in Audio, Flex, Flex 4, Media

Going Commando: Compiling Flex 4 projects in Linux using Free SDK Tools

with 4 comments

This post demonstrates how to setup a Linux (Ubuntu 9+) system to compile Flex 4
projects using Adobe’s Flex 4 SDK.

My assumption is you already know a little something about Flex 4.  That, or you’re
in the process of learning it now.  These instructions focus on the steps necessary to
configure Linux for command line compiling.  However, I don’t explain either Linux
shell commands, MXML code, or the Flex SDK compiler behaviors.  Hopefully you
can find those explainations elsewhere, and this tutorial will walk you through the
missing pieces.

By the way, you will need Flash Player 10 properly installed in order to launch the final
compiled SWF file..

We’ll break the challenge into seven tasks:

  1. Download and prepare the Flex 4 SDK
  2. Setup a folder structure for your workspace and a project
  3. Add a simple MXML application file
  4. Add environment variables to the Linux shell
  5. Setup the flex project config file
  6. Create a reusable compiler script for the project using Bash
  7. Compile and test the project

1: Download the Flex 4 SDK:

http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4

I used “Flex 4.1 Update”, Adobe Flex SDK (169 MB).

When the file finishes downloading, copy it (Right-click > Copy) to your home folder
(Places > Home Folder).

Extract the archive in your home folder (Right-click > Extract Here).

Rename the extracted directory:  flex41

2: Setup the workspace / project folder structure:

Starting in your Home Folder directory, create your workspace first..
Right-click > Create Folder: “flex41wk” (no quotes)

Then browse into the workspace and create your project folder..
Right-click > Create Folder:  “hello” (no quotes)

Within the project folder, create two more folders–“src” and “bin“.

3: Add an MXML file:

Browse into your “src” folder:  Right-click > Create Document > Empty file
Name the file “hello.mxml” (no quotes, make sure to include the extension).
Double-click “hello.mxml” to open it and add the following code..

<?xml version="1.0" encoding="utf-8"?>
<s:Application
 xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:s="library://ns.adobe.com/flex/spark"
 xmlns:mx="library://ns.adobe.com/flex/mx">

 <s:HGroup horizontalCenter="0" verticalCenter="0">
 <s:TextInput id="typeTI"/>
 <s:Button id="postButton"
 label="Say Hi!"
 click="{postTI.text=typeTI.text; typeTI.text=''}"/>
 <s:TextInput id="postTI"/>
 </s:HGroup>

</s:Application>

4: Add Environment Variables:

Think of environment variables as values you burn into the shell of the operating system,
which are convenient for reuse elsewhere when executing other command line functions.
We’ll add two:

Applications > Accessories > Terminal

When the terminal opens, type:

gedit ~/.bashrc

This opens a file for editing.  Disregard everything you see in this file, but scroll to the bottom
of the file so we can add two new entries; of course,replace “__your_profile__” with your
profile folder name:

#full path to flex4 sdk bin added to PATH variable
PATH=$PATH://home/__your_profile__/flex41/bin
export PATH

#full path to flex4 sdk frameworks
flexlib=$flexlib:/home/__your_profile__/flex41/frameworks
export flexlib

When you’re done, save the changes and close the file.  In your terminal window,call the
following to refresh your environment and include the new variables:

source ~/.bashrc

You should now be able to type “echo $flexlib” to confirm that your environment shell
is updated.

5: Tweak the Flex 4 project config file:

The Flex 4 compiler parses an XML config file to glean information about the installation
path of your Flex 4 SDK as well as the path to your project’s “src” directory.  Because a
template of the Flex 4 config file is included with the SDK, we can copy it to the
workspace’s project folder, then modify it.

First, copy the config file from the SDK to your project folder like so;  notice we’re taking
advantage of the $flexlib variable to shorten the command, we’ll use this variable again
shortly:

cp $flexlib/flex-config.xml /home/__your_profile__/flex41wk/hello/flex-config.xml

You should be able to confim the config file template is moved to your project
directory by browsing to the directory through your home folder.  Now we need to edit
the config file so it will recognize the SDK location relative to the local file system. For this,
we’ll also use the $flexlib environment varible.

I provided my flex-config.xml file for download, and you can get it here:

http://www.learningflex4.com/blogassets/flex-config.xml

The recommendation is to use the download for comparison.  Specifically,
note this XML node near the top of the file; you’ll need to change my profile
name to yours:

<source-path>
<path-element>/home/__your_profile__/flex41wk/hello/src/</path-element>
</source-path>

Also, there are many file system paths in this document.  If you downloaded the config file I
provided, look for the instances of ${flexlib} to appear everywhere the compiler will check
the local file system.  Be sure to prepend your resource paths with this key variable.

Once you’re finished editing, make sure to save the file; then close it.

6: Creating a reusable compiler script in Bash

Now we’ll make a reusable bash script to call the compiler (mxmlc) with fixed settings, specific
to this project.  For this, we’ll make a new file and edit it.

Browse to Places > Home Folder > flex41 wk> hello

Right-click > Create Document > empty file

When the new file appears, name it “compile” (LEAVE THE EXTENSION BLANK, no quotes).

Double-click on the file to open it.  In the text editor, add the following lines:

#!/bin/bash
mxmlc -load-config flex-config.xml ./src/hello.mxml -output ./bin/hello.swf

Save it when you’re finished.  The Bash script handles the task of launching the compiler, passing
it a reference to the flex-config.xml file, identifying the “scr” directory, and specifying the output,
“bin/hello.swf”.

Finally, we need to change the permissions of our “compile” script so that it’s executable.  You’ll
need to move to the proper directory first.  So in your terminal window, run the following lines
back-to-back:

cd ~/flex41wk/hello
chmod 755 compile

7: Compile and test..

Now you should be ready to compile and test.  Compile the one- Button app with the following line
in your terminal:

./compile

Assuming you don’t receive any errors, browse to your compiled SWF file:

Places > Home Folder > flex41wk > hello > bin

In this directory, Right-click on “hello.swf” and select “Open with Firefox”.

That should do it.  Enjoy.  – Elijah

Written by elrobis

28 July 2010 at 9:35 am

Posted in Flex 4, Flex SDK, Linux

Tagged with , ,