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
Great, just what i was looking for.
Do you have any .fla example?
Hi Argenis Leon,
I’ve just now added sourcefiles so you can see it in action.
Enjoy
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!!
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.
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
Sorry, little typo there.
You should use: myList.setStyle(”cellRenderer”, com.rockabit.utils.as3.CustomCellRenderer);
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!!
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.
o Thanks!
I will try this again!!
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
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…!
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);
}
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?
thanks for the info, very useful, so how did you set the vertical position of the textField? its not in the sample files…
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.
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.
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;
}
}
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);
}
}
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
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.
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.
you are great!
thx
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.
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?
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.
Wow! Yes, it works now with the embedFonts property set to true.
Thanks
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
That’s a nice and clean solution, I like it
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″})
I figured it out. All I had to enter was
txtOPT1.dropdown.setRendererStyle(”textFormat”, myTextFormat);
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?
@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.
@Gilles
Worked perfectly too ! Definitely the easiest and fastest way to position the textfield