Using the new Rich Text Hovers in Eclipse 3.4

I’m moving away from writing about Agile for a time, to look at some other programming topics. I know that with a new blog, it may be a mistake to switch subjects so abruptly. But then, I’m all about making mistakes.

I’m studying the sample Eclipse plugin projects that come bundled with Eclipse for RCP/Plug-in Developers. I had some adventures trying to track down the cause of a deprecation warning in the first sample, org.eclipse.ui.examples.javaeditor:

The method JavaTextHover.getHoverInfo(ITextViewer, IRegion) overrides a deprecated method from ITextHover

This method became deprecated when Eclipse 3.4 added new methods for implementing text hovers (the little popups that give you information about the text under the cursor, aka “infopops”.) The sample application still uses the older, deprecated form. But what should newer applications use? The documentation for the ITextHover interface, which declares the deprecated method, was moderately helpful at best:

In order to provide backward compatibility for clients of ITextHover, extension interfaces are used as a means of evolution. The following extension interfaces exist:

[...snip...]

ITextHoverExtension2 since version 3.4 allowing a text hover to return hover-specific information objects.

This looked promising. But what’s an “extension interface?” And what does it extend?

Aha! It’s a mixin1. To use it, you modify your existing hover class so that it implements ItextHoverExtension2 as well as the legacy ITextHover interface. In the sample project, I modified the JavaTextHover class, changing this:

public class JavaTextHover implements ITextHover {

to add the new ITextHoverExtension2 interface :

public class JavaTextHover implements 
    ITextHover, ITextHoverExtension2 {
        // ... [other methods aren't shown here]  ...
        public Object getHoverInfo2(ITextViewer textViewer,
                                              IRegion hoverRegion) {
                // For now, just return the same value as 
                // the legacy getHoverInfo()
                return getHoverInfo(textViewer, hoverRegion);
        }

To verify this, I used its own debugger to peek inside Eclipse, to see how it uses the ITextHover object2. Setting a breakpoint on the new getHoverInfo2 method, I saw that the class org.eclipse.jface.text.TextViewerHoverManager detects the hover object’s interface(s) via reflection, and makes the appropriate call to the hover object:

if (hover instanceof ItextHoverExtension2)
    information=
        ((ITextHoverExtension2)hover).getHoverInfo2(fTextViewer, region);
else
    information= hover.getHoverInfo(fTextViewer, region);
EDIT: What I’d written here previously about the return value from getHoverInfo2 was inaccurate. I’ve written a new post that, I hope, provides a clearer picture.

Note that although the method ITextHover.getHoverInfo is now deprecated, its interface ITextHover is not deprecated, even though ITextHover has no other methods. In fact, a number of non-deprecated classes, including org.eclipse.jface.text.source.SourceViewerConfiguration, still use ITextHover as either a parameter or a return type. I haven’t seen any way to route around these classes. If there’s no way around the use of ITextHover, then the editor application is forced to continue implementing the deprecated getHoverInfo method.

I’m well aware that “deprecated” classes and methods tend to hang around. Just the same, I’d rather not be forced into writing deprected methods.


[1] I’m using the term “mixin” in its loosest sense, denoting an optional interface that a class may choose to implement.

[2] One could say that Eclipse’s debugger reflects well upon itself. (Sorry. I’m a reflexive punner.)

, ,

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>