Using the setStyle() and getStyle() methods

You cannot get or set style properties directly on a component as you can with other properties. Instead, you set style properties at run time by using the getStyle() and setStyle() ActionScript methods. When you use the getStyle() and setStyle() methods, you can access the style properties of instances of objects or of style sheets.

Every component exposes these methods. When you are instantiating an object and setting the styles for the first time, you should try to apply style sheets rather than use the setStyle() method because it is computationally expensive. This method should be used only when you are changing an object’s styles during run time. For more information, see Improving performance with the setStyle() method.

Setting styles

You use the getStyle() method in the following way:

var:return_type componentInstance.getStyle(property_name)

The return_type depends on the style that you access. Styles can be of type String, Number, Boolean, or, in the case of skins, Class. The property_name is a String that indicates the name of the style property—for example, fontSize.

The setStyle() method is used like this:

componentInstance.setStyle(property_name, property_value)

The property_value sets the new value of the specified property. To determine valid values for properties, see the ActionScript 3.0 Reference for the Adobe Flash Platform.

The following example uses the getStyle() and setStyle() methods to change the Button’s fontSize style and display the new size in the TextInput:

<?xml version="1.0"?>
<!-- styles/SetSizeGetSize.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    creationComplete="initApp();">
  
  <fx:Script><![CDATA[
    import mx.controls.Alert;  
      
    [Bindable]
    private var curSize:int = 10;
  
    private function initApp():void {
        ip1.setStyle("fontSize", curSize);
        b1.setStyle("fontSize", curSize);
        b2.setStyle("fontSize", curSize);               
    }
  
    public function showStyles():void {
        Alert.show("Font size is " + ip1.getStyle("fontSize") + ".");
     }
     
     public function setNewStyles():void {
        curSize = Number(ip2.text);
        
        ip1.setStyle("fontSize", curSize);
        b1.setStyle("fontSize", curSize);
        b2.setStyle("fontSize", curSize);
     }
  ]]></fx:Script>

  <s:VGroup id="vb">
     <s:TextInput id="ip1" 
        styleName="myClass" 
        text="This is a TextInput control." 
        width="400"
     />

     <s:Label id="lb1" text="Current size: {curSize}" width="400"/>

     <s:Button id="b1" label="Get Style" click="showStyles();"/>

     <s:Form>
        <s:FormItem label="Enter new size:">
            <s:HGroup>
                <s:TextInput text="{curSize}" id="ip2" width="50"/>
                <s:Button id="b2" label="Set Style" click="setNewStyles();"/>
            </s:HGroup>
        </s:FormItem>
     </s:Form>

  </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

You can use the getStyle() method to access style properties regardless of how they were set. If you defined a style property as a tag property inline rather than in an <fx:Style> tag, you can get and set this style. You can override style properties that were applied in any way, such as in an <fx:Style> tag or in an external style sheet.

The following example sets a style property inline, and then reads that property with the getStyle() method:

<?xml version="1.0"?>
<!-- styles/GetStyleInline.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script><![CDATA[
        private function readStyle():void {
            myLabel.text = "Label style is: " + myLabel.getStyle("fontStyle");
        }
    ]]></fx:Script>
    
    <s:VGroup width="500" height="200">  
        <s:Button id="b1" click="readStyle()" label="Get Style"/>
        <s:Label id="myLabel" fontStyle="italic"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

When setting color style properties with the setStyle() method, you can use the hexadecimal format or the VGA color name, as the following example shows:

<?xml version="1.0"?>
<!-- styles/ColorFormatStyleManager.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    creationComplete="initApp()">

  <fx:Script><![CDATA[
     public function initApp():void {
        styleManager.getStyleDeclaration("spark.components.Button").setStyle("color","Blue");
     }

     public function changeStyles(e:Event):void {
        // Check against "255" here, because that is the numeric value of "Blue".
        if (e.currentTarget.getStyle("color") == 255) {
            e.currentTarget.setStyle("color", "Red");
        } else {
            e.currentTarget.setStyle("color", "Blue");
        }
     }
  ]]></fx:Script>

  <s:Button id="myButton" label="Click Here" 
        click="changeStyles(event)"/>
