Nicer Tooltips and balloon help for Flex 4
Keywords: component, flex 4, skin, ToolTipManager, tootlips, usability
Tooltips are a good way to provide a user with additional information for controls and Flex offers Tooltips out of the box. The default Tooltips are fine but when text gets longer than just a few words usability may suffer.
For a current project, I needed more like a balloon help in place of tooltips and therefore decided not to use Flex default tooltips.
Regarding usability of the tooltips (balloon help) I want to be able to
- Display an optional tooltip title
- Display formatted tooltip text
- Display icons
- Colorize the tooltip based on the semantic of the invoking control
- Consistent Placement
- Have all title, text, styles for the tooltips stored in a central location
- Have the tooltips work in a generic and Flex-compliant way
Flex gives you a few ways to customize tooltips from registering your custom ToolTip class to intercepting Tooltip events where you can hook up the custom tooltip. All of these approaches fall either short of the requirements I had or would add additional overhead so I simply created a custom ToolTipManager that would alter the behaviour of the default ToolTipManager.
Here’s a demo of the final result, the approch is described further down.
Since I like to have all resources centralized, the approach I followed was to interpret the value of the tooltip- or the errorString property on a control not as the tooltip text to display but as a partial key to lookup title, text, styles etc. in a resource bundle. Form this partial key concrete keys would be derived to lookup the values for a controls tooltip.
For example
<s:Button label=”OK” tooltip=”ToolTipBundle.okButton” />would point to the ResourceBundle named ‘ToolTipBundle’ and within this to all entries of a key starting with tooltip.okButton. Then the values for title, text etc. will be looked up by the custom ToolTipManager implementation and be applied to the tooltip.
The first token in the tooltip property specifies the name of the resource bundle, the second token the partial key for looking up the entries in the resource bundle. If no second token is specified the id (if any) of the component is being used.
Entries in the resource bundle then refer to the partial key submitted and define the concrete values to use for the tooltip.
tooltip.okButton.title=Title of Tooltip tooltip.okButton.text=Text for this tooltip tooltip.okButton.styleName=CSS class to use for this tooltip tooltip.okButton.placement=bottomRight|bottomLeft|topRight|topLeft tooltip.okButton.color=Color of text tooltip.okButton.chromeColor=Color of tooltip
Color and chromeColor are there for convenience but can also be set via the CSS class specified by styleName. If any of the entries are not specified fallbacks to default values are used.
To make this work some methods of the default ToolTipManager need to be overwritten
override mx_internal function initializeTip():void
This is where the cstom implementation looks up the values and assigns them to the tooltip.
Additionally there’s the
override mx_internal function positionTip():void
method to position the tooltip in a custom way.
The custom ToolTipManager implementation is registered at loading using a custom preloader class.
The custom Tooltip itself is a simple SkinnableComponent associated with a SparkSkin. There’s a required skin part for the text and a dynamic skin part for the label that only gets added if any value for a title is provided.
For both title and text a RichText component is used within the skin so that formatting the text in a rich way is possible. The associated skin is then responsible to draw the tooltip based on the provided placement.
Having set this up, usage of the custom tooltips for any app is simple.
<s:Application preloader="com.hulstkamp.flex.spark.preloaders.CustomMixinPreloader"> </s:Application>
This will register the custom ToolTipManager.
For additional documentation see the source in the demo (view source is enabled).
Similar Posts
Spark Icon Button with Gradient effects and Filter animation, colorized by styles. Flex 4 (Gumbo)
Custom PopUp Rating Component in Spark Flex 4 (Gumbo)
Use SpriteVisualElement to implement a simple component in Flex 4
Flex Tab Key Navigation for custom Spark PopUp
Custom Spark CheckBox Component in Flex 4 (Gumbo)


