Eclipse: Rich Hovers Redux
In Using the new Rich Text Hovers in Eclipse 3.4, I, uh, suggested that perhaps, um, maybe, an implementation of ITextHoverExtension2#getHoverInfo2
(from the package org.eclipse.jface.text
) could return either a String or “An implementation of IInformationControlExtension2
“.
That was a m- mi- mis- mistake. What I meant to say was:
[It] is the responsibility of the implementer of
IInformationControl
andIInformationControlExtension2
to specify the concrete nature of the information control’s input…
In plain(er) English: If you write the hover control, you get to specify the hover information. The implementation of getHoverInfo2
must be aware of the hover control’s implementation, and must conform to its specification.
So as a plug-in author, how can you create hovers with rich display formats? I’ve found two options. The first of these doesn’t even require any of the extensions that I’ve already touched upon.
Using the DefaultHoverControl
Straight out of the box (as it were), the JavaEditor example plug-in is configured to use the default version of the org.eclipse.jface.text.DefaultHoverControl
class. In this configuration, the DefaultHoverControl
treats its text input as raw text (without markup), as shown in the screen shot below.
(Note: The example Java editor plug-in simply copies the current text selection into the hover. In these screen shots, the selection is a Java comment that contains HTML markup.)
Some of the constructors for DefaultHoverControl
enable the control to process a subset of HTML. To use one of these, we need to add the following method to JavaSourceViewerConfiguration
in the sample editor; this overrides the base class implementation in org.eclipse.jface.text.source.SourceViewerConfiguration
:
/** * Returns the information control creator. The creator is a * factory creating information controls for the given source * viewer. This implementation always returns a creator for * <code>JavaInformationControl</code> instances. * * @param sourceViewer the source viewer to be configured * by this configuration * @return the information control creator, or <code>null</code> * if no information support should be installed * @since 2.0 */ public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) { return new IInformationControlCreator() { public IInformationControl createInformationControl(Shell parent) { return new JavaHoverInformationControl(parent); } }; }
Unlike the base class implementation, this version calls the two-argument constructor DefaultInformationControl(parent, false)
. Internally, this constructor will create an HTMLTextPresenter
object, which supports some simple HTML markup.
The emphasis here is on simple HTML. Unfortunately, while HTMLTextPresenter
happily reads the HTML markup, it doesn’t implement very much of it. As this screenshot illustrates, both <code>
and <em>
markup are ignored. (There’s no example hyperlink here, but I can confirm that they’re ignored as well.)
Creating a new hover control
If you need to support richer content than
DefaultInformationControl
can handle, then it’s likely that you’ll need to create your own hover control. This may require some experimentation, as the definitive guide to writing hover controls hasn’t been written yet (or if it has been, its visibility flag is set to false
.)
I’ve put together a demo of a hover control that uses the SWT Browser widget. The JavaHoverInformationControl
class implementation requires only about 150 lines of code, plus a few changes in two other files in the JavaEditor demo. It’s still rough around the edges; you may not be replacing your desktop browser with it anytime soon, but it should help to illustrate how a plug-in author can take control over hover controls.
In this screenshot, you can see that the example comment is now displayed in all of its HTML glory in the hover:
For additional demo value—and to show how this all ties in with ITextHoverExtension2#getHoverInfo2
—the JavaHoverInformationControl
also displays something useful when no text is currently selected:
(Well, it’s useful to me, anyway!)
A few aspects of the demo are worth describing here. The tie-in to ITextHoverExtension2#getHoverInfo2
is through an interface nested within the new JavaHoverInformationControl
class:
public interface IHTMLHoverInfo { /** * @return true if the String returned by getHTMLString() * represents a URL; false if the String contains marked-up text. */ public boolean isURL(); /** * @return The input string to be displayed in the Browser widget * (either as marked-up text, or as a URL.) */ public String getHTMLString(); }
This is reflected in the JavaTextHover
class, which I’ve modified to implementITextHoverExtension2#getHoverInfo2
. This implementation returns an Object
that conforms to the IHTMLHoverInfo
interface:
public class JavaTextHover implements ITextHover, ITextHoverExtension2 { //... other methods are not shown here... public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { // Start with the string returned by the older getHoverInfo() final String selection = getHoverInfo(textViewer, hoverRegion); // If text is selected in the editor window, it's returned as the // hover string. If no text is selected, then the returned hover is // a URL pointing to www.outofwhatbox.com/blog. return new JavaHoverInformationControl.IHTMLHoverInfo() { public boolean isURL() {return selection.length() == 0;} public String getHTMLString() { if (isURL()){ return "http://www.outofwhatbox.com/blog"; } return selection; } }; }
Similarly, the JavaHoverInformationControl#setObject
method will invoke this object’s isURL
method, indicating whether to handle the input as marked-up text or as a URL:
public void setInput(Object input) { // Assume that the input is marked-up text, not a URL fIsURL = false; final String inputString; if (input instanceof IHTMLHoverInfo) { // Get the input string, then see whether it's a URL IHTMLHoverInfo inputInfo = (IHTMLHoverInfo) input; inputString = inputInfo.getHTMLString(); fIsURL= inputInfo.isURL(); //... rest of the code not shown here...
I’ve packaged the JavaHoverInformationControl
implementation with the modified source from the sample org.eclipse.ui.examples.javaeditor
package. It’s available for download as a ZIP file file and as a gzip’d tar file.
Actually i am searching for a rich hovertext. But your download link doesnt work or i dont have the permission to download it. If it is the first case, can you fix it please?
Sorry about that! I’ve fixed the file permissions, so you should be able to download it now.
it doesn’t work at all
Was it the download link that didn’t work, or the control itself?
If the control didn’t work, could you tell me how you tried to run it, and what was the result?
This seems to be a hover for eclipse editors.
How easy/hard would it be to get such a rich html tooltip with color support as in your example (which ignored <code> and <em>) working on an arbitrary SWT control?
I.e. I would like to call something like
new HtmlToolTip(control, "Hello world")
and have it working.
(See also my forum post http://www.eclipse.org/forums/index.php?t=msg&goto=551389&S=15e3e271d91f521d26beb7b2ba809148#msg_551389 )
[edited to fix formatting — dbreslau]
Hi, Henno —
I’m not sure why
org.eclipse.jface.window.ToolTip
andorg.eclipse.jface.text.ITextHover
are separate protocols, but they are. Worse still,org.eclipse.jface.window.ToolTip
is an abstract class with no associated interfaces.The best suggestion that I can offer right now is to try to create a subclass of
org.eclipse.jface.window.ToolTip
that proxies aorg.eclipse.jface.text.ITextHover
implementation. I can’t promise that it would work, or work well, because I haven’t examined theToolTip
API in much detail.[…] this, we can provide a more complex IInformationControl, which holds a Browser control. Please read Dan Breslau’s post for […]