</s:Application>

The executing SWF file for the previous example is shown below:

When you get a color style property with the getStyle() method, Flex returns an integer that represents the hexadecimal value of the style property. To convert this to its hexadecimal format, you use the color variable’s toString() method and pass it the value 16 for the radix (or base):

<?xml version="1.0"?>
<!-- styles/ColorFormatNumericValue.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    creationComplete="initApp()">

  <fx:Style>
     @namespace s "library://ns.adobe.com/flex/spark";

     s|Button {
        color: #66CCFF;
     }
  </fx:Style>

  <fx:Script><![CDATA[
     [Bindable]
     private var n:Number;

     private function initApp():void {
        n = myButton.getStyle("color");
     }

     public function changeStyles(e:Event):void {
        if (myButton.getStyle("color").toString(16) == "ff0000") {
           myButton.setStyle("color", 0x66CCFF);            
        } else {
           myButton.setStyle("color", "Red");           
        }
        
        n = myButton.getStyle("color"); // Returns 16711680
     }
  ]]></fx:Script>

    <s:VGroup>  
        <s:Button id="myButton" label="Click Me" click="changeStyles(event)"/>
        <s:Label id="myLabel" text="0x{n.toString(16).toUpperCase()}"/>
    </s:VGroup>
    
</s:Application>

The executing SWF file for the previous example is shown below:

When you use the setStyle() method to change an existing style (for example, to set the color property of a Button control to something other than 0x000000, the default), Flex does not overwrite the original style setting. You can return to the original setting by setting the style property to null. The following example toggles the color of the Button control between blue and the default by using this technique:

<?xml version="1.0"?>
<!-- styles/ResetStyles.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

     <s:layout>
        <s:VerticalLayout/>
     </s:layout>

    <fx:Script> 
        <![CDATA[
        public function toggleStyle():void {
            if (cb1.selected == true) {
                b1.setStyle("color","blue");
                b1.setStyle("fontSize", 8);
            } else {
                b1.setStyle("color", null);
                b1.setStyle("fontSize", null);
            }                       
        }
        ]]>
    </fx:Script>   
    
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";    

        s|Button {
            color: red;
            fontSize: 25;
        }    
    </fx:Style>

    <s:Button id="b1" label="Click Me"/>

    <s:CheckBox id="cb1" label="Set Style/Unset Style" 
        click="toggleStyle()" selected="false" color="Black"/>
</s:Application>

The executing SWF file for the previous example is shown below:

Improving performance with the setStyle() method

Run-time cascading styles are very powerful, but you should use them sparingly and in the correct context. Dynamically setting styles on an instance of an object means accessing the UIComponent’s setStyle() method. The setStyle() method is one of the most resource-intensive calls in the Flex framework because the call requires notifying all the children of the newly styled object to do another style lookup. The resulting tree of children that must be notified can be quite large.

A common mistake that impacts performance is overusing or unnecessarily using the setStyle() method. In general, you need the setStyle() method only when you want to change styles on existing objects. Do not use it when setting up styles for an object for the first time. Instead, set styles in an <fx:Style> block, through an external CSS style sheet, or as global styles. It is important to initialize your objects with the correct style information if you do not expect these styles to change while your program executes (whether it is your application, a new view in a navigator container, or a dynamically created component).

Some applications must call the setStyle() method during the application or object instantiation. If this is the case, call the setStyle() method early in the instantiation phase. Early in the instantiation phase means setting styles from the component or application's preinitialize event, instead of the creationComplete or other event. By setting the styles as early as possible during initialization, you avoid unnecessary style notification and lookup.

For more information about the component startup life cycle, see Improving startup performance.