May 31st, 2010 at 4:38 pm
This is very sweet. I’m going to take a closer look at this code when I get further with my project.
June 1st, 2010 at 11:28 pm
I was very pleased to see that you have updated your blog with another awesome component as well as your other components
i will integrate it in my current project maybe i had to customize it a bit to fulfill i18n compatibilty (LocalizationMap).
best regards, gurkerl
June 2nd, 2010 at 9:56 am
@Andrew, @Markus
Thanks a lot - glad you found this somehow useful.
@Markus
I’ve been sunk in JEE-Projects during the past months. I’m very happy to be able to work with Flex again, so updates on this blog should get more frequent again - hopefully.
July 5th, 2010 at 2:34 pm
Very Nice Tooltips, thank you very much!!!
Noob question:
There is an easy way into insert a dynamic one?
var impl:NiceToolTipManagerImpl;
impl = NiceToolTipManagerImpl (mx.core.Singleton.getInstance(”mx.managers::IToolTipManager2″));
var toolTip_TL:toolTip_TL = impl.createToolTip(”", 100, 50,null,this) as toolTip_TL;
toolTip_TL.x = …
another aproximation is creating over an object (label,button via xmxl mode) and later manipulate position and values, but no way to acces to .ToolTipInstance ;(
July 5th, 2010 at 10:18 pm
Heru,
not sure if I understand you’re question.
I needed to change the behaviour of how Flex handles the Tooltips that is why I went for a custom ToolTipManagerImpl and this post is about that.
For standard custom tooltips you might want to check the docs.
July 5th, 2010 at 11:40 pm
Yes, you are right, i was complicating the solution xD
Anyway saved to useful libs…
(excuse poor english, i know its hard to help people adding the efford to understand ’strange’ ang. constructions
thanks again!
July 28th, 2010 at 11:58 pm
Hi Andy,
thanks a lot for the tutorial and sharing your code.
Somehow I get this error message: Unable to resolve resource bundle “ToolTipBundle” for locale “en_US”.
do you happen to know why?
thanks and keep up the great work
Linda
July 29th, 2010 at 2:33 pm
Linda
Did you configure the resource bundles?
You need to tell the Flex Compiler where to find the resource bundles.
Go to Project Properties, then Flex Compiler and put this under additional compiler arguments:
-locale en_US -source-path=/locale/
This tells the compiler to lookup the resources for en_US under the path /locale/. Obviousliy ToolTipBundle.properties must be there. At compile time it is embedded via the application (alternatively you could load rb at runtime).
hth
andy
August 10th, 2010 at 1:01 pm
Hi Andy,
thanks a lot for your reply!
I have it working right now and it is working beautifully.
Absolutely love it.
Two more questions though.
1. Images within the tooltips take a bit to appear and I am under the impression that embedding the needed assets could probably help the issue. But how to embed an images such as the one that you specify in the “Tooltip and Image” example?
2. Do you have any idea how to deal with more than one language? I would really like to avoid any redundancy such as having many different tooltip.properties files with different title and text information but identical color, placement and other layout details.
Again. Thank you very much.
Best wishes and kind regards,
Linda
August 10th, 2010 at 2:54 pm
I tend to get the warning:
“The CSS type selector ‘tooltip.NiceToolTip’ was not processed, because the type was not used in the application.”
Do you happen to know why that might be?
August 11th, 2010 at 2:25 pm
@Linda
1. As for Images it is the default behaviour for resource bundles. Flex does not know the class at compile-time. You can try to explicitly embedd the images elsewhere in the application and see if caching does the job.
2. You might want to change the NiceToolTipManagerImpl and pass a default locale for the properties that are identical accross locales. Flex might do this for you via the locale chain anyway.
August 11th, 2010 at 2:29 pm
@Sam
Any path, location info? Did you add any CSS?
If you want to style the custom NiceToolTip then you need something like ah|NiceToolTip (Assuming you use the namespace ah)
August 20th, 2010 at 10:29 am
[...] Author: Andy Hulstkamp Source: http://www.hulstkamp.com/ [...]
August 27th, 2010 at 1:52 am
Mmhh. Thanks for your reply, Andy.
I guess it is me being stopid but where exactly do you specify which styles.css/css the custom NiceToolTip should read for its layout properties?
thank you a lot!! -Sam
September 20th, 2010 at 3:53 pm
Hello,
Is there a way to pass in dynamic text based off the object that the tool tip is called on? I would like to use some of the data to seed part of the text.
Thoughts?
Thanks.
September 21st, 2010 at 10:56 pm
Todd
First note that standard Flex tooltips can be customized and if using the Flex ToolTipManager the value in the tooltip property is interpreted as the string to display in the tooltip. You can set this string any time at runtime - based on your data.
This example uses a custom ToolTipManager to look up title, text, styles etc. in resource bundles. For this, the value in the tooltip property is interpreted as a key to look up the text etc. in the bundles.
In assignResourcesToToolTip() of NiceToolTipManagerImpl you could change the way of how the values are looked up and assigned to the tooltip.
For instance you could introduce further tokens for the value in the tooltip property and parse these tokens as parameters to get a parametrized text from the resource bundle
• Bundle.Key#dynamic text
• parse #tokens to use as params in resource bundle lookup
• var toolTipText:String = ResourceManager.getInstance().getString(bundleKey, lookupKey + “.text”, params);
For a more OOP approach you could introduce some interface like IToolTipTextOverride that has a get / set toolTipOverride():String function.
Let your components implement this interface (returning a string based on your data) and in NiceToolTipManagerImpl check to see if the currentTarget (the component the tooltip should be shown on) is of type IToolTipTextOverride.
If true get the text from the toolTipOverride property of the currentTarget instead of looking it up from the resource bundle and assign this text to the tooltip text.
Andy
November 2nd, 2010 at 6:20 pm
Hi,
I’m having the same issue as the above poster regarding dynamic text in the tooltip. I’m having a hard time implementing/understanding your suggestion. Do you have an example using this approach or could you possibly provide a little more detail?
Thanks
Kevin
November 2nd, 2010 at 8:36 pm
Kevin,
Here’s a quick demo implementation of the aforementioned approaches.
get the fxp here.
Look at NiceToolTipManagerImpl Line #275 and #209 for the code that looks up the text.
Look at TextInputWithOverridenDynamicToolTipText for an example that uses the OOP-Approach.
hope this helps
andy
February 1st, 2011 at 5:42 pm
Thank you a lot Andy. Especially thank you for your last post with example of dynamic tooltip.
March 1st, 2011 at 5:04 pm
Any reason you extend DownloadProgressbar instead of SparkDownloadProgressBar? At first glance they both seem to work correctly, only difference is the look.
March 17th, 2011 at 10:17 am
Thijs
This answer took a while, sorry;-)
There’s no reason to use the DownlaodProgressbar instead of the SparkDownloadProgressBar. I simply didn’t pay much attention, since the only purpose of extending the Progressbar is to inject the custom ToolTipManagerImpl. Thanks for pointing this out!
Andy
June 23rd, 2011 at 12:12 am
Hi Andy,
I’ve incorporated your wonderful Nicer Tooltips into an AIR project I’m working on.
Is there a way to restrict the tooltip to the stage? (it is occasionally popping up partially off-stage
)
thanks,
Mark
September 9th, 2011 at 11:59 am
Hi Andy,
In my application, the tooltip’s title and text should be displayed dynamicly. From example, there is button which label will be often changed by user. And its tooltip will always display the latest label string.
How could I do when use your nice tooltip?
Thanks!
October 19th, 2011 at 10:38 am
Sam,
See the discussion above with Todd and Kevin.