Recipe 9.13.
Formatting Text
Problem
You want to format the text in a text field.
Solution
Use HTML tags, pass a TextFormat object to the
TextField.setTextFormat(
) method, or use a StyleSheet object, and apply it
to the text field's styleSheet property.
Discussion
Although you can set the color of the entire
contents of the text field using the textColor property,
for example, the TextField class doesn't offer precise
control over character formatting. However, there are several ways
in which you can apply more exacting formatting to text fields:
Each of the three ways in which you can apply
formatting to a text field has its own advantages and
disadvantages. Applying HTML formatting is relatively simple, but
it is the most difficult to manage of the different techniques.
Using a TextFormat object is the more complex than applying
formatting via HTML. However, when you want to apply complex
formatting, it is a better option than HTML formatting. Using CSS
with a StyleSheet object allows the greatest flexibility,
and it allows you to load a CSS document, which makes it simple to
maintain because you can edit the CSS document without having to
re-export the .swf file.
For fast and simple formatting, HTML tags are
simplest. For example, the following code displays bolded and
underlined text:
field.html = true;
field.htmlText = "<b>Bold text</b> <u>Underlined text</u>";
You can use TextFormat objects to apply
more complex formatting to the text displayed in text fields. The
first step in formatting text with a TextFormat object is to
instantiate the object by using the constructor method:
var formatter:TextFormat = new TextFormat( );
Next, assign values to the TextFormat
object's properties as you want:
formatter.bold = true; // Bold the text
formatter.color = 0xFFFF00; // Make the text yellow
formatter.blockIndent = 5; // Adjust the margin by 5 points
You can apply text formatting to the existing
text for an entire text field by passing a TextFormat object
to the text field's setTextFormat( ) method:
field.setTextFormat(formatter);
When you invoke the setTextFormat( )
method this way, the formatting from the TextFormat object
is applied to the text already assigned to the text field. The
formatting does not apply to any text assigned to the text field
after the setTextFormat( ) method is invoked. If additional
text is entered by the user, the original text retains its applied
formatting, but the inserted text does not have any special
formatting applied to it. All formatting is removed if the text
value is modified by appending a value by way of ActionScript:
field.text = "this is sample text";
field.setTextFormat(formatter); // Formatting applied
field.text = "this is new text"; // No formatting applied
field.setTextFormat(formatter); // Formatting reapplied
field.text += "appended text"; // Formatting removed
If you make changes to the TextFormat
object, you should reapply the formatting to the text field by
passing the modified object to the setTextFormat( ) method.
Otherwise, the changes are not automatically displayed.
CSS support is available using the
flash.text.StyleSheet class. The StyleSheet
constructor does not require any parameters, as shown here:
var css:StyleSheet = new StyleSheet( );
Table 9-1 lists the
supported CSS properties and the equivalent ActionScript
properties. Use the CSS property names when defining a CSS document
or a string to parse as CSS, and use the ActionScript properties
when defining style objects (as discussed next).
Table 9-1. CSS properties supported by
Flash Player
CSS property |
ActionScript property |
Description |
color
|
color
|
The hexadecimal value as a string in the
format of #RRGGBB. |
display
|
display
|
The way in which the text is displayed in
the text field. The possible options are inline (no line
breaks before or after the text), block (default style
with line breaks before and after), or none (hidden). |
font-family
|
fontFamily
|
A comma-delimited list of font names. In
addition to embedded fonts or named device fonts, Flash Player
supports the following device font groups: _sans,
_serif, _typewriter. You can also use
sans-serif, serif, and mono, and they
will be interpreted as _sans, _serif, and
_typewriter, respectively. |
font-size
|
fontSize
|
The numeric font size. |
font-style
|
fontStyle
|
normal or italic. |
font-weight
|
fontWeight
|
normal or bold. |
kerning
|
kerning
|
TRue or false. Kerning
only works with embedded fonts that support kerning. Additionally,
the .swf must be compiled on Windows for kerning to
work. |
letter-spacing
|
letterSpacing
|
The number of pixels to add between
letters. |
margin-left
|
marginLeft
|
Number of pixels to apply to the left
margin. |
margin-right
|
marginRight
|
Number of pixels to apply to the right
margin. |
text-align
|
textAlign
|
left, center,
right, or justify. |
text-decoration
|
textDecoration
|
none or underline. |
text-indent
|
textIndent
|
Number of pixels to apply as the
indent. |
You can construct a new StyleSheet object
and then populate it in several ways. One way to populate a
StyleSheet object is to define style objects and assign them
by using the setStyle( ) method. A style object is an
associative array with properties from the ActionScript properties
list of Table 9-1. The following
is an example of a style object:
var sampleStyle:Object = new Object( );
sampleStyle.color = "#FFFFFF";
sampleStyle.textAlign = "center";
Note that you can define a style object with
object literal notation as well, as shown here:
var sampleStyle:Object = {color: "#FFFFFF", textAlign: "center"};
Once you've defined one or more style objects,
you can add them to the StyleSheet object with the
setStyle( ) method.
The setStyle( ) method requires two parameters: the name of
the style and the style object. You can define styles for tags as
well as for classes. The following defines a CSS class called
sample:
css.setStyle(".sample", sampleStyle);
Although you can define a stylesheet with style
objects and the setStyle( ) method, the most common and
practical use of the class is to load and parse an external CSS
document. Loading CSS at runtime has the advantage that you can
change the styles by editing the CSS document, and you don't have
to recompile the .swf.
To load a CSS document, use the flash.net.URLLoader class. Once
data from the document has loaded, you can use that data to
populate a StyleSheet object by passing the data to the
parseCSS( ) method of
the object. The next example uses styles.css, a CSS document
defined as follows and saved in the same directory as the
.swf:
p {
font-family: _sans;
color: #FFFFFF;
}
.emphasis {
font-weight: bold;
font-style: italic;
}
The following example illustrates how to load a
CSS document and use that data to populate a StyleSheet
object:
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
import flash.text.TextFieldAutoSize;
import flash.text.StyleSheet;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class CSSText extends Sprite {
public function CSSText( ) {
var loader:URLLoader = new URLLoader( );
loader.addEventListener(Event.COMPLETE, onLoadCSS);
var request:URLRequest = new URLRequest("styles.css");
loader.load(request);
}
private function onLoadCSS(event:Event):void {
var css:StyleSheet = new StyleSheet( );
css.parseCSS(URLLoader(event.target).data);
var field:TextField = new TextField( );
field.autoSize = TextFieldAutoSize.LEFT;
field.wordWrap = true;
field.width = 200;
addChild(field);
field.styleSheet = css;
field.htmlText = "<p><span class='emphasis'>Lorem ipsum</span> dolor sit amet, consectetuer adipiscing elit. Morbi tortor purus, aliquet a, ornare ac, suscipit a, est. Nullam hendrerit molestie erat. Nunc nulla tortor, ullamcorper et, elementum vel, fringilla sed, dui. Praesent fermentum interdum orci.</p>";
}
}
}
There are a few things to watch for when working
with CSS in Flash:
-
CSS can be applied only to text fields rendering
HTML.
-
The HTML and CSS must correspond. For example,
if the CSS defines a class called someCSSClass, then it has
an effect only if the HTML applies that class to some portion of
the text (as in the preceding example).
-
The HTML text must be applied after the CSS is applied.
If you want to allow the user to select from
different CSS documents, it may be helpful to store the HTML text
in a variable or an associative array. Then you can re-apply the
HTML each time the new CSS is loaded, as in the following
example:
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;
import flash.text.StyleSheet;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class CSSText extends Sprite {
private var _field:TextField;
private var _html:String;
public function CSSText( ) {
var css1:TextField = new TextField( );
css1.text = "stylesheet 1";
css1.selectable = false;
var css1Container:Sprite = new Sprite( );
css1Container.addEventListener(MouseEvent.CLICK, onCSS1);
css1Container.addChild(css1);
addChild(css1Container);
var css2:TextField = new TextField( );
css2.text = "stylesheet 2";
css2.selectable = false;
var css2Container:Sprite = new Sprite( );
css2Container.addEventListener(MouseEvent.CLICK, onCSS2);
css2Container.addChild(css2);
addChild(css2Container);
css2Container.y = 25;
_field = new TextField( );
_field.autoSize = TextFieldAutoSize.LEFT;
_field.wordWrap = true;
_field.width = 200;
addChild(_field);
_html = "<p><span class='emphasis'>Lorem ipsum</span> dolor sit amet, consectetuer adipiscing elit. Morbi tortor purus, aliquet a, ornare ac, suscipit a, est. Nullam hendrerit molestie erat. Nunc nulla tortor, ullamcorper et, elementum vel, fringilla sed, dui. Praesent fermentum interdum orci.</p>";
_field.y = 50;
}
private function loadCSS(url:String):void {
var loader:URLLoader = new URLLoader( );
loader.addEventListener(Event.COMPLETE, onLoadCSS);
var request:URLRequest = new URLRequest(url);
loader.load(request);
}
private function onCSS1(event:MouseEvent):void {
loadCSS("styles.css");
}
private function onCSS2(event:MouseEvent):void {
loadCSS("styles2.css");
}
private function onLoadCSS(event:Event):void {
var css:StyleSheet = new StyleSheet( );
css.parseCSS(URLLoader(event.target).data);
_field.styleSheet = css;
_field.htmlText = _html;
}
}
}
See Also
Recipe
9.8 explains how to use HTML-formatted text, Recipe
9.14 explains how to apply formatting to new text rather than
existing text, and Recipe
9.15 applies formatting to individual characters rather than an
entire field.
|