Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Does JavaFX support rich text in Tooltips?

swpalmer-JavaNetSep 30 2011 — edited Oct 6 2011
Does JavaFX support rich text in Tooltips? The docs for Tooltip.setFont say:

"The default font to use for text in the Tooltip. *If the Tooltip's text is rich text* then this font may or may not be used depending on the font information embedded in the rich text, but in any case where a default font is required, this font will be used. "

But I don't know how to set rich text. I tried using HTML the same way Swing works with HTML but that didn't work (it just showed the HTML source).

Comments

867657
Hi

You can put anything you like in the tooltip.

Check out the documentation for the tooltip class...

http://download.oracle.com/javafx/2.0/api/index.html

Among other things it has .install(Node n, Tooltip t) and .setGraphic(Node n)

If you have html you can just put that in WebView (or HTMLEditor) and display it in the tooltip that way.

Cheers,
Nuwanda
swpalmer-JavaNet
The install method has nothing to do with the content of the Tooltip. It's for putting a tooltip on a non-Control Node (that doesn't have a setTooltip method).

The setGraphic method is described as "An optional icon for the Tooltip." ... I suppose this can be "abused" to install an arbitrary Node as the tool tip content rather than an icon.. but if this is a supported use-case then the documentation is quite misleading. I also fail to see how it relates to "rich text" as opposed to completely arbitrary content.

If setGraphic is intended for support of arbitrary content in a Tooltip, the docs and API are a bit awkward. If Tooltip is going to support arbitrary content, then it muddies the API to even have the setText method, only setNode would be necessary. Text or Label Nodes could be supplied if only text content was required.
zonski
For what it's worth, I have also looked for this and as far as I can tell, the answer to your question is basically 'no' - there is no direct support for rich text that I have found. In fact the whole tooltip api seems a bit unloved as there also seems to be no support for common, simple things like managing the time tooltips are visible, etc.

The answer by Nuwanda is legit and I think your best option. I agree it's a nasty little piece of the API both in the approach and in the horrible naming used. However, based on the fact that the 'setGraphic' method on Label also uses the same approach I believe the intention is that you should set an arbitrary node via this method.

Pretty it aint.
Richard Bair-Oracle
Actually, feel free to put anything in as the graphic, that was the design intention.
Richard Bair-Oracle
zonski wrote:
For what it's worth, I have also looked for this and as far as I can tell, the answer to your question is basically 'no' - there is no direct support for rich text that I have found.
That is correct. The trajectory here is to allow you to specify the text and a content type, such that you can have HTML, some form of bbcode, etc as the String content and then specify the content type and we'll be able to interpret it as rich text and format accordingly, and the this would apply to Labels, buttons, tooltips, etc. However, we didn't get that far in 2.0 and so the documentation got ahead of the implementation.
In fact the whole tooltip api seems a bit unloved as there also seems to be no support for common, simple things like managing the time tooltips are visible, etc.
I guess I never figured out how that should all play. The problem with tooltips is that in order to get the semantics right there has to be some coordination between all the different tooltips. I implemented this by having a single tooltip manager that adds listeners and timers and such. So adjusting the time some tooltip is visible is a global setting, but since there is no way in the platform to specify a static constant via CSS, it would require yet some other configuration option, and I didn't want to do that hastily -- hence no config for it. Also, how long tooltips stay up is something that is platform specific (along with how long a delay when hover before it is shown, whether to instantly hide the tooltip or fade it out, etc). So that argues it needs to be applied via CSS so we can customize per platform using the normal theming mechanisms.

Anyway, I wouldn't say it got no love, as much as I didn't manage to figure out a nice way to make it all highly configurable and fit in with the system. So better to leave out the configurability until somebody figures out how to do it in some tidy manner.
The answer by Nuwanda is legit and I think your best option. I agree it's a nasty little piece of the API both in the approach and in the horrible naming used. However, based on the fact that the 'setGraphic' method on Label also uses the same approach I believe the intention is that you should set an arbitrary node via this method.

Pretty it aint.
That's correct, the intention is that you can use the setGraphic to put any arbitrary node in there (including a container with other controls or whatever you want). The name evolved over time, with our current naming (contentDisplay) we maybe could have called it "content" and that would have been better. I didn't think the approach was so bad though. The other approach would have been to only have a content and you would have to manually set the text via button.setContent(new Label("Text")); or something like that which seemed both cumbersome to program as well as removing some potential optimizations that we can use to reduce node count in the skin implementations. But I am curious if you have another approach that would have worked better, where the developer can easily specify text and/or complex sub-scenes.

