org.eclipse.swt.graphics.Image Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2002, 2013 Innoopract Informationssysteme GmbH 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:
* Innoopract Informationssysteme GmbH - initial API and implementation
* EclipseSource - ongoing development
* Rüdiger Herrmann - bug 334511
******************************************************************************/
package org.eclipse.swt.graphics;
import java.io.IOException;
import java.io.InputStream;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.eclipse.rap.rwt.internal.application.ApplicationContextImpl;
import org.eclipse.rap.rwt.internal.application.ApplicationContextUtil;
import org.eclipse.rap.rwt.internal.service.ContextProvider;
import org.eclipse.rap.rwt.service.UISession;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.internal.graphics.InternalImage;
import org.eclipse.swt.internal.graphics.InternalImageFactory;
import org.eclipse.swt.internal.widgets.IDisplayAdapter;
import org.eclipse.swt.widgets.Display;
/**
* Instances of this class are graphics which have been prepared
* for display on a specific device. That is, they are to display
* on widgets with, for example, Button.setImage()
.
*
* If loaded from a file format that supports it, an
* Image
may have transparency, meaning that certain
* pixels are specified as being transparent when drawn. Examples
* of file formats that support transparency are GIF and PNG.
*
* Note: Even though constructors are provided here, it is
* recommended to create images by using one of the getImage
* methods in class Graphics
. These factory methods share images
* among all sessions.
* Creating images via constructors carelessly may lead to bad performance
* and/or unnecessary memory consumption.
*
*
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String)
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String, ClassLoader)
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String, java.io.InputStream)
*/
public final class Image extends Resource {
/**
* The internal resource.
* (Warning: This field is platform dependent)
*
* IMPORTANT: This field is not part of the SWT
* public API. It is marked public only so that it can be shared
* within the packages provided by SWT. It is not available on all
* platforms and should never be accessed from application code.
*
*
* @noreference This field is not intended to be referenced by clients.
*/
public final InternalImage internalImage;
/* This constructor is called by ImageFactory#createImageInstance() */
private Image( Device device, InternalImage internalImage ) {
super( device );
this.internalImage = internalImage;
}
/**
* Constructs an instance of this class by loading its representation
* from the specified input stream. Throws an error if an error
* occurs while loading the image, or if the result is an image
* of an unsupported type. Application code is still responsible
* for closing the input stream.
*
* This constructor is provided for convenience when loading a single
* image only. If the stream contains multiple images, only the first
* one will be loaded. To load multiple images, use
* ImageLoader.load()
.
*
* This constructor may be used to load a resource as follows:
*
*
* static Image loadImage (Display display, Class clazz, String string) {
* InputStream stream = clazz.getResourceAsStream (string);
* if (stream == null) return null;
* Image image = null;
* try {
* image = new Image (display, stream);
* } catch (SWTException ex) {
* } finally {
* try {
* stream.close ();
* } catch (IOException ex) {}
* }
* return image;
* }
*
*
* Note, this constructor is provided for convenience when
* single-sourcing code with SWT. For RWT, the recommended way to create images
* is to use one of the Graphics#getImage()
methods.
*
*
* @param device the device on which to create the image
* @param stream the input stream to load the image from
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device
* - ERROR_NULL_ARGUMENT - if the stream is null
*
* @exception SWTException
* - ERROR_IO - if an IO error occurs while reading from the stream
* - ERROR_INVALID_IMAGE - if the image stream contains invalid data
* - ERROR_UNSUPPORTED_DEPTH - if the image stream describes an image with an unsupported depth
* - ERROR_UNSUPPORTED_FORMAT - if the image stream contains an unrecognized format
*
* @exception SWTError
* - ERROR_NO_HANDLES if a handle could not be obtained for image creation
*
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String)
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String, ClassLoader)
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String, java.io.InputStream)
* @since 1.3
*/
public Image( Device device, InputStream stream ) {
super( checkDevice( device ) );
if( stream == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
internalImage = findInternalImage( stream );
}
/**
* Constructs an instance of this class by loading its representation
* from the file with the specified name. Throws an error if an error
* occurs while loading the image, or if the result is an image
* of an unsupported type.
*
* This constructor is provided for convenience when loading
* a single image only. If the specified file contains
* multiple images, only the first one will be used.
*
*
Note, this constructor is provided for convenience when
* single-sourcing code with SWT. For RWT, the recommended way to create images
* is to use one of the Graphics#getImage()
methods.
*
*
* @param device the device on which to create the image
* @param fileName the name of the file to load the image from
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device
* - ERROR_NULL_ARGUMENT - if the file name is null
*
* @exception SWTException
* - ERROR_IO - if an IO error occurs while reading from the file
* - ERROR_INVALID_IMAGE - if the image file contains invalid data
* - ERROR_UNSUPPORTED_DEPTH - if the image file describes an image with an unsupported depth
* - ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format
*
* @exception SWTError
* - ERROR_NO_HANDLES if a handle could not be obtained for image creation
*
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String)
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String, ClassLoader)
* @see org.eclipse.rap.rwt.graphics.Graphics#getImage(String, java.io.InputStream)
* @since 1.3
*/
public Image( Device device, String fileName ) {
super( checkDevice( device ) );
if( fileName == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
internalImage = findInternalImage( fileName );
}
/**
* Constructs a new instance of this class based on the
* provided image, with an appearance that varies depending
* on the value of the flag. The possible flag values are:
*
* - {@link SWT#IMAGE_COPY}
* - the result is an identical copy of srcImage
*
*
*
* @param device the device on which to create the image
* @param srcImage the image to use as the source
* @param flag the style, either IMAGE_COPY
, IMAGE_DISABLE
or IMAGE_GRAY
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device
* - ERROR_NULL_ARGUMENT - if srcImage is null
* - ERROR_INVALID_ARGUMENT - if the flag is not one of
IMAGE_COPY
, IMAGE_DISABLE
or IMAGE_GRAY
* - ERROR_INVALID_ARGUMENT - if the image has been disposed
*
* @exception SWTException
* - ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon, or is otherwise in an invalid state
* - ERROR_UNSUPPORTED_DEPTH - if the depth of the image is not supported
*
* @exception SWTError
* - ERROR_NO_HANDLES if a handle could not be obtained for image creation
*
* @since 1.3
*/
@SuppressWarnings("javadoc")
public Image( Device device, Image srcImage, int flag ) {
super( checkDevice( device ) );
if( srcImage == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
if( srcImage.isDisposed() ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
switch( flag ) {
case SWT.IMAGE_COPY:
internalImage = srcImage.internalImage;
break;
default:
internalImage = null;
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
break;
}
}
/**
* Constructs an instance of this class from the given
* ImageData
.
*
* @param device the device on which to create the image
* @param imageData the image data to create the image from (must not be null)
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device
* - ERROR_NULL_ARGUMENT - if the image data is null
*
* @exception SWTException
* - ERROR_UNSUPPORTED_DEPTH - if the depth of the ImageData is not supported
*
*
* @since 1.3
*/
public Image( Device device, ImageData imageData ) {
super( checkDevice( device ) );
if( imageData == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
internalImage = findInternalImage( imageData );
}
/**
* Constructs an empty instance of this class with the
* specified width and height. The result may be drawn upon
* by creating a GC and using any of its drawing operations,
* as shown in the following example:
*
* Image i = new Image(device, width, height);
* GC gc = new GC(i);
* gc.drawRectangle(0, 0, 50, 50);
* gc.dispose();
*
*
* Note: Some platforms may have a limitation on the size
* of image that can be created (size depends on width, height,
* and depth). For example, Windows 95, 98, and ME do not allow
* images larger than 16M.
*
*
* @param device the device on which to create the image
* @param width the width of the new image
* @param height the height of the new image
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device
* - ERROR_INVALID_ARGUMENT - if either the width or height is negative or zero
*
* @exception SWTError
* - ERROR_NO_HANDLES if a handle could not be obtained for image creation
*
* @since 1.4
*/
public Image( Device device, int width, int height ) {
super( checkDevice( device ) );
if( width <= 0 || height <= 0 ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
Color white = device.getSystemColor( SWT.COLOR_WHITE );
PaletteData palette = new PaletteData( new RGB[] { white.getRGB() } );
ImageData imageData = new ImageData( width, height, 8, palette );
internalImage = findInternalImage( imageData );
}
/**
* Returns the bounds of the receiver. The rectangle will always
* have x and y values of 0, and the width and height of the
* image.
*
* @return a rectangle specifying the image's bounds
*
* @exception SWTException
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
* - ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon
*
*/
public Rectangle getBounds() {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
return internalImage.getBounds();
}
/**
* Returns an ImageData
based on the receiver
* Modifications made to this ImageData
will not
* affect the Image.
*
* @return an ImageData
containing the image's data and attributes
*
* @exception SWTException
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
* - ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon
*
*
* @see ImageData
* @since 1.3
*/
public ImageData getImageData() {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
ImageData result;
if( device != null ) {
ApplicationContextImpl applicationContext = getApplicationContext();
result = applicationContext.getImageDataFactory().findImageData( internalImage );
} else {
result = internalImage.getImageData();
}
return result;
}
/**
* Sets the color to which to map the transparent pixel.
*
* There are certain uses of Images
that do not support
* transparency (for example, setting an image into a button or label).
* In these cases, it may be desired to simulate transparency by using
* the background color of the widget to paint the transparent pixels
* of the image. This method specifies the color that will be used in
* these cases. For example:
*
* Button b = new Button();
* image.setBackground(b.getBackground());
* b.setImage(image);
*
*
* The image may be modified by this operation (in effect, the
* transparent regions may be filled with the supplied color). Hence
* this operation is not reversible and it is not legal to call
* this function twice or with a null argument.
*
* This method has no effect if the receiver does not have a transparent
* pixel value.
*
*
* @param color the color to use when a transparent pixel is specified
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the color is null
* - ERROR_INVALID_ARGUMENT - if the color has been disposed
*
* @exception SWTException
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
* @since 1.3
*/
public void setBackground( Color color ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
if( color == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
if( color.isDisposed() ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
// do nothing
}
/**
* Returns the color to which to map the transparent pixel, or null if
* the receiver has no transparent pixel.
*
* There are certain uses of Images that do not support transparency
* (for example, setting an image into a button or label). In these cases,
* it may be desired to simulate transparency by using the background
* color of the widget to paint the transparent pixels of the image.
* Use this method to check which color will be used in these cases
* in place of transparency. This value may be set with setBackground().
*
*
* @return the background color of the image, or null if there is no
* transparency in the image
*
* @exception SWTException
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
* @since 1.3
*/
public Color getBackground() {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
// do nothing
return null;
}
private void writeObject( ObjectOutputStream stream ) throws IOException {
if( device == null ) {
throw new NotSerializableException( getClass().getName() );
}
new ImageSerializer( this ).writeObject( stream );
}
private void readObject( ObjectInputStream stream ) throws IOException, ClassNotFoundException {
new ImageSerializer( this ).readObject( stream );
}
private ApplicationContextImpl getApplicationContext() {
Display display = ( Display )device;
IDisplayAdapter adapter = display.getAdapter( IDisplayAdapter.class );
UISession uiSession = adapter.getUISession();
return ApplicationContextUtil.get( uiSession );
}
private static InternalImage findInternalImage( ImageData imageData ) {
return getInternalImageFactory().findInternalImage( imageData );
}
private static InternalImage findInternalImage( InputStream stream ) {
return getInternalImageFactory().findInternalImage( stream );
}
private static InternalImage findInternalImage( String fileName ) {
return getInternalImageFactory().findInternalImage( fileName );
}
private static InternalImageFactory getInternalImageFactory() {
return ContextProvider.getApplicationContext().getInternalImageFactory();
}
}