The ToolTipManager has
two methods that let you programmatically use ToolTips.
These methods are createToolTip() and destroyToolTip(), which
you use to create and destroy new ToolTip objects. When you create
a ToolTip object, you can customize it as you would any object,
with access to its properties, styles, events, and effects.
The createToolTip() method has the following
signature:
The text parameter defines the contents
of the ToolTip.
The x and y parameters define
the x and y coordinates of the ToolTip, relative to the application
container.
The errorTipBorderStyle parameter sets
the location of the pointer on the error tip. This parameter is
optional. If you specify the value of the errorTipBorderStyle parameter
in the createToolTip() method, Flex styles the
ToolTip as an error tip. Valid values are "errorTipRight", "errorTipAbove",
or "errorTipBelow", and indicate the location of
the error tip relative to the component. If you set the errorTipBorderStyle parameter
to null, then the ToolTip is a normal ToolTip,
not an error tip.
The following example shows the valid values and their resulting
locations on the error tip:
The context parameter determines which
StyleManager is used. Typically, you pass the object on which the
ToolTip appears, so that the ToolTip's StyleManager is the same
one use by that object. This object must be of type IUIComponent,
so you might need to cast it in some cases, such as when you want
to specify the context as the event.currentTarget in
an event handler.
For more information about using error tips, see Using error tips.
The createToolTip() method returns a new ToolTip
object that implements the IToolTip interface. You typically cast
the return value of this method to a ToolTip, although it is more
efficient if you do not do this. To cast, you can do one of the
following:
Use the as keyword, as the following
example shows:
myTip = ToolTipManager.createToolTip(s,10,10) as ToolTip;
Use the type(object) casting
syntax, as the following example shows:
These methods of casting differ only in the way that they behave
when a cast fails.
Flex displays the ToolTip until you destroy it. In general, you
should not display more than one ToolTip box at a time, because
it is confusing to the user.
You can use the destroyToolTip() method to destroy
the specified ToolTip object. The destroyToolTip() method
has the following signature:
destroyToolTip(toolTip:IToolTip):void
The toolTip parameter is the ToolTip
object that you want to destroy. This is the object returned by
the createToolTip() method.
The following example creates a custom ToolTip when you move
the mouse over a Panel container that contains three Button controls.
Each Button control has its own ToolTip that appears when you mouse
over that particular control. The big ToolTip disappears only when
you move the mouse away from the Panel container.
<?xml version="1.0"?>
<!-- tooltips/CreatingToolTips.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.managers.ToolTipManager;
import mx.controls.ToolTip;
import mx.core.IUIComponent;
public var myTip:ToolTip;
private function createBigTip(event:Event):void {
var s:String = "These buttons let you save, exit, or continue with the current operation."
myTip = ToolTipManager.createToolTip(s,75,75,null,IUIComponent(event.currentTarget)) as ToolTip;
myTip.setStyle("backgroundColor",0xFFCC00);
myTip.width = 125;
myTip.height = 75;
}
private function destroyBigTip():void {
ToolTipManager.destroyToolTip(myTip);
}
]]>
</fx:Script>
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
s|Panel {
paddingLeft: 5;
paddingRight: 5;
paddingTop: 5;
paddingBottom: 5;
}
</fx:Style>
<s:Panel title="ToolTips" height="200" width="200" rollOver="createBigTip(event)" rollOut="destroyBigTip()">
<s:Button label="OK" y="20" toolTip="Save your changes and exit."/>
<s:Button label="Apply" y="50" toolTip="Apply changes and continue."/>
<s:Button label="Cancel" y="80" toolTip="Cancel and exit."/>
</s:Panel>
</s:Application>
The executing SWF file for the previous example is shown below:
Customizing the current ToolTip
Another approach to customizing ToolTip objects is to intercept
the current ToolTip and customize it rather than using the ToolTipManager
to create a new ToolTip object.
You do this by customizing the ToolTip during one of the ToolTip-related
events like toolTipHide, toolTipShow,
and toolTipShown.
The following example triggers the customization on the ToolTip’s toolTipShown event.
This lets Flex handle all the logic for displaying and hiding the
ToolTip, but lets you modify the current ToolTip’s text, position,
and other properties.
<?xml version="1.0" encoding="utf-8"?>
<!-- tooltips/CustomToolTipInActionScript.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="initApp();">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import spark.components.Button;
import mx.core.IToolTip;
import mx.events.ToolTipEvent;
import mx.managers.ToolTipManager;
import mx.core.FlexGlobals;
public var myTip:IToolTip;
public var b:Button;
private function initApp():void {
b = new Button();
b.addEventListener("toolTipShown", createCustomTip);
b.label = "Click Me";
/* You must create a blank ToolTip so that the control
can dispatch ToolTip-related events. The new ToolTip
will replace this empty ToolTip. */
b.toolTip = " ";
addElement(b);
}
private function createCustomTip(e:ToolTipEvent):void {
var s:String = "This is a ToolTip for the button.";
myTip = ToolTipManager.currentToolTip;
// Customize the text of the ToolTip.
myTip.text = s;
// Customize the alpha of the ToolTip.
myTip.alpha = .6;
// Customize the position of the ToolTip.
myTip.x = FlexGlobals.topLevelApplication.mouseX + 20;
myTip.y = FlexGlobals.topLevelApplication.mouseY;
}
]]>
</fx:Script>
</s:Application>
The executing SWF file for the previous example is shown below:
Implementing the IToolTip interface
You can also create a custom ToolTip by extending an existing
control, such as a Panel or other container, and implementing the
IToolTip interface. The following example uses a Panel container
as the base for a new implementation of the IToolTip interface:
<?xml version="1.0"?>
<!-- tooltips/ToolTipComponents/PanelToolTip.mxml -->
<s:Panel
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
implements="mx.core.IToolTip"
width="200"
alpha=".75">
<fx:Script>
<![CDATA[
[Bindable]
public var bodyText:String = "";
// Implement required methods of the IToolTip interface; these
// methods are not used in this example, though.
public var _text:String;
public function get text():String {
return _text;
}
public function set text(value:String):void {
}
]]>
</fx:Script>
<s:RichText text="{bodyText}" percentWidth="100"/>
</s:Panel>
In your application, you can create a custom ToolTip by intercepting
the toolTipCreate event handler of the target component.
In the event handler, you instantiate the new ToolTip and set its
properties. You then point the toolTip property
of the ToolTipEvent object to the new ToolTip.
In the following example, the first two buttons in the application
use the custom PanelToolTip class in the ToolTipComponents package.
The third button uses a default ToolTip to show you how the two
are different. To run this example, store the PanelToolTip.mxml
file in a subdirectory named ToolTipComponents.
<?xml version="1.0"?>
<!-- tooltips/MainCustomApp.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import ToolTipComponents.PanelToolTip;
import mx.events.ToolTipEvent;
private function createCustomTip(title:String, body:String, event:ToolTipEvent):void {
var ptt:PanelToolTip = new PanelToolTip();
ptt.title = title;
ptt.bodyText = body;
event.toolTip = ptt;
}
]]>
</fx:Script>
<s:Button id="b1"
label="Delete"
toolTip=" "
toolTipCreate="createCustomTip('DELETE','Click this button to delete the report.', event)"
/>
<s:Button id="b2"
label="Generate"
toolTip=" "
toolTipCreate="createCustomTip('GENERATE','Click this button to generate the report.', event)"
/>
<s:Button id="b3"
label="Stop"
toolTip="Click this button to stop the creation of the report. This button uses a standard ToolTip style."
/>
</s:Application>
The executing SWF file for the previous example is shown below:
Positioning custom ToolTips
When you use the ToolTipManager to create a custom ToolTip,
you specify the coordinates of the ToolTip on the Stage. You do
this by specifying the values of the x and y parameters
of the new ToolTip in the createToolTip() method. These
coordinates are relative to the Stage. For example, a value of 0,0
creates a ToolTip at the top-left corner of the application.
In some cases, you might not know the exact position that you
want the ToolTip to be drawn in; instead, you want the location
of the ToolTip to be relative to the target component (the component
that has a ToolTip on it). In those cases, you can use the location
of the target component to calculate the values of these coordinates.
For example, if you want the ToolTip to appear to a component’s right,
you set the ToolTip’s x position to be the x position of the component
plus the component’s width, plus some other value for an offset.
The following image shows the results of this formula:
You also set the value of the ToolTip’s y position to be the
same as the target component’s y position to line the ToolTip and
the component up horizontally.
One way to get the values you need to calculate the x position
of the ToolTip is to use an event handler. Event objects passed
to an event handler can give you the x position and the width of
the target component.
The following example gets the value of the current target’s x, y,
and width properties in the focusIn event handler,
and uses them to position the ToolTip. In this case, the current
target is the TextInput control, and the ToolTip appears to its
right with a 10-pixel offset.
<?xml version="1.0"?>
<!-- tooltips/PlacingToolTips.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
height="100" width="300">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.controls.ToolTip;
import mx.managers.ToolTipManager;
import mx.core.IUIComponent;
private var tip:ToolTip;
private var s:String;
private function showTip(event:Object):void {
s="My ToolTip";
// Position the ToolTip to the right of the current target.
tip = ToolTipManager.createToolTip(s,
event.currentTarget.x + event.currentTarget.width + 10,
event.currentTarget.y, null,IUIComponent(event.currentTarget))
as ToolTip;
}
private function destroyTip(event:Object):void {
ToolTipManager.destroyToolTip(tip);
}
]]>
</fx:Script>
<s:TextInput id="a"
width="100"
focusIn="showTip(event)"
focusOut="destroyTip(event)"/>
<s:TextInput id="b"
width="100"
focusIn="showTip(event)"
focusOut="destroyTip(event)"/>
</s:Application>
The executing SWF file for the previous example is shown below:
The previous example creates a ToolTip on a target component
that is not inside any containers. However, in many cases, your
components will be inside layout containers such as a VGroup or
an HGroup. Under these circumstances, the coordinates you access
in the event handler will be relative to the container and not the
main application. But the ToolTipManager expects global coordinates when
positioning the ToolTip. This will position ToolTips in unexpected
locations.
To avoid this, you can use the contentToGlobal() method
to convert the coordinates in the event handler from local to global.
All components that subclass UIComponent have this method. It takes
a single Point that is relative to the target’s enclosing container
as an argument and returns a Point that is relative to the Stage.
The following example calls the TextInput control’s contentToGlobal() method
to convert the control’s coordinates from those that are relative
to the VGroup container to global coordinates.
<?xml version="1.0"?>
<!-- tooltips/PlacingToolTipsInContainers.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
height="400" width="600">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.controls.ToolTip;
import mx.managers.ToolTipManager;
import mx.core.IUIComponent;
private var tip:ToolTip;
private var s:String;
private function showTipA(event:Object):void {
s="My Tip A";
tip = ToolTipManager.createToolTip(s,
event.currentTarget.x + event.currentTarget.width + 10,
event.currentTarget.y) as ToolTip;
}
private function showTipB(event:Object):void {
s="My Tip B";
var pt:Point = new Point(0,0);
/* Call this method to convert the object's
coordinates inside its container to the stage's
global coordinates. */
pt = event.currentTarget.contentToGlobal(pt);
tip = ToolTipManager.createToolTip(s,
pt.x + event.currentTarget.width + 10, pt.y, null,
IUIComponent(event.currentTarget)) as ToolTip;
}
private function destroyTip(event:Object):void {
ToolTipManager.destroyToolTip(tip);
}
]]>
</fx:Script>
<!-- A ToolTip at the top level. -->
<!-- The event handler for this ToolTip does not use any special
logic to account for whether the ToolTip is inside a container.
But this ToolTip is not inside a container so it positions itself
normally. -->
<s:TextInput id="a"
text="Good ToolTip placement"
width="175"
focusIn="showTipA(event)"
focusOut="destroyTip(event)"/>
<s:VGroup>
<!-- A ToolTip inside a container. -->
<!-- The event handler for this ToolTip accounts for the control
being inside a container and positions the ToolTip using the
contentToGlobal() method. -->
<s:TextInput id="b"
text="Good ToolTip placement"
width="175"
focusIn="showTipB(event)"
focusOut="destroyTip(event)"/>
<!-- A ToolTip inside a container. -->
<!-- The event handler for this ToolTip does not use any special
logic to account for whether the ToolTip is inside a container.
As a result, it positions itself using coordinates that are relative
to the container, but that are not converted to global coordinates. -->
<s:TextInput id="c"
text="Bad ToolTip placement"
width="175"
focusIn="showTipA(event)"
focusOut="destroyTip(event)"/>
</s:VGroup>
</s:Application>
The executing SWF file for the previous example is shown below: