<?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/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>AaronHardy.com &#187; Flex</title>
	<atom:link href="http://aaronhardy.com/tag/flex/feed/" rel="self" type="application/rss+xml" />
	<link>http://aaronhardy.com</link>
	<description>For all your Aaron Hardy needs.</description>
	<lastBuildDate>Fri, 20 Apr 2012 14:53:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>JavaScript for the Flex Dev Slides</title>
		<link>http://aaronhardy.com/flex/javascript-for-flex-devs-slides/</link>
		<comments>http://aaronhardy.com/flex/javascript-for-flex-devs-slides/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 02:02:04 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[backbonejs]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[requirejs]]></category>
		<category><![CDATA[underscorejs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1351</guid>
		<description><![CDATA[Presented at 360&#124;Flex 2012 in Denver, Colorado. View slides as PDF]]></description>
			<content:encoded><![CDATA[<p>Presented at <a href="http://www.360flex.com/" target="_blank">360|Flex</a> 2012 in Denver, Colorado.</p>
<div style="width:100%" id="__ss_12565929"><object id="__sse12565929" width="100%" height="480"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=javascriptforflexdevs-120416205021-phpapp02&#038;stripped_title=javascript-for-flex-devs&#038;userName=Aaronius" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><param name="wmode" value="transparent"/><embed name="__sse12565929" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=javascriptforflexdevs-120416205021-phpapp02&#038;stripped_title=javascript-for-flex-devs&#038;userName=Aaronius" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="100%" height="480"></embed></object></div>
<p><a href='http://aaronhardy.com/wp-content/uploads/2012/04/JavaScriptForFlexDevs.pdf'>View slides as PDF</a></p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/javascript-for-flex-devs-slides/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Speaking on JavaScript at 360&#124;Flex 2012</title>
		<link>http://aaronhardy.com/flex/speaking-on-javascript-at-360flex-2012/</link>
		<comments>http://aaronhardy.com/flex/speaking-on-javascript-at-360flex-2012/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 05:14:19 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[360|Flex]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[speaker]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1154</guid>
		<description><![CDATA[It&#8217;s almost time for another 360&#124;Flex conference! This conference will be held in Denver, Colorado, April 15-18, 2012. Get your tickets fast while discounts are available! It&#8217;s always a huge opportunity to learn new things and get in touch and have fun with the community. I&#8217;ve accepted the honor of speaking at this year&#8217;s conference [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s almost time for another <a href="http://www.360flex.com/" target="_blank">360|Flex</a> conference! This conference will be held in Denver, Colorado, April 15-18, 2012.  Get your tickets fast while discounts are available! It&#8217;s always a huge opportunity to learn new things and get in touch and have fun with the community.</p>
<p>I&#8217;ve accepted the honor of speaking at this year&#8217;s conference and will be speaking on JavaScript on Wednesday at 10:50am.  As you probably know, the Adobe community has really been shaken up over the last few months.  Adobe&#8217;s position on Flash and Flex has morphed and many engineers are taking a closer look at other technologies.  While JavaScript holds a stigma of being a red-headed step-child from the same orphanage as ActionScript 1, many see it as the inevitable future of the web.  While the language hasn&#8217;t evolved much, libraries and patterns have shaped up to help provide an environment conducive to building robust, dynamic enterprise apps.  We&#8217;ll discuss these libraries and patterns, learn how they relate to Flex, and make a comfortable home away from home.</p>
<p>Many of the concepts will be pulled from the <a href="/javascript/javascript-architecture-the-basics/" target="_blank">JavaScript architecture series</a> I recently started. Also, while I am a software engineer at Adobe, my thoughts are my own and do not represent those of Adobe.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/speaking-on-javascript-at-360flex-2012/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Collections And Chaining For Separate Presentation</title>
		<link>http://aaronhardy.com/flex/collections-and-chaining-for-separate-presentation/</link>
		<comments>http://aaronhardy.com/flex/collections-and-chaining-for-separate-presentation/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 19:25:07 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[ArrayCollection]]></category>
		<category><![CDATA[ArrayList]]></category>
		<category><![CDATA[collection chaining]]></category>
		<category><![CDATA[ICollectionView]]></category>
		<category><![CDATA[IList]]></category>
		<category><![CDATA[ListCollectionView]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=897</guid>
		<description><![CDATA[The purpose of this post is to describe the various collection data structures used in Flex and how they relate. Once we understand that, we&#8217;ll look at a problem I see commonly in Flex apps regarding separate collection presentations and how to fix it. Collection Structures First of all, there are a few &#8220;list-like&#8221; data [...]]]></description>
			<content:encoded><![CDATA[<p>The purpose of this post is to describe the various collection data structures used in Flex and how they relate.  Once we understand that, we&#8217;ll look at a problem I see commonly in Flex apps regarding separate collection presentations and how to fix it.<span id="more-897"></span></p>
<h3>Collection Structures</h3>
<p>First of all, there are a few &#8220;list-like&#8221; data structures that you should be aware of.  I&#8217;ll cover some of the basics of each.  I&#8217;m going to omit some classes and details for simplicity.</p>
<ul>
<li><strong><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html" target="_blank">Array</a></strong> &#8211; A list/collection of objects.</li>
<li><strong><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/collections/ArrayList.html" target="_blank">ArrayList</a></strong> &#8211; Wraps (does not extend) an Array and adds event listeners to all of its items.  When the items inside change (are added, removed, or one of their properties is modified), the ArrayList dispatches events so that a component like a List or DataGroup can know it should update its view.</li>
<li><strong><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/collections/ListCollectionView.html" target="_blank">ListCollectionView</a></strong> &#8211; Wraps (does not extend) an ArrayList and adds sorting, filtering, and cursor functionality.  When a filter is applied, all the items remain intact under the hood, it&#8217;s just that they&#8217;re not &#8220;seen&#8221; (hence why it&#8217;s called a collection view) by outside code.  In other words, if a component uses a ListCollectionView as its data provider and the ListCollectionView has a filter, only items passing the filter criteria will show up in the component.</li>
<li><strong><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/collections/ArrayCollection.html" target="_blank">ArrayCollection</a></strong> &#8211; Extends ListCollectionView and allows you to set its source using an Array instead of an ArrayList.  Technically, it just takes the Array and wraps it in an ArrayList for you.  The ListCollectionView code takes it from there.</li>
</ul>
<p>This is the basic relation of these structures.  Now let&#8217;s look at a couple flex collection interfaces and how they fit in.</p>
<ul>
<li><strong><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/collections/IList.html" target="_blank">IList</a></strong> &#8211; Spark dataprovider components (List, DataGroup, ComboBox, etc.) take IList structures only.  IList provides basic access and manipulation methods based on index and, though the interface can&#8217;t enforce it, IList objects generally dispatch CollectionEvent.COLLECTION_CHANGE events to notify the components when internal items have changed so the components can update their views.</li>
<li><strong><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/collections/ICollectionView.html" target="_blank">ICollectionView</a></strong> &#8211; Provides methods and properties for filters, sorts, and cursors.</li>
</ul>
<p>Now let&#8217;s bring this all together.</p>
<p>An Array does not implement IList.  This means you can&#8217;t use it directly in a spark data provider component.  Even if you could, if any of its objects were added, removed, or modified, the component would not know about it because an Array doesn&#8217;t dispatch events.</p>
<p>ArrayList does implement IList.  This means it can be used directly as a data provider component.  If you want to send an Array into a spark data provider component and keep things as light as possible, you can wrap it in an ArrayList and send it in.  As I said before, ArrayList handles dispatching the events needed for the component to be aware of any changes.  One potential downer about ArrayList is it doesn&#8217;t support for&#8230;each loops.</p>
<p>ListCollectionView also implements IList and also implements ICollectionView.  I said before it wraps an ArrayList.  While that&#8217;s generally true, it really can wrap any IList.  So, it&#8217;s an IList itself (so it can be used as a data provider) and it wraps another IList.  ListCollectionView extends Proxy and adds the needed proxy functions to support for&#8230;each loops.  In the end, if you don&#8217;t need sorts, filters, or cursors, the ListCollectionView is likely extra baggage.  </p>
<p>ArrayCollection extends ListCollectionView which likewise means it implements IList and ICollectionView and inherits ListCollectionView&#8217;s functionality.</p>
<p>I&#8217;ve explained these things so you (1) will have a better understanding of what you&#8217;re using, (2) can make more efficient use of the structures, (3) and can make structures of your own that better suite your needs.</p>
<h3>Chaining Collections for Separate Presentation</h3>
<p>One other reason is because it comes into play in a common problem I&#8217;ve seen in Flex apps.  Here&#8217;s an all-too-common scenario: an app loads a list of widgets from the server as an ArrayCollection which it then places on a model that&#8217;s generally available in the app.  In the store portion of the app, users can filter widgets by name by typing in a filter text input.  When the user types a few characters, the store filters the ArrayCollection (the original one pulled from the server) down to only those widgets whose name matches the user&#8217;s input.</p>
<p>At this point or shortly thereafter, some code somewhere else in the app inevitably expects the ArrayCollection to not be filtered. Maybe it&#8217;s a different view in the app that always shows all widgets&#8211;or at least is supposed to.  Because the ArrayCollection has been filtered and is shared in both views, both views show the filtered widgets.</p>
<p>Or&#8230;maybe some code in another portion of the app attempts to access one of the widgets from the ArrayCollection.  If the widget it&#8217;s trying to access has been filtered from of the ArrayCollection&#8217;s &#8220;view&#8221; (not to be confused with a user interface) by the store, there are going to be issues.</p>
<p>So, what&#8217;s the solution?  Use a separate ICollectionView when supporting sorts or filters that shouldn&#8217;t affect other parts of the app.  The underlying data model for the view, however, can be shared.   In the example, you would instantiate a new ArrayCollection or ListCollectionView and set the list property using same the list which the original ArrayCollection wraps.  Since both ICollectionViews now wrap the same ArrayList, if you add or remove an object from the original, app-wide collection it will also do likewise on the store-only collection.  However, if you set a filter or sort on the store collection, it will not apply the filter or sort on the app-wide collection.  This is exactly what we want.</p>
<p>Code says a thousand words, so let&#8217;s see this in action.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>?<span style="color: #0066CC;">xml</span> <span style="color: #0066CC;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> encoding=<span style="color: #ff0000;">&quot;utf-8&quot;</span>?<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>s:WindowedApplication xmlns:fx=<span style="color: #ff0000;">&quot;http://ns.adobe.com/mxml/2009&quot;</span> 
					   xmlns:s=<span style="color: #ff0000;">&quot;library://ns.adobe.com/flex/spark&quot;</span> 
					   xmlns:mx=<span style="color: #ff0000;">&quot;library://ns.adobe.com/flex/mx&quot;</span>
					   initialize=<span style="color: #ff0000;">&quot;createBaseCollection();&quot;</span><span style="color: #66cc66;">&gt;</span>
	<span style="color: #66cc66;">&lt;</span>fx:Script<span style="color: #66cc66;">&gt;</span>
		<span style="color: #66cc66;">&lt;!</span><span style="color: #66cc66;">&#91;</span>CDATA<span style="color: #66cc66;">&#91;</span>
			<span style="color: #0066CC;">import</span> mx.<span style="color: #006600;">collections</span>.<span style="color: #006600;">ArrayCollection</span>;
			<span style="color: #0066CC;">import</span> mx.<span style="color: #006600;">collections</span>.<span style="color: #006600;">ListCollectionView</span>;
&nbsp;
			<span style="color: #66cc66;">&#91;</span>Bindable<span style="color: #66cc66;">&#93;</span>
			protected <span style="color: #000000; font-weight: bold;">var</span> baseCollection:ArrayCollection;
&nbsp;
			<span style="color: #66cc66;">&#91;</span>Bindable<span style="color: #66cc66;">&#93;</span>
			protected <span style="color: #000000; font-weight: bold;">var</span> filteredCollection:ListCollectionView;
&nbsp;
			protected <span style="color: #000000; font-weight: bold;">function</span> createBaseCollection<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
			<span style="color: #66cc66;">&#123;</span>
				baseCollection = <span style="color: #000000; font-weight: bold;">new</span> ArrayCollection<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
				<span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> i:uint; i <span style="color: #66cc66;">&lt;</span> <span style="color: #cc66cc;">100</span>; i++<span style="color: #66cc66;">&#41;</span>
				<span style="color: #66cc66;">&#123;</span>
					<span style="color: #000000; font-weight: bold;">var</span> widget:Widget = <span style="color: #000000; font-weight: bold;">new</span> Widget<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
					widget.<span style="color: #0066CC;">name</span> = <span style="color: #ff0000;">&quot;Widget &quot;</span> + <span style="color: #66cc66;">&#40;</span>i + <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
					widget.<span style="color: #006600;">price</span> = <span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">random</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span>;
					baseCollection.<span style="color: #006600;">addItem</span><span style="color: #66cc66;">&#40;</span>widget<span style="color: #66cc66;">&#41;</span>;
				<span style="color: #66cc66;">&#125;</span>
			<span style="color: #66cc66;">&#125;</span>
&nbsp;
			protected <span style="color: #000000; font-weight: bold;">function</span> createAndFilterSeparateCollection<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
			<span style="color: #66cc66;">&#123;</span>
				filteredCollection = <span style="color: #000000; font-weight: bold;">new</span> ListCollectionView<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
				filteredCollection.<span style="color: #0066CC;">list</span> = baseCollection.<span style="color: #0066CC;">list</span>;
&nbsp;
				filteredCollection.<span style="color: #006600;">filterFunction</span> = filterWidgets;
				filteredCollection.<span style="color: #006600;">refresh</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span>
&nbsp;
			protected <span style="color: #000000; font-weight: bold;">function</span> filterWidgets<span style="color: #66cc66;">&#40;</span>item:Widget<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">Boolean</span>
			<span style="color: #66cc66;">&#123;</span>
				<span style="color: #b1b100;">return</span> item.<span style="color: #006600;">price</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">50</span>;
			<span style="color: #66cc66;">&#125;</span>
&nbsp;
			protected <span style="color: #000000; font-weight: bold;">function</span> addWidget<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
			<span style="color: #66cc66;">&#123;</span>
				<span style="color: #000000; font-weight: bold;">var</span> newWidget:Widget = <span style="color: #000000; font-weight: bold;">new</span> Widget<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
				newWidget.<span style="color: #0066CC;">name</span> = <span style="color: #ff0000;">'NewWidget'</span>;
				newWidget.<span style="color: #006600;">price</span> = <span style="color: #cc66cc;">90</span>;
				baseCollection.<span style="color: #006600;">addItemAt</span><span style="color: #66cc66;">&#40;</span>newWidget, <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span>
		<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&gt;</span>
	<span style="color: #66cc66;">&lt;/</span>fx:Script<span style="color: #66cc66;">&gt;</span>
&nbsp;
	<span style="color: #66cc66;">&lt;</span>s:layout<span style="color: #66cc66;">&gt;</span>
		<span style="color: #66cc66;">&lt;</span>s:VerticalLayout<span style="color: #66cc66;">/&gt;</span>
	<span style="color: #66cc66;">&lt;/</span>s:layout<span style="color: #66cc66;">&gt;</span>
&nbsp;
	<span style="color: #66cc66;">&lt;</span>s:<span style="color: #0066CC;">Button</span> label=<span style="color: #ff0000;">&quot;Create Filtered Collection&quot;</span> click=<span style="color: #ff0000;">&quot;createAndFilterSeparateCollection()&quot;</span><span style="color: #66cc66;">/&gt;</span>
	<span style="color: #66cc66;">&lt;</span>s:<span style="color: #0066CC;">Button</span> label=<span style="color: #ff0000;">&quot;Add Widget&quot;</span> click=<span style="color: #ff0000;">&quot;addWidget();&quot;</span><span style="color: #66cc66;">/&gt;</span>
&nbsp;
	<span style="color: #66cc66;">&lt;</span>s:HGroup<span style="color: #66cc66;">&gt;</span>
		<span style="color: #66cc66;">&lt;</span>s:<span style="color: #0066CC;">List</span> dataProvider=<span style="color: #ff0000;">&quot;{baseCollection}&quot;</span> labelField=<span style="color: #ff0000;">&quot;name&quot;</span><span style="color: #66cc66;">/&gt;</span>
		<span style="color: #66cc66;">&lt;</span>s:<span style="color: #0066CC;">List</span> dataProvider=<span style="color: #ff0000;">&quot;{filteredCollection}&quot;</span> labelField=<span style="color: #ff0000;">&quot;name&quot;</span><span style="color: #66cc66;">/&gt;</span>
	<span style="color: #66cc66;">&lt;/</span>s:HGroup<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;/</span>s:WindowedApplication<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>In the code sample, we see our baseCollection being created within createBaseCollection().  This represents the ArrayCollection that&#8217;s being shared throughout the app.  This doesn&#8217;t need to be an ArrayCollection; it could just be a ListCollectionView or ArrayList.  The baseCollection then shows up in the left list component.  When you click on the Create Filtered Collection button, it calls createAndFilterSeparateCollection() which creates a <i>separate</i> ListCollectionView <i>using the underlying ArrayList that baseCollection is using</i>.</p>
<p>This is important.  This is a new, separate collection view for the same underlying data model.  When this new collection view is filtered, it doesn&#8217;t affect baseCollection.  This means the left list component will show all widgets while the right list component will show a only a subset of the widgets.  But, because they use the same underlying data model (ArrayList), if we add a widget to baseCollection, baseCollection will add it to the underlying data model, which will notify filteredCollection.  If filteredCollection finds that the widget passes the currently applied filter criteria, the widget will show up in its collection view.  This is why, if you click the Add Widget button, you will see the new widget show up in both list components even though addWidget() is only directly adding the widget to baseCollection.</p>
<p>I hope this helps someone out there avoid collection view woes in their app.  Be sure to add a comment if I messed something up or you have a question.  Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/collections-and-chaining-for-separate-presentation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Free Flex Classes in Utah</title>
		<link>http://aaronhardy.com/flex/free-flex-classes-in-utah/</link>
		<comments>http://aaronhardy.com/flex/free-flex-classes-in-utah/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 18:29:21 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[learn]]></category>
		<category><![CDATA[Utah]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=773</guid>
		<description><![CDATA[If you&#8217;re interesting in learning Flex and live in Utah, feel free to join us in American Fork for free classes. Visit our Utah Flex Class Google group to learn more.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re interesting in learning Flex and live in Utah, feel free to join us in American Fork for free classes.  Visit our <a href="http://groups.google.com/group/utahflexclass" target="_blank">Utah Flex Class</a> Google group to learn more.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/free-flex-classes-in-utah/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RedLiteGreenLite</title>
		<link>http://aaronhardy.com/flex/redlitegreenlite/</link>
		<comments>http://aaronhardy.com/flex/redlitegreenlite/#comments</comments>
		<pubDate>Sun, 30 May 2010 21:44:42 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[General Programming]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[amf]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[Google Apps Engine]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[messaging]]></category>
		<category><![CDATA[polling]]></category>
		<category><![CDATA[remoting]]></category>
		<category><![CDATA[RobotLegs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=658</guid>
		<description><![CDATA[Please upgrade your Flash Player This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed. What is it? RedLiteGreenLite is a small, simple app that allows a group of people to communicate the status of something. The status can be either red or green and [...]]]></description>
			<content:encoded><![CDATA[<p><div id="flashcontent9459" style="width:215px; height:180px;"><strong>Please upgrade your Flash Player</strong> This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.</div><script type="text/javascript">
<!-- // <![CDATA[
var so = new SWFObject("http://aaronhardy.com/wp-content/plugins/air-badge/AIRInstallBadge.swf", "Badge", "215", "180", "9.0.115", "#343434");
so.useExpressInstall("http://aaronhardy.com/wp-content/plugins/air-badge/expressinstall.swf");
so.addVariable("airversion", "1.0");
so.addVariable("appname", "RedLiteGreenLite");
so.addVariable("appurl", "http://aaronhardy.com/rlgl/RedLiteGreenLite.air");
so.addVariable("appid", "RedLiteGreenLite");
so.addVariable("pubid", "");
so.addVariable("appversion", ".5");
so.addVariable("imageurl", "/rlgl/rlglinstallbadge.jpg");
so.addVariable("appinstallarg", "installed from web");
so.addVariable("applauncharg", "launched from web");
so.addVariable("helpurl", "help.html");
so.addVariable("hidehelp", "true");
so.addVariable("skiptransition", "false");
so.addVariable("titlecolor", "#00AAFF");
so.addVariable("buttonlabelcolor", "#00AAFF");
so.addVariable("appnamecolor", "#00AAFF");
so.addVariable("str_err_airswf", "<u>Running locally?</u><br/><br/>The AIR proxy swf won't load properly when this is run from the local file system.");
so.write("flashcontent9459");
// ]]&gt; -->
</script>
</p>
<h3>What is it?</h3>
<p>RedLiteGreenLite is a small, simple app that allows a group of people to communicate the status of something.  The status can be either red or green and the subject can be whatever.  That may sound a bit general, but that&#8217;s the point.  It can be used for whatever purpose your crazy mind can come up with.  I&#8217;ll get you started:</p>
<ol>
<li>At work, we have a single shower and a lot of shweaty guys after soccer.  So we know when the shower&#8217;s available, someone can turn the status red when he enters the shower and turn it green when he exits.  This way nobody has to keep stopping by the shower to see if it&#8217;s available.  When it&#8217;s green, it&#8217;s available.   When it&#8217;s red, it&#8217;s not.</li>
<li>At a call center, representatives are split into groups. When one group is on break, no other group is allowed to go on break.  Again, when the status is red, a group is on break and other groups must continue attending the phones.  When the lite is green, the next group is free to take a break.</li>
</ol>
<p>The process is pretty simple: join a group.  Other people join the same group.  When others in the group change the status, you&#8217;ll be notified.  When you change the status, others in the group will be notified.  The status of the group will be persisted across sessions.  In other words, if everyone logs out and then logs back in a week later, the status will remain as it was the last time it was set.<span id="more-658"></span></p>
<p>There&#8217;s no need to explicitly create a group.  When you attempt to join a group, the group will automatically be created if it does not already exist.</p>
<p>The app is free.  As in free free.</p>
<h3>What technologies are used?</h3>
<p>RedLiteGreenLite has a client portion and a server portion.</p>
<p>The client is the app users download and install on their computers.  It&#8217;s built in <a href="http://www.adobe.com/products/flex/" target="_blank">Flex</a> and published for <a href="http://www.adobe.com/products/air/" target="_blank">AIR</a>.  It uses the <a href="http://www.robotlegs.org/" target="_blank">RobotLegs</a> MVCS framework and makes use of <a href="http://en.wikipedia.org/wiki/Action_Message_Format" target="_blank">AMF</a> remoting and messaging.</p>
<p>The server portion is built in <a href="http://www.java.com/en/" target="_blank">Java</a> using <a href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/" target="_blank">BlazeDS</a> and is hosted on <a href="http://code.google.com/appengine/" target="_blank">Google Apps Engine</a>.</p>
<h3>Ooh, that&#8217;s simply juicy.  Tell me more.</h3>
<p>Don&#8217;t mind if I do.  First of all, BlazeDS is an open source implementation of AMF-based remoting and messaging.  Natively it&#8217;s not compatible with Google Apps Engine, but I wanted to use GAE because it&#8217;s extremely scalable, it&#8217;s free (let&#8217;s be honest&#8211;I&#8217;m cheap like that&#8211;this is the main reason), and I wanted the challenge.</p>
<p>To get BlazeDS working on GAE, I recommend following <a href="http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html" target="_blank">Martin Zoldano&#8217;s blog post</a>.  Not only does he outline the steps you&#8217;ll need to take but he provides a critical patch to flex-messaging-core.jar as well.  While you can find this patch re-distributed elsewhere, I recommend posting a comment requesting that he email you the patched jar.  That&#8217;s how he seems to want to distribute his patch and I respect that.  He&#8217;s really helpful and quick to respond so it shouldn&#8217;t be much trouble.</p>
<p>Once BlazeDS was set up and configured, I started to plan the architecture.  First of all, I needed one client in the group to be able to send a message to the rest of the clients in the group.  This could be achieved through the messaging service BlazeDS provides.  However, messaging doesn&#8217;t store state; it just redistributes messages to clients.  I needed the group&#8217;s status to be persisted to storage so (1) when a new client joins a group it can retrieve the group&#8217;s current status and (2) the group&#8217;s status can be retained even when no clients are connected.</p>
<p>By default, BlazeDS&#8217;s messaging configuration uses ActionScriptAdapter to receive and distribute messages between clients.  It doesn&#8217;t persist messages.  To do so, I extend ActionScriptAdapter and persist the status to Google Storage before sending the message out to the other clients.  When clients connect to BlazeDS, they use remoting (not messaging) to retrieve the most recently persisted status for the group.  After the initial status is retrieved, the client talks to other clients using the messaging service.  You can see how this is set up in messaging-config.xml and PersistentASAdapter.java in the <a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">server code</a>.</p>
<p>While GAE has been really nice to get the app up and running, it does have its downsides.  To send messages between clients, BlazeDS can use a few different techniques:</p>
<ul>
<li>Simple polling. The client, at a standard interval, simply asks the server if there is any new information.  The server responds to the request immediately regardless of whether there is new information.</li>
<li>Long polling. The client sends a request to the server.  The server holds onto the request until it has something useful to tell the client at which time it sends back the response.</li>
<li>Streaming.  The client opens an HTTP connection and the connection remains open.  The server shoots messages down the connection whenever it has something to say.  It&#8217;s an &#8220;infinate response&#8221;.</li>
</ul>
<p>While <a href="http://www.dcooper.org/blog/client/index.cfm?mode=entry&#038;entry=8E1439AD-4E22-1671-58710DD528E9C2E7" target="_blank">each approach has its pros and cons</a>, simple polling leaves a lot to be desired as it creates a lot of HTTP traffic.  Unfortunately, from my testing and research, GAE doesn&#8217;t seem to support either of the other two methods.  But hey, it&#8217;s free.  If any of you have a java environment and would like to host RedLiteGreenLite so we can step up our game, let me know.</p>
<p>Last but not least, RedLiteGreenLite is open source.  I&#8217;d love for you to <a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">fork the project</a> and do something cool with it.</p>
<p>Now go have fun!  Install the client using the badge at the top of the post or fork the project using the link below.</p>
<div class="goodies"><a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/redlitegreenlite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ImageInspector: An Image Zoom &amp; Pan Component</title>
		<link>http://aaronhardy.com/flex/imageinspector-an-image-zoom-pan-component/</link>
		<comments>http://aaronhardy.com/flex/imageinspector-an-image-zoom-pan-component/#comments</comments>
		<pubDate>Wed, 12 May 2010 03:11:15 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[inspect]]></category>
		<category><![CDATA[pan]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[scroll]]></category>
		<category><![CDATA[zoom]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=606</guid>
		<description><![CDATA[This type of component is becoming quite popular these days and for good reason: it makes it extremely easy to quickly zoom in and pan around an image. I imagine most all of us have seen an example of this but I&#8217;ve never found the code for one that suits my fancy. So here you [...]]]></description>
			<content:encoded><![CDATA[<p>This type of component is becoming quite popular these days and for good reason: it makes it extremely easy to quickly zoom in and pan around an image.  I imagine most all of us have seen an example of this but I&#8217;ve never found the code for one that suits my fancy.  So here you go.  Here are some possibly unique features I wanted and implemented along with the usual goodies:<span id="more-606"></span></p>
<p>ImageInspector works with images of any aspect ratio.  Also, you&#8217;ll notice the picture-in-picture will size itself to the aspect ratio of the image.  Just set maxWidth and maxHeight and it won&#8217;t get larger than those dimensional limits.</p>
<p>The focal point is maintained during scaling.  For example, zoom in, move the focal point to the corner of the image, zoom out, then zoom in.  Notice that, as you zoom out and in, the focal point is maintained as much as possible.</p>
<p>The focal point and relative scale are both maintained during resizing.  For example, if an image inside ImageInspector is at 200% of its &#8220;fit&#8221; size, ImageInspector is 100% width and height of the window, and the user starts making the window larger, ImageInspector will continue to scale up the image inside it, attempting to keep it at 200% of its &#8220;fit&#8221; size.  Likewise, the focal point will be maintained while resizing the window as well.</p>
<p>Right-click <a href="/samples/imageinspector/Main.html" target="_blank">the demo app</a> to view the source.  The app might take a little while to load because it contains two embedded high-res images.</p>
<div class="goodies"><a href="/samples/imageinspector/Main.html" target="_blank">View Demo</a><a href="http://github.com/Aaronius/ImageInspector" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/imageinspector-an-image-zoom-pan-component/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Container Panner</title>
		<link>http://aaronhardy.com/flex/container-panner/</link>
		<comments>http://aaronhardy.com/flex/container-panner/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 04:03:47 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[drag]]></category>
		<category><![CDATA[pan]]></category>
		<category><![CDATA[scroll]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=535</guid>
		<description><![CDATA[In Flex, the ability to scroll a container is commonplace. The ability to pan a container is not. By panning a container, I mean clicking down and dragging the content area, effectively scrolling the container. I present the container panner. It&#8217;s a single class. Instantiate it and set the container property. That&#8217;s it. If you [...]]]></description>
			<content:encoded><![CDATA[<p>In Flex, the ability to scroll a container is commonplace.  The ability to pan a container is not.  By panning a container, I mean clicking down and dragging the content area, effectively scrolling the container.</p>
<p>I present the container panner.  It&#8217;s a single class.  Instantiate it and set the container property.  That&#8217;s it.  If you want, you can toggle the panning functionality and set custom cursors.  Right-click to view the source.  Go make something crazy.</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_Main_111638851"
			class="flashmovie"
			width="100%"
			height="300">
	<param name="movie" value="/samples/containerpanner/Main.swf" />
	<param name="base" value="/samples/containerpanner/" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/samples/containerpanner/Main.swf"
			name="fm_Main_111638851"
			width="100%"
			height="300">
		<param name="base" value="/samples/containerpanner/" />
	<!--<![endif]-->
		
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="goodies"><a href="http://github.com/Aaronius/ContainerPanner" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/container-panner/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Greener Pastures</title>
		<link>http://aaronhardy.com/life-in-general/greener-pastures/</link>
		<comments>http://aaronhardy.com/life-in-general/greener-pastures/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 19:41:01 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Life in General]]></category>
		<category><![CDATA[best dance you have ever personally witnessed]]></category>
		<category><![CDATA[cup dancer]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[quiznos]]></category>
		<category><![CDATA[quiznos cup]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=515</guid>
		<description><![CDATA[You may have already figured out that Flex development is my primary skill these days. I would say I develop, talk, dream, or think about Flex a large majority of each living day. Today, I&#8217;ve decided to branch out into other skills. Effective immediately, I&#8217;m extending an invitation to all Quiznos franchisees to contact me [...]]]></description>
			<content:encoded><![CDATA[<p>You may have already figured out that Flex development is my primary skill these days.  I would say I develop, talk, dream, or think about Flex a large majority of each living day.  Today, I&#8217;ve decided to branch out into other skills.</p>
<p>Effective immediately, I&#8217;m extending an invitation to all Quiznos franchisees to <a href="/contact-me" target="_blank">contact me</a> for employment as a Quiznos Cup Dancer.  But here are my demands:</p>
<ul>
<li>I must wear the Quiznos cup (<a href="http://aaronhardy.com/wp-content/uploads/2010/03/quiznos_cup.jpg" target="_blank">illustrated here</a>).</li>
<li>I must pay you, Quiznos, the hourly wage you would normally pay a Quiznos Cup Dancer.</li>
<li>I must wear it for a single hour, after which I may and will terminate my employment.</li>
<li>I must commit my full efforts to provide the best Quiznos Cup Dance you have ever personally witnessed.</li>
</ul>
<p><a href="/contact-me" target="_blank">Contact me.</a>  I&#8217;m waiting.  Little Caesars franchisees need not apply.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/life-in-general/greener-pastures/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Queue N Cache</title>
		<link>http://aaronhardy.com/flex/queue-n-cache/</link>
		<comments>http://aaronhardy.com/flex/queue-n-cache/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 00:18:36 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[360|Flex]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[cacheAsBitmap]]></category>
		<category><![CDATA[queue]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=415</guid>
		<description><![CDATA[As promised, below you can find the source code and slides from my Queue N Cache presentation from the 360&#124;Flex conference. For those who were there, thanks for coming. I really enjoy learning with you all and being able to share when I can. First, the demo application for queuing and caching. Keep in mind [...]]]></description>
			<content:encoded><![CDATA[<p>As promised, below you can find the source code and slides from my Queue N Cache presentation from the <a href="http://www.360flex.com/" target="_blank">360|Flex conference</a>.  For those who were there, thanks for coming.  I really enjoy learning with you all and being able to share when I can.</p>
<p>First, the <a href="/samples/queuencache/queuencache/QueueNCache.html" target="_blank">demo application</a> for queuing and caching.  Keep in mind that images loaded into the application will be cached in the browser, so depending on what you&#8217;re wanting to test you may need to clear your browser cache between tests.  Right-click the application to access the source.</p>
<p>Second, the presentation slides.  Here they are as a &#8220;slidecast&#8221; but they&#8217;re a little different than the live ones.  I think the live video will be made available shortly so if you&#8217;re looking for that check back later.  Also, this slidecast was made through SlideShare and their audio-syncing tool is a little limiting so the audio might get unsynced for a moment.  In any case, enjoy!<span id="more-415"></span></p>
<div id="__ss_3331486" style="width: 100%;"><object width="100%" height="470" data="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presoforweb-100303223327-phpapp01&amp;rel=0&amp;stripped_title=queue-n-cache-3331486" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presoforweb-100303223327-phpapp01&amp;rel=0&amp;stripped_title=queue-n-cache-3331486" /><param name="allowfullscreen" value="true" /></object></div>
<div class="goodies"><a href="/samples/queuencache/queuencache/QueueNCache.html" target="_blank">View Demo</a><a href="http://github.com/Aaronius/QueueNCache" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/queue-n-cache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sneak Peek: Queue N Cache</title>
		<link>http://aaronhardy.com/flex/sneak-peek-queue-n-cache/</link>
		<comments>http://aaronhardy.com/flex/sneak-peek-queue-n-cache/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 03:33:29 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[360|Flex]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[queue]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=413</guid>
		<description><![CDATA[The 360&#124;Flex conference is nigh upon us. Don&#8217;t miss out on an excellent opportunity to be one with your species and discuss all things Flex. If you haven&#8217;t yet picked up your ticket, you best get on it! The conference starts on the 7th of March and runs through the 10th in sunny San Jose, [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.360flex.com/" target="_blank">360|Flex conference</a> is nigh upon us.  Don&#8217;t miss out on an excellent opportunity to be one with your species and discuss all things Flex.  If you haven&#8217;t yet picked up your ticket, you best <a href="http://360flex-aaronh.eventbrite.com/" target="_blank">get on it</a>!  The conference starts on the 7th of March and runs through the 10th in sunny San Jose, CA.</p>
<p>This year, yours truly will be presenting the topic Queue N Cache.  With a name like that, I&#8217;m sure flexers worldwide will be scrambling for a seat.  I know I know, you&#8217;re thinking, &#8220;Queuing and caching?  That oughtta be a party.&#8221;  No.  It&#8217;s Queue <strong>*N*</strong> Cache and that&#8217;s one party that runs year-round.  Oh sure, we&#8217;ll talk a little about the ho-hum of your grandma&#8217;s queues and caches, but this is where rubber meets the road with real-world projects and situations where queuing and caching can achieve greatness.  Have you ever sat back and wondered:</p>
<ul>
<li>How could I improve user experience by paying more attention to the user&#8217;s focus?</li>
<li>How could I have greater control over my service calls and asset loaders?  Timeouts and retries?  Call me crazy.</li>
<li>How could I decrease memory usage and processing load by sharing image data?</li>
<li>How could I increase responsiveness through improved data management?</li>
<li>How could I show progress of shared image data in multiple locations?</li>
</ul>
<p>If you can&#8217;t make it (Tuesday @ 2:30) or just can&#8217;t get enough, I&#8217;ll post my slides and code after the preso and you can dig in to your heart&#8217;s content.  See you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/sneak-peek-queue-n-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

