/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.resource;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
/**
* An image descriptor is an object that knows how to create an SWT image. It
* does not hold onto images or cache them, but rather just creates them on
* demand. An image descriptor is intended to be a lightweight representation of
* an image that can be manipulated even when no SWT display exists.
* <p>
* This package defines a concrete image descriptor implementation which reads
* an image from a file (<code>FileImageDescriptor</code>). It also provides
* abstract framework classes (this one and
* <code>CompositeImageDescriptor</code>) which may be subclassed to define news
* kinds of image descriptors.
* </p>
* <p>
* Using this abstract class involves defining a concrete subclass and providing
* an implementation for the <code>getImageData</code> method.
* </p>
* <p>
* There are two ways to get an Image from an ImageDescriptor. The method
* createImage will always return a new Image which must be disposed by the
* caller. Alternatively, createResource() returns a shared Image. When the
* caller is done with an image obtained from createResource, they must call
* destroyResource() rather than disposing the Image directly. The result of
* createResource() can be safely cast to an Image.
* </p>
*
* @see org.eclipse.swt.graphics.Image
*/
public abstract class ImageDescriptor extends DeviceResourceDescriptor {
/**
* A small red square used to warn that an image cannot be created.
* <p>
*/
protected static final ImageData DEFAULT_IMAGE_DATA = new ImageData(6, 6,
1, new PaletteData(new RGB[] { new RGB(255, 0, 0) }));
/**
* Constructs an image descriptor.
*/
protected ImageDescriptor() {
// do nothing
}
/**
* Creates and returns a new image descriptor from a file. Convenience
* method for <code>new FileImageDescriptor(location,filename)</code>.
*
* @param location
* the class whose resource directory contain the file
* @param filename
* the file name
* @return a new image descriptor
*/
public static ImageDescriptor createFromFile(Class location, String filename) {
return new FileImageDescriptor(location, filename);
}
/**
* Creates and returns a new image descriptor given ImageData describing the
* image.
*
* @since 3.1
*
* @param data
* contents of the image
* @return newly created image descriptor
*/
public static ImageDescriptor createFromImageData(ImageData data) {
return new ImageDataImageDescriptor(data);
}
/**
* Creates and returns a new image descriptor for the given image. Note that
* disposing the original Image will cause the descriptor to become invalid.
*
* @since 3.1
*
* @param img
* image to create
* @return a newly created image descriptor
*/
public static ImageDescriptor createFromImage(Image img) {
return new ImageDataImageDescriptor(img);
}
/**
* Creates an ImageDescriptor based on the given original descriptor, but
* with additional SWT flags.
*
* <p>
* Note that this sort of ImageDescriptor is slower and consumes more
* resources than a regular image descriptor. It will also never generate
* results that look as nice as a hand-drawn image. Clients are encouraged
* to supply their own disabled/grayed/etc. images rather than using a
* default image and transforming it.
* </p>
*
* @param originalImage
* image to transform
* @param swtFlags
* any flag that can be passed to the flags argument of
* Image#Image(Device, Image, int)
* @return an ImageDescriptor that creates new images by transforming the
* given image descriptor
*
* @see Image#Image(Device, Image, int)
* @since 3.1
*
*/
public static ImageDescriptor createWithFlags(
ImageDescriptor originalImage, int swtFlags) {
return new DerivedImageDescriptor(originalImage, swtFlags);
}
/**
* Creates and returns a new image descriptor for the given image. This
* method takes the Device that created the Image as an argument, allowing
* the original Image to be reused if the descriptor is asked for another
* Image on the same device. Note that disposing the original Image will
* cause the descriptor to become invalid.
*
* @deprecated use {@link ImageDescriptor#createFromImage(Image)}
* @since 3.1
*
* @param img
* image to create
* @param theDevice
* the device that was used to create the Image
* @return a newly created image descriptor
*/
public static ImageDescriptor createFromImage(Image img, Device theDevice) {
return new ImageDataImageDescriptor(img);
}
/**
* Creates and returns a new image descriptor from a URL.
*
* @param url
* The URL of the image file.
* @return a new image descriptor
*/
// public static ImageDescriptor createFromURL(URL url) {
// if (url == null) {
// return getMissingImageDescriptor();
// }
// return new URLImageDescriptor(url);
// }
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.resource.DeviceResourceDescriptor#createResource(org
* .eclipse.swt.graphics.Device)
*/
public Object createResource(Device device) throws DeviceResourceException {
Image result = createImage(false, device);
if (result == null) {
throw new DeviceResourceException(this);
}
return result;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.resource.DeviceResourceDescriptor#destroyResource(Object
* )
*/
public void destroyResource(Object previouslyCreatedObject) {
((Image) previouslyCreatedObject).dispose();
}
/**
* Creates and returns a new SWT image for this image descriptor. Note that
* each call returns a new SWT image object. The returned image must be
* explicitly disposed using the image's dispose call. The image will not be
* automatically garbage collected. A default image is returned in the event
* of an error.
*
* <p>
* Note: this method differs from createResource(Device) in that the
* returned image must be disposed directly, whereas an image obtained from
* createResource(...) must be disposed by calling destroyResource(...). It
* is not possible to mix-and-match. If you obtained the Image from this
* method, you must not dispose it by calling destroyResource. Clients are
* encouraged to use create/destroyResource and downcast the result to Image
* rather than using createImage.
* </p>
*
* <p>
* Note: it is still possible for this method to return <code>null</code> in
* extreme cases, for example if SWT runs out of image handles.
* </p>
*
* @return a new image or <code>null</code> if the image could not be
* created
*/
public Image createImage() {
return createImage(true);
}
/**
* Creates and returns a new SWT image for this image descriptor. The
* returned image must be explicitly disposed using the image's dispose
* call. The image will not be automatically garbage collected. In the event
* of an error, a default image is returned if
* <code>returnMissingImageOnError</code> is true, otherwise
* <code>null</code> is returned.
* <p>
* Note: Even if <code>returnMissingImageOnError</code> is true, it is still
* possible for this method to return <code>null</code> in extreme cases,
* for example if SWT runs out of image handles.
* </p>
*
* @param returnMissingImageOnError
* flag that determines if a default image is returned on error
* @return a new image or <code>null</code> if the image could not be
* created
*/
public Image createImage(boolean returnMissingImageOnError) {
return createImage(returnMissingImageOnError, Display.getCurrent());
}
/**
* Creates and returns a new SWT image for this image descriptor. The
* returned image must be explicitly disposed using the image's dispose
* call. The image will not be automatically garbage collected. A default
* image is returned in the event of an error.
* <p>
* Note: it is still possible for this method to return <code>null</code> in
* extreme cases, for example if SWT runs out of image handles.
* </p>
*
* @param device
* the device on which to create the image
* @return a new image or <code>null</code> if the image could not be
* created
* @since 2.0
*/
public Image createImage(Device device) {
return createImage(true, device);
}
/**
* Creates and returns a new SWT image for this image descriptor. The
* returned image must be explicitly disposed using the image's dispose
* call. The image will not be automatically garbage collected. In the even
* of an error, a default image is returned if
* <code>returnMissingImageOnError</code> is true, otherwise
* <code>null</code> is returned.
* <p>
* Note: Even if <code>returnMissingImageOnError</code> is true, it is still
* possible for this method to return <code>null</code> in extreme cases,
* for example if SWT runs out of image handles.
* </p>
*
* @param returnMissingImageOnError
* flag that determines if a default image is returned on error
* @param device
* the device on which to create the image
* @return a new image or <code>null</code> if the image could not be
* created
* @since 2.0
*/
public Image createImage(boolean returnMissingImageOnError, Device device) {
ImageData data = getImageData();
if (data == null) {
if (!returnMissingImageOnError) {
return null;
}
data = DEFAULT_IMAGE_DATA;
}
/*
* Try to create the supplied image. If there is an SWT Exception try
* and create the default image if that was requested. Return null if
* this fails.
*/
try {
com.google.gwt.user.client.ui.Image gwtImage = null;
if (this instanceof ImageDataImageDescriptor) {
if (((ImageDataImageDescriptor)this).originalImage != null && ((ImageDataImageDescriptor)this).originalImage.getGwtImage() != null) {
gwtImage = ((ImageDataImageDescriptor)this).originalImage.getGwtImage();
}
}
if (data.transparentPixel >= 0) {
ImageData maskData = data.getTransparencyMask();
return new Image(device, data, maskData, gwtImage);
}
return new Image(device, data, gwtImage);
} catch (SWTException exception) {
if (returnMissingImageOnError) {
try {
return new Image(device, DEFAULT_IMAGE_DATA);
} catch (SWTException nextException) {
return null;
}
}
return null;
}
}
public Image createImageOld(boolean returnMissingImageOnError, Device device) {
ImageData data = getImageData();
if (data == null) {
if (!returnMissingImageOnError) {
return null;
}
data = DEFAULT_IMAGE_DATA;
}
/*
* Try to create the supplied image. If there is an SWT Exception try
* and create the default image if that was requested. Return null if
* this fails.
*/
try {
if (data.transparentPixel >= 0) {
ImageData maskData = data.getTransparencyMask();
return new Image(device, data, maskData);
}
return new Image(device, data);
} catch (SWTException exception) {
if (returnMissingImageOnError) {
try {
return new Image(device, DEFAULT_IMAGE_DATA);
} catch (SWTException nextException) {
return null;
}
}
return null;
}
}
/**
* Creates and returns a new SWT <code>ImageData</code> object for this
* image descriptor. Note that each call returns a new SWT image data
* object.
* <p>
* This framework method is declared public so that it is possible to
* request an image descriptor's image data without creating an SWT image
* object.
* </p>
* <p>
* Returns <code>null</code> if the image data could not be created.
* </p>
*
* @return a new image data or <code>null</code>
*/
public abstract ImageData getImageData();
/**
* Returns the shared image descriptor for a missing image.
*
* @return the missing image descriptor
*/
public static ImageDescriptor getMissingImageDescriptor() {
return MissingImageDescriptor.getInstance();
}
}