Removing the vertical separator from the ComboBox control in Flex
The following example shows how you can remove the vertical separator from the Flex ComboBox control by creating a custom ComboBox skin using ActionScript.
Full code after the jump.
<?xml version="1.0" encoding="utf-8"?> <!-- http://blog.flexexamples.com/2009/03/23/removing-the-vertical-separator-from-the-combobox-control-in-flex/ --> <mx:Application name="ComboBox_skin_test" xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="white"> <mx:ComboBox id="comboBox" dataProvider="[The,Quick,Brown,Fox,Jumps,Over,The,Lazy,Dog]" skin="skins.CustomComboBoxSkin" /> </mx:Application>
The custom ComboBox skin class, skins/CustomComboBoxSkin.as, is as follows:
/** * http://blog.flexexamples.com/2009/03/23/removing-the-vertical-separator-from-the-combobox-control-in-flex/ */ package skins { import flash.display.GradientType; import flash.display.Graphics; import mx.skins.halo.ComboBoxArrowSkin; import mx.skins.halo.HaloColors; import mx.styles.StyleManager; import mx.utils.ColorUtil; public class CustomComboBoxSkin extends ComboBoxArrowSkin { private static var cache:Object = {}; public function CustomComboBoxSkin() { super(); } private static function calcDerivedStyles(themeColor:uint, borderColor:uint, fillColor0:uint, fillColor1:uint):Object { var key:String = HaloColors.getCacheKey(themeColor, borderColor, fillColor0, fillColor1); if (!cache[key]) { var o:Object = cache[key] = {}; HaloColors.addHaloColors(o, themeColor, fillColor0, fillColor1); } return cache[key]; } override protected function updateDisplayList(w:Number, h:Number):void { super.updateDisplayList(w, h); var arrowColor:uint = getStyle("iconColor"); var borderColor:uint = getStyle("borderColor"); var cornerRadius:Number = getStyle("cornerRadius"); var dropdownBorderColor:Number = getStyle("dropdownBorderColor"); var fillAlphas:Array = getStyle("fillAlphas"); var fillColors:Array = getStyle("fillColors"); StyleManager.getColorNames(fillColors); var highlightAlphas:Array = getStyle("highlightAlphas"); var themeColor:uint = getStyle("themeColor"); // The dropdownBorderColor is currently only used // when displaying an error state. if (!isNaN(dropdownBorderColor)) { borderColor = dropdownBorderColor; } var derStyles:Object = calcDerivedStyles(themeColor, borderColor, fillColors[0], fillColors[1]); var borderColorDrk1:Number = ColorUtil.adjustBrightness2(borderColor, -50); var themeColorDrk1:Number = ColorUtil.adjustBrightness2(themeColor, -25); var cornerRadius1:Number = Math.max(cornerRadius - 1, 0); var cr:Object = { tl: 0, tr: cornerRadius, bl: 0, br: cornerRadius }; var cr1:Object = { tl: 0, tr: cornerRadius1, bl: 0, br: cornerRadius1 }; var arrowOnly:Boolean = true; // If our name doesn't include "editable", we are drawing the non-edit // skin which spans the entire control if (name.indexOf("editable") < 0) { arrowOnly = false; cr.tl = cr.bl = cornerRadius; cr1.tl = cr1.bl = cornerRadius1; } var g:Graphics = graphics; g.clear(); // Draw the border and fill. switch (name) { case "upSkin": case "editableUpSkin": { var upFillColors:Array = [ fillColors[0], fillColors[1] ]; var upFillAlphas:Array = [ fillAlphas[0], fillAlphas[1] ]; // border drawRoundRect(0, 0, w, h, cr, [ borderColor, borderColorDrk1 ], 1, verticalGradientMatrix(0, 0, w, h), GradientType.LINEAR, null, { x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 }); // button fill drawRoundRect(1, 1, w - 2, h - 2, cr1, upFillColors, upFillAlphas, verticalGradientMatrix(1, 1, w - 2, h - 2)); // top highlight drawRoundRect(1, 1, w - 2, (h - 2) / 2, { tl: cornerRadius1, tr: cornerRadius1, bl: 0, br: 0 }, [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); break; } case "overSkin": case "editableOverSkin": { var overFillColors:Array; if (fillColors.length > 2) { overFillColors = [ fillColors[2], fillColors[3] ]; } else { overFillColors = [ fillColors[0], fillColors[1] ]; } var overFillAlphas:Array; if (fillAlphas.length > 2) { overFillAlphas = [ fillAlphas[2], fillAlphas[3] ]; } else { overFillAlphas = [ fillAlphas[0], fillAlphas[1] ]; } // border drawRoundRect(0, 0, w, h, cr, [ themeColor, themeColorDrk1 ], 1, verticalGradientMatrix(0, 0, w, h), GradientType.LINEAR, null, { x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 }); // button fill drawRoundRect(1, 1, w - 2, h - 2, cr1, overFillColors, overFillAlphas, verticalGradientMatrix(1, 1, w - 2, h - 2)); // top highlight drawRoundRect(1, 1, w - 2, (h - 2) / 2, { tl: cornerRadius1, tr: cornerRadius1, bl: 0, br: 0 }, [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, verticalGradientMatrix(0, 0, w - 2, (h - 2) / 2)); break; } case "downSkin": case "editableDownSkin": { // border drawRoundRect(0, 0, w, h, cr, [ themeColor, themeColorDrk1 ], 1, verticalGradientMatrix(0, 0, w, h)); // button fill drawRoundRect(1, 1, w - 2, h - 2, cr1, [ derStyles.fillColorPress1, derStyles.fillColorPress2 ], 1, verticalGradientMatrix(1, 1, w - 2, h - 2)); // top highlight drawRoundRect(1, 1, w - 2, (h - 2) / 2, { tl: cornerRadius1, tr: cornerRadius1, bl: 0, br: 0 }, [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas, verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); break; } case "disabledSkin": case "editableDisabledSkin": { var disFillColors:Array = [ fillColors[0], fillColors[1] ]; var disFillAlphas:Array = [ Math.max(0, fillAlphas[0] - 0.15), Math.max(0, fillAlphas[1] - 0.15) ]; // border drawRoundRect(0, 0, w, h, cr, [ borderColor, borderColorDrk1 ], 0.5, verticalGradientMatrix(0, 0, w, h ), GradientType.LINEAR, null, { x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 }); // button fill drawRoundRect(1, 1, w - 2, h - 2, cr1, disFillColors, disFillAlphas, verticalGradientMatrix(0, 0, w - 2, h - 2)); arrowColor = getStyle("disabledIconColor"); break; } } // Draw the triangle. g.beginFill(arrowColor); g.moveTo(w - 11.5, h / 2 + 3); g.lineTo(w - 15, h / 2 - 2); g.lineTo(w - 8, h / 2 - 2); g.lineTo(w - 11.5, h / 2 + 3); g.endFill(); } } }
You can also set the skin style in an external .CSS file or <Style/> block, as seen in the following example:
<?xml version="1.0" encoding="utf-8"?> <!-- http://blog.flexexamples.com/2009/03/23/removing-the-vertical-separator-from-the-combobox-control-in-flex/ --> <mx:Application name="ComboBox_skin_test" xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="white"> <mx:Style> ComboBox { skin: ClassReference("skins.CustomComboBoxSkin"); } </mx:Style> <mx:ComboBox id="comboBox" dataProvider="[The,Quick,Brown,Fox,Jumps,Over,The,Lazy,Dog]" /> </mx:Application>
Or, you can set the skin style using ActionScript, as seen in the following example:
<?xml version="1.0" encoding="utf-8"?> <!-- http://blog.flexexamples.com/2009/03/23/removing-the-vertical-separator-from-the-combobox-control-in-flex/ --> <mx:Application name="ComboBox_skin_test" xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="white"> <mx:Script> <![CDATA[ import skins.CustomComboBoxSkin; protected function btn_click(evt:MouseEvent):void { comboBox.setStyle("skin", CustomComboBoxSkin); } ]]> </mx:Script> <mx:ApplicationControlBar dock="true"> <mx:Button id="btn" label="Set skin" click="btn_click(event);" /> </mx:ApplicationControlBar> <mx:ComboBox id="comboBox" dataProvider="[The,Quick,Brown,Fox,Jumps,Over,The,Lazy,Dog]" /> </mx:Application>
Peter deHaan
Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.
-
Add Widgets (Content Sidebar)
This is your Content Sidebar. Edit this content that appears here in the widgets panel by adding or removing widgets in the Content Sidebar area.
6 Responses to Removing the vertical separator from the ComboBox control in Flex
Leave a Reply Cancel reply
-
Categories
- Accordion
- AccordionHeader
- ActionScript
- AddChild
- AdvancedDataGrid
- Alert
- alpha
- Animate
- AnimateProperties
- Application
- Application (Spark)
- ArrayCollection
- BarChart
- baseColor
- beta
- beta1
- beta2
- Bitmap
- Bitmap/BitmapData
- BitmapData
- BitmapFill
- BitmapFill (Spark)
- BitmapGraphic
- BitmapImage
- BitmapImage (Spark)
- BitmapImageResizeMode
- Border (Spark)
- BorderContainer (Spark)
- Box
- BuildInfo
- Button
- Button (Spark)
- ButtonBar
- ButtonBar (Spark)
- ByteArray
- Camera
- Charting
- CheckBox
- CheckBox (Spark)
- ClassFactory
- CollectionEvent
- Color
- ColorPicker
- ColorUtil
- ComboBox
- ComboBoxArrowSkin
- Compiler
- Component
- Component (Spark)
- Configuration
- Container
- ContextMenu
- ContextMenuEvent
- ContextMenuItem
- CSSCondition
- CSSSelector
- CSSStyleDeclaration
- CurrencyFormatter
- CursorManager
- Data Binding
- DataGrid
- DataGrid (Spark)
- DataGridColumn
- Date
- DateBase
- DateChooser
- DateField
- DateFormatter
- Debugging
- DefaultComplexItemRenderer
- DefaultTileListEffect
- DropDownList
- DropDownList (Spark)
- DropDownListButtonSkin
- DropDownListSkin
- DropShadowFilter
- E4X
- Effects
- Ellipse
- EmailValidator
- Embed
- Event
- Fade
- FileFilter
- FileReference
- fill
- Filters
- Flash
- Flash Integration
- FlashVars
- Flex 3 SDK
- Flex Builder
- Flex Builder 3
- Flex SDK
- Flex4
- FLVPlayback
- FocusManager
- FontLookup
- Fonts
- Form
- Form (Spark)
- FormHeading (Spark)
- FormItem
- FormItem (Spark)
- Forms
- FTETextField (Spark)
- FullScreen
- FullScreenEvent
- FxAnimateColor
- FxButtonBar
- FxCheckBox
- FXG
- FxHScrollBar
- FxHSlider
- FxList
- FxNumericStepper
- FxRadioButton
- FxRotate3D
- FxScroller
- FxTextArea
- FxTextInput
- FxToggleButton
- FxVScrollBar
- FxVSlider
- getStyleDeclaration()
- GradientEntry
- Graphic (Spark)
- HBox
- HDividedBox
- HGroup (Spark)
- HorizontalLayout
- HorizontalList
- HSBColor (Spark)
- HScrollBar (Spark)
- HSlider
- HSlider (Spark)
- HTML template
- ID3Info
- Image
- Image (Spark)
- ImageSnapshot
- itemRenderer
- JointStyle
- Label
- Label (Spark)
- Legend
- LegendItem
- LigatureLevel
- Line
- LinearGradientStroke
- LineScaleMode
- LinkBar
- LinkButton
- List
- List (Spark)
- Menu
- MenuBar
- Metadata
- MetadataEvent
- Model
- Mouse
- MouseCursor
- MouseEvent
- Move
- Namespace
- NavigatorContent (Spark)
- needsSWF
- NetConnection
- NetStream
- Nightly Builds
- NumberBaseRoundType
- NumberFormatter
- NumberValidator
- NumericCompare
- NumericStepper
- NumericStepper (Spark)
- ObjectProxy
- ObjectUtil
- paddingLeft
- paddingRight
- Panel
- Panel (Spark)
- Parallel
- Path
- PieChart
- PieSeries
- PieSeriesItem
- PopUpAnchor (Spark)
- PopUpButton
- PopUpManager
- ProgrammaticSkin
- ProgressBar
- PropertyChangeEvent
- QName
- RadialGradient
- RadioButton
- RadioButton (Spark)
- RadioButtonGroup
- RadioButtonGroup (Spark)
- Rect
- RegExp
- Regular Expressions
- Repeater
- RichEditableText
- RichText
- RichText (Spark)
- RichTextEditor
- Rotate
- Rotate3D (Spark)
- Scroller (Spark)
- Sequence
- setStyle()
- SimpleText
- SimpleText (Spark)
- skinClass
- Slider
- SliderEvent
- SolidColor
- SolidColorStroke
- Sort
- SortField
- Sound
- SoundEffect
- Spinner (Spark)
- SpriteVisualElement (Spark)
- StageDisplayState
- States
- StringUtil
- StringValidator
- StyleManager
- Styles
- SWFLoader
- SWFObject
- System
- SystemManager
- TabBar
- TabBar (Spark)
- TabNavigator
- TabStopFormat
- Text
- Text Layout Framework (TLF)
- TextArea
- TextArea (Spark)
- TextBox
- TextConverter
- TextEvent
- TextFlow
- TextFlowUtil
- TextFormat
- TextGraphic
- TextInput
- TextInput (Spark)
- TextLayoutFormat
- TextView
- Themes
- TileLayout
- TileList
- TileOrientation
- Timer
- TitleWindow
- TitleWindow (Spark)
- TLF
- ToggleButton (Spark)
- ToggleButtonBar
- ToolTip
- Transition
- Tree
- TruncationOptions
- UIComponent
- UIFTETextField
- Updater
- URLLoader
- URLRequest
- URLUtil
- URLVariables
- ValidationResultEvent
- Validator
- Validators
- VBox
- VDividedBox
- Vector
- VerticalLayout
- VerticalLayout (Spark)
- VGroup (Spark)
- Video
- VideoDisplay
- VideoElement
- VideoElement (Spark)
- VideoEvent
- VideoPlayer (Spark)
- VideoPlayerScrubBar
- ViewStack
- VScrollBar (Spark)
- VSlider
- VSlider (Spark)
- XML
- XMLList
- XMLListCollection
- ZipCodeValidator
- ZipCodeValidatorDomainType
- Zoom
-
Articles
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
-
Meta


Thanks for this example. I spent a little bit working on a similar problem: how to remove the gradient border from the border of a combobox. In this process I found that this is a copy of the ComboBoxArrowSkin with a couple minor changes. What I ended up doing was just copy/pasting the ComboBoxArrowSkin class in flex_trunk/frameworks/projects/framework/src/mx/skins/halo and modifying it so that it didn’t apply a gradient to the border. But I wouldn’t have thought of doing that if it wasn’t for this example. Cheers!
I think in one of the Adobe TV clips they showed that if you create a folder structure like this in your project’s src folder: src/mx/skins/halo and put your classes in there, then you wouldn’t have to modify the framework directly. Don’t hold me to that, though.
Nice post, solved my problem and got me on the path to creating a totally custom combobox skin which I needed for my current project.
This is excellent!
What if I only want to change the background gradient or border color? But want to leave the seperator? (Which part of this code removes the seperator?)
Thanks! :)
I tried changing
var arrowOnly:Boolean = true;
to “false” but no change at all.
I found out how to make the changes I wanted after all. I knew there should be a VERY SIMPLE way to do it, but scouring the net did not give me the answers until I stumbled across it in your code. Thanks!
The answer, in my case (change only border color and background-gradient) was to assign a themeColor to the components, which I did in the CSS, like this:
global {
theme-color: #7ab800;
}