1

I came across this code on Vogella which demonstrates creating a LabelProvider for a JFACE tree.

I'm finding it really confusing however. The Image objects, named FOLDER and FILE are defined by calling a method which returns either FOLDER or FILE.

Essentially it's like a dictionary saying insured means someone with insurance and insurance is what some who is insured has. I am confused.

Why doesn't it cause an infinite loop?

package de.vogella.jface.treeviewer.provider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import de.vogella.jface.treeviewer.model.Category;
import de.vogella.jface.treeviewer.model.Todo;

public class TodoLabelProvider extends LabelProvider {

  private static final Image FOLDER = getImage("folder.gif");
  private static final Image FILE = getImage("file.gif");


  @Override
  public String getText(Object element) {
    if (element instanceof Category) {
      Category category = (Category) element;
      return category.getName();
    }
    return ((Todo) element).getSummary();
  }

  @Override
  public Image getImage(Object element) {
    if (element instanceof Category) {
      return FOLDER;
    }
    return FILE;
  }

  // Helper Method to load the images
  private static Image getImage(String file) {
    Bundle bundle = FrameworkUtil.getBundle(TodoLabelProvider.class);
    URL url = FileLocator.find(bundle, new Path("icons/" + file), null);
    ImageDescriptor image = ImageDescriptor.createFromURL(url);
    return image.createImage();

  } 
} 
CodyBugstein
  • 21,984
  • 61
  • 207
  • 363

1 Answers1

4

You're confused because of the method overloading. The calls here:

private static final Image FOLDER = getImage("folder.gif");
private static final Image FILE = getImage("file.gif");

don't call this method:

public Image getImage(Object element) {

They call this one:

private static Image getImage(String file) {

They couldn't call the first method anyway, as it's an instance method and the call is in a static field initializer with no instance to call the method on. But they call the second method anyway because the argument is a string.

It's still pretty odd code - particularly the implementation of getImage(Object element).

Even if it was written like this:

// Bogus code!
private static Image FOLDER = getImage("folder.gif");
private static Image FILE = getImage("file.gif");

private static Image getImage(String name)
{
    return name.equals("FRED") ? FOLDER : FILE;
}

... that still wouldn't cause an infinite loop. You'd just end up with null values. The static field initializer just sets the initial value for the variable. It doesn't associate the variable with the method call such that any access to the variable invokes the method.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Dang sorry for the mixup! But can you explain that last part a bit better - `as it's an instance method and the call is in a static field initializer with no instance to call the method on.`? – CodyBugstein May 24 '13 at 14:54
  • @Imray: Well, which bit don't you understand? Do you understand that `public Image getImage(Object element) { ... }` is declaring an instance method - one that has to be called on an instance of the declaring class? And do you understand that a *static* initializer doesn't have any implicit instance of that class? – Jon Skeet May 24 '13 at 14:56
  • Gotcha... I had to look up what an instance method is but I got it now. Thanks a lot! – CodyBugstein May 24 '13 at 15:20