Package org.embl.ebi.escience.scuflui.renderers

Provides a Service Provider Interface (SPI) for rendering the data in a workflow.


Class Summary
AbstractRenderer Abstract rendering class.
AbstractRenderer.ByJavaClass Accept based on user object type match to a particular Class
AbstractRenderer.ByMimeType Choses to accept a DataThing based upoon its mime type.
AbstractRenderer.ByPattern Accept a DataThing based upon the mime type matching a regular expression pattern.
AWTComponentRenderer Class that renders objects which have a Java Component subclass as their user object
JMolRenderer Renders using the Jmol software for chemical structures
RendererRegistry A registry that maintains a list of all renderer service providers.
SeqVistaRenderer Uses the SeqVista renderer to draw an EMBL or SwissProt sequence
TextTavernaWebUrl View a URL as a clickable HTML URL.
TextTavernaWebUrlFetcher Display the content of a URL.
TextXml Viewer to display XML as a tree.

Exception Summary
RendererException Exception for when renderer-related functions go wrong.

Package org.embl.ebi.escience.scuflui.renderers Description

Provides a Service Provider Interface (SPI) for rendering the data in a workflow.


The SPI API is defined totaly by one class and one interface. org.embl.ebi.escience.scuflui.renderers.RendererSPI defines the interface that must be implemented by a provider. RendererRegistry is a registry for all known renderers. There are additional classes in this package, such as TextRtf which are implementations of the SPI, and these provide support for rendering common data formats.

When data needs to be rendered, the GUI componet will use the registry to find out which, if any, renderers are registered for that data type. The GUI may optionaly chose to present the user with a list of possible renderers, or it may just take the default.

The Registry

The registry is the way that most client code will discover what renderers are available. The registry itself is impemented as a system-wide singleton. Use the RendererRegistry.instance() method to get the registry. If concurrency is an issue, you should synchronize on this instance.

The first part of the API provides list-like access to all registered renderers through the org.embl.ebi.escience.scuflui.renderers.RendererRegistry#addRenderer(org.embl.ebi.escience.scuflui.renderers.RendererSPI), org.embl.ebi.escience.scuflui.renderers.RendererRegistry#removeRenderer(org.embl.ebi.escience.scuflui.renderers.RendererSPI), org.embl.ebi.escience.scuflui.renderers.RendererRegistry#size(), org.embl.ebi.escience.scuflui.renderers.RendererRegistry#get(int) and org.embl.ebi.escience.scuflui.renderers.RendererRegistry#iterator() methods. You can use these to manually update and scan the available renderers.

The second part of the API is used to query for renderers by the data type. RendererRegistry.getRenderer(org.embl.ebi.escience.baclava.DataThing) and RendererRegistry.getRenderers(org.embl.ebi.escience.baclava.DataThing) return the default SPI and a list of all SPIs respectively for the given object and MIME type. This SPI can then be used to create a GUI component that displays that data and MIME type.


The SPI interface, org.embl.ebi.escience.scuflui.renderers.RendererSPI, is very simple. It publishes a name (which should remain constant), icon (conditioned on the data to display), a method to see if the SPI can handle an object and MIME type, and a factory method to create a GUI component for the data object and MIME type.

As a user of the SPI, you can assume that if you obtained the renderer from one of the registry lookup methods, that the renderer can handle that data. Calling the factory method org.embl.ebi.escience.scuflui.renderers.RendererSPI#getComponent(org.embl.ebi.escience.scuflui.renderers.RendererRegistry,org.embl.ebi.escience.baclava.DataThing) should just work. If you are manually looping over some renderers, you should only call this method on the renderers that return true for org.embl.ebi.escience.scuflui.renderers.RendererSPI#canHandle(org.embl.ebi.escience.scuflui.renderers.RendererRegistry,org.embl.ebi.escience.baclava.DataThing).

Writing an SPI implementation

If you have a new data type and wish to develop a renderer for it, you should implement the org.embl.ebi.escience.scuflui.renderers.RendererSPI interface and arrange for it to be registered with the registry. You can name your SPI implementation in any way you wish. Make sure it's a public class and has a public no-args constructor. This is the constructor that will be called by the registry. Your SPI should be thread-safe, as one instance of the SPI will be loaded into the registry and used multiple times, possibly with parallel invocations.

Ensure that the canHandle() method returns true for all data that can be rendererd. This must match the data for which getComponent() works with, or you may confuse the users of this SPI. The getComponent() method can return any JComponent you wish for displaying the data. In the future, we may add API for registering menu items and so forth. At the moment, this JComponent should be totaly self-contained.

The getName() method should always return the same string. The getIcon() method can check the object and MIME type to return an apropreate image for the data but can also return the same icon for all cases.

Lastly, package your renderer up in a .jar file. To this .jar, add a file at META-INF/services/org.embl.ebi.escience.scuflui.renderers.RendererSPI containing the full class-name of your SPI implementation. If you have several different SPIs in your .jar file, then add each class name on its own line. The registry will take care of loading all of the classes listed in this file, and will be able to load in classes from multiple .jar files.

The AbstractRenderer class provides a convenient base-class for making renderers. This will take care of unpacking the mime type list, and stooring a name and icon. It also contains a static inner class ByPattern that will scan mime types with a regular expression, leaving you needing to just implement the getComponent() method.