Home > programming > ComboBox text formatting in AS3

ComboBox text formatting in AS3

After struggling with it for a while, I’ve finally found the way to set embedFonts and a specific textFormat for all text in a Flash CS3 ComboBox component.

First of all, it is wise to create a subclass of fl.controls.ComboBox to represent your custom comboBox. In this class you can then set some styles in the constructor as follows:

package com.rockabit.utils.as3
{
import fl.controls.ComboBox;
import fl.controls.List;

import flash.text.TextFormat;

/**
* Customized ComboBox component. Graphic changes have been made inside the component itself,
* in the library, changes in textual display are made here.
*/
public class CustomComboBox extends ComboBox
{
private var textFormat:TextFormat;

public function CustomComboBox()
{
super();

textFormat = new TextFormat(”Arial”, 10, 0xffffff);

//textField is the top text, in the closed combobox
textField.setStyle(”embedFonts”, true);
textField.setStyle(”textFormat”, textFormat);

//dropdown is the list that shows when you open the combobox
dropdown.setStyle(”cellRenderer”, CustomCellRenderer);
}

override protected function drawLayout():void
{
super.drawLayout();
textField.y = 0;
}
}
}

So in the constructor, I create a TextFormat instance and assign that to the textField variable. I then set the cellRenderer style of the dropdown list, which is a class that describes how each item in the list is formatted. For that I use another custom class, which extends fl.controls.listClasses.CellRenderer:

package com.rockabit.utils.as3
{
import fl.controls.listClasses.CellRenderer;

import flash.text.TextFormat;

/**
* Custom cellRenderer for comboBox list items.
*/
public class CustomCellRenderer extends CellRenderer
{

public function CustomCellRenderer()
{
super();
this.setStyle(”embedFonts”, true);
this.setStyle(”textFormat”, new TextFormat(”Arial”, 10, 0×000000));
}

}

}

All this class does is extend the default CellRenderer class and set some styles in the constructor.

Using these two simple classes, you can easily make sure that all your fonts are embedded in the comboBox component, and give them custom text formatting.

I’ve made a small example .fla file. You’ll notice that I added the Tahoma font to the library with a linkage class, which I instantiate in the TextFormat constructor parameter to get the correct fontName. Because I set the library font to bitmap text andset embedFonts to true in code, you get a nice crisp font display in your combobox.

Edit: I have now also added functionality to the CustomComboBox class to set vertical positioning of the main textfield. Right now this is hardcoded, but that could be changed to listen to a custom style.

Download source:
http://www.rockabit.com/downloads/as3/combobox_example.zip

