Someone in #flex was talking about how there were no good examples for doing uploads with Flex and ColdFusion. Sounded like an excellent topic to cover here. Now this example is a tiny bit more complex than previous examples, because I needed to cover two methods of functionality: single file uploads and multi-file uploads. Both processes are very similar, and in my code they actually share a method.

Disclaimer: This post is not about best practices or anything of that sort. This is just a recount of my first attempt at using Ant with an open-source Flex library project.

Here are the steps I went through (well, minus the steps that did nothing) to get my first Ant build script up & running;

Installing Ant

There were a few steps to get a Flex Builder standalone install up to speed to do stuff with Ant. Eclipse users might or might not need to do these steps.

  • Install Ant (Thanks, Judah!)
    1. In Flex Builder, go to Help > Software Updates > Find and Install
    2. Search for new features to install
    3. Select “The Eclipse Project Updates”
    4. Select The Eclipse Project Updates > Eclipse 3.3.2 > Eclipse Java Development Tools…
    5. Finish the installation process, including restarting Flex Builder
  • Install SVNAnt (Thanks, Phill!)
    1. Download the SVNAnt binary from http://subclipse.tigris.org/svnant.html
    2. Unzip the download, place all the .jar files in /lib/ in your Ant Install directory, which for Flex Builder is Flex Builder 3/plugins/org.apache.ant_${version_number}/lib/
  • Add needed libraries for FTP features
    1. Download the Apache Commons Net and Jakarta-ORO binaries
    2. Unzip both downloads, place all the .jar files in /lib/ in your Ant Install directory (same as above)
  • Finish configuring Ant
    1. Go to Window > Preferences > Ant > Runtime
    2. Click the Ant Home… button
    3. Choose your Ant Install directory (Flex Builder 3/plugins/org.apache.ant_${version_number}/). Be sure to NOT select the lib directory

Your Build Script

So you’ve got everything configured, now what? Let’s start with a build script. Explainations are in the comments. Keep in mind that these directory paths are for OS X, so Windows users will need to switch operating systems or use Windows paths. Probably easier to switch your OS.

  1. Create a build.xml in your project. Populate it with your build code (see my code exmaple below)
  2. Add the Ant view by going to Window > Other Views > Ant
  3. In the new Ant tab, right click and select Add Buildfiles. Select your build.xml file.
  4. Now, whenever you want to make a push, just hit the run button in the Ant tab.

