<?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>Saturnboy &#187; flex4</title>
	<atom:link href="http://saturnboy.com/tag/flex4/feed/" rel="self" type="application/rss+xml" />
	<link>http://saturnboy.com</link>
	<description>Code, Work, and Life</description>
	<lastBuildDate>Wed, 28 Jul 2010 13:20:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>SuperTextInput &#8211; Building a Custom Component in Flex 4</title>
		<link>http://saturnboy.com/2010/07/supertextinput-building-a-custom-component/</link>
		<comments>http://saturnboy.com/2010/07/supertextinput-building-a-custom-component/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 18:59:29 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[custom component]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[skinning]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=1489</guid>
		<description><![CDATA[I&#8217;ve been building a lot of Flex 4 custom components lately, including a sliding drawer, a multiple content area container, and now SuperTextInput. Nor will this be that last, because I think I have a few more in me. I thought it would be useful to spend some time in the details, explaining The Flex [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been building a lot of Flex 4 custom components lately, including a <a href="http://saturnboy.com/2010/06/drawer-component-flex-4/">sliding drawer</a>, a <a href="http://saturnboy.com/2010/07/multiple-content-area-containers/">multiple content area container</a>, and now SuperTextInput.  Nor will this be that last, because I think I have a few more in me.  I thought it would be useful to spend some time in the details, explaining <i>The Flex 4 Way</i> and how I try to walk the path.</p>
<p>SuperTextInput is a prompting, clearable <code>TextInput</code> extension in Flex 4.  It&#8217;s just an enhanced version of the default <code>TextInput</code> control, and as such, it follows a fairly standard pattern of custom component creation.</p>
<h3>Enhanced Component Pattern</h3>
<p>It&#8217;s almost too stupid to call this a pattern, but it&#8217;s <b>so</b> common in custom component creation that I&#8217;ll run with it.  Also, I&#8217;ve found it to be worthwhile to distinguish between adding new functionality to a component already present in the framework (aka an enhanced component) versus creating a truly custom component.</p>
<p class="bottom">The enhanced component pattern is just two simple steps:</p>
<ol>
<li><b>Extend</b> &ndash; extend some default component and add some new functionality</li>
<li><b>Skin</b> &ndash; make it look good</li>
</ol>
<p>In my version of reality, these steps carry equal weight, because almost all worthwhile functionality in Flex touches the UI in some fashion, so the design and UX (the look-and-feel, it&#8217;s usability, the integration into the rest of the app, etc.) are critical. Don&#8217;t forget or skimp on step #2 because it&#8217;s all the client, team, customer ever sees.</p>
<h3>A Prompting TextInput</h3>
<p>Since SuperTextInput has two new pieces of functionality (the prompt and the clear button), I&#8217;ll split them apart, and consider each part separately.  First, the prompt is merely the text you see when the <code>TextInput</code> is empty.  It often becomes a space saving label, because it can be used to tell the user what goes into the <code>TextInput</code> without costing the UI any screen real estate.</p>
<p>Thinking more about the prompt, we want the prompt text to be visible initially, but it should disappear when the user clicks (or tabs) to the control, and only returns when the control loses focus and is still empty.  So this tells us that we need to communicate both the prompt text and it&#8217;s visibility to our skin.  The prompt text can just be a simple <code>Label</code> <code>SkinPart</code>, but it&#8217;s visibility is complicated enough that it makes sense to add a new <code>prompting</code> <code>SkinState</code>.</p>
<p class="bottom">Here&#8217;s a functioning <code>PromptingTextInput</code> custom component (which is simply the prompting code lifted from <code>SuperTextInput.as</code>):</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">package components <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">events</span>.<span style="color: #006600;">FocusEvent</span>;
    <span style="color: #0066CC;">import</span> mx.<span style="color: #006600;">events</span>.<span style="color: #006600;">FlexEvent</span>;
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">components</span>.<span style="color: #006600;">Label</span>;
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">components</span>.<span style="color: #006600;">TextInput</span>;
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">events</span>.<span style="color: #006600;">TextOperationEvent</span>;
&nbsp;
    <span style="color: #66cc66;">&#91;</span>SkinState<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;prompting&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PromptingTextInput <span style="color: #0066CC;">extends</span> TextInput <span style="color: #66cc66;">&#123;</span>
&nbsp;
        <span style="color: #66cc66;">&#91;</span>SkinPart<span style="color: #66cc66;">&#40;</span>required=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">var</span> promptDisplay:Label;
&nbsp;
        <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> _prompt:<span style="color: #0066CC;">String</span> = <span style="color: #ff0000;">''</span>;
        <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> _focused:<span style="color: #0066CC;">Boolean</span> = <span style="color: #000000; font-weight: bold;">false</span>;
&nbsp;
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> PromptingTextInput<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #808080; font-style: italic;">//watch for programmatic changes to text property</span>
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>FlexEvent.<span style="color: #006600;">VALUE_COMMIT</span>, textChangedHandler, <span style="color: #000000; font-weight: bold;">false</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #808080; font-style: italic;">//watch for user changes (aka typing) to text property</span>
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>TextOperationEvent.<span style="color: #006600;">CHANGE</span>, textChangedHandler, <span style="color: #000000; font-weight: bold;">false</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #66cc66;">&#91;</span>Bindable<span style="color: #66cc66;">&#93;</span>
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">get</span> prompt<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">String</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #b1b100;">return</span> _prompt;
        <span style="color: #66cc66;">&#125;</span>
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">set</span> prompt<span style="color: #66cc66;">&#40;</span>value:<span style="color: #0066CC;">String</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>_prompt <span style="color: #66cc66;">!</span>= value<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                _prompt = value;
                <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>promptDisplay <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>
                    promptDisplay.<span style="color: #0066CC;">text</span> = value;
                <span style="color: #66cc66;">&#125;</span>
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> textChangedHandler<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            invalidateSkinState<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        override protected <span style="color: #000000; font-weight: bold;">function</span> focusInHandler<span style="color: #66cc66;">&#40;</span>event:FocusEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span>.<span style="color: #006600;">focusInHandler</span><span style="color: #66cc66;">&#40;</span>event<span style="color: #66cc66;">&#41;</span>;
            _focused = <span style="color: #000000; font-weight: bold;">true</span>;
            invalidateSkinState<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
        override protected <span style="color: #000000; font-weight: bold;">function</span> focusOutHandler<span style="color: #66cc66;">&#40;</span>event:FocusEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span>.<span style="color: #006600;">focusOutHandler</span><span style="color: #66cc66;">&#40;</span>event<span style="color: #66cc66;">&#41;</span>;
            _focused = <span style="color: #000000; font-weight: bold;">false</span>;
            invalidateSkinState<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        override protected <span style="color: #000000; font-weight: bold;">function</span> partAdded<span style="color: #66cc66;">&#40;</span>partName:<span style="color: #0066CC;">String</span>, instance:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span>.<span style="color: #006600;">partAdded</span><span style="color: #66cc66;">&#40;</span>partName, instance<span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>instance == promptDisplay<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                promptDisplay.<span style="color: #0066CC;">text</span> = prompt;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        override protected <span style="color: #000000; font-weight: bold;">function</span> getCurrentSkinState<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">String</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>prompt.<span style="color: #0066CC;">length</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&amp;&amp;</span> <span style="color: #0066CC;">text</span>.<span style="color: #0066CC;">length</span> == <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&amp;&amp;</span> <span style="color: #66cc66;">!</span>_focused<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                <span style="color: #b1b100;">return</span> <span style="color: #ff0000;">'prompting'</span>;
            <span style="color: #66cc66;">&#125;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #0066CC;">super</span>.<span style="color: #006600;">getCurrentSkinState</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>In addition to the <code>promptDisplay</code> <code>SkinPart</code> and the new <code>prompting</code> <code>SkinState</code>, there is a lot of other stuff going on in the above code.  First, as is typical with data-driven <code>SkinPart</code>s, we back the <code>promptDisplay</code> with a good old <code>prompt</code> property.  The net is the fairly common pattern of: check if the <code>SkinPart</code> is not null, then do something to it.  So in the <code>prompt</code> setter, we assign the incoming value to the private <code>_prompt</code> variable, then check if <code>promptDisplay</code> is available and if yes, set it&#8217;s <code>text</code> property.  The setter does the job of updating the prompt, but only once everything is happily running.  In order to get the data to the skin initially, we must use the <code>partAdded()</code> override to pass the local prompt to the <code>promptDisplay</code>&#8216;s <code>text</code> property.  And that&#8217;s it for the prompt text.</p>
<p>The prompt visibility part requires lots of event watching, and also <code>SkinState</code> stuff because we made the choice to push visibility via the <code>prompting</code> <code>SkinState</code>.  First, we wire up both the programmatic text change events and the user text change events to a handler, <code>textChangedHandler()</code>, that does nothing more than invalidate the state.  <code>TextInput</code> change events are a <a href="http://stackoverflow.com/questions/283497/capturing-user-input-from-flex-textinput-control-which-event-to-use">little wacky</a>, but the code works fine.  Next, instead of wiring the focus events to another handler (as seen in this <a href="http://www.andymcintosh.com/?p=207">prompting <code>TextInput</code> component</a> by Andy McIntosh), we simply override the protected handlers in the parent and add our focus-tracking logic directly.  Finally, we override <code>getCurrentSkinState()</code> to do the work of figuring out whether or not the prompt should be displayed.</p>
<p class="bottom">A skin for <code>PromptingTextInput</code> is now trivial because our component does the work of pushing the important information to the skin.  If we ignore all the pretty stuff, the skin is very simple:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;">&lt;?xml version=<span style="color: #ff0000;">&quot;1.0&quot;</span> encoding=<span style="color: #ff0000;">&quot;utf-8&quot;</span>?<span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:SparkSkin</span> ...<span style="color: #7400FF;">&gt;</span></span>
    ...
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:states</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;normal&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;prompting&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;disabled&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:states</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:RichEditableText</span> id=<span style="color: #ff0000;">&quot;textDisplay&quot;</span> ... <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> id=<span style="color: #ff0000;">&quot;promptDisplay&quot;</span> includeIn=<span style="color: #ff0000;">&quot;prompting&quot;</span> ... <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:SparkSkin</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>We add the <code>prompting</code> <code>State</code> to the list of states and also add the <code>promptDisplay</code> <code>Label</code> component.  By using the standard inline state syntax, <code>includeIn=&quot;prompting&quot;</code> our <code>Label</code> is shown only in the <code>prompting</code> state.</p>
<h3>A Clearable TextInput</h3>
<p>The second piece of SuperTextInput functionality is the clear button.  The clear button appears when the <code>TextInput</code> has a value, and when clicked, it clears that value (which re-displays the prompt).  Again, there are two pieces of information the need to be communicated to the skin to create the clear button functionality: the button itself and it&#8217;s visibility.  In this case, since the visibility is so simple (on if <code>TextInput</code> has a value, otherwise off), we&#8217;ll just punt and manage it directly in the component.  Therefore, the only a <code>Button</code> <code>SkinPart</code> for the clear button will be pushed to the skin.</p>
<p class="bottom">Here&#8217;s a functioning <code>ClearableTextInput</code> custom component (which is simply the clear button code lifted from <code>SuperTextInput.as</code>):</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">package components <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">events</span>.<span style="color: #006600;">Event</span>;
    <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">events</span>.<span style="color: #006600;">MouseEvent</span>;
    <span style="color: #0066CC;">import</span> mx.<span style="color: #006600;">events</span>.<span style="color: #006600;">FlexEvent</span>;
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">components</span>.<span style="color: #0066CC;">Button</span>;
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">components</span>.<span style="color: #006600;">TextInput</span>;
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">events</span>.<span style="color: #006600;">TextOperationEvent</span>;
&nbsp;
    <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ClearableTextInput <span style="color: #0066CC;">extends</span> TextInput <span style="color: #66cc66;">&#123;</span>
&nbsp;
        <span style="color: #66cc66;">&#91;</span>SkinPart<span style="color: #66cc66;">&#40;</span>required=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">var</span> clearButton:<span style="color: #0066CC;">Button</span>;
&nbsp;
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> ClearableTextInput<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #808080; font-style: italic;">//watch for programmatic changes to text property</span>
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>FlexEvent.<span style="color: #006600;">VALUE_COMMIT</span>, textChangedHandler, <span style="color: #000000; font-weight: bold;">false</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #808080; font-style: italic;">//watch for user changes (aka typing) to text property</span>
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>TextOperationEvent.<span style="color: #006600;">CHANGE</span>, textChangedHandler, <span style="color: #000000; font-weight: bold;">false</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> textChangedHandler<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>clearButton<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                clearButton.<span style="color: #0066CC;">visible</span> = <span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">text</span>.<span style="color: #0066CC;">length</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> clearClick<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:MouseEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">text</span> = <span style="color: #ff0000;">''</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        override protected <span style="color: #000000; font-weight: bold;">function</span> partAdded<span style="color: #66cc66;">&#40;</span>partName:<span style="color: #0066CC;">String</span>, instance:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span>.<span style="color: #006600;">partAdded</span><span style="color: #66cc66;">&#40;</span>partName, instance<span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>instance == clearButton<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                clearButton.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, clearClick<span style="color: #66cc66;">&#41;</span>;
                clearButton.<span style="color: #0066CC;">visible</span> = <span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">text</span> <span style="color: #66cc66;">!</span>= <span style="color: #000000; font-weight: bold;">null</span> <span style="color: #66cc66;">&amp;&amp;</span> <span style="color: #0066CC;">text</span>.<span style="color: #0066CC;">length</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        override protected <span style="color: #000000; font-weight: bold;">function</span> partRemoved<span style="color: #66cc66;">&#40;</span>partName:<span style="color: #0066CC;">String</span>, instance:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span>.<span style="color: #006600;">partRemoved</span><span style="color: #66cc66;">&#40;</span>partName, instance<span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>instance == clearButton<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                clearButton.<span style="color: #006600;">removeEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, clearClick<span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>After the <code>PromptingTextInput</code>, the <code>ClearableTextInput</code> is a little more straightforward.  First, we have the <code>clearButton</code> <code>SkinPart</code> and it&#8217;s <code>clearClick()</code> event handler.  Wiring the handler function to the button is done in the <code>partAdded()</code> override, and un-wiring in the <code>partRemoved()</code> override.  Next, button visibility is managed by watching for both programmatic text change events and user text change events.  The handler, <code>textChangedHandler()</code>, sets the button as visible when the control has text in it.</p>
<p>As I mentioned above, I decided against pushing the <code>clearButton</code>&#8216;s visibility down to the skin via a <code>SkinState</code>, and instead chose to manage it inside the component by setting <code>clearButton.visible</code> directly.  I tend to favor the <code>SkinState</code> method when more than one thing needs to change in the skin or if I need advanced visuals (like transitions).  If I need to do just one thing and I don&#8217;t care about visuals, I&#8217;ll do it inside the component.  The two examples here aren&#8217;t the best to illustrate the two options, but that&#8217;s my general thought process when building a custom component and custom skin.</p>
<p class="bottom">A skin for <code>ClearingTextInput</code> is super trivial.  Again, ignoring all the pretty stuff, the skin is:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;">&lt;?xml version=<span style="color: #ff0000;">&quot;1.0&quot;</span> encoding=<span style="color: #ff0000;">&quot;utf-8&quot;</span>?<span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:SparkSkin</span> ...<span style="color: #7400FF;">&gt;</span></span>
    ...
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:states</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;normal&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;disabled&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:states</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:RichEditableText</span> id=<span style="color: #ff0000;">&quot;textDisplay&quot;</span> ... <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Button</span> id=<span style="color: #ff0000;">&quot;clearButton&quot;</span> ... <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:SparkSkin</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>Just add the <code>clearButton</code> <code>Button</code> and position it.</p>
<h3>Fusion, Glorious Fusion</h3>
<p>The fusion process of creating <code>SuperTextInput</code> from <code>PromptingTextInput</code> and <code>ClearableTextInput</code> is nothing more than copy and paste.  <code>SuperTextInput</code> has lots of uses, but my favorite is to use it to capture text input to filter a list.  It also works great as a search box, or in any smart form UI.  Enjoy.</p>
<p class="bottom">Here&#8217;s the finished product showing all three custom components skinned and ready for action (view source enabled):</p>
<div id="flashcontent-supertextinput">
Flash is required.  <a href="http://www.adobe.com/go/getflashplayer">Get it here!</a>
</div>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/flex4/super_text_input/SuperTextInput.html">SuperTextInput</a> (<a href="http://saturnboy.com/proj/flex4/super_text_input/srcview/SuperTextInput.zip">download</a>)</li>
</ul>
<div>
<script type="text/javascript">
swfobject.embedSWF('http://saturnboy.com/proj/flex4/super_text_input/SuperTextInput.swf', 'flashcontent-supertextinput', '240', '94', '10.0.0', 'playerProductInstall.swf', false, { bgColor:'#ffffff', base:'.' });
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/07/supertextinput-building-a-custom-component/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building Flex 4 Containers with Multiple Content Areas</title>
		<link>http://saturnboy.com/2010/07/multiple-content-area-containers/</link>
		<comments>http://saturnboy.com/2010/07/multiple-content-area-containers/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 22:48:18 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[custom component]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[skinning]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=1454</guid>
		<description><![CDATA[Back in the days of Flex 3, if you wanted multiple content areas in your main application, you&#8217;d need to arrange some set of containers (Canvas, HBox, VBox) in the app and fill them with content. It was just your basic Flex 3 development process. The danger, of course, is that you are mixing content [...]]]></description>
			<content:encoded><![CDATA[<p>Back in the days of Flex 3, if you wanted multiple content areas in your main application, you&#8217;d need to arrange some set of containers (<code>Canvas</code>, <code>HBox</code>, <code>VBox</code>) in the app and fill them with content.  It was just your basic Flex 3 development process.  The danger, of course, is that you are mixing content with presentation, aka bad separation of concerns.  Today, with the power of Flex 4 skins, we can avoid this issue by moving the presentation layer into a skin (or set of skins).  And thus, we can do a much better job achieving a happy level of separation of concerns.</p>
<h3>The Flex 3 Way</h3>
<p class="bottom">To give a concrete example, I&#8217;ll build a blog layout (yes, another blog layout) with a header, footer, sidebar, and main content areas.  But before we get started, let&#8217;s review the old Flex 3 way:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:HBox</span> id=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:Image</span> source=<span style="color: #ff0000;">&quot;@Embed('assets/logo.png')&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/mx:HBox</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:Canvas</span> id=<span style="color: #ff0000;">&quot;body&quot;</span> width=<span style="color: #ff0000;">&quot;800&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:Text</span> text=<span style="color: #ff0000;">&quot;main content&quot;</span> width=<span style="color: #ff0000;">&quot;600&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:VBox</span> id=<span style="color: #ff0000;">&quot;sidebar&quot;</span> x=<span style="color: #ff0000;">&quot;600&quot;</span> width=<span style="color: #ff0000;">&quot;200&quot;</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:Text</span> text=<span style="color: #ff0000;">&quot;Sidebar&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:Text</span> text=<span style="color: #ff0000;">&quot;sidebar content&quot;</span> width=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/mx:VBox</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/mx:Canvas</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:VBox</span> id=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:Text</span> text=<span style="color: #ff0000;">&quot;2010 saturnboy&quot;</span> styleName=<span style="color: #ff0000;">&quot;footer&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/mx:VBox</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>The above code comes from a previous post, <a href="http://saturnboy.com/2009/02/designing-in-flex/">Designing in Flex 3</a>, but has been modified to make sense here.  You&#8217;ve got you basic blog design: a box for the header, footer, and body, where body is subsequently is divided into a main content area and a sidebar.</p>
<h3>The 3-in-4 Way, aka The Wrong Way</h3>
<p>The unfortunate next step in a Flex developer&#8217;s evolution is what I like to call the Flex 3-in-4 way.  This is a the way of neanderthals,  which is to say, it is an evolutionary dead end.  If you ever have the bad luck to see 3-in-4 code, you can be sure you are dealing with a novice Flex 4 developer.  In general, the 3-in-4 way consists of making the simple transcription: <code>Canvas</code> &rarr; <code>Group</code>, <code>HBox</code> &rarr; <code>HGroup</code>, <code>VBox</code> &rarr; <code>VGroup</code>.  But the most damning tipoff of a 3-in-4 developer is the assertion that one is now a Flex 4 developer and the learning curve wasn&#8217;t all that bad.  While I do think Flex 4 is more of an evolutionary release than a revolutionary release, it&#8217;s different enough.  And it is particularly different on the design side of the framework, how it handles skins, layout, etc.</p>
<p class="bottom">If we just transcribe the above example, we get some classic 3-in-4 code:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;s:HGroup</span> id=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> text=<span style="color: #ff0000;">&quot;Multi Content Area Example&quot;</span> styleName=<span style="color: #ff0000;">&quot;header&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:HGroup</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Group</span> id=<span style="color: #ff0000;">&quot;body&quot;</span> width=<span style="color: #ff0000;">&quot;800&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> text=<span style="color: #ff0000;">&quot;main content&quot;</span> width=<span style="color: #ff0000;">&quot;600&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:VGroup</span> x=<span style="color: #ff0000;">&quot;600&quot;</span> width=<span style="color: #ff0000;">&quot;200&quot;</span> styleName=<span style="color: #ff0000;">&quot;sidebarBox&quot;</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> text=<span style="color: #ff0000;">&quot;Sidebar&quot;</span> styleName=<span style="color: #ff0000;">&quot;title&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> text=<span style="color: #ff0000;">&quot;sidebar content&quot;</span> styleName=<span style="color: #ff0000;">&quot;sidebar&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:VGroup</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Group</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:VGroup</span> id=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> text=<span style="color: #ff0000;">&quot;2010 saturnboy&quot;</span> styleName=<span style="color: #ff0000;">&quot;footer&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:VGroup</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>*Barf*, please <b>not</b> do this.  This code has all the same issues as the Flex 3 code in the first example, and moreover it is a slap in the face of <i>The Flex 4 Way</i> and all of its improvements.</p>
<h3>The Flex 4 Way</h3>
<p>Yes, there is a Flex 4 Way and it looks like this.</p>
<p class="bottom">First, we rewrite the main app using a custom container.  Ignoring the specifics of the custom container for a moment, here is the re-written main app (minus some clutter):</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;containers:headerContent</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> text=<span style="color: #ff0000;">&quot;Multi Content Area Example&quot;</span> styleName=<span style="color: #ff0000;">&quot;header&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/containers:headerContent</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;containers:sidebarContent</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:RichText</span> left=<span style="color: #ff0000;">&quot;0&quot;</span> right=<span style="color: #ff0000;">&quot;0&quot;</span> styleName=<span style="color: #ff0000;">&quot;sidebar&quot;</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:content</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:p</span> fontSize=<span style="color: #ff0000;">&quot;20&quot;</span><span style="color: #7400FF;">&gt;</span></span>Sidebar<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:p</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:p</span><span style="color: #7400FF;">&gt;</span></span>sidebar content<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:p</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:content</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:RichText</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/containers:sidebarContent</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;containers:footerContent</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> text=<span style="color: #ff0000;">&quot;2010 saturnboy&quot;</span> styleName=<span style="color: #ff0000;">&quot;footer&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/containers:footerContent</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:RichText</span> left=<span style="color: #ff0000;">&quot;0&quot;</span> right=<span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:content</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:p</span> fontSize=<span style="color: #ff0000;">&quot;30&quot;</span><span style="color: #7400FF;">&gt;</span></span>Content<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:p</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:p</span><span style="color: #7400FF;">&gt;</span></span>main content<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:p</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:content</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:RichText</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>As you can see, the main app is now a nice set of semantic buckets, one for each of the content areas.  Header stuff goes in the <code>headerContent</code> bucket, footer stuff goes in the <code>footerContent</code> bucket, etc.</p>
<h3>Building a Multi Content Area Container</h3>
<p>Second, we need to create a custom container with the nice set of semantic buckets used in the above code.  This is achieved by following a straightforward formula:</p>
<ol>
<li><b>Extend SkinnableContainer</b> &ndash; Extend <code>SkinnableContainer</code> or some child class.  In our sample app, our custom container extends <code>Application</code> (which extends <code>SkinnableContainer</code>).</li>
<li><b>Add Buckets</b> &ndash; add some content buckets (in the form of <i>xxx</i><code>Content</code>) as <code>Array</code>s.  These become the MXML tags used to bucket components together.  Each content bucket has a public getter, but most importantly a public setter that accepts an incoming <code>Array</code> of <code>IVisualElement</code>s and uses the magical <code>mxmlContent</code> property to assign it to the associated <code>SkinPart</code>.</li>
<li><b>Add SkinParts</b> &ndash; add some matching SkinParts (in the form of <i>xxx</i><code>Group</code>) as spark <code>Group</code>s.  There are used in the custom skin to display the content.  Also, I usually set <code>required=&quot;false&quot;</code> to make everything optional.</li>
<li><b>Add partAdded() &amp; partRemoved()</b> &ndash; override the new Flex 4 skinning lifecycle methods to wire the incoming content to the outgoing <code>SkinPart</code>.</li>
</ol>
<p class="bottom">The custom component code is actually easier to follow then the description.  Here is a custom container with only one additional content bucket, <code>sidebarContent</code>, and its matching <code>SkinPart</code>, <code>sidebarGroup</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">package containers <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">components</span>.<span style="color: #006600;">Group</span>;
    <span style="color: #0066CC;">import</span> spark.<span style="color: #006600;">components</span>.<span style="color: #006600;">Application</span>;
&nbsp;
    <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MainApp <span style="color: #0066CC;">extends</span> Application <span style="color: #66cc66;">&#123;</span>
        <span style="color: #66cc66;">&#91;</span>SkinPart<span style="color: #66cc66;">&#40;</span>required=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">var</span> sidebarGroup:Group;
&nbsp;
        <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> _sidebarContent:<span style="color: #0066CC;">Array</span> = <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> MainApp<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #66cc66;">&#91;</span>ArrayElementType<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;mx.core.IVisualElement&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">get</span> sidebarContent<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">Array</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #b1b100;">return</span> _sidebarContent;
        <span style="color: #66cc66;">&#125;</span>
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">set</span> sidebarContent<span style="color: #66cc66;">&#40;</span>value:<span style="color: #0066CC;">Array</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            _sidebarContent = value;
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>sidebarGroup<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                sidebarGroup.<span style="color: #006600;">mxmlContent</span> = value;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        override protected <span style="color: #000000; font-weight: bold;">function</span> partAdded<span style="color: #66cc66;">&#40;</span>partName:<span style="color: #0066CC;">String</span>, instance:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span>.<span style="color: #006600;">partAdded</span><span style="color: #66cc66;">&#40;</span>partName, instance<span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>instance == sidebarGroup<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                sidebarGroup.<span style="color: #006600;">mxmlContent</span> = _sidebarContent;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        override protected <span style="color: #000000; font-weight: bold;">function</span> partRemoved<span style="color: #66cc66;">&#40;</span>partName:<span style="color: #0066CC;">String</span>, instance:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">super</span>.<span style="color: #006600;">partRemoved</span><span style="color: #66cc66;">&#40;</span>partName, instance<span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>instance == sidebarGroup<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                sidebarGroup.<span style="color: #006600;">mxmlContent</span> = <span style="color: #000000; font-weight: bold;">null</span>;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Following the four steps: we extend <code>Application</code>, have a <code>sidebarContent</code> bucket and its associated <code>sidebarGroup</code> <code>SkinPart</code>, and override <code>partAdded()</code> and <code>partRemoved()</code> to wire everything together.</p>
<h3>Skinning a Multi Content Area Container</h3>
<p>Skinning in Flex 4 is awesome, and like everyone says, it&#8217;s easily one of the best new features in the framework.  While I find the skinning process fairly straightforward, I would never call it trivial, mostly due to the depth and flexibility of the skinning system.</p>
<p>We need a custom skin for our custom multi content area component.  This is probably the 10% case for skinning, but it&#8217;s also the coolest.  In my experience, an average Flex 4 app has many <code>Button</code> skins (like 10 or even 20), a few default component skins (skins for <code>List</code>, <code>DropDownList</code>, <code>TextInput</code>, etc.), and maybe only two or three skins for custom components.</p>
<p>The skin itself is nothing special.  To display our custom component&#8217;s <code>SkinPart</code>s, we simply include a <code>Group</code> with the matching <code>id</code> attribute.  For example, our skin will include a <code>&lt;s:Group id="sidebarGroup" /&gt;</code> to display the <code>sidebarGroup</code> <code>SkinPart</code>.  Just rinse, wash, repeat, to add all of our custom content areas in the container to the skin.</p>
<p class="bottom">Here is a trivial skin:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Skin</span> ... <span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Metadata</span><span style="color: #7400FF;">&gt;</span></span>
        [HostComponent(&quot;containers.MainApp&quot;)]
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Metadata</span><span style="color: #7400FF;">&gt;</span></span> 
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:states</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;normal&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;disabled&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:states</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:VGroup</span> left=<span style="color: #ff0000;">&quot;40&quot;</span> right=<span style="color: #ff0000;">&quot;40&quot;</span> top=<span style="color: #ff0000;">&quot;40&quot;</span> bottom=<span style="color: #ff0000;">&quot;40&quot;</span> gap=<span style="color: #ff0000;">&quot;20&quot;</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Group</span> id=<span style="color: #ff0000;">&quot;headerGroup&quot;</span> width=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Group</span> id=<span style="color: #ff0000;">&quot;contentGroup&quot;</span> width=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Group</span> id=<span style="color: #ff0000;">&quot;sidebarGroup&quot;</span> width=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Group</span> id=<span style="color: #ff0000;">&quot;footerGroup&quot;</span> width=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:VGroup</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Skin</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>In this trivial skin, we just shove all the content groups (including <code>SkinnableContainer</code>&#8216;s default <code>Group</code>, <code>contentGroup</code>) into a <code>VGroup</code>.  Also note, we correctly set <code>HostComponent</code> to our custom container.  If you are thinking, &quot;Hey, this skin looks similar to the Flex 3 and 3-in-4 example code, just minus the content&quot; that&#8217;s exactly the point.</p>
<p class="bottom">Lastly, we wire out skin to our custom component via CSS:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">containers|MainApp <span style="color: #00AA00;">&#123;</span>
    skinClass<span style="color: #00AA00;">:</span>ClassReference<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'skins.TrivialAppSkin'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Using <code>skinClass</code> to wire a skin to a component is <b>so</b> 2009.  The sample app has its CSS inline, but in any real app I&#8217;ll always put this in an external file.</p>
<h3>Conclusion</h3>
<p>After this, there&#8217;s really not much more to say.  You can certainly create a more complicated arrangement of the multiple content areas by making a more complicated skin.  I&#8217;ve done exactly this in the final sample, which includes three different skins and a skin switcher (click 1, 2, or 3 to switch skins).</p>
<p>&raquo; <a href="http://saturnboy.com/proj/flex4/multi_content_area/MultiContentArea.html">view MultiConentArea sample</a> (view source enabled)</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/flex4/multi_content_area/MultiContentArea.html">MultiContentArea</a> (<a href="http://saturnboy.com/proj/flex4/multi_content_area/srcview/MultiContentArea.zip">download</a>)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/07/multiple-content-area-containers/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Drawer Component in Flex 4</title>
		<link>http://saturnboy.com/2010/06/drawer-component-flex-4/</link>
		<comments>http://saturnboy.com/2010/06/drawer-component-flex-4/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 04:31:09 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[custom component]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[flexlib]]></category>
		<category><![CDATA[skinning]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=1418</guid>
		<description><![CDATA[I needed a good way to have a large settings panel with a minimal visual impact. The obvious answer is to hide or minimize or collapse the settings panel when not in use. I thought about using Flexlib&#8216;s WindowShade component (which I&#8217;ve dicussed in detail in Styling Flexlib&#8217;s WindowShade), but why reuse something when you [...]]]></description>
			<content:encoded><![CDATA[<p>I needed a good way to have a large settings panel with a minimal visual impact.  The obvious answer is to hide or minimize or collapse the settings panel when not in use.  I thought about using <a href="http://code.google.com/p/flexlib/">Flexlib</a>&#8216;s WindowShade component (which I&#8217;ve dicussed in detail in <a href="http://saturnboy.com/2009/03/styling-flexlib-windowshade/">Styling Flexlib&#8217;s WindowShade</a>), but why reuse something when you can reinvent the wheel?  Plus, it always helps to hone my Flex 4 custom component kung-fu.  So, I chose to implement a simple sliding drawer component from scratch as a Flex 4 component.</p>
<p class="bottom">The Drawer component is a vanilla container (it actually extends <code>SkinnableContainer</code>), so it will happily take any spark component for its children.  Before I dive into my implementation, let&#8217;s check out the finished drawer component in action (view source enabled):</p>
<div id="flashcontent-drawer" style="background-color:#eee">
Flash is required.  <a href="http://www.adobe.com/go/getflashplayer">Get it here!</a>
</div>
<p> Just click on the handle to open and close the drawer.</p>
<h3>Extending <code>SkinnableContainer</code></h3>
<p>The Drawer component itself, is just pure AS3, but the demo above uses a few MXML skins to achieve the desired look-and-feel.  This is a pretty standard pattern that I see during Flex 4 development, so expect it when you write your own custom components.</p>
<p class="bottom">We&#8217;ll review the component implementation in two steps.  First, we focus on the skin state management aspect of the drawer.  Here&#8217;s the relevant code (taken from <code>Drawer.as</code>):</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #66cc66;">&#91;</span>SkinState<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;opened&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Drawer <span style="color: #0066CC;">extends</span> SkinnableContainer <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> _opened:<span style="color: #0066CC;">Boolean</span> = <span style="color: #000000; font-weight: bold;">false</span>;
&nbsp;
    <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">get</span> opened<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">Boolean</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">return</span> _opened;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">set</span> opened<span style="color: #66cc66;">&#40;</span>value:<span style="color: #0066CC;">Boolean</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>_opened <span style="color: #66cc66;">!</span>= value<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            _opened = value;
            invalidateSkinState<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    override protected <span style="color: #000000; font-weight: bold;">function</span> getCurrentSkinState<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">String</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#40;</span>opened ? <span style="color: #ff0000;">'opened'</span> : <span style="color: #0066CC;">super</span>.<span style="color: #006600;">getCurrentSkinState</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span>
    ...
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The <code>Drawer</code> component can either be closed (the default) or opened.  To model theses states, we use the <code>normal</code> state from the superclass to represent the closed drawer, and add a new <code>opened</code> <code>SkinState</code> to represent the opened drawer.  We just expose a simple <code>opened</code> boolean property with a custom getter and setter, and then override the <code>getCurrentSkinState()</code> method.  It&#8217;s important to remember the states we are talking about are skin states, and not <i>component</i> states (see <a href="http://saturnboy.com/2009/09/flex4-component-states-skin-states/">Flex 4 Component States vs. Skin States</a> for the difference).</p>
<p class="bottom">Second, we focus on the action of opening and closing the drawer.  Here&#8217;s the relevant code (taken from <code>Drawer.as</code>):</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Drawer <span style="color: #0066CC;">extends</span> SkinnableContainer <span style="color: #66cc66;">&#123;</span>
    ...
    <span style="color: #66cc66;">&#91;</span>SkinPart<span style="color: #66cc66;">&#40;</span>required=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">var</span> openButton:<span style="color: #0066CC;">Button</span>;
&nbsp;
    <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> clickHandler<span style="color: #66cc66;">&#40;</span>event:MouseEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
        opened = <span style="color: #66cc66;">!</span>opened;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    override protected <span style="color: #000000; font-weight: bold;">function</span> partAdded<span style="color: #66cc66;">&#40;</span>partName:<span style="color: #0066CC;">String</span>, instance:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #0066CC;">super</span>.<span style="color: #006600;">partAdded</span><span style="color: #66cc66;">&#40;</span>partName, instance<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>instance == openButton<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            openButton.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, clickHandler<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    override protected <span style="color: #000000; font-weight: bold;">function</span> partRemoved<span style="color: #66cc66;">&#40;</span>partName:<span style="color: #0066CC;">String</span>, instance:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #0066CC;">super</span>.<span style="color: #006600;">partRemoved</span><span style="color: #66cc66;">&#40;</span>partName, instance<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>instance == openButton<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            openButton.<span style="color: #006600;">removeEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, clickHandler<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The <code>Drawer</code> component includes a simple spark button, as an optional <code>SkinPart</code>, that is used to initiate the state change.  The <code>partAdded()</code> and <code>partRemoved()</code> methods are overridden to manage and adding and removing of the button&#8217;s click event handler.  And lastly, the <code>clickHandler()</code> method flips between skin states by toggling the <code>opened</code> boolean property.</p>
<h3>Usage</h3>
<p class="bottom">Using the <code>Drawer</code> is the same as any container.  In MXML, just put any child components you want between the container&#8217;s open and close tags:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;containers:Drawer</span> ... skinClass=<span style="color: #ff0000;">&quot;skins.DrawerSkin&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #808080; font-style: italic;">&lt;!-- components go here --&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/containers:Drawer</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>Here we also apply the <code>DrawerSkin</code> to our container.</p>
<h3>Skins</h3>
<p class="bottom">The <code>DrawerSkin</code> is responsible for creating the desired look-and-feel and generally making the <code>Drawer</code> component look cool.  Here are the interesting parts of the skin:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Skin</span> ...<span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Metadata</span><span style="color: #7400FF;">&gt;</span></span>
        [HostComponent(&quot;containers.Drawer&quot;)]
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Metadata</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:states</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;normal&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;opened&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:State</span> name=<span style="color: #ff0000;">&quot;disabled&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:states</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
   ...
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Button</span> id=<span style="color: #ff0000;">&quot;openButton&quot;</span> ...</span>
<span style="color: #000000;">            skinClass=<span style="color: #ff0000;">&quot;skins.DrawerOpenButtonSkin&quot;</span></span>
<span style="color: #000000;">            skinClass.opened=<span style="color: #ff0000;">&quot;skins.DrawerCloseButtonSkin&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Group</span> id=<span style="color: #ff0000;">&quot;contentGroup&quot;</span> ... includeIn=<span style="color: #ff0000;">&quot;opened&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Skin</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>The <code>DrawerSkin</code> has three skin states, <code>normal</code> and <code>disabled</code> are inherited from <code>SkinnableContainer</code>, but <code>opened</code> is our custom skin state.  The skin also includes the optional <code>openButton</code> <code>SkinPart</code>, which itself uses two custom buttons skins, one for the open drawer and one for the closed drawer.  Lastly, note that the container&#8217;s content is only displayed when the skin is in the <code>opened</code> state via the newfangled inline state syntax: <code>includeIn=&quot;opened&quot;</code>.</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/flex4/drawer/Drawer.html">Drawer</a> (<a href="http://saturnboy.com/proj/flex4/drawer/srcview/Drawer.zip">download</a>)</li>
</ul>
<div>
<script type="text/javascript">
swfobject.embedSWF('http://saturnboy.com/proj/flex4/drawer/Drawer.swf', 'flashcontent-drawer', '520', '340', '10.0.0', 'playerProductInstall.swf', false, { bgColor:'#eeeeee', base:'.' });
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/06/drawer-component-flex-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Managing Event Listeners in Flex 4</title>
		<link>http://saturnboy.com/2010/03/event-listeners-in-flex-4/</link>
		<comments>http://saturnboy.com/2010/03/event-listeners-in-flex-4/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 04:59:47 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[flex4]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=1089</guid>
		<description><![CDATA[Event-driven programming is at the heart of Flex. It also lies close to the heart of insanity for the developer. When an application becomes too loosely coupled, things get painful fast. The perfect storm arrives when you marry an event-driven UI with an event-driven asynchronous backend. Better async testing becomes the least of your problems, [...]]]></description>
			<content:encoded><![CDATA[<p>Event-driven programming is at the heart of Flex.  It also lies close to the heart of insanity for the developer.  When an application becomes too loosely coupled, things get painful fast.  The perfect storm arrives when you marry an event-driven UI with an event-driven asynchronous backend.  <a href="http://saturnboy.com/2010/02/async-testing-with-flexunit4/">Better async testing</a> becomes the least of your problems, and you are constantly trying to figure out who is listening to what, when.</p>
<p>In these cases, I often find that some simple runtime management of event listeners can really help.  To begin, I start with some component whose listeners I want to manage, then I override the <code>addEventListener()</code> and <code>removeEventListener()</code> functions in that component to always keep track of who is actively listening.</p>
<p class="bottom">Here is the basic code that can be added to any component (actually any descendent of <code>EventDispatcher</code> which is basically everything in Flex):</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> _listeners:<span style="color: #0066CC;">Object</span> = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>;
&nbsp;
override <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> addEventListener<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span>:<span style="color: #0066CC;">String</span>, listener:<span style="color: #000000; font-weight: bold;">Function</span>, useCapture:<span style="color: #0066CC;">Boolean</span>=<span style="color: #000000; font-weight: bold;">false</span>, priority:<span style="color: #0066CC;">int</span>=<span style="color: #cc66cc;">0</span>, useWeakReference:<span style="color: #0066CC;">Boolean</span>=<span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0066CC;">super</span>.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span>, listener, useCapture, priority, useWeakReference<span style="color: #66cc66;">&#41;</span>;
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>_listeners.<span style="color: #006600;">hasOwnProperty</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #66cc66;">&#40;</span>_listeners<span style="color: #66cc66;">&#91;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#93;</span> as <span style="color: #0066CC;">Array</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>listener<span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #66cc66;">&#123;</span>
        _listeners<span style="color: #66cc66;">&#91;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #66cc66;">&#91;</span>listener<span style="color: #66cc66;">&#93;</span>;
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
override <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> removeEventListener<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span>:<span style="color: #0066CC;">String</span>, listener:<span style="color: #000000; font-weight: bold;">Function</span>, useCapture:<span style="color: #0066CC;">Boolean</span>=<span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0066CC;">super</span>.<span style="color: #006600;">removeEventListener</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span>, listener, useCapture<span style="color: #66cc66;">&#41;</span>;
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>_listeners.<span style="color: #006600;">hasOwnProperty</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">var</span> listeners:<span style="color: #0066CC;">Array</span> = _listeners<span style="color: #66cc66;">&#91;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#93;</span> as <span style="color: #0066CC;">Array</span>;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>listeners.<span style="color: #0066CC;">length</span> <span style="color: #66cc66;">&lt;</span>= <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">delete</span> _listeners<span style="color: #66cc66;">&#91;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#93;</span>;
        <span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">var</span> idx:<span style="color: #0066CC;">int</span> = listeners.<span style="color: #0066CC;">indexOf</span><span style="color: #66cc66;">&#40;</span>listener<span style="color: #66cc66;">&#41;</span>;
            <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>idx <span style="color: #66cc66;">!</span>= -<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                listeners.<span style="color: #0066CC;">splice</span><span style="color: #66cc66;">&#40;</span>idx,<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>We just store all listeners of a given event type in an array, and store the array as the values in a hash keyed by event type.  When a new listener is added via <code>addEventListener()</code>, we check if any listeners of that event type exist.  If yes, we push the new listener onto the array.  If no, we create a new one-item array containing just the new listener.  The tracking process for <code>removeEventListener()</code> is just the opposite.</p>
<p class="bottom">Once we have all the listener bookkeeping in place, we can add any type of event listener management that we want.  For example, he&#8217;s a <code>removeAllEventListeners()</code> function:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> removeAllEventListeners<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span>:<span style="color: #0066CC;">String</span> = <span style="color: #ff0000;">''</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span>.<span style="color: #0066CC;">length</span> == <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> t:<span style="color: #0066CC;">String</span> <span style="color: #b1b100;">in</span> _listeners<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            removeAllEventListeners<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>_listeners.<span style="color: #006600;">hasOwnProperty</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>hasEventListener<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #b1b100;">for</span> each <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> listener:<span style="color: #000000; font-weight: bold;">Function</span> <span style="color: #b1b100;">in</span> _listeners<span style="color: #66cc66;">&#91;</span><span style="color: #0066CC;">type</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                removeEventListener<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">type</span>, listener<span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Nothing cosmic, as <a href="http://stu-stern.blogspot.com/">my boss</a> likes to say, just walk all the listeners of a given event type and remove them.  If the event type is blank, just use some dirty recursion to walk all the types to remove everything.</p>
<p class="bottom">Here is a sample application which is tracking all the listeners on a <code>Panel</code> component (view source enabled):</p>
<div id="flashcontent-listener-tracker">
Flash is required.  <a href="http://www.adobe.com/go/getflashplayer">Get it here!</a>
</div>
<p>You can add/remove a custom listener for the <i>foo</i> custom event type using the buttons.  Or hit <i>remove all</i> to clear everything (including the listeners attached by default by the Flex framework).</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/flex4/listener_tracker/ListenerTracker.html">ListenerTracker</a> (<a href="http://saturnboy.com/proj/flex4/listener_tracker/srcview/ListenerTracker.zip">download</a>)</li>
</ul>
<div>
<script type="text/javascript">
swfobject.embedSWF('http://saturnboy.com/proj/flex4/listener_tracker/ListenerTracker.swf', 'flashcontent-listener-tracker', '320', '150', '10.0.0', 'playerProductInstall.swf', false, { bgColor:'#ffffff', base:'.' });
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/03/event-listeners-in-flex-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Faking Transaction in LCDS 3</title>
		<link>http://saturnboy.com/2010/02/faking-transaction-in-lcds-3/</link>
		<comments>http://saturnboy.com/2010/02/faking-transaction-in-lcds-3/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 11:58:09 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[LCDS]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=1000</guid>
		<description><![CDATA[Alas, LCDS 3 doesn&#8217;t support the notion of transaction (in the sense of a Database Transaction). I assume that somewhere deep within the system transactions are used to ensure correctness of data in the db, but none of this is exposed to the user. Fortunately, it is possible to bundle up a bunch of updates [...]]]></description>
			<content:encoded><![CDATA[<p>Alas, <a href="http://www.adobe.com/products/livecycle/dataservices/">LCDS 3</a> doesn&#8217;t support the notion of transaction (in the sense of a <a href="http://en.wikipedia.org/wiki/Database_transaction">Database Transaction</a>). I assume that somewhere deep within the system transactions are used to ensure correctness of data in the db, but none of this is exposed to the user. Fortunately, it is possible to bundle up a bunch of updates on the client and push them all at once to the server. <i>Fake transactions</i>, as I like to call them, are quite useful.  But they can also be dangerous because they are not really transactions (hence the <i>fake</i> part), and don&#8217;t always work as you would hope.</p>
<h5>Fake It</h5>
<p>Faking a tranaction is done using the <code>autoCommit</code> property on a generated service.  According to the <a href="http://help.adobe.com/en_US/LiveCycleDataServicesES/3.0/Developing/index.html">docs</a>, setting <code>autoCommit</code> to <code>false</code> blocks Data Management from pushing any changes to the server until <code>commit()</code> is called manually.</p>
<p class="bottom">Here&#8217;s a <a href="http://help.adobe.com/en_US/LiveCycleDataServicesES/3.0/Developing/WSc3ff6d0ea77859461172e0811f00f7045b-7f83.html#WSc3ff6d0ea77859461172e0811f00f6f23a-7ff7">direct quote</a>:</p>
<blockquote><p>&#8220;&#8230;set a <code>DataService</code> component <code>autoCommit</code> property to false to allow only manual calls to the <code>commit()</code> method. It is important to set <code>autoCommit</code> to <code>false</code> when you are going to make more than one change&#8230;so that the <code>DataService</code> component can batch those changes and send them in one batch to the destination.&#8221;</p></blockquote>
<p class="bottom">So to make life easy, I made a simple static function that does the <code>autoCommit</code> gymnastics:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #0066CC;">static</span> <span style="color: #000000; font-weight: bold;">function</span> fakeIt<span style="color: #66cc66;">&#40;</span>service:DataService, func:<span style="color: #000000; font-weight: bold;">Function</span><span style="color: #66cc66;">&#41;</span>:AsyncToken <span style="color: #66cc66;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>service.<span style="color: #006600;">autoCommit</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #0066CC;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #0066CC;">Error</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;ERROR: autoCommit is already off.&quot;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>service.<span style="color: #006600;">commitRequired</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #0066CC;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #0066CC;">Error</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;ERROR: another transaction is already open.&quot;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    service.<span style="color: #006600;">autoCommit</span> = <span style="color: #000000; font-weight: bold;">false</span>;
    func<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #000000; font-weight: bold;">var</span> token:AsyncToken = service.<span style="color: #006600;">commit</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
    service.<span style="color: #006600;">autoCommit</span> = <span style="color: #000000; font-weight: bold;">true</span>;
    <span style="color: #b1b100;">return</span> token;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>After some error handling, we toggle <code>autoCommit</code> to false, call our function, then commit any updates, toggle <code>autoCommit</code> back on, and return the token.</p>
<h5>Usage</h5>
<p>Using our fake transaction function is straight forward, and typically involves passing in and inline anonymous function.</p>
<p class="bottom">Imagine our favorite example of teams and players, where each team has one-to-many players.  We might choose to perform a sequence of operations to add a new player to an existing team, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span> token:AsyncToken = FakeTransaction.<span style="color: #006600;">fakeIt</span><span style="color: #66cc66;">&#40;</span>
    teamService.<span style="color: #006600;">serviceControl</span>,
    <span style="color: #000000; font-weight: bold;">function</span> <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: #808080; font-style: italic;">//rename the team</span>
        team.<span style="color: #0066CC;">name</span> = <span style="color: #ff0000;">'Denver Nuggetz'</span>;
&nbsp;
        <span style="color: #808080; font-style: italic;">//create player</span>
        <span style="color: #000000; font-weight: bold;">var</span> p:Player = <span style="color: #000000; font-weight: bold;">new</span> Player<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        p.<span style="color: #0066CC;">name</span> = <span style="color: #ff0000;">'Carmelo Anthony'</span>;
&nbsp;
        <span style="color: #808080; font-style: italic;">//wire both side of relationship</span>
        p.<span style="color: #006600;">team</span> = team;
        team.<span style="color: #006600;">players</span>.<span style="color: #006600;">addItem</span><span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">&#41;</span>;
&nbsp;
        playerService.<span style="color: #006600;">createPlayer</span><span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
token.<span style="color: #006600;">addResponder</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> AsyncResponder<span style="color: #66cc66;">&#40;</span>successHandler, faultHandler<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>In this case, the fake transaction is used to ensure the team is renamed and the player is added.  Both operations occur together, so it should not be possible to have the new player on the old team, or have the renamed team without the new player.</p>
<h5>Warning! Danger!</h5>
<p>Experience has shown me that fake transactions don&#8217;t always work as one would expect if they were real transactions. Sometimes, particularly when you are manipulating entities already under Data Management, it seems like operations are not really batched but instead executed one at a time.  Thankfully, it appears that LCDS is order preserving, and by that I mean it doesn&#8217;t magically re-order things.  LCDS always executes operations in the order they come in.  I can only recommend you test your application vigorously to ensure what you expect to happen actually happens (<a href="http://flexunit.org/">FlexUnit4</a> is pretty awesome for <a href="http://saturnboy.com/2010/02/async-testing-with-flexunit4/">testing async backends</a>). </p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/wp-content/uploads/2010/01/FakeTransaction.as">FakeTransaction.as</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/02/faking-transaction-in-lcds-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Like Peas and Carrots: LCDS 3 and UTF-8</title>
		<link>http://saturnboy.com/2010/02/lcds-and-utf-8/</link>
		<comments>http://saturnboy.com/2010/02/lcds-and-utf-8/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 17:54:32 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[LCDS]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[UTF-8]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=958</guid>
		<description><![CDATA[I just wrote about how to handle special characters in Flex 4 when written as HTML entities in MXML. Now I&#8217;ve moved my data with the special characters out of MXML and down into a MySQL database. Data access is provided by a vanilla LCDS 3 backend. I now have a very different problem than [...]]]></description>
			<content:encoded><![CDATA[<p>I just wrote about how to handle <a href="http://saturnboy.com/2010/01/special-characters-flex-4/">special characters in Flex 4</a> when written as HTML entities in MXML. Now I&#8217;ve moved my data with the special characters out of MXML and down into a MySQL database.  Data access is provided by a vanilla <a href="http://www.adobe.com/products/livecycle/dataservices/">LCDS 3</a> backend. I now have a very different problem than what I had before: How do I get UTF-8 data out of the database with LCDS and onto the display?</p>
<h5>MySQL and UTF-8</h5>
<p>In theory, LCDS is perfectly happy with special characters and foreign languages (here&#8217;s a link to <a href="http://help.adobe.com/en_US/livecycle/9.0/programLC/langref/charset-codes.html">supported characters sets</a> in LiveCycle ES2). So this time around, our problem has nothing to do with Flex 4 or LCDS, instead it&#8217;s all about the database. For our example, we&#8217;ll skip the pure model driven development route and just start with a simple database with a single <code>players</code> table.</p>
<p class="bottom">Create the database:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">DATABASE</span> ballerz <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARACTER <span style="color: #993333; font-weight: bold;">SET</span> utf8 COLLATE utf8_general_ci;
<span style="color: #993333; font-weight: bold;">CREATE</span> USER <span style="color: #ff0000;">'baller'</span>@<span style="color: #ff0000;">'localhost'</span> <span style="color: #993333; font-weight: bold;">IDENTIFIED</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">'password'</span>;
<span style="color: #993333; font-weight: bold;">GRANT</span> <span style="color: #993333; font-weight: bold;">ALL</span> PRIVILEGES <span style="color: #993333; font-weight: bold;">ON</span> ballerz<span style="color: #66cc66;">.*</span> <span style="color: #993333; font-weight: bold;">TO</span> baller@localhost;</pre></div></div>

<p>It is possible to configure MySQL to default to UTF-8 friendly behavior but the <code>CREATE DATABASE</code> command guarantees that the newly created db will be happy.</p>
<p class="bottom">Create the <code>players</code> table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> players <span style="color: #66cc66;">&#40;</span>
  id int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Nothing special here, just use <code>VARCHAR</code> for the text fields.  In this case, we only have the player&#8217;s name.</p>
<p class="bottom">Insert some sample data:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Carmelo Anthony&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Chaunçey Billups&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Nenê&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Këñÿõn Martin&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;LeBrøn James&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">6</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Mo Williams&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">7</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Shaquille O†Neal&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">8</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Ænderson Varejao&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> players <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Zýdrunãs Ílgauskãs&quot;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>I put some extra special characters into the <code>INSERT</code> statements just for fun.</p>
<blockquote class="deeper"><p><b>Digging Deeper:</b> When connecting to MySQL from the commandline you can use the <code>--default-character-set=utf8</code> option to force your terminal to show UTF-8 characters correctly.</p></blockquote>
<h5>LCDS and UTF-8</h5>
<p>Now that the database is correctly setup to handle UTF-8, the rest of the LCDS setup is straight forward (see my getting started <a href="http://saturnboy.com/2009/07/get-started-lcds-mysql-1/">part 1</a> and <a href="http://saturnboy.com/2009/07/get-started-lcds-mysql-2/">part 2</a> posts). Create a new LCDS webapp via copy-and-paste from the template app, then fire up Flash Builder 4 and get to work.  In the Modeler plugin, configure a new RDS connection and just drag-and-drop the players table into the model.</p>
<p class="bottom">Here&#8217;s a screenshot of our LCDS model:</p>
<div class="span-14 last" style="min-height:274px;">
<img src="http://saturnboy.com/wp-content/uploads/2010/01/lcds_utf8_model.png" alt="model" width="391" height="264" />
</div>
<p class="bottom">And here&#8217;s a screenshot of the running app (remember this is backed by LCDS, so no running demo):</p>
<div class="span-14 last" style="min-height:180px;">
<img src="http://saturnboy.com/wp-content/uploads/2010/01/lcds_utf8_screenshot.png" alt="screenshot" width="390" height="170" />
</div>
<p class="bottom">Lastly, the frontend code showing just the highlights:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;">&lt;?xml version=<span style="color: #ff0000;">&quot;1.0&quot;</span> encoding=<span style="color: #ff0000;">&quot;utf-8&quot;</span>?<span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Application</span> ...</span>
<span style="color: #000000;">        creationComplete=<span style="color: #ff0000;">&quot;complete()&quot;</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Script</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;">&lt;!<span style="color: #66cc66;">&#91;</span>CDATA<span style="color: #66cc66;">&#91;</span></span>
<span style="color: #000000;">           private function complete<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:void <span style="color: #66cc66;">&#123;</span></span>
<span style="color: #000000;">                getPlayers.token = playerService.getAll<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</span>
<span style="color: #000000;">            <span style="color: #66cc66;">&#125;</span></span>
<span style="color: #000000;">        <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Script</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Declarations</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:CallResponder</span> id=<span style="color: #ff0000;">&quot;getPlayers&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;Ballerz:PlayerService</span> id=<span style="color: #ff0000;">&quot;playerService&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Declarations</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:List</span> </span>
<span style="color: #000000;">            dataProvider=<span style="color: #ff0000;">&quot;{getPlayers.lastResult}&quot;</span></span>
<span style="color: #000000;">            labelField=<span style="color: #ff0000;">&quot;name&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Application</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>Again, no magic here, I use a simple <code>getAll()</code> query to retrieve the entire <code>players</code> table then feed it into a <code>List</code> via the <code>CallResponder</code>&#8216;s <code>lastResult</code> property.</p>
<h5>Conclusion</h5>
<p>So the moral of our story is: if you correctly configure your database to support UTF-8 and you correctly get UTF-8 data into your tables, then everything just works.  LCDS will transparently get data out of the db and Flex will transparently get it onto the screen.</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/lcds/ballerz/Ballerz.tgz">Ballerz.tgz</a></li>
<li><a href="http://saturnboy.com/proj/lcds/ballerz/create_db.sql">create_db.sql</a></li>
<li><a href="http://saturnboy.com/proj/lcds/ballerz/create_tables.sql">create_tables.sql</a></li>
<li><a href="http://saturnboy.com/proj/lcds/ballerz/data.sql">data.sql</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/02/lcds-and-utf-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Async Testing with FlexUnit 4</title>
		<link>http://saturnboy.com/2010/02/async-testing-with-flexunit4/</link>
		<comments>http://saturnboy.com/2010/02/async-testing-with-flexunit4/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 20:58:53 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[flexunit4]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=1019</guid>
		<description><![CDATA[I tend to spend a large portion of my development time worrying about the various interfaces across the application. I like to worry about UX (aka the interface between the user and my app). I like to worry about the ORM (aka the interface between the database and my code). And I especially like to [...]]]></description>
			<content:encoded><![CDATA[<p>I tend to spend a large portion of my development time worrying about the various interfaces across the application.  I like to worry about UX (aka the interface between the user and my app).  I like to worry about the ORM (aka the interface between the database and my code).  And I especially like to worry about the client-side service layer (aka the interface between the backend and the frontend).  When I worry, I very quickly find myself writing tests.</p>
<p>The new hotness in Flex testing is, of course, <a href="http://www.gorillalogic.com/flexmonkey">FlexMonkey</a>, developed and open-sourced by my company, <a href="http://www.gorillalogic.com/">Gorilla Logic</a>.  The next best Flex testing platform, and the new hotness in its own right, is <a href="http://www.flexunit.org/">FlexUnit 4</a>, developed and open-sourced by our partners at <a href="http://www.digitalprimates.com/">Digital Primates</a>.  FlexUnit 4 is <i>the</i> Flex 4 unit testing framework.  Because of its awesome async testing support, along with many other great features, it is ideally suited to test client-side service layers.  In this post, I&#8217;m going to explore async testing with FlexUnit 4 to better understand how I can help mitigate the pain of asynchronous backend services that are ever-present in enterprise Flex applications.</p>
<h3>Test: Create Team</h3>
<p>Let&#8217;s imagine I have my favorite data model of teams and players, with a one-to-many relationship between the two entities.  Next, let&#8217;s assume that I wrote a beautiful client-side service layer that has both basic CRUD operations like create team and delete team, and more complex operations like trade player.  I&#8217;d like to cover everything with a set of tests so I can spend my time worrying about other things.</p>
<p class="bottom">Here&#8217;s a simple async test case for the basic create team operation:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #66cc66;">&#91;</span>Test<span style="color: #66cc66;">&#40;</span>async<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> createTeam<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> token:AsyncToken = service.<span style="color: #006600;">createTeam</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Los Angeles Lakers'</span><span style="color: #66cc66;">&#41;</span>;
    token.<span style="color: #006600;">addResponder</span><span style="color: #66cc66;">&#40;</span>Async.<span style="color: #006600;">asyncResponder</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #000000; font-weight: bold;">new</span> TestResponder<span style="color: #66cc66;">&#40;</span>createTeam2, fault<span style="color: #66cc66;">&#41;</span>, TIMEOUT<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> createTeam2<span style="color: #66cc66;">&#40;</span>event:ResultEvent, passThroughData:<span style="color: #0066CC;">Object</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> token:AsyncToken = service.<span style="color: #006600;">getAllTeams</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
    token.<span style="color: #006600;">addResponder</span><span style="color: #66cc66;">&#40;</span>Async.<span style="color: #006600;">asyncResponder</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #000000; font-weight: bold;">new</span> TestResponder<span style="color: #66cc66;">&#40;</span>createTeam3, fault<span style="color: #66cc66;">&#41;</span>, TIMEOUT<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> createTeam3<span style="color: #66cc66;">&#40;</span>event:ResultEvent, passThroughData:<span style="color: #0066CC;">Object</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> teams:ArrayCollection = event.<span style="color: #006600;">result</span> as ArrayCollection;
    assertThat<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Team not created'</span>, <span style="color: #ff0000;">'Los Angeles Lakers'</span>, inArray<span style="color: #66cc66;">&#40;</span>teams.<span style="color: #006600;">toArray</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>First, we create a new team, then we load all the teams, and lastly, we verify that the newly created team is in the list.  There are two important things to note: async stuff is everywhere (<code>[Test(async)]</code> metadata, <code>AsyncToken</code>, <code>AsyncResponder</code>, etc.), and there is a chain of functions (<code>createTeam()</code> chains to <code>createTeam2()</code> which chains to <code>createTeam3()</code>).  In particular, the <b>chain</b> pattern is characteristic of any async testing.  Every single non-trivial async test involves a chain of function calls to do the work of testing an asynchronous backend.</p>
<p class="bottom">Here&#8217;s a simple diagram of the chain for the create team test:</p>
<div class="span-14 last" style="min-height:134px;">
<img src="http://saturnboy.com/wp-content/uploads/2010/02/diagram_test-create-team.png" alt="create-team" width="528" height="124" /></div>
<p>Each diagram box is just a logic operation in our test, and they also happen to correspond exactly to the functions that make up the test chain.</p>
<h3>Test: Trade Player</h3>
<p>When testing the more complex client-side service layer operations, or simply writing more complex tests, the chain pattern often develops branches and sub-chains as various pieces of state are verified asynchronously.</p>
<p class="bottom">A good example is the trade player operation, which we might test using a chain with two branches: one to verify the player was removed from old team, and one to verify the player was added to the new team.  Here&#8217;s the diagram:</p>
<div class="span-14 last" style="min-height:292px;">
<img src="http://saturnboy.com/wp-content/uploads/2010/02/diagram_test-trade-player.png" alt="trade-player" width="528" height="282" /></div>
<p>We don&#8217;t really care what goes on inside the client-side service layer to achieve this, or even what happens on the backend (it&#8217;s probably just as simple as changing the <code>team_id</code> column on the <code>players</code> table to the new team&#8217;s id).  We only care that the test passes.</p>
<p class="bottom">And the accompanying test code:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #66cc66;">&#91;</span>Test<span style="color: #66cc66;">&#40;</span>async<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> tradePlayer<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> token:AsyncToken = service.<span style="color: #006600;">tradePlayer</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Carmelo Anthony'</span>, <span style="color: #ff0000;">'Denver Nuggets'</span>, <span style="color: #ff0000;">'Cleveland Cavaliers'</span><span style="color: #66cc66;">&#41;</span>;
    token.<span style="color: #006600;">addResponder</span><span style="color: #66cc66;">&#40;</span>Async.<span style="color: #006600;">asyncResponder</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #000000; font-weight: bold;">new</span> TestResponder<span style="color: #66cc66;">&#40;</span>tradePlayer2, fault<span style="color: #66cc66;">&#41;</span>, TIMEOUT<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> tradePlayer2<span style="color: #66cc66;">&#40;</span>event:ResultEvent, passThroughData:<span style="color: #0066CC;">Object</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> token:AsyncToken = service.<span style="color: #006600;">getPlayersByTeam</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Denver Nuggets'</span><span style="color: #66cc66;">&#41;</span>;
    token.<span style="color: #006600;">addResponder</span><span style="color: #66cc66;">&#40;</span>Async.<span style="color: #006600;">asyncResponder</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #000000; font-weight: bold;">new</span> TestResponder<span style="color: #66cc66;">&#40;</span>tradePlayer3, fault<span style="color: #66cc66;">&#41;</span>, TIMEOUT<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
    <span style="color: #000000; font-weight: bold;">var</span> token2:AsyncToken = service.<span style="color: #006600;">getPlayersByTeam</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Cleveland Cavaliers'</span><span style="color: #66cc66;">&#41;</span>;
    token2.<span style="color: #006600;">addResponder</span><span style="color: #66cc66;">&#40;</span>Async.<span style="color: #006600;">asyncResponder</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #000000; font-weight: bold;">new</span> TestResponder<span style="color: #66cc66;">&#40;</span>tradePlayer4, fault<span style="color: #66cc66;">&#41;</span>, TIMEOUT<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> tradePlayer3<span style="color: #66cc66;">&#40;</span>event:ResultEvent, passThroughData:<span style="color: #0066CC;">Object</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> players:ArrayCollection = event.<span style="color: #006600;">result</span> as ArrayCollection;
    assertThat<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Traded player not removed from old team'</span>, <span style="color: #ff0000;">'Carmelo Anthony'</span>, <span style="color: #0066CC;">not</span><span style="color: #66cc66;">&#40;</span>inArray<span style="color: #66cc66;">&#40;</span>players.<span style="color: #006600;">toArray</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> tradePlayer4<span style="color: #66cc66;">&#40;</span>event:ResultEvent, passThroughData:<span style="color: #0066CC;">Object</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> players:ArrayCollection = event.<span style="color: #006600;">result</span> as ArrayCollection;
    assertThat<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Traded player not added to new team'</span>, <span style="color: #ff0000;">'Carmelo Anthony'</span>, inArray<span style="color: #66cc66;">&#40;</span>players.<span style="color: #006600;">toArray</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The interesting part occurs in the second step in the chain, <code>tradePlayer2()</code>.  In this function, we use a pair of <code>AsyncToken</code>s, to fork the chain into two sub-chains.  One sub-chain gets all the players on the old team and verifies that the traded player has been removed.  And the other sub-chain gets all the players on the new team and verifies that the trade player has been added.</p>
<h3>A Better Approach</h3>
<p>Right now, the chained function approach is the only approach for testing an asynchronous client-side service layer.  As another example, you can see the chained function approach appears again when I tested an <a href="http://www.adobe.com/products/livecycle/dataservices/">LCDS</a>-powered backend in my <a href="http://www.insideria.com/2009/12/getting-real-with-lcds-3-beta.html">Getting Real with LCDS, Part 1</a> article at <a href="http://www.insideria.com/">InsideRIA.com</a>.</p>
<p>There has got to be something better, right?  Chained functions work fine, but boy are they ugly looking in code.  I&#8217;ve been having a <a href="http://forums.adobe.com/thread/568166">discussion</a> on the FlexUnit forums about better async testing.  The general wisdom is that one could use the <code>Sequence</code> interfaces to build an async action and have the <a href="http://docs.flexunit.org/asdocs/org/fluint/sequence/SequenceRunner.html"><code>SequenceRunner</code></a> manage the chain.  Currently, the best documentation on Sequences is the old <a href="http://code.google.com/p/fluint/wiki/Sequences">Fluint wiki doc</a>.  In enterprise Flex development, async backends tend to swarm like locusts, so I hope to have some code to show soon to streamline the testing process.</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/flexunit4/test_basketball/TestBasketball.html">TestBasketball</a> (<a href="http://saturnboy.com/proj/flexunit4/test_basketball/TestRunner.html">run tests</a>, <a href="http://saturnboy.com/proj/flexunit4/test_basketball/srcview/index.html">view source</a>, <a href="http://saturnboy.com/proj/flexunit4/test_basketball/srcview/TestBaketball.zip">download</a>)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/02/async-testing-with-flexunit4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Better HTML Template for Flex 4</title>
		<link>http://saturnboy.com/2010/01/a-better-html-template-for-flex-4/</link>
		<comments>http://saturnboy.com/2010/01/a-better-html-template-for-flex-4/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 19:25:43 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[flex4]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=977</guid>
		<description><![CDATA[Adobe took a big step forward using swfobject.js to handle swf embedding in Flex 4&#8242;s index.template.html, but in my opinion they didn&#8217;t go quite far enough. Here are my changes: Short and sweet, so I can understand what the hell is going on. Use Google AJAX Libraries API to include swfobject.js. No IE6 crap. No [...]]]></description>
			<content:encoded><![CDATA[<p>Adobe took a big step forward using <a href="http://code.google.com/p/swfobject/">swfobject.js</a> to handle swf embedding in Flex 4&#8242;s <code>index.template.html</code>, but in my opinion they didn&#8217;t go quite far enough.</p>
<p class="bottom">Here are my changes:</p>
<ol>
<li>Short and sweet, so I can understand what the hell is going on.</li>
<li>Use <a href="http://code.google.com/apis/ajaxlibs/">Google AJAX Libraries API</a> to include <code>swfobject.js</code>.</li>
<li>No IE6 crap.</li>
<li>No Browser History crap.</li>
</ol>
<p class="bottom">Here&#8217;s my current version:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;${application}&lt;/title&gt;
&nbsp;
&lt;style type=&quot;text/css&quot; media=&quot;screen&quot;&gt;
html, body, #flashcontent { height:${height}; }
body { margin:0; padding:0; overflow:hidden; }
&lt;/style&gt;
&nbsp;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
swfobject.embedSWF(
    '${swf}.swf',
    'flashcontent',
    '${width}', '${height}',
    '${version_major}.${version_minor}.${version_revision}',
    '${expressInstallSwf}',
    false,
    { 'bgColor':'${bgcolor}' });
&lt;/script&gt;
&lt;/head&gt;
&nbsp;
&lt;body&gt;
&lt;div id=&quot;flashcontent&quot;&gt;
Flash is required.  &lt;a href=&quot;http://www.adobe.com/go/getflashplayer&quot;&gt;Get it here!&lt;/a&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></div></div>

<h5>Flashvars</h5>
<p class="bottom">Using <code>flashvars</code> is easy with SWFObject (see the <code>embedSWF()</code> method in the <a href="http://code.google.com/p/swfobject/wiki/api">docs</a>), just put them in as a Javascript <code>hash</code> like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot;&gt;
swfobject.embedSWF(
    '${swf}.swf',
    'flashcontent',
    '${width}', '${height}',
    '${version_major}.${version_minor}.${version_revision}',
    '${expressInstallSwf}',
    { key1:'val1', key2:'val2', key3:'val3' },
    { 'bgColor':'${bgcolor}' });
&lt;/script&gt;</pre></div></div>

<h5>View Source</h5>
<p class="bottom">Lastly, here&#8217;s a little trick that I use to embed flash into a post on this blog (or anywhere else) that enables view source to work with a relative url, so I can leave the <code>viewSourceURL</code> attribute alone (defaults to <code>viewSourceURL="srcview/index.html"</code>).</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot;&gt;
swfobject.embedSWF(
    '${swf}.swf',
    'flashcontent',
    '${width}', '${height}',
    '${version_major}.${version_minor}.${version_revision}',
    '${expressInstallSwf}',
    false,
    { 'bgColor':'${bgcolor}', base:'.' });
&lt;/script&gt;</pre></div></div>

<p>Adding the <code>base</code> parameter, and setting it to <code>'.'</code>, tells the embedded SWF to lookup urls relative to itself.  The net effect is that view source just works.</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/wp-content/uploads/2010/01/index.template.html">index.template.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/01/a-better-html-template-for-flex-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Special Characters in Flex 4</title>
		<link>http://saturnboy.com/2010/01/special-characters-flex-4/</link>
		<comments>http://saturnboy.com/2010/01/special-characters-flex-4/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 05:07:31 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[regexp]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=926</guid>
		<description><![CDATA[Recently, I was caught by a special characters vs. html entities issue in Flex 4. For reference, you can read more about special characters in the text property of a text component in the official docs. And also here on Flex Examples. Unfortunately, neither of these was exactly what I was looking for. The Problem [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I was caught by a special characters vs. html entities issue in Flex 4.  For reference, you can read more about special characters in the <code>text</code> property of a text component in the <a href="http://help.adobe.com/en_US/Flex/4.0/UsingSDK/WS2db454920e96a9e51e63e3d11c0bf69084-7d53.html">official docs</a>.  And also <a href="http://blog.flexexamples.com/2007/08/02/using-special-characters-in-your-flex-applications/">here</a> on <a href="http://blog.flexexamples.com/">Flex Examples</a>.  Unfortunately, neither of these was exactly what I was looking for.</p>
<h5>The Problem</h5>
<p>I had an array of names in ActionScript that potentially contained special characters, and I wanted to output them in a spark <code>List</code> component.  Nothing magical required, just get them on the screen.</p>
<h5>Solution #1</h5>
<p class="bottom">One option, which I&#8217;ve <b>NEVER</b> seen in anyone&#8217;s code ever, is to move the definition of the array into its own <code>Script</code> tag without the <code>CDATA</code> block.  For example:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;</span>fx<span style="color: #000000; font-weight: bold;">:</span>Script<span style="color: #000000; font-weight: bold;">&gt;</span>
    <span style="color: #000000;">&#91;</span>Bindable<span style="color: #000000;">&#93;</span> <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #6699cc; font-weight: bold;">var</span> nuggets<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">Array</span> = <span style="color: #000000;">&#91;</span>
        <span style="color: #990000;">'Carmelo Anthony'</span>,
        <span style="color: #990000;">'Chauncey Billups'</span>,
        <span style="color: #990000;">'Nen&amp;#234;'</span>,
        <span style="color: #990000;">'Kenyon Martin'</span><span style="color: #000000;">&#93;</span>;
<span style="color: #000000; font-weight: bold;">&lt;/</span>fx<span style="color: #000000; font-weight: bold;">:</span>Script<span style="color: #000000; font-weight: bold;">&gt;</span></pre></div></div>

<p>Now, it doesn&#8217;t matter if we use single quotes (<code>'</code>) or double quotes (<code>"</code>), because outside of the <code>CDATA</code> block all numeric html entities are processed.  The fact that Flash Builder 4 automatically inserts the <code>CDATA</code> block when you open a <code>Script</code> tag probably means that almost no one has ever even heard of this possible solution.  It&#8217;s so weird, I can&#8217;t recommend this solution.</p>
<blockquote class="deeper"><p><b>Digging Deeper:</b> The <a href="http://help.adobe.com/en_US/Flex/4.0/UsingSDK/WS2db454920e96a9e51e63e3d11c0bf69084-7d53.html">official docs</a> will tell you that only a few named html entities work (<code>&amp;lt;</code>, <code>&amp;gt;</code>, <code>&amp;amp;</code>, <code>&amp;quot;</code>, <code>&amp;apos;</code>), and after that you must use numeric html entities (<code>&amp;#NNN;</code>).</p></blockquote>
<h5>Solution #2</h5>
<p class="bottom">Another option, that I actually thought of first, is to process the numeric html entities via a regular expression to output the correct special character.  For example:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> makeSpecialChars<span style="color: #000000;">&#40;</span>item<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">Object</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">String</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #0033ff; font-weight: bold;">return</span> item.<span style="color: #004993;">toString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #004993;">replace</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight: bold;">/&amp;</span>#\<span style="color: #004993;">d</span><span style="color: #000000; font-weight: bold;">+</span>;<span style="color: #000000; font-weight: bold;">/</span>g, replaceFunc<span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> replaceFunc<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">String</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> s<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">String</span> = <span style="color: #004993;">arguments</span><span style="color: #000000;">&#91;</span><span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#93;</span>;
    s = s.<span style="color: #004993;">substring</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">2</span>, s.<span style="color: #004993;">length</span> <span style="color: #000000; font-weight: bold;">-</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span>;
    s = <span style="color: #004993;">String</span>.<span style="color: #004993;">fromCharCode</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">parseInt</span><span style="color: #000000;">&#40;</span>s<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #0033ff; font-weight: bold;">return</span> s;
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>We use a simple regular expression to match any numeric html entity, and then call a replacement function to do the work of converting the entity into a special character.  The static method <code>String.fromCharCode</code> does the actual conversion.</p>
<p class="bottom">Putting the converter code together with a <code>List</code>&#8216;s <code>labelFunction</code> property and we get this:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Script</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;">&lt;!<span style="color: #66cc66;">&#91;</span>CDATA<span style="color: #66cc66;">&#91;</span></span>
<span style="color: #000000;">    <span style="color: #66cc66;">&#91;</span>Bindable<span style="color: #66cc66;">&#93;</span> private var nuggets2:Array = <span style="color: #66cc66;">&#91;</span></span>
<span style="color: #000000;">        <span style="color: #ff0000;">'Carmelo Anthony'</span>,</span>
<span style="color: #000000;">        <span style="color: #ff0000;">'Chauncey Billups'</span>,</span>
<span style="color: #000000;">        <span style="color: #ff0000;">'Nen&amp;#234;'</span>,</span>
<span style="color: #000000;">        <span style="color: #ff0000;">'Kenyon Martin'</span><span style="color: #66cc66;">&#93;</span>;</span>
&nbsp;
<span style="color: #000000;">    private function makeSpecialChars<span style="color: #66cc66;">&#40;</span>item:Object<span style="color: #66cc66;">&#41;</span>:String <span style="color: #66cc66;">&#123;</span></span>
<span style="color: #000000;">        ...same as above...</span>
<span style="color: #000000;">    <span style="color: #66cc66;">&#125;</span></span>
<span style="color: #000000;"><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Script</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:List</span> dataProvider=<span style="color: #ff0000;">&quot;{new ArrayList(nuggets2)}&quot;</span></span>
<span style="color: #000000;">    labelFunction=<span style="color: #ff0000;">&quot;makeSpecialChars&quot;</span> <span style="color: #7400FF;">/&gt;</span></span></pre></div></div>

<p>For each element in the array, the <code>labelFunction</code> gets called and any numeric html entity is converted into the corresponding special character.  No magic.</p>
<h5>The Result</h5>
<p class="bottom">Here is the final result with both Solution #1 and Solution #2 together (view source enabled):</p>
<div id="flashcontent-special-chars">
Flash is required.  <a href="http://www.adobe.com/go/getflashplayer">Get it here!</a>
</div>
<p>If you view the source, you can see that I&#8217;m using two separate <code>Script</code> tags, one with a <code>CDATA</code> block and one without.  Who does that?</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/flex4/special_chars/SpecialChars.html">SpecialChars</a> (<a href="http://saturnboy.com/proj/flex4/special_chars/srcview/SpecialChars.zip">download</a>)</li>
</ul>
<div>
<script type="text/javascript">
swfobject.embedSWF('http://saturnboy.com/proj/flex4/special_chars/SpecialChars.swf', 'flashcontent-special-chars', '420', '160', '10.0.0', 'playerProductInstall.swf', false, { bgColor:'#ffffff', base:'.' });
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/01/special-characters-flex-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LCDS and MySQL Views</title>
		<link>http://saturnboy.com/2009/12/lcds-and-mysql-views/</link>
		<comments>http://saturnboy.com/2009/12/lcds-and-mysql-views/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 19:31:56 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[flex4]]></category>
		<category><![CDATA[LCDS]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=849</guid>
		<description><![CDATA[Once upon a time, in what now seems to be a prior life, I became a published author when my thesis hit the university press. That time has come again. After much effort, the second longest thing I have ever written has been published by InsideRIA. I wrote a two-part article titled Getting Real with [...]]]></description>
			<content:encoded><![CDATA[<p>Once upon a time, in what now seems to be a prior life, I became a published author when my thesis hit the university press.  That time has come again.  After much effort, the second longest thing I have ever written has been published by <a href="http://www.insideria.com/">InsideRIA</a>.  I wrote a two-part article titled <i>Getting Real with LCDS 3</i> (<a href="http://www.insideria.com/2009/12/getting-real-with-lcds-3-beta.html">Part 1</a> &#038; <a href="http://www.insideria.com/2009/12/getting-real-with-lcds-3-part.html">Part 2</a>) that covers the basics of model driven development with LCDS 3.  Yeah me.</p>
<h5>More Fun with LCDS</h5>
<p>Since I&#8217;m such a new-stuff-loving guy I can&#8217;t help but return to the backend after a few months on the frontend with various <a href="http://www.axiis.org/">Axiis</a> visualizations (<a href="http://saturnboy.com/2009/10/axiis-quest-for-cool/">here</a> &#038; <a href="http://saturnboy.com/2009/11/interactive-visualization-with-axiis/">here</a>) and a <a href="http://www.gskinner.com/libraries/gtween/">GTween</a> animation (<a href="http://saturnboy.com/2009/12/gtween-easing-flex-4/">here</a>).  So, it&#8217;s back to LCDS.  Of course, since I last wrote about LCDS, Adobe has shipped <a href="http://www.adobe.com/products/livecycle/dataservices/">LCDS 3</a>, but thankfully they still provide a free developer trial.  This time around, I&#8217;ll look at LCDS and <a href="http://dev.mysql.com/doc/refman/5.1/en/create-view.html">MySQL Views</a>.</p>
<h5>Create Database and Tables</h5>
<p class="bottom">First, let&#8217;s set the scene by constructing a new database and some tables. Here&#8217;s the database:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">DATABASE</span> football;
<span style="color: #993333; font-weight: bold;">CREATE</span> USER <span style="color: #ff0000;">'baller'</span>@<span style="color: #ff0000;">'localhost'</span> <span style="color: #993333; font-weight: bold;">IDENTIFIED</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">'password'</span>;
<span style="color: #993333; font-weight: bold;">GRANT</span> <span style="color: #993333; font-weight: bold;">ALL</span> PRIVILEGES <span style="color: #993333; font-weight: bold;">ON</span> football<span style="color: #66cc66;">.*</span> <span style="color: #993333; font-weight: bold;">TO</span> baller@localhost;</pre></div></div>

<p class="bottom">And here are the tables:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> teams <span style="color: #66cc66;">&#40;</span>
  id int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> players <span style="color: #66cc66;">&#40;</span>
  id int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  salary int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  team_id int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> games <span style="color: #66cc66;">&#40;</span>
  id int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  team_id int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  opp_id int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  points int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  win tinyint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Lastly, we insert some <a href="http://saturnboy.com/proj/lcds/football/data.sql">sample data</a> into the database via a script.  The final result is our familiar teams-and-players database, but this time with an additional <code>games</code> table.</p>
<h5>MySQL Views</h5>
<p>A database <i>view</i> is one way to push logic and computations down from the application layer into the database.  A judicious use of views can really help keep the application layer nice and clean.  But much like database de-normalization, adding views to the database often feels like premature optimization, so be careful.  LCDS and the Modeler plugin treat database views just like tables, so everything just works (sort of).  </p>
<p><a href="http://www.mysql.com/">MySQL</a> is a full-featured database that provides a simple <code>CREATE VIEW</code> syntax.  For our purposes, a <i>view</i> can be thought of as nothing more than another table that is constructed from other tables via a <code>SELECT</code> statement.  Because of this, database views are sometimes called <i>virtual tables</i>.  The <code>SELECT</code> statement used to construct the view is often very complicated, involving multiple tables, joins, functions, expressions, and more.</p>
<p class="bottom">For our example, we will construct two views.  First, the <code>team_summary</code> view packages up information from the <code>teams</code> and <code>players</code> tables:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">VIEW</span> team_summary <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">SELECT</span>
  t<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">,</span>
  t<span style="color: #66cc66;">.</span>name<span style="color: #66cc66;">,</span>
  COUNT<span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> num_players<span style="color: #66cc66;">,</span>
  ROUND<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">.</span>salary<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1000000</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> payroll<span style="color: #66cc66;">,</span>
  ROUND<span style="color: #66cc66;">&#40;</span>AVG<span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">.</span>salary<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> avg_salary<span style="color: #66cc66;">,</span>
  MIN<span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">.</span>salary<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> lowest_salary<span style="color: #66cc66;">,</span>
  MAX<span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">.</span>salary<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> highest_salary
<span style="color: #993333; font-weight: bold;">FROM</span> teams <span style="color: #993333; font-weight: bold;">AS</span> t<span style="color: #66cc66;">,</span> players <span style="color: #993333; font-weight: bold;">AS</span> p <span style="color: #993333; font-weight: bold;">WHERE</span> t<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> p<span style="color: #66cc66;">.</span>team_id <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> t<span style="color: #66cc66;">.</span>id;</pre></div></div>

<p class="bottom">The <code>CREATE VIEW</code> above joins the <code>teams</code> and <code>players</code> tables to create seven columns.  Here&#8217;s a brief description of the generated columns:</p>
<hr class="bottom" style="height: 3px;" />
<div class="span-3">&nbsp;<b>id</b></div>
<div class="span-10 last">team id directly from teams table</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>name</b></div>
<div class="span-10 last">team name directly from teams table</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>num_players</b></div>
<div class="span-10 last">count up all player ids</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>payroll</b></div>
<div class="span-10 last">sum all player salaries</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>avg_salary</b></div>
<div class="span-10 last">average all player salaries</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>highest_salary</b></div>
<div class="span-10 last">find the maximum player salary</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>lowest_salary</b></div>
<div class="span-10 last">find the minimum player salary</div>
<hr style="height: 3px;" />
<p class="bottom">Next, we create the <code>game_summary</code> view to collect data from the <code>teams</code> and <code>games</code> tables:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">VIEW</span> game_summary <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">SELECT</span>
  t<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">,</span>
  t<span style="color: #66cc66;">.</span>name<span style="color: #66cc66;">,</span>
  CAST<span style="color: #66cc66;">&#40;</span>CONCAT<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>g<span style="color: #66cc66;">.</span>win<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'-'</span><span style="color: #66cc66;">,</span> COUNT<span style="color: #66cc66;">&#40;</span>g<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> SUM<span style="color: #66cc66;">&#40;</span>g<span style="color: #66cc66;">.</span>win<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> CHAR<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> record<span style="color: #66cc66;">,</span>
  CAST<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>g<span style="color: #66cc66;">.</span>points<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> SIGNED<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> points_for
<span style="color: #993333; font-weight: bold;">FROM</span> teams <span style="color: #993333; font-weight: bold;">AS</span> t<span style="color: #66cc66;">,</span> games <span style="color: #993333; font-weight: bold;">AS</span> g <span style="color: #993333; font-weight: bold;">WHERE</span> t<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> g<span style="color: #66cc66;">.</span>team_id <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> t<span style="color: #66cc66;">.</span>id;</pre></div></div>

<p class="bottom">And a brief description of the generated columns:</p>
<hr class="bottom" style="height: 3px;" />
<div class="span-3">&nbsp;<b>id</b></div>
<div class="span-10 last">team id directly from teams table</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>name</b></div>
<div class="span-10 last">team name directly from teams table</div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>record</b></div>
<div class="span-10 last">concatenate number of wins with number of losses (computed via total games minus wins) </div>
<hr class="bottom" style="background-color:#aaa; height:1px;" />
<div class="span-3">&nbsp;<b>points_for</b></div>
<div class="span-10 last">sum up all the team&#8217;s points for all games</div>
<hr style="height: 3px;" />
<blockquote class="deeper"><p><b>Digging Deeper:</b> The <code>CAST</code> statements are not necessary to construct the <code>game_summary</code> view as far as MySQL is concerned, but I need them to force the correct column types to make LCDS happy.</p></blockquote>
<h5>LCDS 3 and the Modeler Plugin</h5>
<p class="bottom">Now that our database is happily configured, fire up Flash Builder 4 and switch to the Modeler plugin.  Create and configure a new LCDS webapp, and then take a look at the RDS Dataview panel:</p>
<div class="span-14 last" style="min-height:275px;">
<img src="http://saturnboy.com/wp-content/uploads/2009/12/mysql-views-rds-dataview.png" alt="rds-dataview" width="329" height="265" />
</div>
<p class="bottom">You can see both views and tables.  Next, simply drag whatever tables or views you want over to the Modeler.  Here&#8217;s the final model for our sample application:</p>
<div class="span-14 last" style="min-height:283px;">
<img src="http://saturnboy.com/wp-content/uploads/2009/12/mysql-views-model.png" alt="model" width="495" height="263" />
</div>
<h5>LCDS Modeler Tricks &amp; Tips</h5>
<p class="bottom">There are a couple of tricks to getting views working correctly in LCDS:</p>
<ol>
<li>Mark each view entity as persistent in the Properties panel (in theory, views can support updates to only those columns that are one-to-one mapped to a table)</li>
<li>Set the <code>id</code> column as the <code>ID</code> property (this is required because views don&#8217;t have primary keys, so you have to tell LCDS what to do)</li>
<li>Verify that the database types have correctly come across to LCDS, if not add a <code>CAST</code> to the view column to force the correct type (see table below)</li>
</ol>
<p class="bottom">Here&#8217;s a simple table showing how the types move from the MySQL database to LCDS, and then from LCDS to PASOs (aka Plain old ActionScript Objects):</p>
<hr class="bottom" style="height: 3px; width:320px;" />
<div class="span-2">&nbsp;<b>MySQL</b></div>
<div class="span-1">&rarr;</div>
<div class="span-2"><b>LCDS</b></div>
<div class="span-1">&rarr;</div>
<div class="span-2 last"><b>PASOs</b></div>
<hr class="bottom" style="background-color:#aaa; width:320px; height: 2px;" />
<div class="span-3">&nbsp;int</div>
<div class="span-3">int</div>
<div class="span-2 last">int</div>
<hr class="bottom" style="background-color:#aaa; width:320px; height:1px;" />
<div class="span-3">&nbsp;bigint</div>
<div class="span-3">long</div>
<div class="span-2 last">int</div>
<hr class="bottom" style="background-color:#aaa; width:320px; height:1px;" />
<div class="span-3">&nbsp;decimal</div>
<div class="span-3">double</div>
<div class="span-2 last">Number</div>
<hr class="bottom" style="background-color:#aaa; width:320px; height:1px;" />
<div class="span-3">&nbsp;varchar</div>
<div class="span-3">string</div>
<div class="span-2 last">String</div>
<hr style="height: 3px; width:320px;" />
<h5>Data</h5>
<p class="bottom">We can view the data in the database by using the RDS Query Viewer.  Here is the <code>team_summary</code> data:</p>
<div class="span-14 last" style="min-height:229px;">
<img src="http://saturnboy.com/wp-content/uploads/2009/12/mysql-views-rds-query-team-summary.png" alt="team-summary" width="530" height="219" />
</div>
<p class="bottom">And here is the <code>game_summary</code> data:</p>
<div class="span-14 last" style="min-height:239px;">
<img src="http://saturnboy.com/wp-content/uploads/2009/12/mysql-views-rds-query-game-summary.png" alt="game-summary" width="530" height="219" />
</div>
<h5>The App</h5>
<p class="bottom">Alas, since this is an LCDS app, no running demo is possible.  Here&#8217;s a screenshot instead, showing a selected team and the associated team &amp; game summary data.</p>
<div class="span-14 last" style="min-height:214px;">
<img src="http://saturnboy.com/wp-content/uploads/2009/12/mysql-views-app-screenshot.png" alt="screenshot" width="505" height="194" style="border: 1px solid #ccc; padding: 10px;" />
</div>
<p>Our sample app closely follows the plan I set forward in <a href="http://www.insideria.com/2009/12/getting-real-with-lcds-3-part.html">Getting Real with LCDS, Part 2</a>.  We define our services and associated <code>CallResponder</code>&#8216;s in MXML, and event handlers in ActionScript.</p>
<p class="bottom">Here is the relevant section of code showing the various event handlers:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> teamChangeHandler<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> teamId:<span style="color: #0066CC;">int</span> = <span style="color: #0066CC;">list</span>.<span style="color: #006600;">selectedItem</span>.<span style="color: #006600;">id</span>
	getTeamSummary.<span style="color: #006600;">token</span> = teamSummaryService.<span style="color: #006600;">getById</span><span style="color: #66cc66;">&#40;</span>teamId<span style="color: #66cc66;">&#41;</span>;
	getGameSummary.<span style="color: #006600;">token</span> = gameSummaryService.<span style="color: #006600;">getById</span><span style="color: #66cc66;">&#40;</span>teamId<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getTeamSummaryResult<span style="color: #66cc66;">&#40;</span>event:ResultEvent<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> summary:TeamSummary = <span style="color: #66cc66;">&#40;</span>event.<span style="color: #006600;">result</span> as IList<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">getItemAt</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> as TeamSummary;
	numPlayers.<span style="color: #0066CC;">text</span> = summary.<span style="color: #006600;">numPlayers</span>.<span style="color: #0066CC;">toString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	payroll.<span style="color: #0066CC;">text</span> = cf2.<span style="color: #006600;">format</span><span style="color: #66cc66;">&#40;</span>summary.<span style="color: #006600;">payroll</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #ff0000;">' million'</span>;
	avgSalary.<span style="color: #0066CC;">text</span> = cf.<span style="color: #006600;">format</span><span style="color: #66cc66;">&#40;</span>summary.<span style="color: #006600;">avgSalary</span><span style="color: #66cc66;">&#41;</span>;
	lowestSalary.<span style="color: #0066CC;">text</span> = cf.<span style="color: #006600;">format</span><span style="color: #66cc66;">&#40;</span>summary.<span style="color: #006600;">lowestSalary</span><span style="color: #66cc66;">&#41;</span>;
	highestSalary.<span style="color: #0066CC;">text</span> = cf.<span style="color: #006600;">format</span><span style="color: #66cc66;">&#40;</span>summary.<span style="color: #006600;">highestSalary</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getGameSummaryResult<span style="color: #66cc66;">&#40;</span>event:ResultEvent<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> summary:GameSummary = <span style="color: #66cc66;">&#40;</span>event.<span style="color: #006600;">result</span> as IList<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">getItemAt</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> as GameSummary;
	record.<span style="color: #0066CC;">text</span> = summary.<span style="color: #006600;">record</span>;
	pointsFor.<span style="color: #0066CC;">text</span> = summary.<span style="color: #006600;">pointsFor</span>.<span style="color: #0066CC;">toString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p class="bottom">And here is the MXML <code>Declarations</code> block:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Declarations</span><span style="color: #7400FF;">&gt;</span></span>
	<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:CallResponder</span> id=<span style="color: #ff0000;">&quot;getAllTeams&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
	<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:CallResponder</span> id=<span style="color: #ff0000;">&quot;getTeamSummary&quot;</span> result=<span style="color: #ff0000;">&quot;getTeamSummaryResult(event)&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
	<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:CallResponder</span> id=<span style="color: #ff0000;">&quot;getGameSummary&quot;</span> result=<span style="color: #ff0000;">&quot;getGameSummaryResult(event)&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
	<span style="color: #000000;"><span style="color: #7400FF;">&lt;football:TeamService</span> id=<span style="color: #ff0000;">&quot;teamService&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
	<span style="color: #000000;"><span style="color: #7400FF;">&lt;football:TeamSummaryService</span> id=<span style="color: #ff0000;">&quot;teamSummaryService&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
	<span style="color: #000000;"><span style="color: #7400FF;">&lt;football:GameSummaryService</span> id=<span style="color: #ff0000;">&quot;gameSummaryService&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Declarations</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>The application is very simple.  When a user clicks on a team, the <code>teamChangeHandler()</code> is called.  The handler queries the LCDS backend and sets the <code>CallResponder</code>&#8216;s <code>token</code> property.  When the asynchronous backend eventually returns some data, the data is forwarded to the appropriate result handler.  In the result handler, the incoming PASO has it&#8217;s properties are formatted and then assigned to the matching form element for display.</p>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/lcds/football/Football.zip">Football.zip</a></li>
<li><a href="http://saturnboy.com/proj/lcds/football/create_db.sql">create_db.sql</a></li>
<li><a href="http://saturnboy.com/proj/lcds/football/create_tables.sql">create_tables.sql</a></li>
<li><a href="http://saturnboy.com/proj/lcds/football/create_views.sql">create_views.sql</a></li>
<li><a href="http://saturnboy.com/proj/lcds/football/data.sql">data.sql</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2009/12/lcds-and-mysql-views/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
