Setting the border color on the MX Accordion container headers in Flex

In a previous example, “Setting the border style on the MX Accordion container in Flex”, we saw how you could set the border style on an MX Accordion container in Flex 3 by setting the borderStyle style.

The following example shows how you can set the border color on an MX Accordion container headers in Flex 3 by setting the borderColor style on the Accordion container’s headerStyleName style selector.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/06/23/setting-the-border-color-on-the-mx-accordion-container-headers-in-flex/ -->
<mx:Application name="MX_Accordion_headerStyleName_borderColor_test"
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">
 
    <mx:Style>
        .accHead {
            borderColor: red;
        }
    </mx:Style>
 
    <mx:Accordion id="acc"
            headerStyleName="accHead"
            width="500" height="300">
        <mx:VBox label="Red" />
        <mx:VBox label="Orange" />
        <mx:VBox label="Yellow" />
        <mx:VBox label="Green" />
        <mx:VBox label="Blue" />
    </mx:Accordion>
 
</mx:Application>

[GoogleAdsWide]

View source is enabled in the following example.

9 thoughts on “Setting the border color on the MX Accordion container headers in Flex

  1. Unfortunately, this doesn’t work in a Flex 4 project which is quite frustrating (I used your exact code and it works using the Flex 3 framework, but not Flex 4). Is there any way to style Accordion headers in Flex 4?

    1. @Phil Chung,

      In Flex 4 it looks like you can create a custom AccordionHeaderSkin and do something like the following:

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
              xmlns:s="library://ns.adobe.com/flex/spark" 
              xmlns:mx="library://ns.adobe.com/flex/mx">
       
          <fx:Style>
              .accHead {
                  skin: ClassReference("MXAccHdSkn");
              }
          </fx:Style>
       
          <mx:Accordion id="acc"
                  headerStyleName="accHead"
                  width="500" height="300">
              <mx:VBox label="Red" />
              <mx:VBox label="Orange" />
              <mx:VBox label="Yellow" />
              <mx:VBox label="Green" />
              <mx:VBox label="Blue" />
          </mx:Accordion>
       
      </s:Application>

      And the custom Accordion header skin, MXAccHdSkn.mxml, is as follows:

      <?xml version="1.0" encoding="utf-8"?>
      <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:s="library://ns.adobe.com/flex/spark" 
              minWidth="21" minHeight="21"
              alpha.disabled="0.5">
          <!-- states -->
          <s:states>
              <s:State name="up" />
              <s:State name="over" />
              <s:State name="down" />
              <s:State name="disabled" />
              <s:State name="selectedUp" />
              <s:State name="selectedOver" />
              <s:State name="selectedDown" />
              <s:State name="selectedDisabled" />
          </s:states>
       
          <fx:Script>
              <![CDATA[
                  override protected function initializationComplete():void {
                      useChromeColor = true;
                      super.initializationComplete();
                  }
              ]]>
          </fx:Script>
       
          <!-- layer 3: fill -->
          <s:Rect left="1" right="1" top="1" bottom="1">
              <s:fill>
                  <s:LinearGradient rotation="90">
                      <s:GradientEntry color="0xFFFFFF" color.over="0xBBBDBD" color.down="0xAAAAAA" 
                                       alpha="0.85" />
                      <s:GradientEntry color="0xD8D8D8" color.over="0x9FA0A1" color.down="0x929496" 
                                       alpha="0.85" />
                  </s:LinearGradient>
              </s:fill>
          </s:Rect>
       
          <!-- layer 4: fill lowlight -->
          <s:Rect left="1" right="1" top="1" bottom="1">
              <s:fill>
                  <s:LinearGradient rotation="270">
                      <s:GradientEntry color="0x000000" ratio="0.0" alpha="0.0627" />
                      <s:GradientEntry color="0x000000" ratio="0.48" alpha="0.0099" />
                      <s:GradientEntry color="0x000000" ratio="0.48001" alpha="0" />
                  </s:LinearGradient>
              </s:fill>
          </s:Rect>
       
          <!-- layer 5: fill highlight -->
          <s:Rect left="1" right="1" top="1" bottom="1">
              <s:fill>
                  <s:LinearGradient rotation="90">
                      <s:GradientEntry color="0xFFFFFF"
                                       ratio="0.0"
                                       alpha="0.33" alpha.over="0.22" alpha.down="0.12"/>
                      <s:GradientEntry color="0xFFFFFF"
                                       ratio="0.48"
                                       alpha="0.33" alpha.over="0.22" alpha.down="0.12" />
                      <s:GradientEntry color="0xFFFFFF"
                                       ratio="0.48001"
                                       alpha="0" />
                  </s:LinearGradient>
              </s:fill>
          </s:Rect>
       
          <!-- layer 6: highlight stroke (all states except down) -->
          <s:Rect left="1" right="1" top="1" bottom="1" excludeFrom="down">
              <s:stroke>
                  <s:LinearGradientStroke rotation="90">
                      <s:GradientEntry color="0xFFFFFF" alpha.over="0.22" />
                      <s:GradientEntry color="0xD8D8D8" alpha.over="0.22" />
                  </s:LinearGradientStroke>
              </s:stroke>
          </s:Rect>
       
          <!-- layer 6: highlight stroke (down state only) -->
          <s:Rect left="1" top="1" bottom="1" width="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.07" />
              </s:fill>
          </s:Rect>
          <s:Rect right="1" top="1" bottom="1" width="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.07" />
              </s:fill>
          </s:Rect>
          <s:Rect left="1" top="1" right="1" height="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.25" />
              </s:fill>
          </s:Rect>
          <s:Rect left="1" top="2" right="1" height="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.09" />
              </s:fill>
          </s:Rect>
       
          <!-- layer 2: border -->
          <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20">
              <s:stroke>
                  <s:SolidColorStroke color="red" 
                          alpha="1" alpha.over="1" alpha.down="1" />
              </s:stroke>
          </s:Rect>
       
      </s:SparkSkin>

      So, not as easy as it was in Flex 3, but it should be fairly easy to create your own custom Accordion header skin that looks for a borderColor style and sets the border color in an updateComplete() event handler or something.

      Hope that helps,
      Peter

    2. Actually, speaking of custom skins which poll for the borderColor style, here’s a simple example:

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
              xmlns:s="library://ns.adobe.com/flex/spark" 
              xmlns:mx="library://ns.adobe.com/flex/mx">
       
          <fx:Style>
              .accHead {
                  borderColor: red;
                  skin: ClassReference("MXAccHdSkn");
              }
          </fx:Style>
       
          <fx:Script>
              <![CDATA[
                  protected function setBorderColor(value:Object):void {
                      try {
                          var cssObj:CSSStyleDeclaration = styleManager.getStyleDeclaration(".accHead");
                          cssObj.setStyle("borderColor", value);
                      } catch (err:*) {
                          // Ignore
                      }
                  }
              ]]>
          </fx:Script>
       
          <s:controlBarContent>
              <s:Button label="red" click="setBorderColor('red');" />
              <s:Button label="orange" click="setBorderColor('haloOrange');" />
              <s:Button label="yellow" click="setBorderColor('yellow');" />
          </s:controlBarContent>
       
          <mx:Accordion id="acc"
                  headerStyleName="accHead"
                  width="500" height="300"
                  horizontalCenter="0" verticalCenter="0">
              <mx:VBox label="Red" />
              <mx:VBox label="Orange" />
              <mx:VBox label="Yellow" />
              <mx:VBox label="Green" />
              <mx:VBox label="Blue" />
          </mx:Accordion>
       
      </s:Application>

      And the new custom Accordion header skin, MXAccHdSkn.mxml, is as follows:

      <?xml version="1.0" encoding="utf-8"?>
      <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:s="library://ns.adobe.com/flex/spark" 
              minWidth="21" minHeight="21"
              alpha.disabled="0.5">
          <!-- states -->
          <s:states>
              <s:State name="up" />
              <s:State name="over" />
              <s:State name="down" />
              <s:State name="disabled" />
              <s:State name="selectedUp" />
              <s:State name="selectedOver" />
              <s:State name="selectedDown" />
              <s:State name="selectedDisabled" />
          </s:states>
       
          <fx:Script>
              <![CDATA[
                  override protected function initializationComplete():void {
                      useChromeColor = true;
                      super.initializationComplete();
                  }
       
                  override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
                      borderStroke.color = getStyle("borderColor");
                      super.updateDisplayList(unscaledWidth, unscaledHeight);
                  }
              ]]>
          </fx:Script>
       
          <!-- layer 3: fill -->
          <s:Rect left="1" right="1" top="1" bottom="1">
              <s:fill>
                  <s:LinearGradient rotation="90">
                      <s:GradientEntry color="0xFFFFFF" color.over="0xBBBDBD" color.down="0xAAAAAA" 
                                       alpha="0.85" />
                      <s:GradientEntry color="0xD8D8D8" color.over="0x9FA0A1" color.down="0x929496" 
                                       alpha="0.85" />
                  </s:LinearGradient>
              </s:fill>
          </s:Rect>
       
          <!-- layer 4: fill lowlight -->
          <s:Rect left="1" right="1" top="1" bottom="1">
              <s:fill>
                  <s:LinearGradient rotation="270">
                      <s:GradientEntry color="0x000000" ratio="0.0" alpha="0.0627" />
                      <s:GradientEntry color="0x000000" ratio="0.48" alpha="0.0099" />
                      <s:GradientEntry color="0x000000" ratio="0.48001" alpha="0" />
                  </s:LinearGradient>
              </s:fill>
          </s:Rect>
       
          <!-- layer 5: fill highlight -->
          <s:Rect left="1" right="1" top="1" bottom="1">
              <s:fill>
                  <s:LinearGradient rotation="90">
                      <s:GradientEntry color="0xFFFFFF"
                                       ratio="0.0"
                                       alpha="0.33" alpha.over="0.22" alpha.down="0.12"/>
                      <s:GradientEntry color="0xFFFFFF"
                                       ratio="0.48"
                                       alpha="0.33" alpha.over="0.22" alpha.down="0.12" />
                      <s:GradientEntry color="0xFFFFFF"
                                       ratio="0.48001"
                                       alpha="0" />
                  </s:LinearGradient>
              </s:fill>
          </s:Rect>
       
          <!-- layer 6: highlight stroke (all states except down) -->
          <s:Rect left="1" right="1" top="1" bottom="1" excludeFrom="down">
              <s:stroke>
                  <s:LinearGradientStroke rotation="90">
                      <s:GradientEntry color="0xFFFFFF" alpha.over="0.22" />
                      <s:GradientEntry color="0xD8D8D8" alpha.over="0.22" />
                  </s:LinearGradientStroke>
              </s:stroke>
          </s:Rect>
       
          <!-- layer 6: highlight stroke (down state only) -->
          <s:Rect left="1" top="1" bottom="1" width="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.07" />
              </s:fill>
          </s:Rect>
          <s:Rect right="1" top="1" bottom="1" width="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.07" />
              </s:fill>
          </s:Rect>
          <s:Rect left="1" top="1" right="1" height="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.25" />
              </s:fill>
          </s:Rect>
          <s:Rect left="1" top="2" right="1" height="1" includeIn="down">
              <s:fill>
                  <s:SolidColor color="0x000000" alpha="0.09" />
              </s:fill>
          </s:Rect>
       
          <!-- layer 2: border -->
          <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20">
              <s:stroke>
                  <s:SolidColorStroke id="borderStroke" color="0x000000" 
                          alpha="1" alpha.over="1" alpha.down="1" />
              </s:stroke>
          </s:Rect>
       
      </s:SparkSkin>

      Peter

  2. Thanks for the quick reply Peter! Actually I had done it exactly how you explained using a skin class, however it wasn’t working until I noticed in your code that you use “skin” instead of “skinClass”. Is there a reason why “skin” is used here for the skin class but pretty much every other case of skinning I’ve come across in Flex 4 uses “skinClass”?

    Thanks again.

    1. @Phil Chung,

      Great question! I honestly don’t know. I think that skin was just the first thing I tried since that is what it was in Flex 3.x.
      I can try playing around with it a bit more later and see if I can get a better idea of what is going on.

      Looking at the Flex 4.0 defaults.css, it seems that the AccordionHeader style there uses the skin style as well:

      AccordionHeader {
      	disabledSkin: ClassReference(null);
      	downSkin: ClassReference(null);
      	horizontalGap: 2;
      	overSkin: ClassReference(null);
      	paddingLeft: 5;
      	paddingRight: 5;
      	paddingBottom: 0;
      	paddingTop: 0;
      	selectedDisabledSkin: ClassReference(null);
      	selectedDownSkin: ClassReference(null);
      	selectedOverSkin: ClassReference(null);
      	selectedUpSkin: ClassReference(null);
      	skin: ClassReference("mx.skins.spark.AccordionHeaderSkin");
      	textAlign: "left";
      	upSkin: ClassReference(null);
      }

      Peter

  3. Hello peter , I was reading 1 of your old blog regarding tree control

    http://blog.flexexamples.com/2008/04/04/creating-a-simple-image-gallery-with-the-flex-tree-control/

    while running the application i get two errors ..
    1)Access of possibly undefined property dataDescriptor through a reference with static type Tree.
    2)Access of possibly undefined property selectedItem through a reference with static type Tree.

    Please help me out.
    Atleast tell me out what is the mistake I m doing . I am stucked on that poitnt . PLease
    Apoorv

  4. Do you suppose accordion headers use “skin” instead of “skinClass” because they’re MX controls, whereas all the other controls we’ve been skinning are Spark controls?

Comments are closed.