Loosely coupled but tightly integrated

I was never happy with how tightly coupled my image viewer is to the resources API. It seems to me that an image viewer is a pretty handy, general-purpose thing. The initial implementation can display images contained in files. But images come from other places. Items in an auction have images; so do the results of queries against Flickr.

I reworked the plug-in to make it exploit the Eclipse adapter mechanism. The adapter mechanism is one of those handy things that makes it possible to build plug-ins that work really well together but know nothing about each other. Strange? You bet. But very powerful.

The basic idea is that I want my image viewer to display an image for the selected thing. Whatever it is. So it registers a selection listener with the workbench selection service; the selection listener is notified whenever a selection occurs in a table, tree, editor, whatever. The image viewer looks at the selection and tries to determine how to display an image for it. To do this, it attempts to adapt the selected thing into an instance of the ImageProvider type (ImageProvider is a class that I’ve provided). It then asks the ImageProvider for the image. If the selected thing cannot be adapted to the appropriate type, the whole process is aborted (so the image viewer displays the last thing that was selected that could provide an image).

To insulate my image viewer from having any knowledge of the resources API, I created a separate plug-in which provides an extension to the org.eclipse.core.runtime.adapters extension point. This extension contributes a factory that knows how to adapt objects that implement org.eclipse.core.resources.IFile into an ImageProvider. This new plug-in knows about both the image viewer plug-in and the resources plug-in, but these other plug-ins each knows nothing about the other.

Adding support to display images for other types of objects is pretty easy: I just have to add another extension to org.eclipse.core.runtime.adapters and we’re off to the races. No changes are required to the image viewer to display this new type of thing.

If you’re curious about how all this works import this project set. If you just want to use the image viewer, you can get the plug-ins here. Just drop the contents of this ZIP file into your “plugins” directory (I’ll get around to building an update site someday).

This entry was posted in Uncategorized. Bookmark the permalink.

3 Responses to Loosely coupled but tightly integrated

  1. Brad says:

    You might want to use org.eclipse.jface.resource.ImageDescriptor instead of ImageProvider, since it seems to do what you want, and pre-existing plug-ins may already provide adapters for ImageDescriptor.

  2. Dan says:

    The adapter mechanism in Eclipse is powerful but you have to be careful because if there are multiple adapter factories registered against the same type then the first one that is found will always win.

  3. Michael D. Elder says:

    Hi Wayne, Could you provide an “ImageProvider” implementation for “image” types in the Variables view (from the Debug perspective). I would love to be able to select an Image or ImageDescriptor in that view and see the actual image that is rendered. Currently the only thing you see is the “toString()” method, and for images, it just renders a number (e.g. “Image{8723738}”). I’ve been debugging decorator problems for the last day or so, and that kind of tool would have made it easier. -MDE.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s