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.