001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jface.resource;
011:
012: import java.net.URL;
013:
014: import org.eclipse.swt.SWTException;
015: import org.eclipse.swt.graphics.Device;
016: import org.eclipse.swt.graphics.Image;
017: import org.eclipse.swt.graphics.ImageData;
018: import org.eclipse.swt.graphics.PaletteData;
019: import org.eclipse.swt.graphics.RGB;
020: import org.eclipse.swt.widgets.Display;
021:
022: /**
023: * An image descriptor is an object that knows how to create
024: * an SWT image. It does not hold onto images or cache them,
025: * but rather just creates them on demand. An image descriptor
026: * is intended to be a lightweight representation of an image
027: * that can be manipulated even when no SWT display exists.
028: * <p>
029: * This package defines a concrete image descriptor implementation
030: * which reads an image from a file (<code>FileImageDescriptor</code>).
031: * It also provides abstract framework classes (this one and
032: * <code>CompositeImageDescriptor</code>) which may be subclassed to define
033: * news kinds of image descriptors.
034: * </p>
035: * <p>
036: * Using this abstract class involves defining a concrete subclass
037: * and providing an implementation for the <code>getImageData</code>
038: * method.
039: * </p>
040: * <p>
041: * There are two ways to get an Image from an ImageDescriptor. The method
042: * createImage will always return a new Image which must be disposed by
043: * the caller. Alternatively, createResource() returns a shared
044: * Image. When the caller is done with an image obtained from createResource,
045: * they must call destroyResource() rather than disposing the Image directly.
046: * The result of createResource() can be safely cast to an Image.
047: * </p>
048: *
049: * @see org.eclipse.swt.graphics.Image
050: */
051: public abstract class ImageDescriptor extends DeviceResourceDescriptor {
052:
053: /**
054: * A small red square used to warn that an image cannot be created.
055: * <p>
056: */
057: protected static final ImageData DEFAULT_IMAGE_DATA = new ImageData(
058: 6, 6, 1, new PaletteData(new RGB[] { new RGB(255, 0, 0) }));
059:
060: /**
061: * Constructs an image descriptor.
062: */
063: protected ImageDescriptor() {
064: // do nothing
065: }
066:
067: /**
068: * Creates and returns a new image descriptor from a file.
069: * Convenience method for
070: * <code>new FileImageDescriptor(location,filename)</code>.
071: *
072: * @param location the class whose resource directory contain the file
073: * @param filename the file name
074: * @return a new image descriptor
075: */
076: public static ImageDescriptor createFromFile(Class location,
077: String filename) {
078: return new FileImageDescriptor(location, filename);
079: }
080:
081: /**
082: * Creates and returns a new image descriptor given ImageData
083: * describing the image.
084: *
085: * @since 3.1
086: *
087: * @param data contents of the image
088: * @return newly created image descriptor
089: */
090: public static ImageDescriptor createFromImageData(ImageData data) {
091: return new ImageDataImageDescriptor(data);
092: }
093:
094: /**
095: * Creates and returns a new image descriptor for the given image. Note
096: * that disposing the original Image will cause the descriptor to become invalid.
097: *
098: * @since 3.1
099: *
100: * @param img image to create
101: * @return a newly created image descriptor
102: */
103: public static ImageDescriptor createFromImage(Image img) {
104: return new ImageDataImageDescriptor(img);
105: }
106:
107: /**
108: * Creates an ImageDescriptor based on the given original descriptor, but with additional
109: * SWT flags.
110: *
111: * <p>
112: * Note that this sort of ImageDescriptor is slower and consumes more resources than
113: * a regular image descriptor. It will also never generate results that look as nice as
114: * a hand-drawn image. Clients are encouraged to supply their own disabled/grayed/etc. images
115: * rather than using a default image and transforming it.
116: * </p>
117: *
118: * @param originalImage image to transform
119: * @param swtFlags any flag that can be passed to the flags argument of Image#Image(Device, Image, int)
120: * @return an ImageDescriptor that creates new images by transforming the given image descriptor
121: *
122: * @see Image#Image(Device, Image, int)
123: * @since 3.1
124: *
125: */
126: public static ImageDescriptor createWithFlags(
127: ImageDescriptor originalImage, int swtFlags) {
128: return new DerivedImageDescriptor(originalImage, swtFlags);
129: }
130:
131: /**
132: * Creates and returns a new image descriptor for the given image. This
133: * method takes the Device that created the Image as an argument, allowing
134: * the original Image to be reused if the descriptor is asked for another
135: * Image on the same device. Note that disposing the original Image will
136: * cause the descriptor to become invalid.
137: *
138: * @deprecated use {@link ImageDescriptor#createFromImage(Image)}
139: * @since 3.1
140: *
141: * @param img image to create
142: * @param theDevice the device that was used to create the Image
143: * @return a newly created image descriptor
144: */
145: public static ImageDescriptor createFromImage(Image img,
146: Device theDevice) {
147: return new ImageDataImageDescriptor(img);
148: }
149:
150: /**
151: * Creates and returns a new image descriptor from a URL.
152: *
153: * @param url The URL of the image file.
154: * @return a new image descriptor
155: */
156: public static ImageDescriptor createFromURL(URL url) {
157: if (url == null) {
158: return getMissingImageDescriptor();
159: }
160: return new URLImageDescriptor(url);
161: }
162:
163: /* (non-Javadoc)
164: * @see org.eclipse.jface.resource.DeviceResourceDescriptor#createResource(org.eclipse.swt.graphics.Device)
165: */
166: public Object createResource(Device device)
167: throws DeviceResourceException {
168: Image result = createImage(false, device);
169: if (result == null) {
170: throw new DeviceResourceException(this );
171: }
172: return result;
173: }
174:
175: /* (non-Javadoc)
176: * @see org.eclipse.jface.resource.DeviceResourceDescriptor#destroyResource(Object)
177: */
178: public void destroyResource(Object previouslyCreatedObject) {
179: ((Image) previouslyCreatedObject).dispose();
180: }
181:
182: /**
183: * Creates and returns a new SWT image for this image descriptor. Note that
184: * each call returns a new SWT image object. The returned image must be
185: * explicitly disposed using the image's dispose call. The image will not be
186: * automatically garbage collected. A default image is returned in the event
187: * of an error.
188: *
189: * <p>
190: * Note: this method differs from createResource(Device) in that the returned image
191: * must be disposed directly, whereas an image obtained from createResource(...)
192: * must be disposed by calling destroyResource(...). It is not possible to
193: * mix-and-match. If you obtained the Image from this method, you must not dispose
194: * it by calling destroyResource. Clients are encouraged to use
195: * create/destroyResource and downcast the result to Image rather than using
196: * createImage.
197: * </p>
198: *
199: * <p>
200: * Note: it is still possible for this method to return <code>null</code>
201: * in extreme cases, for example if SWT runs out of image handles.
202: * </p>
203: *
204: * @return a new image or <code>null</code> if the image could not be
205: * created
206: */
207: public Image createImage() {
208: return createImage(true);
209: }
210:
211: /**
212: * Creates and returns a new SWT image for this image descriptor. The
213: * returned image must be explicitly disposed using the image's dispose
214: * call. The image will not be automatically garbage collected. In the event
215: * of an error, a default image is returned if
216: * <code>returnMissingImageOnError</code> is true, otherwise
217: * <code>null</code> is returned.
218: * <p>
219: * Note: Even if <code>returnMissingImageOnError</code> is true, it is
220: * still possible for this method to return <code>null</code> in extreme
221: * cases, for example if SWT runs out of image handles.
222: * </p>
223: *
224: * @param returnMissingImageOnError
225: * flag that determines if a default image is returned on error
226: * @return a new image or <code>null</code> if the image could not be
227: * created
228: */
229: public Image createImage(boolean returnMissingImageOnError) {
230: return createImage(returnMissingImageOnError, Display
231: .getCurrent());
232: }
233:
234: /**
235: * Creates and returns a new SWT image for this image descriptor. The
236: * returned image must be explicitly disposed using the image's dispose
237: * call. The image will not be automatically garbage collected. A default
238: * image is returned in the event of an error.
239: * <p>
240: * Note: it is still possible for this method to return <code>null</code>
241: * in extreme cases, for example if SWT runs out of image handles.
242: * </p>
243: *
244: * @param device
245: * the device on which to create the image
246: * @return a new image or <code>null</code> if the image could not be
247: * created
248: * @since 2.0
249: */
250: public Image createImage(Device device) {
251: return createImage(true, device);
252: }
253:
254: /**
255: * Creates and returns a new SWT image for this image descriptor. The
256: * returned image must be explicitly disposed using the image's dispose
257: * call. The image will not be automatically garbage collected. In the even
258: * of an error, a default image is returned if
259: * <code>returnMissingImageOnError</code> is true, otherwise
260: * <code>null</code> is returned.
261: * <p>
262: * Note: Even if <code>returnMissingImageOnError</code> is true, it is
263: * still possible for this method to return <code>null</code> in extreme
264: * cases, for example if SWT runs out of image handles.
265: * </p>
266: *
267: * @param returnMissingImageOnError
268: * flag that determines if a default image is returned on error
269: * @param device
270: * the device on which to create the image
271: * @return a new image or <code>null</code> if the image could not be
272: * created
273: * @since 2.0
274: */
275: public Image createImage(boolean returnMissingImageOnError,
276: Device device) {
277:
278: ImageData data = getImageData();
279: if (data == null) {
280: if (!returnMissingImageOnError) {
281: return null;
282: }
283: data = DEFAULT_IMAGE_DATA;
284: }
285:
286: /*
287: * Try to create the supplied image. If there is an SWT Exception try and create
288: * the default image if that was requested. Return null if this fails.
289: */
290:
291: try {
292: if (data.transparentPixel >= 0) {
293: ImageData maskData = data.getTransparencyMask();
294: return new Image(device, data, maskData);
295: }
296: return new Image(device, data);
297: } catch (SWTException exception) {
298: if (returnMissingImageOnError) {
299: try {
300: return new Image(device, DEFAULT_IMAGE_DATA);
301: } catch (SWTException nextException) {
302: return null;
303: }
304: }
305: return null;
306: }
307: }
308:
309: /**
310: * Creates and returns a new SWT <code>ImageData</code> object
311: * for this image descriptor.
312: * Note that each call returns a new SWT image data object.
313: * <p>
314: * This framework method is declared public so that it is
315: * possible to request an image descriptor's image data without
316: * creating an SWT image object.
317: * </p>
318: * <p>
319: * Returns <code>null</code> if the image data could not be created.
320: * </p>
321: *
322: * @return a new image data or <code>null</code>
323: */
324: public abstract ImageData getImageData();
325:
326: /**
327: * Returns the shared image descriptor for a missing image.
328: *
329: * @return the missing image descriptor
330: */
331: public static ImageDescriptor getMissingImageDescriptor() {
332: return MissingImageDescriptor.getInstance();
333: }
334: }
|