<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Michael Christoff &#187; flex</title>
	<atom:link href="http://mchristoff.com/category/code/flex/feed/" rel="self" type="application/rss+xml" />
	<link>http://mchristoff.com</link>
	<description>Participating in Life.</description>
	<lastBuildDate>Sat, 05 Dec 2009 04:18:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using the AIR 2.0 Native Process API to control MPlayer</title>
		<link>http://mchristoff.com/2009/12/using-the-air-2-0-nativeprocess-api-to-control-mplayer/</link>
		<comments>http://mchristoff.com/2009/12/using-the-air-2-0-nativeprocess-api-to-control-mplayer/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 08:00:03 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://mchristoff.com/?p=111</guid>
		<description><![CDATA[
Adobe AIR has been a big step forward in creating cross-platform applications. Unfortunately, there are still some big gotchas. For us at cloud.tv our biggest issue are the lack of media playback options. Our AIR-based media center, cloudskipper, can play any media Flash supports, which has gotten better since Adobe added H.264 support in Flash [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="lightbox"  border="0" href="http://img.skitch.com/20091203-qu9xhuh4axsfkbmixu7ukrbsub.jpg" rel="lightbox[111]"><img alt="" src="http://img.skitch.com/20091203-qu9xhuh4axsfkbmixu7ukrbsub.jpg" title="AIRmplayer" class="alignnone" width="580" height="350" /></a></p>
<p>Adobe AIR has been a big step forward in creating cross-platform applications. Unfortunately, there are still some big gotchas. For us at cloud.tv our biggest issue are the lack of media playback options. Our AIR-based media center, cloudskipper, can play any media Flash supports, which has gotten better since Adobe added H.264 support in Flash 9.0.124, but still leaves out a lot (XVID, AAC audio supporrt, etc). This is particularly true with desktop media where there dozens of different codecs.</p>
<p>Luckily, a few weeks ago Adobe released the beta of AIR 2.0 and with that the NativeProcess API. The NativeProcess API essentially allows you to invoke any native process similar to how you would via the command line but in your AIR app. You then communicate with that process via STDIN and STDOUT. Jeff Swartz over at the Adobe Developer Connection wrote nice <a href="http://www.adobe.com/devnet/air/flex/quickstart/interacting_with_native_process.html">introduction</a> to this, which I highly recommend.</p>
<p>Can we use this new capability to do something a little more interesting than &#8220;echotest&#8221;, like say play a video HD video encoded with XVID? I&#8217;m happy to say that with some caveats the answer is yes =)</p>
<h4>Media Player Choice</h4>
<p>The first thing we need to play media is well&#8230; a media player. Not just any media player, a media player with a few specific requirements:</p>
<ol>
<li>Plays many different media types (this probably means it has various media codecs packaged with it)</li>
<li>Cross platform (mac, linux, windows)</li>
<li>Can be invoked via the command line</li>
<li>Can receive input and send out via STDIN/STDOUT</li>
<li>Open source (distribution limitations and the inability to make modifications are show stoppers for commercial software)</li>
</ol>
<p>From my research the only two media players I could find that meet both these requirements are <a href="http://www.videolan.org/vlc/">VLC</a> and <a href="http://www.mplayerhq.hu">MPlayer</a>.  Both MPlayer and VLC can be invoked via the command line. They also both have modes where they work with STDIN/STDOUT, &#8220;remote control&#8221; mode (use the argument -Irc) in VLC and &#8220;slave&#8221; mode (use the argument -slave) in MPlayer. You can find about VLC&#8217;s remote control mode <a href="http://www.videolan.org/doc/play-howto/en/ch04.html">here</a> and MPlayer&#8217;s slave mode <a href="http://www.mplayerhq.hu/DOCS/tech/slave.txt">here</a>.</p>
<p>VLC seems to actually be able to play a wider array of media, but the choice for me came down to what will work with AIR. Unfortunately, for some reason I just couldn&#8217;t get AIR to play nice with VLC in remote control mode. AIR seems to ignore the -Irc argument and just open up VLC. Maybe, I&#8217;m missing something with VLC, but I was able to get MPlayer to open up just fine in slave mode so that made my choice moving forward pretty easy.</p>
<h4>MPlayer Installation</h4>
<p>The easiest way to install MPlayer on OS X is via <a href="http://">macports</a>. Just open up the terminal and type the command &#8220;sudo port install mplayer-devel&#8221;. Now sit back make yourself a cup of coffee, maybe have lunch or go for a run around the block while macports compiles and installs mplayer and all of it&#8217;s dependencies. Note we&#8217;re using mplayer-devel, which I assume is the &#8220;latest&#8221; development release. This has some fixes to make MPlayer work on Snow Leopard and generally seems pretty stable (you can still install &#8220;mplayer&#8221; if you&#8217;re on Leopard or below). When MPlayer is done compiling/installing do a mplayer -v to make sure everything installed correctly. Then execute &#8220;which mplayer&#8221; and not the location (it will most likely be /opt/local/bin/mplayer). Note MPlayer&#8217;s location because we&#8217;re going to need this later.</p>
<p>Windows seems to be a bit tricker. <a href="http://www.mplayerhq.hu/">MPlayer HQ</a> seems to have both windows soure and binaries though so I&#8217;d recommend heading over there. I&#8217;d love to hear some first hand reports on this.</p>
<p>If your on linux I think app-get should work similiarly to macports, but I haven&#8217;t tested this.</p>
<h4>AIR 2 SDK Installaton</h4>
<p>You&#8217;re going to need to install the AIR 2 SDK to take advantage of the NativeProcess API. Luckily, I just posted a guide on how to do this =) You can check that out here: <a href="http://mchristoff.com/2009/12/installing-the-adobe-air-2-beta-sdk-on-os-x/">Installing the AIR 2 SDK on OS X</a> (this is be pretty similiar for linux and windows).</p>
<h4>The Code</h4>
<p>Ok, finally, to the code! I&#8217;m not going to go through everything line by line here,  but I will go over the key parts.</p>
<p><strong>Update Application Descriptor</strong><br />
Extended desktop mode needs to be enabled for NativeProccess support.</p>
<div class="codecolorer-container xml vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;supportedProfiles<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>extendedDesktop<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/supportedProfiles<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p><strong>Set the location of mplayer</strong></p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">protected const MAC_MPLAYER_PATH:<span style="color: #0066CC;">String</span> = <span style="color: #ff0000;">'/opt/local/bin/mplayer'</span>;<br />
protected const WIN_MPLAYER_PATH:<span style="color: #0066CC;">String</span> = <span style="color: #ff0000;">'c:<span style="color: #000099; font-weight: bold;">\\</span>path<span style="color: #000099; font-weight: bold;">\\</span>to<span style="color: #000099; font-weight: bold;">\\</span>mplayer'</span>;</div></div>
<p>(Sorry, didn&#8217;t add linux, but it should be fairly trivial)</p>
<p><strong>Create the arguments</strong></p>
<p>The three arguments we&#8217;re passing to MPlayer are:</p>
<ol>
<li>slave &#8211; switches MPlayer to use STDIN/STDOUT, making communication with AIR possible. You can find more information about slave mode <a href="http://www.mplayerhq.hu/DOCS/tech/slave.txt">here</a>.</li>
<li>quiet &#8211; makes output less verbose. this speeds things up a bit and make STDOUT parasing more reliable. Read more on MPlayer&#8217;s <a href="http://www.mplayerhq.hu/DOCS/man/en/mplayer.1.html">man page</a>.</li>
<li>idle &#8211; supposed to keep mplayer open when a file finishes playing, but doesn&#8217;t seem to work though.</li>
</ol>
<p> Note, file here is the platform specific mplayer executable.</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">var</span> nativeProcessStartupInfo:NativeProcessStartupInfo = &nbsp;<span style="color: #000000; font-weight: bold;">new</span> NativeProcessStartupInfo<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
nativeProcessStartupInfo.<span style="color: #006600;">executable</span> = file;<br />
<span style="color: #000000; font-weight: bold;">var</span> args:Vector.<span style="color: #66cc66;">&lt;</span>String<span style="color: #66cc66;">&gt;</span> = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>String<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
args.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'-slave'</span><span style="color: #66cc66;">&#41;</span>;<br />
args.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'-quiet'</span><span style="color: #66cc66;">&#41;</span>;<br />
args.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'-idle'</span><span style="color: #66cc66;">&#41;</span>;<br />
args.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>mediaFile.<span style="color: #006600;">nativePath</span><span style="color: #66cc66;">&#41;</span>;<br />
nativeProcessStartupInfo.<span style="color: #0066CC;">arguments</span> = args;</div></div>
<p><strong>Send commands to STDIN</strong></p>
<p>This is pretty straight forward. I wrote a little wrapper called &#8220;cmd&#8221; to handle error checking, but really all it does is write to the process&#8217;s standard input.</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> cmd<span style="color: #66cc66;">&#40;</span>cmdStr:<span style="color: #0066CC;">String</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>process <span style="color: #66cc66;">&amp;&amp;</span> process.<span style="color: #006600;">running</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; process.<span style="color: #006600;">standardInput</span>.<span style="color: #006600;">writeUTFBytes</span><span style="color: #66cc66;">&#40;</span>cmdStr + <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></div>
<p><strong>Receive commands from STDOUT and parse</strong></p>
<p>MPlayer sends back information in a standard format. This means we just have to parse out certain strings to get the information we want. In this case we&#8217;re looking for the video&#8217;s position and length to update the scrubber.</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">process.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>ProgressEvent.<span style="color: #006600;">STANDARD_OUTPUT_DATA</span>, onOutputData<span style="color: #66cc66;">&#41;</span>;<br />
protected <span style="color: #000000; font-weight: bold;">function</span> onOutputData<span style="color: #66cc66;">&#40;</span>event:ProgressEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">var</span> output:<span style="color: #0066CC;">String</span> = process.<span style="color: #006600;">standardOutput</span>.<span style="color: #006600;">readUTFBytes</span><span style="color: #66cc66;">&#40;</span>process.<span style="color: #006600;">standardOutput</span>.<span style="color: #006600;">bytesAvailable</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; outputText += output;<br />
&nbsp; textReceived.<span style="color: #006600;">verticalScrollPosition</span> = textReceived.<span style="color: #006600;">maxVerticalScrollPosition</span>;<br />
&nbsp; <br />
&nbsp; <span style="color: #000000; font-weight: bold;">var</span> arr:<span style="color: #0066CC;">Array</span>;<br />
&nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>output.<span style="color: #0066CC;">indexOf</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ANS_TIME_POSITION'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;</span> -1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; arr = output.<span style="color: #0066CC;">split</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ANS_TIME_POSITION='</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; vidPosition = <span style="color: #0066CC;">parseFloat</span><span style="color: #66cc66;">&#40;</span>arr<span style="color: #66cc66;">&#91;</span>1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; <br />
&nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>output.<span style="color: #0066CC;">indexOf</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ANS_LENGTH'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;</span> -1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; arr = output.<span style="color: #0066CC;">split</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ANS_LENGTH='</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; vidLength = <span style="color: #0066CC;">parseFloat</span><span style="color: #66cc66;">&#40;</span>arr<span style="color: #66cc66;">&#91;</span>1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></div>
<p><strong>Scrubbing</strong><br />
Scrubbing is a little tricker because we have to worry about states (paused or playing). I also added the volume hack you see people because issuing all commands unpauses MPlayer and causes an audible pop.</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">protected <span style="color: #000000; font-weight: bold;">function</span> onScrub<span style="color: #66cc66;">&#40;</span>event:SliderEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>playing<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// cmd('volume 0 1');</span><br />
&nbsp; &nbsp; cmd<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'mute 1'</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; cmd<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'pause'</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; cmd<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'seek '</span>+ <span style="color: #66cc66;">&#40;</span>event.<span style="color: #006600;">currentTarget</span> as HSlider<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">value</span> + <span style="color: #ff0000;">' 2'</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; cmd<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'get_time_pos'</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>playing<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; cmd<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'pause'</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></div>
<h4>Download  source: </h4>
<p><a href="http://mchristoff.com/code/AIRmplayer.mxml">AIRmplayer.mxml</a> and <a href="http://mchristoff.com/code/AIRmplayer-app.xml">AIRmplayer-app.mxml</a></p>
<h4>Playing Audio</h4>
<p>From my tests MPlayer actually performs very well with audio. Not only does it seem to play mp3, m4a, ogg, flac, it also handles large files MUCH better than flash and even iTunes. There also aren&#8217;t the same windowing issues you have with video (except for m4a&#8217;s with visual content).</p>
<h4>Issues and Final Thoughts</h4>
<p>This is by no means  a complete solution. There are several issues that need to be addressed before I would consider it viable in production environment:</p>
<ol>
<li>windowing &#8211; communicating between the MPlayer window and the AIR app is challenge if you want to integrate video playback</li>
<li>separate app &#8211; as stands MPlayer opens up it&#8217;s dock icon (on os x) when it opens up a new movie window</li>
<li>distribution &#8211;  it will be tricky to compile mplayer with all dependencies localized in order to distribute it as native installer</li>
</ol>
<p>Challenges aside,  I think this still serves as an interesting demo of the possibilities of what we can now do with AIR 2 and the NativeProcess API.</p>
<h4>Resources</h4>
<p><a href="http://blogs.adobe.com/cantrell/archives/2009/11/air_2_public_beta_resources.html">http://blogs.adobe.com/cantrell/archives/2009/11/air_2_public_beta_resources.html</a><br />
<a href="http://www.adobe.com/devnet/air/flex/quickstart/interacting_with_native_process_02.html">http://www.adobe.com/devnet/air/flex/quickstart/interacting_with_native_process_02.html</a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fmchristoff.com%2F2009%2F12%2Fusing-the-air-2-0-nativeprocess-api-to-control-mplayer%2F&amp;linkname=Using%20the%20AIR%202.0%20Native%20Process%20API%20to%20control%20MPlayer"><img src="http://mchristoff.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://mchristoff.com/2009/12/using-the-air-2-0-nativeprocess-api-to-control-mplayer/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Installing the Adobe AIR 2 Beta SDK on OS X</title>
		<link>http://mchristoff.com/2009/12/installing-the-adobe-air-2-beta-sdk-on-os-x/</link>
		<comments>http://mchristoff.com/2009/12/installing-the-adobe-air-2-beta-sdk-on-os-x/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 09:08:38 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://mchristoff.com/?p=114</guid>
		<description><![CDATA[I&#8217;m sure I&#8217;m not the only one who was super stoked when Adobe released the beta of AIR 2.0. For those not familiar,  Adobe added a laundry list of new toys, like support for mass storage devices, UDP sockets, and my personal favorite native code integration. You can check out the full list at Adobe [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m sure I&#8217;m not the only one who was super stoked when Adobe released the beta of AIR 2.0. For those not familiar,  Adobe added a laundry list of new toys, like support for mass storage devices, UDP sockets, and my personal favorite <strong>native code integration</strong>. You can check out the full list at <a href="http://labs.adobe.com/technologies/air2/">Adobe Labs.</a></p>
<p>Of course, as these things always seem to go with beta stuff it wasn&#8217;t completely trivial to get things up and a running so I decided to write this post up. Note these instructions assume you&#8217;re using Flex 3 and Flex Builder 3, but there&#8217;s no reason this shouldn&#8217;t work with Flex 4 and Flash Builder 4. I haven&#8217;t tried this yet because I haven&#8217;t made the jump myself, but would love to hear from anyone who can verify this. Without further ado&#8230;</p>
<p>1. <strong>Download and run the AIR 2.0 runtime and SDK</strong> &#8211; <a href="http://labs.adobe.com/downloads/air2.html">http://labs.adobe.com/downloads/air2.html</a></p>
<p>2. <strong>Make a copy of your Flex SDK</strong> &#8211; On OS X this should located in ~/Applications/Adobe\ Flex\ Builder\ 3/sdks. I called mine &#8220;3.4andAir2&#8243;. Alternatively if you haven&#8217;t updated your flex SDK in a while you can get the latest version of Flex 3 from <a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3">here</a>.</p>
<p>3. <strong>Overlay the AIR 2 SDK over the copied SDK</strong> &#8211; Since the AIR SDK is interwoven with  the Flex SDK this is actually a bit tricky. I first tried to do it manually by copying over each relevant file and folder. I&#8217;m not sure if I was careless, but flex builder didn&#8217;t recognize any of the AIR 2.0 API calls. Luckily, I did a bit of search and found the &#8220;ditto&#8221; command, which will do exactly what we need.  Once you&#8217;ve mounted the AIR 2 dmg, open up your terminal and you can use ditto as follows to overlay AIR 2.0:</p>
<p>ditto -V /Volumes/AIR\ SDK/ /Applications/Adobe\ Flex\ Builder\ 3/sdks/3.4andAir2/</p>
<p>This should ovewrite the AIR 1.5 SDK with AIR 2.0 SDK.</p>
<p>4. <strong>Add the new SDK to Flex Builder</strong> &#8211; Go to Flex Builder &gt; Preferences &gt; Installed Flex SDKs &gt; Add&#8230; Point it to your 3.4andAir2 sdk folder you made.</p>
<p>5. <strong>Start a new project</strong></p>
<p>6. <strong>Change compiler settings to point to the new SDK</strong> &#8211; Project &gt; Properties &gt; Flex Compiler &gt; Use a Specific SDK</p>
<p>7. <strong>Change the application descriptior file </strong>- Change the line 2 to: &lt;application xmlns=&#8221;http://ns.adobe.com/air/application/2.0beta&#8221;&gt;</p>
<p>8. <strong>Verify</strong> &#8211; Add the following line of code and make sure you don&#8217;t get any build errors:</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> process:NativeProcess</div></div>
<p>That&#8217;s it! Stay tuned for my next post where I&#8217;ll dig into the NativeProcess API!</p>
<p><strong>Update: </strong>In response to my blog post <span><a href="http://blogs.adobe.com/cantrell/">Christian Cantrell</a>, AIR product manger, pointed out the key to getting the overlaying to work is not using the finder. Other methods besides ditto also work like cp -r and tar -xfj</span></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fmchristoff.com%2F2009%2F12%2Finstalling-the-adobe-air-2-beta-sdk-on-os-x%2F&amp;linkname=Installing%20the%20Adobe%20AIR%202%20Beta%20SDK%20on%20OS%20X"><img src="http://mchristoff.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://mchristoff.com/2009/12/installing-the-adobe-air-2-beta-sdk-on-os-x/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Extending Flex 3 Components</title>
		<link>http://mchristoff.com/2009/08/extending-flex-3-components/</link>
		<comments>http://mchristoff.com/2009/08/extending-flex-3-components/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 05:15:11 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://mchristoff.com/?p=56</guid>
		<description><![CDATA[If you&#8217;ve more than dabbled with Flex I&#8217;m sure you&#8217;ve come to a point where your excitement for all the whiz-bang awesomeness you can do so easily is replaced by dread when you realize a component is doing about 90% of what you want. Sometimes 90% just aint good enough though, right? Exactly, that&#8217;s why [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve more than dabbled with Flex I&#8217;m sure you&#8217;ve come to a point where your excitement for all the whiz-bang awesomeness you can do so easily is replaced by dread when you realize a component is doing about 90% of what you want. Sometimes 90% just aint good enough though, right? Exactly, that&#8217;s why I figured I&#8217;d write a little tutorial on how to extend a Flex component based on real-life problem I had with the Flex 3.x Tree control. So without further ado&#8230;</p>
<p>The Flex 3 tree control has an issue with icons. The issue is you cannot define icons via the XML dataprovider for branch nodes (a branch is defined as non-leaf node). That sentence is a bit dense so let me explain with an example.</p>
<p>The following xml code is the dataprovider of a Flex tree:</p>
<div class="codecolorer-container xml vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menu<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;node</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Home&quot;</span> <span style="color: #000066;">icon</span>=<span style="color: #ff0000;">&quot;appIcon&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;node</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Channels&quot;</span> <span style="color: #000066;">icon</span>=<span style="color: #ff0000;">&quot;channelsIcon&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;channel</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Vimeo HD Channel&quot;</span> <span style="color: #000066;">thumb</span>=<span style="color: #ff0000;">&quot;http://images.vimeo.com/channelbadge-113006734.jpg&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;channel</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Vimeo Staff Picks&quot;</span> <span style="color: #000066;">thumb</span>=<span style="color: #ff0000;">&quot;http://images.vimeo.com/channelbadge-112957409.jpg&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/node<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/menu<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>The flex team was nice enough to create an iconField attribute, which allows you to define an icon for any node in your tree. In our case we&#8217;ll use &#8220;@icon&#8221; like so:</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &lt;mx:Tree dataProvider=&quot;myXMLListCollection&quot; iconField=&quot;@icon&quot;/&gt;</div></div>
<p>You&#8217;d expect the icon attribute to work on every node right? Wrong:</p>
<p><img alt="" src="http://img.skitch.com/20090917-ean8mh8yrc5a3rhmy4whwxjta8.jpg" title="Tree Menu Broken" class="alignnone" width="228" height="80" /></p>
<p>The second node (label=&#8221;Channels&#8221;) renders with the default icon instead of the defined channelsIcon (this is defined as an embedded image which is not shown).</p>
<p>I&#8217;m actually not sure if it&#8217;s an issue, a design flaw, or if there&#8217;s another way to do what I want that I&#8217;m just not getting. Either way, I did the first thing I always do when a Flex component doesn&#8217;t behave the way I want&#8230; open the hood and start hacking.</p>
<p>If you&#8217;ve never taken a look at the source of Flex component it&#8217;s actually pretty easy. Just navigate to whichever Flex SDK your using and you&#8217;ll find Tree.as in [your-flex-directory]/frameworks/project/framework/src/mx/controls/Tree.as. The easiest way to get to this file if you&#8217;re using Flex Builder is to cmd+click (ctrl-click on windows I believe) the component in mxml or actionscript. If everythings linked correctly Tree.as</p>
<p>So now you&#8217;ve got the source, what the heck do you do with this 3452 line monster? Well, this changes a bit each time, but in our case with the Tree component I decided to just look through the methods of Tree and see if i could find a promising one. Low and behold on line 1169 there&#8217;s a public method named itemToIcon. So noq f we track back a bit we can see that itemToIcon is used in initListData (line 2659). Specifically we see that on line 2666 we have this:</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">treeListData.<span style="color: #006600;">icon</span> = itemToIcon<span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Bingo! It look like itemToIcon might just be what we&#8217;re looking for. Unfortunately, there&#8217;s no documentation for this method, but if we just take a second to think about the method name, it&#8217;s inputs and outputs, we can quickly see that itemToIcon converts an item object into an icon class. Scanning a little further down we can start to see series of if / else if / else statements that define the priority in which an icon is returned:</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>iconClass<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> iconClass;<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>iconFunction <span style="color: #66cc66;">!</span>= <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> iconFunction<span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>branch<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0066CC;">getStyle</span><span style="color: #66cc66;">&#40;</span>open ? <span style="color: #ff0000;">&quot;folderOpenIcon&quot;</span> : <span style="color: #ff0000;">&quot;folderClosedIcon&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #b1b100;">else</span><br />
<span style="color: #808080; font-style: italic;">//let's check the item itself</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>item is <span style="color: #0066CC;">XML</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">try</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span>.<span style="color: #0066CC;">length</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">!</span>= 0<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;icon = <span style="color: #0066CC;">String</span><span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">catch</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:<span style="color: #0066CC;">Error</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>item is <span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">try</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>iconField <span style="color: #66cc66;">&amp;&amp;</span> item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon = item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>item.<span style="color: #006600;">icon</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon = item.<span style="color: #006600;">icon</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">catch</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:<span style="color: #0066CC;">Error</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></div>
<p>Basically, itemToIcon prioritizes what icon the item will use by the following conditionals:</p>
<ol>
<li>does iconClass exist? (this has to do with the itemIcons parameter existing)</li>
<li>is an IconFunction defined?</li>
<li>is it a branch?</li>
<li>does iconField exist?</li>
</ol>
<p>It seem like case 1 should be able to handle custom branch icons, but I could not figure out how to get that to work with XML (any enlightenment on this would be appreciated). It was easy enough to figure out the logic and rearrange it though.</p>
<p>If you take a look at the priority of operations you should see the problem at case 3. If it finds a node that&#8217;s a branch it uses the default folder icon (either folderOpenIcon or folderClosedIcon). If you remember our example tree this is exactly our problem. Rather than the tree item rendering the default icon renders. Now if we looks at the 4th case, we see that the logic is there to use the iconField (@icon in our case), but it never gets to it on branch nodes! It just uses the default icons because of case 3.</p>
<p>Luckily we should be able to just create a new component that extends the Tree component and override the itemToIcon method with our new logic. Essentially all we have to do is take case 4, and make it the top priority, like so:</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> IconTree <span style="color: #0066CC;">extends</span> Tree<br />
<span style="color: #66cc66;">&#123;</span><br />
override <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> itemToIcon<span style="color: #66cc66;">&#40;</span>item:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #000000; font-weight: bold;">Class</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>item == <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">null</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> icon:<span style="color: #66cc66;">*</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> open:<span style="color: #0066CC;">Boolean</span> = isItemOpen<span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> branch:<span style="color: #0066CC;">Boolean</span> = isBranch<span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> uid:<span style="color: #0066CC;">String</span> = itemToUID<span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//first lets check the component</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> iconClass:<span style="color: #000000; font-weight: bold;">Class</span> =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; itemIcons <span style="color: #66cc66;">&amp;&amp;</span> itemIcons<span style="color: #66cc66;">&#91;</span>uid<span style="color: #66cc66;">&#93;</span> ?<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; itemIcons<span style="color: #66cc66;">&#91;</span>uid<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span>open ? <span style="color: #ff0000;">&quot;iconID2&quot;</span> : <span style="color: #ff0000;">&quot;iconID&quot;</span><span style="color: #66cc66;">&#93;</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">null</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// put precident of object and xml over</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>item is <span style="color: #0066CC;">XML</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">try</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span>.<span style="color: #0066CC;">length</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">!</span>= 0<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;icon = <span style="color: #0066CC;">String</span><span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> <span style="color: #0066CC;">catch</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:<span style="color: #0066CC;">Error</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>item is <span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">try</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>iconField <span style="color: #66cc66;">&amp;&amp;</span> item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon = item<span style="color: #66cc66;">&#91;</span>iconField<span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>item.<span style="color: #006600;">icon</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon = item.<span style="color: #006600;">icon</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> &nbsp;<span style="color: #0066CC;">catch</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:<span style="color: #0066CC;">Error</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>icon == <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>iconClass<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> iconClass;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>iconFunction <span style="color: #66cc66;">!</span>= <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> iconFunction<span style="color: #66cc66;">&#40;</span>item<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>branch<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0066CC;">getStyle</span><span style="color: #66cc66;">&#40;</span>open ? <span style="color: #ff0000;">&quot;folderOpenIcon&quot;</span> : <span style="color: #ff0000;">&quot;folderClosedIcon&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #808080; font-style: italic;">/* xml object check used to bed here */</span> <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//set default leaf icon if nothing else was found</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>icon == <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; icon = <span style="color: #0066CC;">getStyle</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;defaultLeafIcon&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//convert to the correct type and class</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>icon is <span style="color: #000000; font-weight: bold;">Class</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> icon;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>icon is <span style="color: #0066CC;">String</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; iconClass = <span style="color: #000000; font-weight: bold;">Class</span><span style="color: #66cc66;">&#40;</span>systemManager.<span style="color: #006600;">getDefinitionByName</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">String</span><span style="color: #66cc66;">&#40;</span>icon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>iconClass<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> iconClass;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> document<span style="color: #66cc66;">&#91;</span>icon<span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">else</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">Class</span><span style="color: #66cc66;">&#40;</span>icon<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></tbody></table></div>
<p>If you look at line 21 you&#8217;ll see that now we&#8217;re putting the logic to use the iconField as priority 1. All should be gravy right? Not so fast&#8230;</p>
<p><strong>Attempted access of inaccessible property isBranch through a reference with static type cloudtv.components:IconTree</strong></p>
<p>Unfortunately, isBranch (used on line 12) is private function in Tree, therefore we cannot use it in our custom component. We could if isBranch was protected (or public). In fact I don&#8217;t really see a reason for any method to ever be private, but dont get me started on that&#8230;</p>
<p>Anyway, there&#8217;s any easy, although not so elegant solution to this problem: copy &#038; paste. If we just copy the method isBranch to our new component everything works just fine and we have exactly what we want by using our custom component (I call it IconTree). Take a look see:</p>
<p><img alt="" src="http://img.skitch.com/20090917-k2jbpk2dyre24rnyci8ctjj9qd.jpg" title="Tree Menu Correct" class="alignnone" width="227" height="80" /></p>
<p>That wasn&#8217;t that hard was it? Well it was kind of a pain, but at least we got the result we wanted =) </p>
<p>In case you find this particular case useful here is link to the entire componenent: <a href='http://mchristoff.com/wp-content/uploads/2009/08/IconTree.as'>IconTree.as</a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fmchristoff.com%2F2009%2F08%2Fextending-flex-3-components%2F&amp;linkname=Extending%20Flex%203%20Components"><img src="http://mchristoff.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://mchristoff.com/2009/08/extending-flex-3-components/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
