views:

2157

answers:

5

I'm creating a new Flex component (Flex 3). I'd like it to have a default style. Is there a naming convention or something for my .cs file to make it the default style? Am I missing something?

+6  A: 

Two ways, generally. One's just by referencing the class name directly -- so for example, if you'd created a new component class MyComponent in ActionScript, or indirectly by making an MXML component extending another UIComponent called MyComponent, in both cases, the component would pick up the styles declared in your external stylesheet, provided that stylesheet's been imported into your application (e.g., via Style source):

MyComponent
{
     backgroundColor: #FFFFFF;
}

Another way is by setting the UIComponent's styleName property (as a string):

public class MyComponent
{
     // ...

     this.styleName = "myStyle";

     // ...
}

... and defining the style in the CSS file like so (note the dot notation):

.myStyle
{
     backgroundColor: #FFFFFF;
}

Make sense?

Christian Nunciato
I wasted a lot of time getting this all to work, so for anyone seeking additional assistance:This is a great answer, this works, but for an additional good reference, check out the answer below by Yarin. When you follow Yarin's answer, make sure the CSS file name is actually called "defaults.css" No other name will work even though you can include any css file into the project. Argh.
davidemm
@davidemm: Good point I've clarified my answer
Yarin
+4  A: 

In addition to what Christian Nunciato suggested, another option is to define a static initializer for your Flex component's styles. This allows you to set the default styles without requiring the developer to include a CSS file.

private static function initializeStyles():void
{
 var styles:CSSStyleDeclaration = StyleManager.getStyleDeclaration("ExampleComponent");
 if(!styles)
 {
  styles = new CSSStyleDeclaration();
 }

 styles.defaultFactory = function():void
 {
  this.exampleNumericStyle = 4;
  this.exampleStringStyle = "word to your mother";
  this.exampleClassStyle = DefaultItemRenderer //make sure to import it!
 }

 StyleManager.setStyleDeclaration("ExampleComponent", styles, false);
}
//call the static function immediately after the declaration
initializeStyles();
joshtynjala
A: 

A refinement of what joshtynjala suggested:

public class CustomComponent extends UIComponent {
    private static var classConstructed:Boolean = classConstruct();

    private static function classConstruct():Boolean {
        if (!StyleManager.getStyleDeclaration("CustomComponent")) {
            var cssStyle:CSSStyleDeclaration = new CSSStyleDeclaration();
            cssStyle.defaultFactory = function():void {
                this.fontFamily = "Tahoma";
                this.backgroundColor = 0xFF0000;
                this.backgroundAlpha = 0.2;
            }
            StyleManager.setStyleDeclaration("CustomComponent", cssStyle, true);
        }
        return true;
    }
}

I've read this in the docs somewhere; the classContruct method gets called automatically.

Darren
... and here's the linkhttp://livedocs.adobe.com/flex/3/html/help.html?content=skinstyle_3.html
Darren
It's fairly obvious why classConstruct gets called and it's rather unfortunate that the docs aren't more verbose on this subject. It get's called because the static variable classConstructed is set by calling the static method classConstruct. Any static variable or code block will be executed when the type is first referenced, before any instantiation has ocurred. I haven't tried this, but I'm fairly certain that just using a static block will yield the same result, with no redundant variables declared and less clutter.
macke
+3  A: 

Christian's right about applying the CSS, but if you're planning on using the component in a library across projects, you're gonna want to write a default css file for that library. Here's how you do it:

  1. Create a css file called "defaults.css" (Only this file name will work!) and put it at the top level under the "src" folder of your library. If the css file references any assets, they have to be under "src" as well.
  2. (IMPORTANT!) Go to library project's Properties > Flex Library Build Path > Assets and include the css file and all assets.

That's how the Adobe team sets up all their default styles, now you can do it too. Just figured this out- huge

Yarin
Rather I should give credit where it's due: Henk and Chris in responses here: http://parallaxed.net/article/css-type-selectors-are-not-supported-in-components?commented=1
Yarin
A: 

To create a default style you can also have a property in your class and override the styleChanged() function in UIComponent, eg to only draw a background color across half the width of the component:

// this metadata helps flex builder to give you auto complete when writing
// css for your CustomComponent
[Style(name="customBackgroundColor", type="uint", format="color", inherit="no")]

public class CustomComponent extends UIComponent {

    private static const DEFAULT_CUSTOM_COLOR:uint = 0x00FF00;

    private var customBackgroundColor:uint = DEFAULT_CUSTOM_COLOR;

    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged(styleProp);

        var allStyles:Boolean = (!styleProp || styleProp == "styleName");

        if(allStyles || styleProp == "customBackgroundColor")
        {
            if(getStyle("customBackgroundColor") is uint);
            {
                customBackgroundColor = getStyle("customBackgroundColor");
            }
            else
            {
                customBackgroundColor = DEFAULT_CUSTOM_COLOR;
            }
            invalidateDisplayList();
        }

        // carry on setting any other properties you might like
        // check out UIComponent.styleChanged() for more examples
    }

    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        graphics.clear();
        graphics.beginFill(customBackgroundColor);
        graphics.drawRect(0,0,unscaledWidth/2,unscaledHeight);
    }
}

You could also create a setter for the customBackgroundColor that called invalidateDisplayList(), so you could also set the customBackgroundColor property programatically as well as through css.

Andy