Cheers
Richard
zonski
Hi Richard,

It's great to get some (a whole lot!) of input from the JFX team on the forum. My adjectives may have been a little strong in the previous post, no offence intended. The whole JFX platform is an impressive piece of work and I'm hooked.

Regarding some alternate ideas for the ToolTip API, I have some suggestions and thoughts to throw in the mix for what it's worth. Take what you like from it, ignore the rest!

API

Is there a reason why we need a static ToolTip.install(node, tooltip) ? I was looking for a non-static Node.setToolTip(ToolTip) originally and this still makes more sense to me (setToolTip(null) would uninstall). For me the ToolTip is conceptually an attribute of the Node in the same way that a Border is or a Style. You wouldn't have Border.install(Node, Border) for example. This is a small thing but makes it easier to find and gives a more consistent API and usage in my opinion.

Also, is there a need/advantage for the ToolTip class to be exposed to us directly as API consumers. What if we could just install an arbitrary node as a tooltip on a component. Something like:
myNode.setToolTip(new Label("My tooltip"));
Internally the implementation could put it in a PopUp and do whatever it needs to. Giving the internal popup a style class would allow custom styling and ideally it would be within the selector of the component. So if myComponent had a style class so named, then a style selector of .myComponent .toolTip { ... } would apply to it. Or you could just style all default tooltips using the unclassified .toolTip style.

The only real tradeoff for this that I can see is that we would lose access to the 'activatedProperty' which might be useful in some cases. If it is then perhaps a solution would be to have either a toolTipPopup property or just a 'toolTipActivated' property on Node itself (I prefer the later).

It would also be nice to have a simple convenience method that took a string, i.e. myNode.setToolTip("My tooltip") for the common case (80%) of setting simple tooltips. This would just create a Label and then call setToolTip(Node). Using bbcode in this would be great - but ideally this would be supported at the 'Labeled' level and not be specific to ToolTips.

If the above doesn't work for you then I would still suggest just adding a couple of nice convenience methods for ToolTip.install. So you have ToolTip.install(Node, Sting) and ToolTip.install(Node, Node) that are just helper methods to simplify the API call for the major use cases.

Global Tooltip Settings

I have often had cases (in Swing) where I wanted ToolTips to behave differently based on the context they are used in. A common example is a graphical component (e.g. a gant chart, a map, a floorplan) where I want the tooltip to pop up quickly and stay visible until I move the mouse away. I don't want the same settings on the other controls in the same app (buttons, menus, etc). So for me 'global settings' aren't great. I'd rather see each component have it's own specific tooltip settings, with 'global defaults'.

This probably needs a bit more thinking about but I reckon the css style mechanism could achieve this. Could we not have things like
.toolTip { 
  -fx-show-delay: 30; 
  -fx-dismiss-on: mouseExit; 
  -fx-dismiss-delay: 30; 
  -fx-show-animation: grow; // as an example of something that would be cool to be able to do
  -fx-dismiss-animation: fade;  
}
The above CSS would set the defaults. If the owning Node's style class acted as the parent CSS selector then you could style individual Nodes with .myNode .toolTip { ... }

Thinking about this, perhaps some of these styles are applicable to PopUp class itself. Just a thought.

Labelled.setGraphic

For me this is just a naming thing. It is common across most (possibly all) the platforms that I've used for this to be called an 'Icon'. Semantically that's what I am setting on the Label. Having the ability to set an arbitrary Node as the Icon is quite cool and powerful, however in the context of something Labelled it is still conceptually an Icon. 'Content' doesn't really do anything for me on a semantic level either, to me content = the label + the icon. Personally I'd vote for this method to be called setIcon(Node) - 'personally' being the operative word :)

Another small thing on this is that now to actually set an Image (the 80% case) on the Label, I now need to create a Node as well as an Image. This is just that little bit more verbose than I would like and in FXML it is even more verbose, needing a whole set of embedded XML tags. Ideally a convenience method for setGraphic (or setIcon) would exist that took an Image directly to avoid some hoops. Same for the constructor that currently takes a node.

These are just some thoughts and some feedback. As I said, I'm impressed with JFX and being a long-time champion of Java Desktop (I have fought the web bandits off in many a company to get Swing in), I am genuinely excited about what JFX is going to do to this space.

Nice work.

Cheers,
zonski
1 - 6
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Nov 3 2011
Added on Sep 30 2011
6 comments
1,098 views