Archive

Posts Tagged ‘NavigatorContentServiceLabelProvider’

Writing an Eclipse Plug-in (Part 19): A Quick Display Fix

February 28, 2010 2 comments

[I am deep into solving a CNF issue, but since I haven’t solved it yet you will have to settle for a bug fix.]

Random bug: when the cursor hovers over the custom navigator title bar a tooltip opens letting us know that the navigator can’t find a label for the root node. The full error message is Error: no label provider for R/. Tells you everything you need to know. Except what the problem is. Or how to fix it. Or, for Eclipse novices, what R/ means.

Luckily this is something that we are not afflicted with here at Hidden Clause. The message did tell us everything we needed to know. The Custom Navigator label provider is ignoring the root node used by the navigator (the R/ referred to in the error) and returning an empty string. The code for LabelProvider.getText() is:

   public String getText(Object element) {
        String text = ""; //$NON-NLS-1$
        if (ICustomProjectElement.class.isInstance(element)) {
            text = ((ICustomProjectElement)element).getText();
        }
        // else ignore the element

        return text;
    }

(Notice how it so brilliantly ignores everything except elements of type ICustomProjectElement.)

What the message also tells us, by not telling us, is that our zero-length string appears to be causing consternation in the navigator. It is causing so much consternation that the navigator thinks no label provider is available to supply it with a default label for the root node.

That something is easily fixed in the LabelProvider. I’m not sure why Eclipse does not default to no string for the root (damn, those double negatives!), but it does not so we have to assign something to it. Since the standard behavior for other navigator views is to use the name of the view, in this case Custom Plug-in Navigator, that is what we will do.

  1. Open LabelProvider.java
  2. Change getText() to include an else if:
       public String getText(Object element) {
            String text = ""; //$NON-NLS-1$
            if (ICustomProjectElement.class.isInstance(element)) {
                text = ((ICustomProjectElement)element).getText();
            } else if (IWorkspaceRoot.class.isInstance(element)) {
                text = "Custom Plug-in Navigator";
            }
            // else ignore the element
    
            return text;
        }
    
  3. Start the runtime workbench and behold the beauty of our new string.

For Those of You Who Care

I discovered the solution to the above by putting a breakpoint in LabelProvider.getText() and walking the call tree. NavigatorContentServiceLabelProvider.findStyledText() quite explicitly changed the original empty string returned by LabelProvider.getText() into a null which caused NavigatorContentServiceLabelProvider.getStyledText() to assign the error message to the navigator view. It makes sense, it just wasn’t what I wanted.

Extra credit: Run the Externalize String Wizard on LabelProvider.java and add the new string to the message.properties file.

What Just Happened?

Fixed a bug. Contain your excitement.

The cat was not impressed and refused to come out.

Code

messages.properties

CustomProjectParent_Project_Folder=icons/project-folder.png
CustomProjectSchema_Project_Schema=icons/project-schema.png
CustomProjectSchemaFilters_Project_Schema_Filters=icons/project-schema-filters.png
CustomProjectSchemaTables_Project_Schema_Tables=icons/project-schema-tables.png
CustomProjectSchemaViews_Project_Schema_Views=icons/project-schema-views.png
CustomProjectStoredProcedures_Project_Stored_Procedures=icons/project-stored-procedures.png
LabelProvider_Custom_Plugin_Navigator=Custom Plug-in Navigator

LabelProvider.java

/**
 * Coder beware: this code is not warranted to do anything.
 *
 * Copyright Oct 17, 2009 Carlos Valcarcel
 */
package customnavigator.navigator;

import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;

/**
 * @author carlos
 *
 */
public class LabelProvider implements ILabelProvider {

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
     */
    @Override
    public Image getImage(Object element) {
        Image image = null;
        
        if (ICustomProjectElement.class.isInstance(element)) {
            image = ((ICustomProjectElement)element).getImage();
        }
        // else ignore the element
        
        return image;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
     */
    @Override
    public String getText(Object element) {
        String text = ""; //$NON-NLS-1$
        if (ICustomProjectElement.class.isInstance(element)) {
            text = ((ICustomProjectElement)element).getText();
        } else if (IWorkspaceRoot.class.isInstance(element)) {
            text = Messages.LabelProvider_Custom_Plugin_Navigator;
        }
        // else ignore the element
        
        return text;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
     */
    @Override
    public void addListener(ILabelProviderListener listener) {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
     */
    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
     */
    @Override
    public boolean isLabelProperty(Object element, String property) {
        // TODO Auto-generated method stub
        return false;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
     */
    @Override
    public void removeListener(ILabelProviderListener listener) {
        // TODO Auto-generated method stub

    }

}