Friday, March 02, 2012

Intellij needs to introduce the Lookup API

I'm looking today at the toolbar classes from IntelliJ IDEA and I'm surprised by the amount of instanceof I see.

For example, NavBarPresentation.getIcon looks like this:

public static Icon getIcon(final Object object, final boolean open) {
    if (!NavBarModel.isValid(object)) return null;
    if (object instanceof Project) return PROJECT_ICON;
    if (object instanceof Module) return ModuleType.get(((Module)object)).getNodeIcon(false);
    try {
      if (object instanceof PsiElement) {
        Icon icon = ApplicationManager.getApplication().runReadAction(new Computable() {
          public Icon compute() {
            return ((PsiElement)object).isValid() ? ((PsiElement)object)
              .getIcon(open ? Iconable.ICON_FLAG_OPEN : Iconable.ICON_FLAG_CLOSED) : null;
          }
        });
        
        if (icon != null && (icon.getIconHeight() > 16 || icon.getIconWidth() > 16)) {
          icon = IconUtil.cropIcon(icon, 16, 16);
        }
        return icon;
      }
    }
    catch (IndexNotReadyException e) {
      return null;
    }
    if (object instanceof JdkOrderEntry) return ((JdkOrderEntry)object).getJdk().getSdkType().getIcon();
    if (object instanceof LibraryOrderEntry) return IconLoader.getIcon("/nodes/ppLibClosed.png");
    if (object instanceof ModuleOrderEntry) return ModuleType.get(((ModuleOrderEntry)object).getModule()).getNodeIcon(false);
    return null;
  }

That's just horrendous!

What they need to do is introduce a mechanism similar to the Lookup API from NetBeans.

Then, if object is a Lookup.Provider, just call getLookup().lookup(Icon.class).

The above method becomes

public static Icon getIcon(final Object object, final boolean open) {
    if (!NavBarModel.isValid(object)) return null;
    if (!(object instanceof Lookup.Provider)) return null;
    Lookup lookup = ((Lookup.Provider)object).getLookup();
    return lookup.lookup(Icon.class);
  }

and each of the individual classes (Project, Module, PsiElement, JdkOrderEntry, LibraryOrderEntry, ModuleOrderEntry) will have to add into their lookup the given Icon.

As it is right now, the existing code has a lot of imports. What looks like a little Swing module (com.intellij.ide.navigationToolbar) imports hundreds of classes from all over the place and seems to be a pain to read and maintain.

Truth be told, the code is from 2008 -- perhaps the newer stuff already has a similar mechanism.

PS: While I am a NetBeans guy, I'm not trying to start a flamewar. I actually want to see if I can reuse navigationToolbar but all these imports are making it really difficult.

No comments:

The Trouble with Harry time loop

I saw The Trouble with Harry (1955) a while back and it didn't have a big impression on me. But recently I rewatched it and was amazed a...