Filed under: actionScript, components, development, flash, flex, jwo_lib
If you have done any custom component development then you have most likely attempted some level of default styling for your custom components. Very recently I developed a custom component for jwo_lib that required button skins located in a swf. I am not particularly too fond of following Flex’s default.css styling model as if you are attempting to create a component library then that css file also has to be included in the swc.
Assuming for the moment that we are not using an external css file to embed assets (i.e. Flex’s default method), that leaves us only two other options.
- define a separate class (I generally call it an AssetImporter) with bindable, embedded, public properties referencing the needed assets from the swf. This entails another class to be added to the library.
- define the default class styling in the class itself.
I opted for the latter option. Two reasons for this: 1) it doesn’t require yet another file to be added to the library and 2) the styling associated with the component in question is located in the most logical place for that component, the class file itself. Again this is default styling, meaning how I the creator intended the component to look like. So again this is the most logical place for the code to reside.
Now we need the class code to perform all this nonsense. I do all my default styling via the method that Adobe recommends but for some reason does not do themselves. Funny though how none of the examples explain how to programmatically embed assets via this method. Check this out:
private static var defaultStylesInitialized:Boolean = setDefaultStyles();
private static function setDefaultStyles ():Boolean
{
//copy over old styles if applicable
var oldS:CSSStyleDeclaration = StyleManager.getStyleDeclaration("TextInput");
var s:CSSStyleDeclaration = new CSSStyleDeclaration();
if (oldS)
{
//copy over old styles
s = oldS;
//clear old style
StyleManager.clearStyleDeclaration("TextInput", true);
}
//create embedded skin vars
[Embed (source="/assets/swf/closeButtonSkins.swf", symbol="CloseButton_disabledSkin")]
var disabledSkin:Class;
[Embed (source="/assets/swf/closeButtonSkins.swf", symbol="CloseButton_downSkin")]
var downSkin:Class;
[Embed (source="/assets/swf/closeButtonSkins.swf", symbol="CloseButton_overSkin")]
var overSkin:Class;
[Embed (source="/assets/swf/closeButtonSkins.swf", symbol="CloseButton_upSkin")]
var upSkin:Class;
//add new default styles
s.setStyle("horizontalGap", 5);
s.setStyle("disabledSkin", disabledSkin);
s.setStyle("downSkin", downSkin);
s.setStyle("overSkin", overSkin);
s.setStyle("upSkin", upSkin);
StyleManager.setStyleDeclaration("TextInput", s, true);
return true;
}
Hope that helps
16 Comments so far
Leave a comment
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