Categories: programming Tags:
  1. April 15th, 2008 at 23:50 | #1

    Great, just what i was looking for.
    Do you have any .fla example?

  2. admin
    April 16th, 2008 at 09:47 | #2

    Hi Argenis Leon,

    I’ve just now added sourcefiles so you can see it in action.

    Enjoy :)

  3. stephanie
    July 9th, 2008 at 18:30 | #3

    Hi,

    I’m not quite familiar to AS3 and I have tried to use the 2 AS file you provided to change color of the List, but there were errors.

    So just wonder if the same .as file can be used to set the text colour for the component – List?

    Thanks!!

  4. Stephanie
    July 10th, 2008 at 08:32 | #4

    Hi, Just wonder if the above method can be used for List Component too? Cos’ I am not really familiar with AS3, and I have tried with your files but I cannot change color of the Text color in List Component.

    Thanks.

  5. admin
    July 10th, 2008 at 16:40 | #5

    To use it for a List component, you could set the cellRenderer style to use the CustomCellRenderer class I provided and define the text formatting in there.

    So if your list is called “myList”, then you could use myList..setStyle(”cellRenderer”, com.rockabit.utils.as3.CustomCellRenderer);
    This should make sure your list items use that class when they are displayed, so any changes in text format settings in that class should be reflected visually in your list.

    Good luck :)

  6. admin
    July 10th, 2008 at 16:41 | #6

    Sorry, little typo there.
    You should use: myList.setStyle(”cellRenderer”, com.rockabit.utils.as3.CustomCellRenderer);

  7. Stephanie
    July 11th, 2008 at 04:39 | #7

    Thanks for your reply…

    But I still have some questions in my head… so I don’t have to use or amend CustomCombo.as?

    And do I have to type something like this com.rockabit.utils.as3.CustomComboBox” in the Linkage of the List component?

    Because I have tried to type myList.setStyle(”cellRenderer”, com.rockabit.utils.as3.CustomCellRenderer); to the fla, but there are errors…

    Thanks again!!

  8. admin
    July 11th, 2008 at 07:49 | #8

    No, you don’t need the CustomComboBox class in this case.
    Also, if you use these classes, make sure they are in the correct folder structure. This means that in the folder of your project you need to place the class in com/rockabit/utils/as3. You could also put the class directly where your other files are (so right next to your .fla file), but then you should change the first line of the class to just ‘package’ and not ‘package com.rockabit.utils.as3′.

    If this does not help, please copy paste the errors here so I can see what the problem is exactly.

  9. stephanie
    July 17th, 2008 at 17:56 | #9

    o Thanks!

    I will try this again!! ;)

  10. Jason
    July 23rd, 2008 at 22:06 | #10

    Dude!!!!!!!!!!!!!!!!!!!!!!!!!!

    I am so glad i found you website!
    The crap on this site…
    http://blogs.adobe.com/pdehaan/2008/03/using_embedded_fonts_with_the_3.html

    I couldn’t get to work. As soon as I uploaded the flash file to our servers, no embeded Fonts showed up. The ComboBox component needs a little tweeking I think.

    Thanks agin, I am much less stressed now.
    -Jason

  11. August 16th, 2008 at 00:40 | #11

    Thanks and thanks again! The CustomCellRenderer class was just what I needed… I’d been trying to rotate a ComboBox for hours and seeing no text…!

  12. Elder
    August 27th, 2008 at 16:40 | #12

    hi!
    i’m trying to change the font but everytime i change it, the text disappears and only appears with the correct font if i delete the line with setStyle(”embedFonts”)… it’s strange! here’s my code:

    public function CustomComboBox() {
    super();
    textFormat = new TextFormat(”BellGothic Blk BT”, 11, 0×000000);
    textField.setStyle(’embedFonts’, true);
    // it only works if i comment the line above or if i set it to false
    textField.setStyle(’textFormat’, textFormat);
    dropdown.setStyle(’cellRenderer’, CustomCellRenderer);
    }

  13. Matt
    August 28th, 2008 at 03:08 | #13

    Very nice blog, thank you for the information!

    However, I am running into one problem. I am trying to load the CustomComboBox class at run time… everything works great except for one thing.

    If I select an item from the ComboBox list, the list hides and the item is selected. However, if I go to click on the comboBox again to drop down this list, I get this error:

    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at fl.controls::List/drawList()
    at fl.controls::List/draw()
    at fl.core::UIComponent/drawNow()
    at fl.controls::List/scrollToIndex()
    at fl.controls::SelectableList/scrollToSelected()
    at fl.controls::ComboBox/open()
    at fl.controls::ComboBox/onToggleListVisibility()

    If I try a second, third… millionith time, I get this error:

    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at fl.controls::ComboBox/close()
    at fl.controls::ComboBox/onToggleListVisibility()

    Do you have any idea why this is happening?

  14. November 12th, 2008 at 17:37 | #14

    thanks for the info, very useful, so how did you set the vertical position of the textField? its not in the sample files…

  15. admin
    November 12th, 2008 at 17:54 | #15

    It is, actually. Check the drawLayout method in the CustomComboBox class, that’s where it happens.

    Matt: Sorry I haven’t responded earlier, I’m sure you’ve found the problem by now…
    I can’t really say what’s going wrong, as I don’t have that problem using this same setup. Somewhere some object is removed which is not on the stage, or which is in another parent than it is being removed from, but I can’t tell what or how from just that error.

  16. zenMonkey
    November 25th, 2008 at 23:07 | #16

    Thanks so much for your post, twas very helpful!

    Any clue on how to apply anti-aliasing/sharpness/gridFitType/thickness to the text formatting. With textfields this is trivial. Hrrmmm.

  17. zenMonkey
    November 26th, 2008 at 00:13 | #17

    OK, I figured out how to tweak the text props further, snippets below.

    //snip
    import flash.text.*;
    public class CustomComboBox extends ComboBox
    {
    private var textFormat:TextFormat;

    public function CustomComboBox()
    {
    super();

    textFormat = new TextFormat(new CustomComponentFont().fontName, 11, 0×000000);
    textFormat.align = TextFormatAlign.CENTER;

    //textField is the top text, in the closed combobox
    textField.setStyle(’embedFonts’, true);
    textField.setStyle(’textFormat’, textFormat);

    textField.textField.antiAliasType = AntiAliasType.ADVANCED;
    textField.textField.gridFitType = GridFitType.SUBPIXEL;
    textField.textField.thickness = 0;
    textField.textField.sharpness = 200;

    //dropdown is the list that shows when you open the combobox
    dropdown.setStyle(’cellRenderer’, CustomCellRenderer);
    }
    override protected function drawLayout():void
    {
    super.drawLayout();
    textField.y = 2;
    }
    }

    //snip
    import flash.text.*;

    /**
    * Custom cellRenderer for comboBox list items.
    */
    public class CustomCellRenderer extends CellRenderer
    {

    public function CustomCellRenderer()
    {
    super();
    this.setStyle(’embedFonts’, true);
    var tf:TextFormat = new TextFormat(new CustomComponentFont().fontName, 11, 0×000000);
    tf.align = “center”;
    this.setStyle(’textFormat’, tf);

    textField.antiAliasType = AntiAliasType.ADVANCED;
    textField.gridFitType = GridFitType.SUBPIXEL;
    textField.thickness = 0;
    textField.sharpness = 200;

    }
    override protected function drawLayout():void
    {
    super.drawLayout();
    textField.y = 1;
    }

    }

  18. December 3rd, 2008 at 14:23 | #18

    That’s a really helpful little snippet, just the ticket!

    Enabled me to easily add some roll over effects to the text:

    public class DropDownRenderer extends CellRenderer
    {
    private var effect:SomeEffect;
    private var isOver:Boolean;

    private var tfOver:TextFormat;
    private var tfOut:TextFormat;

    public function DropDownRenderer()
    {
    tfOver = new TextFormat(”Univers UltraCondensed”,14,0×000000,null,null,null,null,null,null,3,null,null,0.45);
    tfOut = new TextFormat(”Univers UltraCondensed”,14,0xFFFFFF,null,null,null,null,null,null,3,null,null,0.45);
    effect = new SomeEffect(textField);

    isOver = false;

    addEventListener(MouseEvent.ROLL_OVER, onOver);
    addEventListener(MouseEvent.ROLL_OUT, onOut);

    setStyle(”embedFonts”,true);
    setStyle(”textFormat”,tfOut);

    textField.y += 1;
    }

    override protected function drawLayout():void
    {
    if(isOver)
    {
    effect.setText(label);
    effect.go();
    }
    }

    private function onOver(e:MouseEvent):void
    {
    isOver = true;
    setStyle(”textFormat”,tfOver);
    }

    private function onOut(e:MouseEvent):void
    {
    isOver = false;
    setStyle(”textFormat”,tfOut);
    }
    }

  19. admin
    December 3rd, 2008 at 14:36 | #19

    That’s a great addition!
    If you would implement an animation library such as Tweener you could even animate the colorTransform property in response to mouse interaction to make a smooth transition. I hadn’t even thought of creating custom mouse over effects :)

  20. Carmen
    April 9th, 2009 at 19:13 | #20

    Hello, i found your post so interesting, but i have a problem, well i have a sfw wich is called from other one and in this one i used your example to embending fonts, everithing seems ok but when i turned to false the enabled property from the combobox i can’t se the font (the text in it), i don’t speak or write in english very well but i hope you could help me. thanks.

  21. April 11th, 2009 at 20:00 | #21

    Just thought I’d mention that in order to set the anti-alias on the textField of the combobox, you have to reference the TextField element that is inside the “textField” property of the combobox, like this:

    cb.textField.textField.antiAliasType = AntiAliasType.ADVANCED;

    The textField property of the ComboBox is not a TextField, it is and TextInput. TextInput doesn’t have an antiAliasType property, you have to access the internal TextField of the TextInput which has an antiAliasType property.

  22. June 27th, 2009 at 13:44 | #22

    you are great!
    thx

  23. DJ
    August 21st, 2009 at 16:50 | #23

    This helped me accomplish what I was trying to. However, I’ve found a way to simplify this if you are looking to just change the font quickly for a combo.

    var my_ft:Font = new VerdanaFont();
    var my_tf:TextFormat = new TextFormat();
    my_tf.font = my_ft.fontName;

    var cb:ComboBox = new ComboBox();
    cb.dropdown.setRendererStyle(”embedFonts”, true);
    cb.dropdown.setRendererStyle(”textFormat”, my_tf);
    cb.textField.setStyle(”embedFonts”, true);
    cb.textField.setStyle(”textFormat”, my_tf);
    cb.setStyle(”embedFonts”, true);
    cb.setStyle(”textFormat”, my_tf);

    That should set all of the textfield’s fonts for ComboBox cb. Again, this is more of a “quick and dirty” (but still clean code) way of doing it.

  24. Julia
    September 21st, 2009 at 17:44 | #24

    Hi guys,

    Any “quick and dirty” code to add items to the combo? My code:

    //create the text format I need
    var myTextFormat:TextFormat = new TextFormat();
    myTextFormat.font=”Avenir LT 35 Light”;
    myTextFormat.size= 12;
    myTextFormat.color = 0×930000;

    //getting the first combo and setting the style to the textfield
    comboStyle1=ComboBox(getChildByName(”cbStyle1″));
    comboStyle1.width = 139;
    comboStyle1.height = 22;
    comboStyle1.textField.setStyle(”textFormat”, myTextFormat);

    //creating data provider for the dropdown
    var dp:DataProvider = new DataProvider();
    dp.addItem( { iconSource:”Label 1″, label:”Item 1″ } );
    dp.addItem( { iconSource:”Label 2″, label:”Item 2″ } );
    dp.addItem( { iconSource:”Label3″, label:”Item 3″ } );

    comboStyle1.dropdown.iconField =”iconSource”;comboStyle1.dropdown.dataProvider =dp;
    trace(comboStyle1.dataProvider.length); //outputs fine but the items don’t show up in the list

    comboStyle1.dropdown.setStyle(”cellRenderer”, CustomCellRenderer);

    //retrieve second combo
    comboStyle2=ComboBox(getChildByName(”cbStyle2″));
    comboStyle2.width = 139;
    comboStyle2.height = 22;

    //add items using combo’s data provider
    comboStyle2.dataProvider.addItem({label:”Label0″});
    comboStyle2.dataProvider.addItem({label:”Label1″});

    //set style
    comboStyle2.textField.setStyle(”textFormat”, myTextFormat);
    comboStyle2.dropdown.setStyle(”cellRenderer”, CustomCellRenderer);

    The CustomCellRenderer works fine on elements added from the authoring tool but if I try to add items from the code, nothing shows !!! Am I missing something here?

  25. admin
    September 21st, 2009 at 20:06 | #25

    Are you embedding the fonts?
    I don’t see code to set the embedFonts tyle to true for the textfield.
    Try using textField.setStyle(”embedFonts”, true); with every textfield you set the text format for, and see if that helps.

    Fonts are always a hassle with Flash, don’t ask me why. Even if the font is embedded in your application, it could be that it doesn’t show up if you don’t set embedFonts.
    Oh, and sometimes I find that it also helps to set the defaultTextFormat property of a textfield to the TextFormat you want to use.

    Anyway, I hope that works for you.

  26. Julia
    September 22nd, 2009 at 14:19 | #26

    Wow! Yes, it works now with the embedFonts property set to true.

    Thanks :)

  27. October 16th, 2009 at 17:06 | #27

    I encounter the problem you mention, the textField is to low and truncated. But I don’t want to extend the ComboBox class for that, to me that is more or less a bug. Whatever, here’s my solution :

    // THIS SETUP LEADS TO A TRUNCATED TEXTFIELD
    cb.height = 16;
    cb.prompt = “choose a country”;
    var f:TextFormat = new TextFormat();
    f.size = 10;
    cb.textField.setStyle(”textFormat”, f);

    // FORCE TO DRAW NOW
    // (forces the cb to run its drawLayout function now and to position
    // the textField where you don’t want it)
    cb.drawNow();

    // NOW DO YOUR POSITIONNING
    // now that the cb has done what he thought he should,
    // you can do what YOU want
    cb.textField.setSize(cb.textField.width, 15);
    cb.textField.y = 0;

    This did the trick for me.
    Cheers,
    Gilles

  28. admin
    October 16th, 2009 at 17:08 | #28

    That’s a nice and clean solution, I like it :)

  29. Kathleen
    October 27th, 2009 at 00:32 | #29

    Here is the code I have for my combobox, however I’m wanting to change the color of the dropdown text. Can you help me with this code? The code I have applied right now only changes the selected text, not the dropdown text.

    // ComboBox info \\
    var myTextFormat:TextFormat = new TextFormat();
    myTextFormat.font = “Arial”;
    myTextFormat.color = 0xFFFFFF;
    myTextFormat.size = 13;

    txtOPT1.textField.setStyle(”textFormat”, myTextFormat);
    txtOPT1.dropdown.rowHeight = 30;
    txtOPT1.prompt = ” Select”;
    txtOPT1.addItem({label:” 1 Ticket”, text:”1″})
    txtOPT1.addItem({label:” 2 Tickets”, text:”2″})
    txtOPT1.addItem({label:” 3 Tickets”, text:”3″})
    txtOPT1.addItem({label:” 4 Tickets”, text:”4″})
    txtOPT1.addItem({label:” 5 Tickets”, text:”5″})
    txtOPT1.addItem({label:” 6 Tickets”, text:”6″})
    txtOPT1.addItem({label:” 7 Tickets”, text:”7″})
    txtOPT1.addItem({label:” 8 Tickets”, text:”8″})
    txtOPT1.addItem({label:” 9 Tickets”, text:”9″})
    txtOPT1.addItem({label:” 10 Tickets”, text:”10″})

  30. Kathleen
    October 27th, 2009 at 00:55 | #30

    I figured it out. All I had to enter was

    txtOPT1.dropdown.setRendererStyle(”textFormat”, myTextFormat);

  31. Tibi
    November 27th, 2009 at 13:53 | #31

    Is there any way to ‘manipulate’ the textField component of the combobox? For my project I must use a non-standard font. the embedding and formatting applied work, but unfortunately, (probably due to the font’s nature), the text appears a little off with 2-3 pixels and basically get’s a little out of the box when rendering the combobox. I tried in all ways to try to “move” the textfield’s with 2-3 points upper but no matter what i try it never moves. Anybody got an idea what could be done?

  32. December 1st, 2009 at 01:07 | #32

    @Tibi:

    Had this same problem today. Here’s the solution.

    The textField property of the ComboBox class returns a TextInput Object. TextInput inherits from Sprite, so it has access to addChild() removeChild() etc. Instead of setting the prompt property of the ComboBox, I created a TextField and added it to ComboBox.textField:

    var prompt_txt:TextField = new TextField();
    prompt_txt.embedFonts = true;
    prompt_txt.defaultTextFormat = new TextFormat(”FontName”, 12, 0×333333);
    prompt_txt.text = “Prompt”;
    prompt_txt.y = -6;

    var comboBox:ComboBox = new ComboBox();
    comboBox.textField.addChild(prompt_txt);
    addChild(comboBox);

    There you have it, a correctly positioned “prompt”, now, getting the selected states to show up properly, that’s much more difficult, I’m halfway through coding it, hope this’ll get you on the correct path though.

  33. Kevin
    February 12th, 2010 at 19:22 | #33

    @Gilles
    Worked perfectly too ! Definitely the easiest and fastest way to position the textfield

  1. No trackbacks yet.