As you’ve already learned in earlier chapters, the Flex framework provides a large library of components, including layout containers and UI controls. However, in addition to the components themselves, the framework also provides libraries that offer you advanced features and functionality when working with those components. In this chapter, we’ll look at the features and functionality these libraries provide. Specifically, we’ll discuss tool tips, pop ups, cursor management, drag-and-drop, the ability to customize list-based items, and focus management and keyboard control.
When an application contains graphics, it can often be helpful to users if you provide text-based descriptions to accompany the graphics. This is especially beneficial when the meaning of a particular UI element is not immediately obvious. It can also be useful for low-sighted and non-sighted users who rely on screen readers. Rather than cluttering the user interface with many text-based descriptions of graphics, however, many applications use tool tips, which are blocks of text that appear when the user moves the mouse over a visual element. In the following sections you’ll learn how to work with Flex tool tips.
All components that inherit from UIComponent
(which includes all UI controls
and layout containers) implement a toolTip
getter/setter property, which allows you to assign a string to the object that it
will use to display tool tips. You can set the property inline using
MXML, as in the following example:
<mx:Button id="button" label="Tool Tip Example" toolTip="Display Tool Tip" />
You can also set the toolTip
property in ActionScript:
button.toolTip = "Example of Tool Tips";
By default, the toolTip
property value for a component is null
. When the value is null
or an empty string, no tool tip appears.
When you assign the property a non-null
value, the tool tip appears after a short
delay once the user moves the mouse over the object and keeps the mouse
over the object. The tool tip then disappears after a delay (customizing
the delay is discussed in the “Customizing Tool Tip Settingsˮ sections
in this chapter) or after the user moves the mouse outside the object,
whichever occurs first.
You can also use data binding to set the value of a tool tip for an object. The following example uses data binding to update the value of the tool tip text for a button based on the text input value:
<mx:VBox> <mx:Button id="button" label="Button" toolTip="{textInput.text}" /> <mx:TextInput id="textInput" /> </mx:VBox>
There are rules that determine the tool tip behavior for
containers and child components. The innermost component always takes highest precedence.
If the innermost component has a valid tool tip text value, the tool tip
for that component will be triggered. If not, the trigger bubbles up to
the container until either a valid tool tip text value is found or no
more containers exist. The following simple example illustrates this
behavior. Because the button has a tool tip text value, moving the mouse
over the button will trigger that component’s tool tip. And because the
text input has no tool tip text setting, the trigger will bubble up to
the VBox
container, displaying the
container’s tool tip.
<mx:VBox toolTip="This is the VBox tool tip."> <mx:Button id="button" label="Button" toolTip="This is the button tool tip." /> <mx:TextInput id="textInput" /> </mx:VBox>
Navigator components such as accordions and tab navigators have a different default behavior in
this regard. Whereas most container children will trigger the parent
container tool tip, the children of navigator components do not. The
only triggers for the container tool tips are the navigator elements
corresponding to the containers. For example, in a tab navigator the
tabs will trigger the tool tips for the corresponding containers. The
following example illustrates this behavior. The accordion has two
elements, each a VBox
container. Each
VBox
specifies a toolTip
value. Each VBox
instance contains one button. The button
within the first VBox
does not
specify a toolTip
value, whereas the
second does. If you test this code, you’ll see that the tool tips for
the VBox
containers are never
triggered by the child buttons.
<mx:Accordion height="200" width="200"> <mx:VBox toolTip="A"> <mx:Button label="Button 1" /> </mx:VBox> <mx:VBox toolTip="B"> <mx:Button label="Button 2" toolTip="Button" /> </mx:VBox> </mx:Accordion>
Although in most cases you will likely add tool tips using the
toolTip
property as described in the
preceding section, you can also add tool tips programmatically using the
mx.managers.ToolTipManager
class.
Using the static createToolTip()
method you can add new tool tips. You need to specify three parameters: the text to display
in the tool tip, the x coordinate for the tool tip,
and the y coordinate for the tool tip. The
coordinates are relative to the application itself, which means that
values of 0 and 0 will place the tool tip in the upper left of the
application. The following code adds a new tool tip to the application
at 100, 100:
ToolTipManager.createToolTip("Example programmatic tool tip", 100, 100);
Clearly, using the toolTip
property is simpler to implement, and therefore, in most cases it is
preferable to use the toolTip
property instead of the createToolTip()
method. However, there are a
few good reasons to use the createToolTip()
method:
Flex will display only one tool tip at a time of the tool tips
defined by the toolTip
property
of components. Therefore, if you want to display two or more tool
tips simultaneously, you must define all of them or all except one
of them using the createToolTip()
method.
The createToolTip()
method
returns a reference to the new ToolTip
object, which allows you to
programmatically control that object.
Tool tips are instances of the mx.controls.ToolTip
class, which is a UIComponent
subclass. That means you can
programmatically control ToolTip
objects in much the same way as you can other sorts of components. The
createToolTip()
method returns a
reference to the new tool tip, though the return type for createToolTip()
is the interface mx.core.IToolTip
rather than the concrete type
of ToolTip
.
If you programmatically create a tool tip, you will also need to
programmatically remove it. You can remove tool tips using the ToolTipManager.destroyToolTip()
method, which
requires that you pass it the tool tip you want to remove. Typically
you’ll call destroyToolTip()
after
the user moves the mouse outside of the UI element. You can call the
destroyToolTip()
method immediately
after the mouse moves outside the element, or you can use a Timer object
to add a slight delay.
By default, tool tips have a maximum width of 300 pixels, and the text automatically wraps at that width. You can see the default behavior with the following example:
<mx:Button id="button" label="Tool Tip" toolTip="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer commodo lacus sed dui. Pellentesque est nisi, semper sit amet, feugiat eu, pellentesque id, erat." />
This example creates a button that has a tool tip with the default maximum width so that the text automatically wraps to form three lines.
You can control the maximum width of the tool tip using the static
mx.controls.ToolTip.maxWidth
property. The default value is 300
,
which accounts for the default width of 300 pixels. If you set the value
of the property, it affects the width of all tool tips within the
application that are displayed from that point forward, unless and until
you assign a new value to the property. There is no API for controlling
the maximum width of an individual tool tip when using the toolTip
property to create the tool tip. If
you’d like to control the width of an individual tool tip, you must
create it using ToolTipManager.createToolTip()
. The following
example uses a button with a tool tip. Initially, the maximum width of
the tool tip is set to the default. However, when the user clicks on the
button, it sets the maximum width to 500. Mousing over the button again
will display the tool tip text on just two lines.
<mx:Button id="button" label="Tool Tip" toolTip="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer commodo lacus sed dui. Pellentesque est nisi, semper sit amet, feugiat eu, pellentesque id, erat." click="mx.controls.ToolTip.maxWidth = 500" />
Tool tips use automatic word wrap to add soft line breaks when the
text reaches the maximum width. If you want to add a hard line break, you can do so by
inserting a newline character (
),
carriage return (
), or form feed
character (f
) in the tool tip text
when assigning the text using ActionScript. When using an MXML
attribute, you should use the
XML entity, as in the following
example:
<mx:Button id="button" label="Tool Tip" toolTip="Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Integer commodo lacus sed dui. Pellentesque
est nisi, semper sit amet, feugiat eu, pellentesque id, erat." />
You can customize the look of tool tips using styles. The Flex
framework doesn’t provide a convenient way in which to set the styles of
individual tool tips created using the toolTip
property. You must set the tool tip
style globally for all instances if you are going for convenience. You
can do so by changing the ToolTip
style definition. The following illustrates how to change the style
definition using a Style
tag:
<mx:Style> ToolTip { fontFamily: "_typewriter"; backgroundColor: #FFFFFF; } </mx:Style>
You can use ActionScript to set the style using the StyleManager.getStyleDeclaration()
method to
retrieve the ToolTip
declaration. You
can then use setStyle()
to change
individual styles:
var toolTipDeclaration:CSSStyleDeclaration = StyleManager.getStyleDeclaration("ToolTip"); toolTipDeclaration.setStyle("fontFamily", "_typewriter");
If you want to use a specific font, and you want to ensure that the user will be able to view the tool tip with that specific font, you can embed the font. Embedding the font for tool tips works just as it would for any other text for which you use styles. The following example embeds a font called Georgia:
<mx:Style> @font-face { src: local("Georgia"); fontFamily: GeorgiaEmbedded; } ToolTip { fontFamily: GeorgiaEmbedded; backgroundColor: #FFFFFF; } </mx:Style>
Although setting tool tip styles globally is the more convenient
way to style tool tips, it has the drawback of not allowing you to
customize the appearance of individual tool tips. If you want to
customize individual tool tips you must create the instances using the
ToolTipManager.createToolTip()
method
as described in the previous section. You can then apply styles to the
instances as you would other components, using the setStyle()
method or the styleName
property.
You can customize several global tool tip settings using the
mx.managers.ToolTipManager
class. Using the static enabled
property you can enable and disable
tool tips globally. This can be useful if, for example, you want to
temporarily disable tool tips while the application is awaiting a
response to a remote procedure call. The default value of the enabled
property is true
, which means that if you want tool tips
enabled, you don’t have to do anything. If you want to disable tool
tips, you can set the value to false
:
ToolTipManager.enabled = false;
Of course, you’ll need to set the property to true
again if you want to reenable tool
tips:
ToolTipManager.enabled = true;
The showDelay
, hideDelay
, and scrubDelay
static properties allow you to
control the amount of delay before showing and hiding tool tips. The
showDelay
property controls the
amount of time before a tool tip displays after a user moves the mouse
over the object. The value is specified in milliseconds. The default
value is 500
, which means the tool
tip displays half a second after the user moves the mouse over the
object. The following sets the delay to one second:
ToolTipManager.showDelay = 1000;
Tool tips disappear after the user moves the mouse off an object.
However, they can also disappear after a delay even while the mouse is
still over the object. The hideDelay
property
determines the number of milliseconds before the tool tip disappears.
The default value is 10000
, which
means the tool tip disappears after 10 seconds. Setting the value to
0
is the same as telling the tool
tips to disappear as soon as they appear, so they are never shown. You
can use a value of Infinity
(a global
constant) if you want the tool tips to remain visible as long as the
mouse is over the object:
ToolTipManager.hideDelay = Infinity;
The scrubDelay
property allows
you to specify the amount of allowable delay between mousing out of one
object and mousing over another object to omit the show delay on the
second object. This is especially important if there is a long show
delay. For example, if you have a line of buttons, each with tool tips,
you may want the user to be able to scroll across the buttons quickly
and read the tool tips. Without the scrub delay setting, the user would
have to pause over each button for the show delay duration before he
could see the tool tip. The scrub delay setting says that if the amount
of time between mousing out of one object and mousing over a second
object is less than a specified number of milliseconds, the application
should display the tool tip for the second object immediately. The
default value for scrubDelay
is
100
. The greater the value for
scrubDelay
, the more likely it is
that the user will have to delay before showing the tool tip on objects
after mousing over them in succession.
The ToolTipManager
class also
allows you to use a custom class as a tool tip. This is a very rare
use case, and for that reason we won’t discuss it in detail. However,
you can assign a DisplayObject
class reference to the static toolTipClass
property to use that class as
the tool tip blueprint:
ToolTipManager.toolTipClass = CustomClass;
If you want to be able to use the custom class in the same way
as a standard tool tip (e.g., set the tool tip text), the custom class
must also implement mx.core.IToolTip
. Because IToolTip
extends IUIComponent
, the most practical way to
implement IToolTip
is to first
extend mx.core.UIComponent
and then
to implement just the specific interface defined by IToolTip
.
You can apply effects such as blurs, motion, and so on, to the
showing and hiding of tool tips. You can use any effect that you can use with any Flex
component. As with almost all other tool tip settings, using the most
convenient and practical approach the effect settings apply globally to
all tool tips. You can set the effect that gets applied when showing the
tool tips by way of the ToolTipManager.showEffect
property, and you can set the effect that gets applied when hiding
the tool tips by way of the ToolTipManager.hideEffect
property. Example 10-1 illustrates how this works, and
it demonstrates that you can use not only single effects, but also
composite effects.
Example 10-1. Applying composite effects
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initializeHandler(event)"> <mx:Style> @font-face { src: local("Georgia"); fontFamily: GeorgiaEmbedded; } ToolTip { fontSize: 16; fontFamily: GeorgiaEmbedded; backgroundColor: #FFFFFF; } </mx:Style> <mx:Script> <![CDATA[ import mx.managers.ToolTipManager; private function initializeHandler(event:Event):void { ToolTipManager.showEffect = toolTipShowEffect; ToolTipManager.hideEffect = toolTipHideEffect; } ]]> </mx:Script> <mx:Parallel id="toolTipShowEffect"> <mx:Fade alphaFrom="0" alphaTo="1" duration="1000" /> <mx:Blur blurXFrom="10" blurYFrom="10" blurXTo="0" blurYTo="0" duration="1000" /> </mx:Parallel> <mx:Parallel id="toolTipHideEffect"> <mx:Fade alphaFrom="1" alphaTo="0" duration="1000" /> <mx:Blur blurXFrom="0" blurYFrom="0" blurXTo="10" blurYTo="10" duration="1000" /> </mx:Parallel> <mx:Button id="button" label="Tool Tip" toolTip="Tool Tip Effect Example" /> </mx:Application>
You’ll notice that Example 10-1 embeds the font for the tool tips. This is because the font must be embedded to properly animate the alpha of the text. In this particular example, the blur portion of the effect causes the tool tips to be rendered as bitmap surfaces, lessening the need to embed the font. However, even with the bitmap surfaces enabled, the text can still quickly flash before fading in unless the font is embedded.
Although applying effects to tool tips globally is the most
convenient approach, it is not the only way to apply effects. If you
want to apply an effect to an individual tool tip, then you must construct the individual tool tip using the
ToolTipManager.createToolTip()
and
apply the effect to the individual tool tip using the setStyle()
method.