Development
Spark StackedFormSkin with ridiculous padding
May 10th
The spark StackedFormSkin is fantastic for laying out forms in a way that use a minimal amount of horizontal space, but still look nice and are a nice default look and feel for forms that you might be creating. The downside to them is that they have an absurd amount of padding around the items (perhaps flex is expecting you to use 16pt fonts or something.) The really unfortunate part is that the paddings are not available for modification via CSS. In other words, if you are frustrated that you can’t set the padding on a spark Form with the StackedFormSkin (and StackedFormItemSkin) then this is the post for you!
Here’s an example of a form using the standard StackedFormSkin

Note all of the wasted space around the various components. I have added the following, which simply adds the ability to specify the padding around the components (with the original static values as the defaults.)
StylableStackedFormSkin
<!--?xml version="1.0" encoding="utf-8"?-->
<!-- ADOBE SYSTEMS INCORPORATED Copyright 2010 Adobe Systems Incorporated All Rights Reserved. NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms of the license agreement accompanying it. -->
<![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.Form")] ]]>
<![CDATA[ [Bindable] private var paddingLeft:Number = 10; [Bindable] private var paddingRight:Number = 10; [Bindable] private var paddingTop:Number = 10; [Bindable] private var paddingBottom:Number = 10; [Bindable] private var gap:Number = 7; /** * @private */ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void { updateNumberStyle('paddingLeft'); updateNumberStyle('paddingRight'); updateNumberStyle('paddingTop'); updateNumberStyle('paddingBottom'); updateNumberStyle('gap'); // Push backgroundColor and backgroundAlpha directly. // Handle undefined backgroundColor by hiding the background object. if (isNaN(getStyle("backgroundColor"))) { background.visible = false; } else { background.visible = true; bgFill.color = getStyle("backgroundColor"); bgFill.alpha = getStyle("backgroundAlpha"); } super.updateDisplayList(unscaledWidth, unscaledHeight); } private function updateNumberStyle(styleName:String, internalPropertyName:String = null):void { if(!internalPropertyName) { internalPropertyName = styleName; } if(!isNaN(getStyle(styleName))) { this[internalPropertyName] = getStyle(styleName); } } ]]>
<!--- Defines the appearance of the Form class's background. -->
<!--- @private -->
<!-- Note: setting the minimum size to 0 here so that changes to the host component's size will not be thwarted by this skin part's minimum size. This is a compromise, more about it here: http://bugs.adobe.com/jira/browse/SDK-21143 -->
<!--- Displays the error text of the Form. -->
<!-- We set Form's showErrorTip and showErrorSkin to false, so we set them back to true for the Form's elements -->
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
StylableStackedFormItemSkin
<!--?xml version="1.0" encoding="utf-8"?-->
<!-- ADOBE SYSTEMS INCORPORATED Copyright 2010 Adobe Systems Incorporated All Rights Reserved. NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms of the license agreement accompanying it. -->
<!-- host component -->
<![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.FormItem")] ]]>
<![CDATA[ [Bindable] private var paddingLeft:Number = 10; [Bindable] private var paddingRight:Number = 10; [Bindable] private var paddingTop:Number = 10; [Bindable] private var paddingBottom:Number = 10; /** * @private */ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void { updateNumberStyle('paddingLeft'); updateNumberStyle('paddingRight'); updateNumberStyle('paddingTop'); updateNumberStyle('paddingBottom'); // Push backgroundColor and backgroundAlpha directly. // Handle undefined backgroundColor by hiding the background object. if (isNaN(getStyle("backgroundColor"))) { background.visible = false; } else { background.visible = true; bgFill.color = getStyle("backgroundColor"); bgFill.alpha = getStyle("backgroundAlpha"); } var indicatorSource:Object; if (currentState == "error" || currentState == "requiredAndError") indicatorSource = getStyle("errorIndicatorSource"); else if (currentState == "required" || "requiredAndDisabled") indicatorSource = getStyle("requiredIndicatorSource"); if (indicatorSource && indicatorDisplay) { indicatorDisplay.source = indicatorSource; } super.updateDisplayList(unscaledWidth, unscaledHeight); } /** * @private */ override public function setCurrentState(stateName:String, playTransition:Boolean=true):void { super.setCurrentState(stateName, playTransition); invalidateDisplayList(); } private function updateNumberStyle(styleName:String, internalPropertyName:String = null):void { if(!internalPropertyName) { internalPropertyName = styleName; } if(!isNaN(getStyle(styleName))) { this[internalPropertyName] = getStyle(styleName); } } ]]>
<!--- The column containing the sequence label. -->
<!--- The column containing the FormItem's label and content. -->
<!--- The column containing the FormItem's help content. -->
<!--- @private -->
<!--- @private -->
<!--- Defines the appearance of the FormItem's background. -->
<!--- @private -->
<!--- @copy spark.components.FormItem#sequenceLabelDisplay -->
<!--- @copy spark.components.FormItem#labelDisplay -->
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
<!--- @private -->
<!--- @copy spark.components.FormItem#helpContentGroup -->
default.css
/*Form Styling*/
s|Form {
skinClass: ClassReference("StylableStackedFormSkin");
paddingLeft: 0;
paddingRight: 0;
paddingTop: 0;
paddingBottom: 0;
gap: 0;
}
s|FormItem {
skinClass: ClassReference("StylableStackedFormItemSkin");
paddingLeft: 0;
paddingRight: 0;
paddingTop: 0;
paddingBottom: 0;
}
As you can see with the image below, the amount of space can be reduced to a much more appropriate amount for smaller font sizes.

Flex Spark Forms Overrdraw Woes
May 10th
When working with Flex (in particular with the spark framework) you run into scenarios where labels and other text-type fields will overdraw their containers. This is particularly obvious when you have a Spark form. I’ve noticed this with the Flex 4.5 and 4.6 SDKs.

The reason it does this is that the default Group (and it’s subclasses VGroup and HGroup) do not, by default, scroll when the content is larger than the container size. Their default behavior is to allow overdrawing. To resolve, simply wrap your Group parent in a s:Scroller tag, as below:
BEFORE:
<s:Form width="100%" height="100%">
<s:FormItem label="Name" width="100%">
<s:TextInput id="Name" />
</s:FormItem>
</s:Form>
AFTER:
<s:Scroller width="100%" height="100%"> <s:VGroup width="100%" height="100%"> <s:Form width="100%" height="100%"> <s:FormItem label="Name" width="100%"> <s:TextInput id="Name" /> </s:FormItem> </s:Form> </s:VGroup> </s:Scroller>

Your end result is a form that work much more nicely with the container. If the content requires more space than that allowed by the Form’s container, it will go into a scroll-state.
Adobe AIR and iOS Certificate Woes
Mar 30th
I’ve recently gotten into Adobe Air on mobile devices (seeing as I had to write an iPad app for work, and our main UI is all built in Flex, this was a perfect framework for me.) Getting ready to go on vacation, I ran into a very frustrating problem when I tried to load the application onto my device for testing. “APP_NAME could not be installed.”
Adobe Air works on mobile devices by cross-compiling the flash into iOS native code. During the cross-compile, the application is signed for deployment via the Apple App Store (or Ad-Hoc distribution.) This signature process through me off my game, as there are a combination of certificates, provisioning profiles, and other madness.
I was finally able to get my application to run and install correctly when I did the following:
1) Found the “Distribution” certificate. This is generated on the Apple website using the Certificate Request mechanism
2) Generated a Ad Hoc Distribution certificate for my application. This should be tied to the Distribution certificate
3) Set the application id in the application config to the name of the Apple application id (without the “company prefix”)
4) Signed the application using adt, the certificate, the mobile provision, and the appropriate application config.
The part that caught me up was the application ID didn’t match the one in the configuration file, and so my application wouldn’t install. This was particularly frustrating as the adt still signed the .ipa file, it just wouldn’t load on my iPad.
Long story short, if you get this error, make absolutely sure you are signing it with the right id.
Btw, I have a simple project template with ant that will do all this for those that are interested. Let me know if you want me to post it.
- Posted from my iPad
Running Lejos on RCX 2.0 and Mac OSX Snow Leopard
Mar 27th
Yesterday I purchased a Lego Mindstorms NXT 2.0 for my son.
It was ridiculously expensive. I had a focus on robotics in my BS program, so I was excited to build some robots with him. At the time, we used the Lego Robotics Invention System (now called RCX). I went onto craigslist and found one of these machines so that I could build robots with my son, but without the $300+ pricetag.
After procuring the machine, I spent some time trying to setup the development environment I had used back in college. Unfortunately, the C toolchain I had used was not available for Mac (at least, I couldn’t find a tutorial on setting it up.) I found an interesting firmware replacement at lejos.org that allows you to code your applications in java, using a custom library set.
Being a Java developer by day, this appealed to me quite a bit. So I set about the long process of trying to get lejos to work on my 64-bit Snow Leopard MBP… and failed miserably. There were compilation issues (conversion of 64-bit pointers to 32-bit handles in the code necessary to communicate with the IR tower (used to program the RCX).
Finally, I found http://lejos.sourceforge.net/forum/viewtopic.php?f=10&t=1673, and the link by tsinn where he’d setup an installer for the lejos subsystem and toolchain onto Mac OSX 10.5 (a 32-bit system). After downloading his system, then making a couple of tweaks, I was able to generate the following package: http://kennelbound.com/downloads/lejos3.zip
To use, simply do the following:
1) Download and extract the lejos3,zip to a local folder (such as /personal/lejos3)
2) Edit the lejos.env file and change the LEJOS_HOME to point to the directory where you extracted it.
3) Open a command console, and cd to the LEJOS_HOME directory
4) Type in “source lejos.env” (without the quotes)
5) cd to the LEJOS_HOME/bin directory
6) Install the firmware onto the RCX using “./firmdl” without the quotes
7) You should see some progress. Once it completes, you now have the RCX running lejos!
You can test it with a simple Hello World application:
1) cd to lejos3/examples/test/hworld
2) execute “lejosjc HelloWorld; lejos HelloWorld” without the quotes to compile and send the program to the RCX.
3) Once it’s done, on the RCX, press the “Run” button.
You should see “hello world” on the RCX’s LCD.
Next time, I’ll write down how I have Intellij setup so that I can run and load the applications with ease!