<project name="MyProject" default="svn.live" basedir=".">
  <!-- set the taskdef's -->
  <taskdef resource="svntask.properties"/>
  <taskdef resource="flexTasks.tasks"/>
  
  <!-- set some properties -->
  <property name="TEMP_DIR" value="/tmp/MyProject_Temp/"/>
  <property name="FLEX_HOME" value="/Applications/Adobe Flex Builder 3/sdks/3.0.0/"/>
  <property name="APP_ROOT" value="~/Documents/Flex Builder 3/MyProject/"/>
  
  <target name="svn.live">
    <!-- clear out the temp dir -->
    <delete dir="${TEMP_DIR}"/>
    
    <!-- let's get the latest build from SVN to a temp directory -->
    <svn>
      <export srcUrl="http://svn.mysite.com/MyProject/trunk/" destPath="${TEMP_DIR}MyProject/"/>
    </svn>
    <echo>SVN Export Complete</echo>
    
    <!-- build the ASDocs from the source -->
    <exec executable="${FLEX_HOME}/bin/asdoc" failonerror="true">
      <arg line="-source-path ${TEMP_DIR}MyProject/"/>
      <arg line="-doc-sources ${TEMP_DIR}MyProject/"/>
      <arg line="-excmVFR676W26F&R6W&ƗF646F&R6W&ƗF64FV6FW"6F&R6W&ƗF64V6FW"6F&R6W&ƗF64'6TW'&"6F&R6W&ƗF64FV6F&R6W&ƗF64FV旦W"6F&R6W&ƗF64FVGR"ࠐ&rƖS"FFRtג&r&V7BF72r"ࠐ&rƖS"WGWBGDTD'ו&V7BF72"ࠐWV3ࠐV6F727&VFVCV6ࠐ'VBFRFW7B7v2g&FR6W&6RࠐWV2WV7WF&S"GdUW&62"fW'&#'G'VR#ࠐ&rƖS"6W&6RFGDTD'ו&V7B"ࠐ&rƖS"֖6^ude-sources ${TEMP_DIR}MyProject/"/>
      <arg line="-output ${TEMP_DIR}MyProject/bin/MyProject.swc"/>
    </exec>
    <echo>SWC Built</echo>
    
    <!-- create zip files to upload -->
    <mkdir dir="${TEMP_DIR}zip/"/>
    <exec executable="zip" dir="${TEMP_DIR}">
      <arg line="-r ${TEMP_DIR}zip/MyProject.zip MyProject/"/>
    </exec>
    <echo>Source Zip Created</echo>
    <exec executable="zip" dir="${TEMP_DIR}MyProject/bin/">
      <arg line="${TEMP_DIR}/zip/MyProject.swc.zip MyProject.swc"/>
    </exec>
    <echo>SWC Zip Created</echo>
    
    <!-- upload files -->
    <ftp server="ftp.mysite.com"
      userid="username"
      password="password"
      passive="true"
      remotedir="path/to/upload"
    >
      <fileset dir="${TEMP_DIR}zip/"/>
    </ftp>
    <echo>Zip Files Uploaded</echo>
    <ftp server="ftp.mysite.com"
      userid="username"
      password="password"
      passive="true"
      remotedir="path/to/upload/docs"
    >
      <fileset dir="${TEMP_DIR}MyProject/docs/"/>
    </ftp>
    <echo>Zip Files Uploaded</echo>
  </target>
</project>

I’m not going to cover asdoc/compc/mxmlc command line options here, there’s plenty of great docs out there.
You can also read more about the svn task, exec task and ftp task at their respective documentation pages.

Now that you’ve got a start to finish example, go forth and Ant!

There was some confusion in #flex yesterday. The question came up on how a child component could access the parent component. Eventually, it came down to they wanted to pass some data from the child back to the parent.

Well, the “black box” method of component programming says that we should use custom events to send data from the component back to the parent. I whipped up an example that uses both a basic custom event and a custom event that passes back data.

One note, when you create your own event that passes back data, you not only need to add your custom attributes, but you also need to override the clone() method. Look at the MyCustomEvent.as file in the source.

You can view the example here. As always, right-click to view the source.

Someone on #flex asked about preventing text from appearing in a TextInput or TextArea, when the user is using a keyboard shortcut. After a little discussion, I came up with a working example. I decided to use shift-space to simplify things.

The first assumption is that you’re listening for keyboard shortcuts at the application level:

application.addEventListener(KeyboardEvent.KEY_UP,shortcutHandler);

Now, you’ve got your input box, and it’s listeners:
<mx:TextArea height="100%" width="95%" keyDown="shortcutPreprocess(event)" textInput="shortcutPreventer(event)"/>

private function shortcutPreprocess(e:KeyboardEvent):void {
  if (e.shiftKey && e.keyCode == 32) {
      _isShiftSpace = true;
    } else {
      _isShiftSpace = false;
    }
}

private function shortcutPreventer(e:Event):void {
  if (_isShiftSpace) {
    e.stopImmediatePropagation();
    e.preventDefault();
  }
}

Note that I had to set a boolean in my shortcutPreprocess method, and then I check for the boolean in shortcutPreventer. The reason being is that the textInput event doesn’t pass in the KeyboardEvent in any way, so I don’t know if there was a key combo pressed.

Working example & source:
http://www.iotashan.com/examples/KeyboardShortcut/

Over the weekend I was writing a simple little app, and came across something that should have been trivial, but turned out to throw me for a loop momentarily. I needed to drive some data from XML instead of my tried-and-true ColdFusion components, and I realized I’d never done it before. So, here’s the example:

