Skip to content

Internal image management_124649509

nxi edited this page Apr 9, 2015 · 1 revision

Gumtree : Internal image management

Created by Tony Lam, last modified on Jul 09, 2009
This page describes a useful programming pattern for management internal image within a plug-in. Due to the limitation of underlying OS platform, the number of SWT image object can be sometimes limited. For many frequently used images within a plug-in, it is best to use the JFace image registry to manage theirs life cycle (lazy instantiation and disposal). By default the image registry comes with all Eclipse UI based plug-in activator, but it does not mean it easy to use. During the development of GumTree, we have developed a useful pattern using Java enum to manage frequently used images. Here is a template of InternalImage class:
public enum InternalImage {

    // Add more image if required
    UP("/icons/upward_nav.gif"),
    DOWN("/icons/downward_nav.gif");
    
    private InternalImage(String path) {
        this.path = path;
    }
    
    public Image getImage() {
        return getRegistry().get(name());
    }
    
    public ImageDescriptor getDescriptor() {
        return getRegistry().getDescriptor(name());
    }
    
    public static boolean isInstalled() {
        return registry != null;
    }
    
    public static synchronized void dispose() {
        registry.dispose();
        registry = null;
    }
    
    private String path() {
        return path;
    }
    
    private static ImageRegistry getRegistry() {
        if (registry == null) {
            synchronized (InternalImage.class) {
                if (registry == null) {
                    registry = new ImageRegistry(Display.getDefault());
                    for (InternalImage key : values()) {
                        registry.put(key.name(), Activator
                                .imageDescriptorFromPlugin(Activator.PLUGIN_ID,
                                        key.path()));
                    }
                }
            }
        }
        return registry;
    }
    
    private String path;
    
    private static volatile ImageRegistry registry;
    
}
To use the image, simply call:
Image image = InternalImage.UP.getImage());
A problem of this implementation is that it require manual disposal. This is because we cannot listen to the framework for bundle stop event as it will be too late to do disposal. So the safest way is to dispose it manually under the stop() method in the Activator:
public void stop(BundleContext context) throws Exception {
    if (InternalImage.isInstalled()) {
        InternalImage.dispose();
    }
    ...
}
Document generated by Confluence on Apr 01, 2015 00:11
Clone this wiki locally