I don’t understand why you would get the old style declaration from the StyleManager and copy it into a new one before adding your own styles and assigning it back.
Is this because the call to set style will cascade through the entire display list, and you want to reduce this performance hit?
Comment by Tony Fendall Sunday, September 23, 2007 @ 9:22 pmhttp://mannu.livejournal.com/404681.html
Comment by Ben Sunday, September 23, 2007 @ 11:34 pmHi Tony,
Keep in mind these are just my opinions that haven’t really been tested against anything other than my own logic. But the reason why I do it this way is a) doing it via the private static method initializes the default styles only once during the first time the first instance of this class is instantiated. So you get a performance saver there.
As for why I grab the old declaration, I wanted to preserve the existing TextInput styles. I guess I could’ve just copied them to the new style again but I think for it persist I had to use the StyleManager to set it again. I haven’t really tried it another way such as just added my new styles to the old style declaration and seeing if it sticks. I will give this a try. But if you find something to the contrary please report back.
Comment by jwopitz Monday, September 24, 2007 @ 2:34 amMakes sense
Comment by Tony Fendall Tuesday, September 25, 2007 @ 8:42 pmIt’s very strange but I’m trying this way and I’m getting this error:
1000: Ambiguos reference to setStyle
in lines like this
s.setStyle(”trashButtonDisabledSkin”, disabledSkin);
It’s strange since s is a CSSStyleDeclaration and setStyle has two params: String and Object.
Someone knows where is the problem?
Thanks
Comment by Carlos Rovira Monday, October 8, 2007 @ 8:05 amthis has something to do with using namespaces. Are you using the mx_internal namespace anywhere? If so rather than using that statement and then a general reference to a property with that namespace try doing this:
mx_internal:property
Let us know if that works for you too.
Comment by jwopitz Monday, October 8, 2007 @ 4:44 pmHi,
As you stated I’m using mx_internal in that class. This is an extension of a ComboBox. But in I’m not using mx_internal in the code with the problem. Here is the problematic code:
private static var defaultStylesInitialized:Boolean = setDefaultStyles();
private static function setDefaultStyles():Boolean {
var oldS:CSSStyleDeclaration = StyleManager.getStyleDeclaration(”NewComboBox”);
var s:CSSStyleDeclaration = new CSSStyleDeclaration();
if (oldS) {
s = oldS;
StyleManager.clearStyleDeclaration(”NewComboBox”, true);
}
s.setStyle(”newButtonDisabledSkin”, disabledSkin);
s.setStyle(”newButtonDownSkin”, downSkin);
s.setStyle(”newButtonOverSkin”, overSkin);
s.setStyle(”newButtonUpSkin”, upSkin);
StyleManager.setStyleDeclaration(”NewComboBox”, s, true);
return true;
}
[Embed (source="/icons/disnew.png")]
private var disabledSkin:Class;
[Embed (source="/icons/downnew.png")]
private var downSkin:Class;
[Embed (source="/icons/overnew.png")]
private var overSkin:Class;
[Embed (source="/icons/upnew.png")]
Comment by Carlos Rovira Monday, October 8, 2007 @ 9:37 pmprivate var upSkin:Class;
Try placing the embedding vars as local vars inside the setDefaultStyles method. This is also a good approach because then you embed these assets once per class rather than per instance (i think)
Comment by jwopitz Monday, October 8, 2007 @ 9:58 pmHello, very nice site, keep up good job!
Comment by Stasigr Monday, October 29, 2007 @ 12:14 pmAdmin good, very good.
Hello, very nice site, keep up good job!
Comment by Stasigrii Sunday, November 4, 2007 @ 4:19 pmAdmin good, very good.
looking back at this post as reference (for myself since I forget things all the time), I found Mannu’s link about an alternate way of tackling the default styles. http://mannu.livejournal.com/404681.html
In the post he states that the default way proposed by Adobe is wrong. However he did not make any claims as to why. I would like to know why, because the defaultFactory property on a CSSSTyleDeclaration instance leads me to believe what he is saying makes some sense. Any input is much appreciated.
Comment by jwopitz Tuesday, November 20, 2007 @ 4:19 amDid you ever figure out why Adobe’s recommended practice was wrong? Your way makes sense to me. Like you, I would like to know why Mannu thinks the Adobe method is wrong. Thanks!
Comment by Bruce Denham Friday, December 21, 2007 @ 2:49 pmNo I didn’t. He never responded back. I tried leaving a comment on his site but unfortunately he was using LiveJournal which doesn’t seem to allow for it.
My only guess is that it allows you to set the default styles in css syntax rather than doing each style via s.setStyle(”styleName”, value);
I’d certainly be up to hearing the other side as I am no expert in this realm of flex. Mannu where are you?
Comment by jwopitz Friday, December 21, 2007 @ 3:37 pmMannu is actually Manish Jethani and he was an engineer at Adobe for Flex 2. My guess is that he was referring to the fact that sometimes setStyle() doesn’t work in the private static method. I have no idea why or when, but I know it happens because its what led me to originally find his post. defaultFactory() worked where setStyle() did not. I think its something to do with order and precedence of styles and how they get set but that is all still pretty much voodoo to me. A bit more discussion here: http://tech.groups.yahoo.com/group/flexcoders/messages/97963?threaded=1&m=e&var=1&tidx=1
Comment by Ben Wednesday, January 23, 2008 @ 10:07 pmDidn’t even think to copy the old style declaration. Thanks that solved all of my CSS problems.
Comment by Lance Tuesday, April 22, 2008 @ 11:08 pmcan we avoid default skins of flex that are not required?
Comment by Ronald Sunday, May 10, 2009 @ 2:21 pmhttp://askmeflash.com/article_m.php?p=article&id=6