First off, you need to actually get the XML file using a HTTPService:

<mx:HTTPService id="sectionService" url="pet.xml" resultFormat="e4x" result="sectionResult(event)"/>

Looks simple enough, but to produce valid XML, I needed to have a root node around my other nodes:

<?xml version="1.0" encoding="utf-8"?>
<varieties>
  <variety name="Standard"/>
  <variety name="Angora"/>
  <variety name="Satin"/>
  <variety name="Rex"/>
  <variety name="Texel"/>
  <variety name="Satin Texel"/>
  <variety name="Satin Rex"/>
  <variety name="Satin Angora"/>
  <variety name="Fuzzy"/>
  <variety name="Fuzzy Angora"/>
  <variety name="Fuzzy Hairless"/>
  <variety name="Fuzzy Hairless Angora"/>
  <variety name="Hairless"/>
</varieties>

Now, when I put this directly into a XMLList object, I got a ComboBox with one option… my entire XML packet. It took a few tries to realize that I needed to make the DataProvider only the “variety” nodes, and that was easy to do:

private function varietyResult(e:ResultEvent):void {
  varietyXML = XMLList(e.result.variety);
}

So, for everyone who likes to see the whole picture, like me, here’s the entire MXML code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" initialize="init()">
  <mx:HTTPService id="varietyService" url="varieties.xml" resultFormat="e4x" result="varietyResult(event)"/>
  <mx:Script>
    <![CDATA[
      import mx.rpc.events.ResultEvent;
      
      [Bindable] private var varietyXML:XMLList;
      
      private function init():void {
        varietyService.send();
      }
      
      private function varietyResult(e:ResultEvent):void {
        varietyXML = XMLList(e.result.variety);
      }
    ]]>
  </mx:Script>
  <mx:ComboBox id="variety" dataProvider="{varietyXML}" labelField="@name"/>
</mx:Application>

Shan’s Simple Examples: Scale all children in Flex

Posted on January 24th, 2008 by Shan

I’ve decided since I attempt to help people in #flex (on EFNet) and #coldfusion / #cfflex (on DALNet) on a daily basis, that I’ll pick one simple question and try to whip up an example for everyone to see.

Today, someone asked how to scale all children of a container. The basic answer is to just loop over all the children, and set their scaleX and scaleY properties.

Click through for the example and source code.

Shan’s Simple Examples

Posted on January 24th, 2008 by Shan

I’ve started a series of posts on the Webapper blog called Shan’s Simple Examples. I’ll cover Flex and ColdFusion examples as I help others in the IRC channels #flex (EFNet) and #coldfusion / #cfflex (on DALNet).
Hopefully this will turn into a nice library of quick HOW-TOs for us developers.
See a list of blog postings.
View the [...]

Flex Not-So Custom Preloader

Posted on January 17th, 2008 by Shan

Today I got a request to change the “Loading” text in the preloader of a Flex app. To my surprise, I didn’t see any examples on how to do this, so I thought I’d share my results.

When you like the existing preloader, but want to just make little tiny changes to it, here’s what you do. You’ll first need to go ahead and create a custom preloader class that extends DownloadProgressBar (the default preloader). In this new class, you’ll see the spot where you can just make tweaks to the preloader’s values:

package org.iotashan.components
{
  import mx.preloaders.DownloadProgressBar;

  public class CustomPreloader extends DownloadProgressBar
  {
    public function CustomPreloader()
    {
      super();
      // set your properties here
      this.downloadingLabel = "Getting the hampster to run on the wheel";
    }
    
  }
}

Once you’ve created this custom preloader, you just have to assign it to your application:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" preloader="org.iotashan.components.CustomPreloader">

That’s it. Check out the live example here.

Welcome to my new site!

Posted on December 2nd, 2007 by Shan

I’ve finally given in and started my own blog. Nobody’s going to read it, but I needed somewhere to post stuff not appropriate for the Webapper blog. I’m not entirely sure what all I’m going to do here, but I guess I can do anything I like since nobody’s reading
I also re-designed my [...]