Java/SWT JFace Eclipse/Image
Содержание
- 1 Capture a widget image with a GC
- 2 Clip Image
- 3 Create an icon (in memory)
- 4 Demonstrates how to draw images
- 5 Display an animated GIF
- 6 Display an image in a group
- 7 Double Buffer
- 8 Draw Images Example
- 9 File Icon Util
- 10 Image Analyzer in SWT
- 11 Image Basics
- 12 Rotate and flip an image
- 13 Set icons with different resolutions
- 14 SWT and Image
- 15 Transfer type to transfer SWT ImageData objects.
Capture a widget image with a GC
<source lang="java">
/*
* GC example snippet: capture a widget image with a GC * * For a list of all SWT example snippets see * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets */
import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; public class Snippet95 {
public static void main(String[] args) { final Display display = new Display(); final Shell shell = new Shell(display); shell.setText("Widget"); shell.setBounds(10, 10, 200, 200); final Table table = new Table(shell, SWT.MULTI); table.setLinesVisible(true); table.setBounds(10, 10, 100, 100); for (int i = 0; i < 9; i++) { new TableItem(table, SWT.NONE).setText("item" + i); } Button button = new Button(shell, SWT.PUSH); button.setText("Capture"); button.setBounds(10, 140, 50, 20); button.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { Point tableSize = table.getSize(); GC gc = new GC(table); final Image image = new Image(display, tableSize.x, tableSize.y); gc.copyArea(image, 0, 0); gc.dispose(); Shell popup = new Shell(shell); popup.setText("Image"); popup.setBounds(50, 50, 200, 200); popup.addListener(SWT.Close, new Listener() { public void handleEvent(Event e) { image.dispose(); } }); Canvas canvas = new Canvas(popup, SWT.NONE); canvas.setBounds(10, 10, 150, 150); canvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { e.gc.drawImage(image, 0, 0); } }); popup.open(); } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
}
</source>
Clip Image
<source lang="java">
/******************************************************************************
* All Right Reserved. * Copyright (c) 1998, 2004 Jackwind Li Guojie * * Created on 2004-4-19 15:03:55 by JACK * $Id$ * *****************************************************************************/
import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Region; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /**
* */
public class Clipping {
Display display = new Display(); Shell shell = new Shell(display); public Clipping() { shell.setLayout(new FillLayout()); final Canvas canvas = new Canvas(shell, SWT.NULL); final Image image = new Image(display, "jexp.gif"); canvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { Region region = new Region(); region.add(new int[]{60, 10, 10, 100, 110, 100}); e.gc.setClipping(region); e.gc.drawImage(image, 0, 0); } }); shell.setSize(200, 140); shell.open(); //textUser.forceFocus(); // Set up the event loop. while (!shell.isDisposed()) { if (!display.readAndDispatch()) { // If no more entries in event queue display.sleep(); } } display.dispose(); } private void init() { } public static void main(String[] args) { new Clipping(); }
}
</source>
Create an icon (in memory)
<source lang="java">
/*
* GC example snippet: create an icon (in memory) * * For a list of all SWT example snippets see * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets */
import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; 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.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class Snippet70 {
public static void main(String[] args) { Display display = new Display(); Color red = display.getSystemColor(SWT.COLOR_RED); Color white = display.getSystemColor(SWT.COLOR_WHITE); Color black = display.getSystemColor(SWT.COLOR_BLACK); Image image = new Image(display, 20, 20); GC gc = new GC(image); gc.setBackground(red); gc.fillRectangle(5, 5, 10, 10); gc.dispose(); ImageData imageData = image.getImageData(); PaletteData palette = new PaletteData(new RGB[] { new RGB(0, 0, 0), new RGB(0xFF, 0xFF, 0xFF), }); ImageData maskData = new ImageData(20, 20, 1, palette); Image mask = new Image(display, maskData); gc = new GC(mask); gc.setBackground(black); gc.fillRectangle(0, 0, 20, 20); gc.setBackground(white); gc.fillRectangle(5, 5, 10, 10); gc.dispose(); maskData = mask.getImageData(); Image icon = new Image(display, imageData, maskData); Shell shell = new Shell(display); Button button = new Button(shell, SWT.PUSH); button.setImage(icon); button.setSize(60, 60); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } icon.dispose(); image.dispose(); mask.dispose(); display.dispose(); }
}
</source>
Demonstrates how to draw images
<source lang="java">
//Send questions, comments, bug reports, etc. to the authors: //Rob Warner (rwarner@interspatial.ru) //Robert Harris (rbrt_harris@yahoo.ru) import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; /**
* This class demonstrates how to draw images */
public class DrawImagesDemo {
public void run() { Display display = new Display(); final Shell shell = new Shell(display); // Load an image final Image image = new Image(display, this.getClass().getResourceAsStream( "jexp.gif")); System.out.println(image.getImageData().scanlinePad); image.getImageData().scanlinePad = 40; System.out.println(image.getImageData().scanlinePad); shell.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { // Draw the untainted image event.gc.drawImage(image, 0, 0); // Determine how big the drawing area is Rectangle rect = shell.getClientArea(); // Get information about the image ImageData data = image.getImageData(); // Calculate drawing values int srcX = data.width / 4; int srcY = data.height / 4; int srcWidth = data.width / 2; int srcHeight = data.height / 2; int destWidth = 2 * srcWidth; int destHeight = 2 * srcHeight; // Draw the image event.gc.drawImage(image, srcX, srcY, srcWidth, srcHeight, rect.width - destWidth, rect.height - destHeight, destWidth, destHeight); } }); shell.setText("Draw Images"); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } image.dispose(); display.dispose(); } /** * The application entry point * * @param args the command line arguments */ public static void main(String[] args) { new DrawImagesDemo().run(); }
}
</source>
Display an animated GIF
<source lang="java">
/*
* Image example snippet: display an animated GIF * * For a list of all SWT example snippets see * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets */
import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; public class Snippet141 {
static Display display; static Shell shell; static GC shellGC; static Color shellBackground; static ImageLoader loader; static ImageData[] imageDataArray; static Thread animateThread; static Image image; static final boolean useGIFBackground = false; public static void main(String[] args) { display = new Display(); shell = new Shell(display); shell.setSize(300, 300); shell.open(); shellGC = new GC(shell); shellBackground = shell.getBackground(); FileDialog dialog = new FileDialog(shell); dialog.setFilterExtensions(new String[] {"*.gif"}); String fileName = dialog.open(); if (fileName != null) { loader = new ImageLoader(); try { imageDataArray = loader.load(fileName); if (imageDataArray.length > 1) { animateThread = new Thread("Animation") { public void run() { /* Create an off-screen image to draw on, and fill it with the shell background. */ Image offScreenImage = new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight); GC offScreenImageGC = new GC(offScreenImage); offScreenImageGC.setBackground(shellBackground); offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth, loader.logicalScreenHeight); try { /* Create the first image and draw it on the off-screen image. */ int imageDataIndex = 0; ImageData imageData = imageDataArray[imageDataIndex]; if (image != null && !image.isDisposed()) image.dispose(); image = new Image(display, imageData); offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); /* Now loop through the images, creating and drawing each one * on the off-screen image before drawing it on the shell. */ int repeatCount = loader.repeatCount; while (loader.repeatCount == 0 || repeatCount > 0) { switch (imageData.disposalMethod) { case SWT.DM_FILL_BACKGROUND: /* Fill with the background color before drawing. */ Color bgColor = null; if (useGIFBackground && loader.backgroundPixel != -1) { bgColor = new Color(display, imageData.palette.getRGB(loader.backgroundPixel)); } offScreenImageGC.setBackground(bgColor != null ? bgColor : shellBackground); offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width, imageData.height); if (bgColor != null) bgColor.dispose(); break; case SWT.DM_FILL_PREVIOUS: /* Restore the previous image before drawing. */ offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); break; } imageDataIndex = (imageDataIndex + 1) % imageDataArray.length; imageData = imageDataArray[imageDataIndex]; image.dispose(); image = new Image(display, imageData); offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); /* Draw the off-screen image to the shell. */ shellGC.drawImage(offScreenImage, 0, 0); /* Sleep for the specified delay time (adding commonly-used slow-down fudge factors). */ try { int ms = imageData.delayTime * 10; if (ms < 20) ms += 30; if (ms < 30) ms += 10; Thread.sleep(ms); } catch (InterruptedException e) { } /* If we have just drawn the last image, decrement the repeat count and start again. */ if (imageDataIndex == imageDataArray.length - 1) repeatCount--; } } catch (SWTException ex) { System.out.println("There was an error animating the GIF"); } finally { if (offScreenImage != null && !offScreenImage.isDisposed()) offScreenImage.dispose(); if (offScreenImageGC != null && !offScreenImageGC.isDisposed()) offScreenImageGC.dispose(); if (image != null && !image.isDisposed()) image.dispose(); } } }; animateThread.setDaemon(true); animateThread.start(); } } catch (SWTException ex) { System.out.println("There was an error loading the GIF"); } } while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
}
</source>
Display an image in a group
<source lang="java">
/*
* Image example snippet: display an image in a group * * For a list of all SWT example snippets see * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets */
import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Shell; public class Snippet112 {
public static void main(String[] args) { Display display = new Display(); final Image image = new Image(display, 20, 20); Color color = display.getSystemColor(SWT.COLOR_RED); GC gc = new GC(image); gc.setBackground(color); gc.fillRectangle(image.getBounds()); gc.dispose(); color.dispose(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); Group group = new Group(shell, SWT.NONE); group.setLayout(new FillLayout()); group.setText("a square"); Canvas canvas = new Canvas(group, SWT.NONE); canvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { e.gc.drawImage(image, 0, 0); } }); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } image.dispose(); display.dispose(); }
}
</source>
Double Buffer
<source lang="java">
/*******************************************************************************
* All Right Reserved. Copyright (c) 1998, 2004 Jackwind Li Guojie * * Created on 2004-4-18 16:12:14 by JACK $Id$ * ******************************************************************************/
import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class DoubleBuffer {
Display display = new Display(); Shell shell = new Shell(display); public DoubleBuffer() { shell.setLayout(new FillLayout()); final Image imageEclipse = new Image(display, "jexp.gif");
// final Canvas canvas = new Canvas(shell, SWT.NULL); // canvas.addPaintListener(new PaintListener() { // public void paintControl(PaintEvent e) { // Point size = canvas.getSize(); // // int x1 = (int) (Math.random() * size.x); // int y1 = (int) (Math.random() * size.y); // int x2 = Math.max(canvas.getBounds().width - x1 - 10, 50); // int y2 = Math.max(canvas.getBounds().height - y1 - 10, 50); // // // e.gc.drawRoundRectangle(x1, y1, x2, y2, 5, 5); // // display.timerExec(100, new Runnable() { // public void run() { // canvas.redraw(); // } // }); // // } // });
final Canvas doubleBufferedCanvas = new Canvas(shell, SWT.NO_BACKGROUND); doubleBufferedCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { // Creates new image only absolutely necessary. Image image = (Image) doubleBufferedCanvas.getData("double-buffer-image"); if (image == null || image.getBounds().width != doubleBufferedCanvas.getSize().x || image.getBounds().height != doubleBufferedCanvas.getSize().y) { image = new Image( display, doubleBufferedCanvas.getSize().x, doubleBufferedCanvas.getSize().y); doubleBufferedCanvas.setData("double-buffer-image", image); } // Initializes the graphics context of the image. GC imageGC = new GC(image); imageGC.setBackground(e.gc.getBackground()); imageGC.setForeground(e.gc.getForeground()); imageGC.setFont(e.gc.getFont()); // Fills background. Rectangle imageSize = image.getBounds(); imageGC.fillRectangle(0, 0, imageSize.width + 1, imageSize.height + 1); // Performs actual drawing here ... Point size = doubleBufferedCanvas.getSize(); int x1 = (int) (Math.random() * size.x); int y1 = (int) (Math.random() * size.y); int x2 = Math.max(doubleBufferedCanvas.getBounds().width - x1 - 10, 50); int y2 = Math.max(doubleBufferedCanvas.getBounds().height - y1 - 10, 50); imageGC.drawRoundRectangle(x1, y1, x2, y2, 5, 5); // Draws the buffer image onto the canvas. e.gc.drawImage(image, 0, 0); imageGC.dispose(); display.timerExec(100, new Runnable() { public void run() { doubleBufferedCanvas.redraw(); } }); } }); shell.setSize(300, 200); shell.open(); //textUser.forceFocus(); // Set up the event loop. while (!shell.isDisposed()) { if (!display.readAndDispatch()) { // If no more entries in event queue display.sleep(); } } display.dispose(); } /** * Equips the specified canvas with double buffering to reduce flicker. * * @param canvas */ public static void enableDoubleBuffer(Canvas canvas) { } public static void main(String[] args) { new DoubleBuffer(); }
}
</source>
Draw Images Example
<source lang="java">
/******************************************************************************
* All Right Reserved. * Copyright (c) 1998, 2004 Jackwind Li Guojie * * Created on 2004-4-19 10:44:37 by JACK * $Id$ * *****************************************************************************/
import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /**
* */
public class DrawImages {
Display display = new Display(); Shell shell = new Shell(display); public DrawImages() { shell.setLayout(new FillLayout()); Canvas canvas = new Canvas(shell, SWT.NULL); final Image image = new Image(display, "jexp.gif"); canvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { e.gc.drawImage(image, 10, 10); e.gc.drawImage(image, 0, 0, 100, 100, 200, 10, 200, 50); } }); shell.setSize(430, 200); shell.open(); //textUser.forceFocus(); captureControl(canvas, "canvas.bmp"); // Set up the event loop. while (!shell.isDisposed()) { if (!display.readAndDispatch()) { // If no more entries in event queue display.sleep(); } } display.dispose(); } /** * Captures the specified control and saves the result into a file in the BMP format. * @param control * @param fileName */ public static void captureControl(Control control, String file) { GC gc = new GC(control); Image image = new Image(control.getDisplay(), control.getSize().x, control.getSize().y); gc.copyArea(image, 0, 0); ImageLoader loader = new ImageLoader(); loader.data = new ImageData[] { image.getImageData() }; loader.save(file, SWT.IMAGE_BMP); gc.dispose(); } private void init() { } public static void main(String[] args) { new DrawImages(); }
}
</source>
File Icon Util
<source lang="java">
/******************************************************************************
* All Right Reserved. * Copyright (c) 1998, 2004 Jackwind Li Guojie * * Created on 2004-7-14 7:50:09 by JACK * $Id$ * *****************************************************************************/
import java.io.File; import org.apache.rumons.net.ftp.FTPFile; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Display; /**
* File icon provider. A display object must be created before * you can access this method. */
public class FileIconUtil {
static ImageRegistry imageRegistry; static Image iconFolder; static Image iconFile; static { iconFolder = new Image(Display.getCurrent(), "jexp.gif"); iconFile = new Image(Display.getCurrent(), "jexp.gif"); } /** * Returns an icon representing the specified file. * * @param file * @return */ public static Image getIcon(File file) { if (file.isDirectory()) return iconFolder; int lastDotPos = file.getName().indexOf("."); if (lastDotPos == -1) return iconFile; Image image = getIcon(file.getName().substring(lastDotPos + 1)); return image == null ? iconFile : image; } /** * Returns an icon representing the specified file. * * @param file * @return */ public static Image getIcon(FTPFile file) { if (file.isDirectory()) return iconFolder; int lastDotPos = file.getName().indexOf("."); if (lastDotPos == -1) return iconFile; Image image = getIcon(file.getName().substring(lastDotPos + 1)); return image == null ? iconFile : image; } /** * Returns the icon for the file type with the specified extension. * * @param extension * @return */ private static Image getIcon(String extension) { if (imageRegistry == null) imageRegistry = new ImageRegistry(); Image image = imageRegistry.get(extension); if (image != null) return image; Program program = Program.findProgram(extension); ImageData imageData = (program == null ? null : program.getImageData()); if (imageData != null) { image = new Image(Display.getCurrent(), imageData); imageRegistry.put(extension, image); } else { image = iconFile; } return image; }
}
</source>
Image Analyzer in SWT
<source lang="java">
import java.io.InputStream; import java.net.URL; import java.text.MessageFormat; import java.util.ResourceBundle; import java.util.Vector; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTError; import org.eclipse.swt.SWTException; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.graphics.ImageLoaderEvent; import org.eclipse.swt.graphics.ImageLoaderListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.printing.PrintDialog; import org.eclipse.swt.printing.Printer; import org.eclipse.swt.printing.PrinterData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.rubo; import org.eclipse.swt.widgets.ruposite; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Sash; import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class ImageAnalyzer {
Display display; Shell shell; Canvas imageCanvas, paletteCanvas; Label typeLabel, sizeLabel, depthLabel, transparentPixelLabel, timeToLoadLabel, screenSizeLabel, backgroundPixelLabel, locationLabel, disposalMethodLabel, delayTimeLabel, repeatCountLabel, paletteLabel, dataLabel, statusLabel; Combo backgroundCombo, scaleXCombo, scaleYCombo, alphaCombo; Button incrementalCheck, transparentCheck, maskCheck, backgroundCheck; Button previousButton, nextButton, animateButton; StyledText dataText; Sash sash; Color whiteColor, blackColor, redColor, greenColor, blueColor, canvasBackground; Font fixedWidthFont; Cursor crossCursor; GC imageCanvasGC; int paletteWidth = 140; // recalculated and used as a width hint int ix = 0, iy = 0, py = 0; // used to scroll the image and palette float xscale = 1, yscale = 1; // used to scale the image int alpha = 255; // used to modify the alpha value of the image boolean incremental = false; // used to incrementally display an image boolean transparent = true; // used to display an image with transparency boolean showMask = false; // used to display an icon mask or transparent // image mask boolean showBackground = false; // used to display the background of an // animated image boolean animate = false; // used to animate a multi-image file Thread animateThread; // draws animated images Thread incrementalThread; // draws incremental images String lastPath; // used to seed the file dialog String currentName; // the current image file or URL name String fileName; // the current image file ImageLoader loader; // the loader for the current image file ImageData[] imageDataArray; // all image data read from the current file int imageDataIndex; // the index of the current image data ImageData imageData; // the currently-displayed image data Image image; // the currently-displayed image Vector incrementalEvents; // incremental image events long loadTime = 0; // the time it took to load the current image static final int INDEX_DIGITS = 4; static final int ALPHA_CONSTANT = 0; static final int ALPHA_X = 1; static final int ALPHA_Y = 2; class TextPrompter extends Dialog { String message = ""; String result = null; Shell dialog; Text text; public TextPrompter(Shell parent, int style) { super(parent, style); } public TextPrompter(Shell parent) { this(parent, SWT.APPLICATION_MODAL); } public String getMessage() { return message; } public void setMessage(String string) { message = string; } public String open() { dialog = new Shell(getParent(), getStyle()); dialog.setText(getText()); dialog.setLayout(new GridLayout()); Label label = new Label(dialog, SWT.NULL); label.setText(message); label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); text = new Text(dialog, SWT.SINGLE | SWT.BORDER); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.widthHint = 300; text.setLayoutData(data); Composite buttons = new Composite(dialog, SWT.NONE); GridLayout grid = new GridLayout(); grid.numColumns = 2; buttons.setLayout(grid); buttons.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); Button ok = new Button(buttons, SWT.PUSH); ok.setText("OK"); data = new GridData(); data.widthHint = 75; ok.setLayoutData(data); ok.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { result = text.getText(); dialog.dispose(); } }); Button cancel = new Button(buttons, SWT.PUSH); cancel.setText("Cancel"); data = new GridData(); data.widthHint = 75; cancel.setLayoutData(data); cancel.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { dialog.dispose(); } }); dialog.setDefaultButton(ok); dialog.pack(); dialog.open(); while (!dialog.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } return result; } } public static void main(String[] args) { Display display = new Display(); ImageAnalyzer imageAnalyzer = new ImageAnalyzer(); Shell shell = imageAnalyzer.open(display); while (!shell.isDisposed()) if (!display.readAndDispatch()) display.sleep(); display.dispose(); } public Shell open(Display dpy) { // Create a window and set its title. this.display = dpy; shell = new Shell(display); shell.setText("Image_analyzer"); // Hook resize and dispose listeners. shell.addControlListener(new ControlAdapter() { public void controlResized(ControlEvent event) { resizeShell(event); } }); shell.addShellListener(new ShellAdapter() { public void shellClosed(ShellEvent e) { animate = false; // stop any animation in progress if (animateThread != null) { // wait for the thread to die before disposing the shell. while (animateThread.isAlive()) { if (!display.readAndDispatch()) display.sleep(); } } e.doit = true; } }); shell.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { // Clean up. if (image != null) image.dispose(); whiteColor.dispose(); blackColor.dispose(); redColor.dispose(); greenColor.dispose(); blueColor.dispose(); fixedWidthFont.dispose(); crossCursor.dispose(); } }); // Create colors and fonts. whiteColor = new Color(display, 255, 255, 255); blackColor = new Color(display, 0, 0, 0); redColor = new Color(display, 255, 0, 0); greenColor = new Color(display, 0, 255, 0); blueColor = new Color(display, 0, 0, 255); fixedWidthFont = new Font(display, "courier", 10, 0); crossCursor = new Cursor(display, SWT.CURSOR_CROSS); // Add a menu bar and widgets. createMenuBar(); createWidgets(); shell.pack(); // Create a GC for drawing, and hook the listener to dispose it. imageCanvasGC = new GC(imageCanvas); imageCanvas.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { imageCanvasGC.dispose(); } }); // Open the window shell.open(); return shell; } void createWidgets() { // Add the widgets to the shell in a grid layout. GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.numColumns = 2; shell.setLayout(layout); // Separate the menu bar from the rest of the widgets. Label separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); GridData gridData = new GridData(); gridData.horizontalSpan = 2; gridData.horizontalAlignment = GridData.FILL; separator.setLayoutData(gridData); // Add a composite to contain some control widgets across the top. Composite controls = new Composite(shell, SWT.NULL); RowLayout rowLayout = new RowLayout(); rowLayout.marginTop = 0; rowLayout.marginBottom = 5; rowLayout.spacing = 8; controls.setLayout(rowLayout); gridData = new GridData(); gridData.horizontalSpan = 2; controls.setLayoutData(gridData); // Combo to change the background. Group group = new Group(controls, SWT.NULL); group.setLayout(new RowLayout()); group.setText("Background"); backgroundCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY); backgroundCombo.setItems(new String[] { "None", "White", "Black", "Red", "Green", "Blue" }); backgroundCombo.select(backgroundCombo.indexOf("White")); backgroundCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { changeBackground(); } }); // Combo to change the x scale. String[] values = { "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "2", "3", "4", "5", "6", "7", "8", "9", "10", }; group = new Group(controls, SWT.NULL); group.setLayout(new RowLayout()); group.setText("X_scale"); scaleXCombo = new Combo(group, SWT.DROP_DOWN); for (int i = 0; i < values.length; i++) { scaleXCombo.add(values[i]); } scaleXCombo.select(scaleXCombo.indexOf("1")); scaleXCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { scaleX(); } }); // Combo to change the y scale. group = new Group(controls, SWT.NULL); group.setLayout(new RowLayout()); group.setText("Y_scale"); scaleYCombo = new Combo(group, SWT.DROP_DOWN); for (int i = 0; i < values.length; i++) { scaleYCombo.add(values[i]); } scaleYCombo.select(scaleYCombo.indexOf("1")); scaleYCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { scaleY(); } }); // Combo to change the alpha value. group = new Group(controls, SWT.NULL); group.setLayout(new RowLayout()); group.setText("Alpha_K"); alphaCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY); for (int i = 0; i <= 255; i += 5) { alphaCombo.add(String.valueOf(i)); } alphaCombo.select(alphaCombo.indexOf("255")); alphaCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { alpha(); } }); // Check box to request incremental display. group = new Group(controls, SWT.NULL); group.setLayout(new RowLayout()); group.setText("Display"); incrementalCheck = new Button(group, SWT.CHECK); incrementalCheck.setText("Incremental"); incrementalCheck.setSelection(incremental); incrementalCheck.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { incremental = ((Button) event.widget).getSelection(); } }); // Check box to request transparent display. transparentCheck = new Button(group, SWT.CHECK); transparentCheck.setText("Transparent"); transparentCheck.setSelection(transparent); transparentCheck.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { transparent = ((Button) event.widget).getSelection(); if (image != null) { imageCanvas.redraw(); } } }); // Check box to request mask display. maskCheck = new Button(group, SWT.CHECK); maskCheck.setText("Mask"); maskCheck.setSelection(showMask); maskCheck.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { showMask = ((Button) event.widget).getSelection(); if (image != null) { imageCanvas.redraw(); } } }); // Check box to request background display. backgroundCheck = new Button(group, SWT.CHECK); backgroundCheck.setText("Background"); backgroundCheck.setSelection(showBackground); backgroundCheck.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { showBackground = ((Button) event.widget).getSelection(); } }); // Group the animation buttons. group = new Group(controls, SWT.NULL); group.setLayout(new RowLayout()); group.setText("Animation"); // Push button to display the previous image in a multi-image file. previousButton = new Button(group, SWT.PUSH); previousButton.setText("Previous"); previousButton.setEnabled(false); previousButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { previous(); } }); // Push button to display the next image in a multi-image file. nextButton = new Button(group, SWT.PUSH); nextButton.setText("Next"); nextButton.setEnabled(false); nextButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { next(); } }); // Push button to toggle animation of a multi-image file. animateButton = new Button(group, SWT.PUSH); animateButton.setText("Animate"); animateButton.setEnabled(false); animateButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { animate(); } }); // Label to show the image file type. typeLabel = new Label(shell, SWT.NULL); typeLabel.setText("Type_initial"); typeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // Canvas to show the image. imageCanvas = new Canvas(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE); imageCanvas.setBackground(whiteColor); imageCanvas.setCursor(crossCursor); gridData = new GridData(); gridData.verticalSpan = 15; gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; imageCanvas.setLayoutData(gridData); imageCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { if (image != null) paintImage(event); } }); imageCanvas.addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent event) { if (image != null) { showColorAt(event.x, event.y); } } }); // Set up the image canvas scroll bars. ScrollBar horizontal = imageCanvas.getHorizontalBar(); horizontal.setVisible(true); horizontal.setMinimum(0); horizontal.setEnabled(false); horizontal.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { scrollHorizontally((ScrollBar) event.widget); } }); ScrollBar vertical = imageCanvas.getVerticalBar(); vertical.setVisible(true); vertical.setMinimum(0); vertical.setEnabled(false); vertical.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { scrollVertically((ScrollBar) event.widget); } }); // Label to show the image size. sizeLabel = new Label(shell, SWT.NULL); sizeLabel.setText("Size_initial"); sizeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the image depth. depthLabel = new Label(shell, SWT.NULL); depthLabel.setText("Depth_initial"); depthLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the transparent pixel. transparentPixelLabel = new Label(shell, SWT.NULL); transparentPixelLabel.setText("Transparent_pixel_initial"); transparentPixelLabel.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the time to load. timeToLoadLabel = new Label(shell, SWT.NULL); timeToLoadLabel.setText("Time_to_load_initial"); timeToLoadLabel.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); // Separate the animation fields from the rest of the fields. separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the logical screen size for animation. screenSizeLabel = new Label(shell, SWT.NULL); screenSizeLabel.setText("Animation_size_initial"); screenSizeLabel.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the background pixel. backgroundPixelLabel = new Label(shell, SWT.NULL); backgroundPixelLabel.setText("Background_pixel_initial"); backgroundPixelLabel.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the image location (x, y). locationLabel = new Label(shell, SWT.NULL); locationLabel.setText("Image_location_initial"); locationLabel .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the image disposal method. disposalMethodLabel = new Label(shell, SWT.NULL); disposalMethodLabel.setText("Disposal_initial"); disposalMethodLabel.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the image delay time. delayTimeLabel = new Label(shell, SWT.NULL); delayTimeLabel.setText("Delay_initial"); delayTimeLabel.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); // Label to show the background pixel. repeatCountLabel = new Label(shell, SWT.NULL); repeatCountLabel.setText("Repeats_initial"); repeatCountLabel.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL)); // Separate the animation fields from the palette. separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // Label to show if the image has a direct or indexed palette. paletteLabel = new Label(shell, SWT.NULL); paletteLabel.setText("Palette_initial"); paletteLabel .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // Canvas to show the image"s palette. paletteCanvas = new Canvas(shell, SWT.BORDER | SWT.V_SCROLL | SWT.NO_REDRAW_RESIZE); paletteCanvas.setFont(fixedWidthFont); paletteCanvas.getVerticalBar().setVisible(true); gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.FILL; GC gc = new GC(paletteLabel); paletteWidth = gc.stringExtent("Max_length_string").x; gc.dispose(); gridData.widthHint = paletteWidth; gridData.heightHint = 16 * 11; // show at least 16 colors paletteCanvas.setLayoutData(gridData); paletteCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { if (image != null) paintPalette(event); } }); // Set up the palette canvas scroll bar. vertical = paletteCanvas.getVerticalBar(); vertical.setVisible(true); vertical.setMinimum(0); vertical.setIncrement(10); vertical.setEnabled(false); vertical.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { scrollPalette((ScrollBar) event.widget); } }); // Sash to see more of image or image data. sash = new Sash(shell, SWT.HORIZONTAL); gridData = new GridData(); gridData.horizontalSpan = 2; gridData.horizontalAlignment = GridData.FILL; sash.setLayoutData(gridData); sash.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { if (event.detail != SWT.DRAG) { ((GridData) paletteCanvas.getLayoutData()).heightHint = SWT.DEFAULT; Rectangle paletteCanvasBounds = paletteCanvas.getBounds(); int minY = paletteCanvasBounds.y + 20; Rectangle dataLabelBounds = dataLabel.getBounds(); int maxY = statusLabel.getBounds().y - dataLabelBounds.height - 20; if (event.y > minY && event.y < maxY) { Rectangle oldSash = sash.getBounds(); sash.setBounds(event.x, event.y, event.width, event.height); int diff = event.y - oldSash.y; Rectangle bounds = imageCanvas.getBounds(); imageCanvas.setBounds(bounds.x, bounds.y, bounds.width, bounds.height + diff); bounds = paletteCanvasBounds; paletteCanvas.setBounds(bounds.x, bounds.y, bounds.width, bounds.height + diff); bounds = dataLabelBounds; dataLabel.setBounds(bounds.x, bounds.y + diff, bounds.width, bounds.height); bounds = dataText.getBounds(); dataText.setBounds(bounds.x, bounds.y + diff, bounds.width, bounds.height - diff); // shell.layout(true); } } } }); // Label to show data-specific fields. dataLabel = new Label(shell, SWT.NULL); dataLabel.setText("Pixel_data_initial"); gridData = new GridData(); gridData.horizontalSpan = 2; gridData.horizontalAlignment = GridData.FILL; dataLabel.setLayoutData(gridData); // Text to show a dump of the data. dataText = new StyledText(shell, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL); dataText.setBackground(display .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); dataText.setFont(fixedWidthFont); gridData = new GridData(); gridData.horizontalSpan = 2; gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.FILL; gridData.heightHint = 128; gridData.grabExcessVerticalSpace = true; dataText.setLayoutData(gridData); dataText.addMouseListener(new MouseAdapter() { public void mouseDown(MouseEvent event) { if (image != null && event.button == 1) { showColorForData(); } } }); dataText.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent event) { if (image != null) { showColorForData(); } } }); // Label to show status and cursor location in image. statusLabel = new Label(shell, SWT.NULL); statusLabel.setText(""); gridData = new GridData(); gridData.horizontalSpan = 2; gridData.horizontalAlignment = GridData.FILL; statusLabel.setLayoutData(gridData); } Menu createMenuBar() { // Menu bar. Menu menuBar = new Menu(shell, SWT.BAR); shell.setMenuBar(menuBar); createFileMenu(menuBar); createAlphaMenu(menuBar); return menuBar; } void createFileMenu(Menu menuBar) { // File menu MenuItem item = new MenuItem(menuBar, SWT.CASCADE); item.setText("File"); Menu fileMenu = new Menu(shell, SWT.DROP_DOWN); item.setMenu(fileMenu); // File -> Open File... item = new MenuItem(fileMenu, SWT.PUSH); item.setText("OpenFile"); item.setAccelerator(SWT.MOD1 + "O"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuOpenFile(); } }); // File -> Open URL... item = new MenuItem(fileMenu, SWT.PUSH); item.setText("OpenURL"); item.setAccelerator(SWT.MOD1 + "U"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuOpenURL(); } }); // File -> Reopen item = new MenuItem(fileMenu, SWT.PUSH); item.setText("Reopen"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuReopen(); } }); new MenuItem(fileMenu, SWT.SEPARATOR); // File -> Save item = new MenuItem(fileMenu, SWT.PUSH); item.setText("Save"); item.setAccelerator(SWT.MOD1 + "S"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuSave(); } }); // File -> Save As... item = new MenuItem(fileMenu, SWT.PUSH); item.setText("Save_as"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuSaveAs(); } }); // File -> Save Mask As... item = new MenuItem(fileMenu, SWT.PUSH); item.setText("Save_mask_as"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuSaveMaskAs(); } }); new MenuItem(fileMenu, SWT.SEPARATOR); // File -> Print item = new MenuItem(fileMenu, SWT.PUSH); item.setText("Print"); item.setAccelerator(SWT.MOD1 + "P"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuPrint(); } }); new MenuItem(fileMenu, SWT.SEPARATOR); // File -> Exit item = new MenuItem(fileMenu, SWT.PUSH); item.setText("Exit"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { shell.close(); } }); } void createAlphaMenu(Menu menuBar) { // Alpha menu MenuItem item = new MenuItem(menuBar, SWT.CASCADE); item.setText("Alpha"); Menu alphaMenu = new Menu(shell, SWT.DROP_DOWN); item.setMenu(alphaMenu); // Alpha -> K item = new MenuItem(alphaMenu, SWT.PUSH); item.setText("K"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuComposeAlpha(ALPHA_CONSTANT); } }); // Alpha -> (K + x) % 256 item = new MenuItem(alphaMenu, SWT.PUSH); item.setText("(K + x) % 256"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuComposeAlpha(ALPHA_X); } }); // Alpha -> (K + y) % 256 item = new MenuItem(alphaMenu, SWT.PUSH); item.setText("(K + y) % 256"); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { menuComposeAlpha(ALPHA_Y); } }); } void menuComposeAlpha(int alpha_op) { if (image == null) return; animate = false; // stop any animation in progress Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT); shell.setCursor(waitCursor); imageCanvas.setCursor(waitCursor); try { if (alpha_op == ALPHA_CONSTANT) { imageData.alpha = alpha; } else { imageData.alpha = -1; switch (alpha_op) { case ALPHA_X: for (int y = 0; y < imageData.height; y++) { for (int x = 0; x < imageData.width; x++) { imageData.setAlpha(x, y, (x + alpha) % 256); } } break; case ALPHA_Y: for (int y = 0; y < imageData.height; y++) { for (int x = 0; x < imageData.width; x++) { imageData.setAlpha(x, y, (y + alpha) % 256); } } break; default: break; } } displayImage(imageData); } finally { shell.setCursor(null); imageCanvas.setCursor(crossCursor); waitCursor.dispose(); } } void menuOpenFile() { animate = false; // stop any animation in progress resetScaleCombos(); // Get the user to choose an image file. FileDialog fileChooser = new FileDialog(shell, SWT.OPEN); if (lastPath != null) fileChooser.setFilterPath(lastPath); fileChooser.setFilterExtensions(new String[] { "*.bmp; *.gif; *.ico; *.jpg; *.pcx; *.png; *.tif", "*.bmp", "*.gif", "*.ico", "*.jpg", "*.pcx", "*.png", "*.tif" }); fileChooser.setFilterNames(new String[] { "All_images" + " (bmp, gif, ico, jpg, pcx, png, tif)", "BMP (*.bmp)", "GIF (*.gif)", "ICO (*.ico)", "JPEG (*.jpg)", "PCX (*.pcx)", "PNG (*.png)", "TIFF (*.tif)" }); String filename = fileChooser.open(); lastPath = fileChooser.getFilterPath(); if (filename == null) return; Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT); shell.setCursor(waitCursor); imageCanvas.setCursor(waitCursor); try { loader = new ImageLoader(); if (incremental) { // Prepare to handle incremental events. loader.addImageLoaderListener(new ImageLoaderListener() { public void imageDataLoaded(ImageLoaderEvent event) { incrementalDataLoaded(event); } }); incrementalThreadStart(); } // Read the new image(s) from the chosen file. long startTime = System.currentTimeMillis(); imageDataArray = loader.load(filename); loadTime = System.currentTimeMillis() - startTime; if (imageDataArray.length > 0) { // Cache the filename. currentName = filename; fileName = filename; // If there are multiple images in the file (typically GIF) // then enable the Previous, Next and Animate buttons. previousButton.setEnabled(imageDataArray.length > 1); nextButton.setEnabled(imageDataArray.length > 1); animateButton.setEnabled(imageDataArray.length > 1 && loader.logicalScreenWidth > 0 && loader.logicalScreenHeight > 0); // Display the first image in the file. imageDataIndex = 0; displayImage(imageDataArray[imageDataIndex]); resetScrollBars(); } } catch (SWTException e) { showErrorDialog("Loading_lc", filename, e); } catch (SWTError e) { showErrorDialog("Loading_lc", filename, e); } finally { shell.setCursor(null); imageCanvas.setCursor(crossCursor); waitCursor.dispose(); } } void menuOpenURL() { animate = false; // stop any animation in progress resetScaleCombos(); // Get the user to choose an image URL. TextPrompter textPrompter = new TextPrompter(shell, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM); textPrompter.setText("OpenURLDialog"); textPrompter.setMessage("EnterURL"); String urlname = textPrompter.open(); if (urlname == null) return; Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT); shell.setCursor(waitCursor); imageCanvas.setCursor(waitCursor); try { URL url = new URL(urlname); InputStream stream = url.openStream(); loader = new ImageLoader(); if (incremental) { // Prepare to handle incremental events. loader.addImageLoaderListener(new ImageLoaderListener() { public void imageDataLoaded(ImageLoaderEvent event) { incrementalDataLoaded(event); } }); incrementalThreadStart(); } // Read the new image(s) from the chosen URL. long startTime = System.currentTimeMillis(); imageDataArray = loader.load(stream); stream.close(); loadTime = System.currentTimeMillis() - startTime; if (imageDataArray.length > 0) { currentName = urlname; fileName = null; // If there are multiple images (typically GIF) // then enable the Previous, Next and Animate buttons. previousButton.setEnabled(imageDataArray.length > 1); nextButton.setEnabled(imageDataArray.length > 1); animateButton.setEnabled(imageDataArray.length > 1 && loader.logicalScreenWidth > 0 && loader.logicalScreenHeight > 0); // Display the first image. imageDataIndex = 0; displayImage(imageDataArray[imageDataIndex]); resetScrollBars(); } } catch (Exception e) { showErrorDialog("Loading", urlname, e); } finally { shell.setCursor(null); imageCanvas.setCursor(crossCursor); waitCursor.dispose(); } } /* * Called to start a thread that draws incremental images as they are * loaded. */ void incrementalThreadStart() { incrementalEvents = new Vector(); incrementalThread = new Thread("Incremental") { public void run() { // Draw the first ImageData increment. while (incrementalEvents != null) { // Synchronize so we don"t try to remove when the vector is // null. synchronized (ImageAnalyzer.this) { if (incrementalEvents != null) { if (incrementalEvents.size() > 0) { ImageLoaderEvent event = (ImageLoaderEvent) incrementalEvents .remove(0); if (image != null) image.dispose(); image = new Image(display, event.imageData); imageData = event.imageData; imageCanvasGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); } else { yield(); } } } } display.wake(); } }; incrementalThread.setDaemon(true); incrementalThread.start(); } /* * Called when incremental image data has been loaded, for example, for * interlaced GIF/PNG or progressive JPEG. */ void incrementalDataLoaded(ImageLoaderEvent event) { // Synchronize so that we do not try to add while // the incremental drawing thread is removing. synchronized (this) { incrementalEvents.addElement(event); } } void menuSave() { if (image == null) return; animate = false; // stop any animation in progress // If the image file type is unknown, we can"t "Save", // so we have to use "Save As...". if (imageData.type == SWT.IMAGE_UNDEFINED || fileName == null) { menuSaveAs(); return; } Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT); shell.setCursor(waitCursor); imageCanvas.setCursor(waitCursor); try { // Save the current image to the current file. loader.data = new ImageData[] { imageData }; loader.save(fileName, imageData.type); } catch (SWTException e) { showErrorDialog("Saving_lc", fileName, e); } catch (SWTError e) { showErrorDialog("Saving_lc", fileName, e); } finally { shell.setCursor(null); imageCanvas.setCursor(crossCursor); waitCursor.dispose(); } } void menuSaveAs() { if (image == null) return; animate = false; // stop any animation in progress // Get the user to choose a file name and type to save. FileDialog fileChooser = new FileDialog(shell, SWT.SAVE); fileChooser.setFilterPath(lastPath); if (fileName != null) { String name = fileName; int nameStart = name.lastIndexOf(java.io.File.separatorChar); if (nameStart > -1) { name = name.substring(nameStart + 1); } fileChooser.setFileName(name); } fileChooser.setFilterExtensions(new String[] { "*.bmp", "*.gif", "*.ico", "*.jpg", "*.png" }); fileChooser.setFilterNames(new String[] { "BMP (*.bmp)", "GIF (*.gif)", "ICO (*.ico)", "JPEG (*.jpg)", "PNG (*.png)" }); String filename = fileChooser.open(); lastPath = fileChooser.getFilterPath(); if (filename == null) return; // Figure out what file type the user wants saved. // We need to rely on the file extension because FileDialog // does not have API for asking what filter type was selected. int filetype = determineFileType(filename); if (filetype == SWT.IMAGE_UNDEFINED) { MessageBox box = new MessageBox(shell, SWT.ICON_ERROR); box.setMessage(createMsg("Unknown_extension", filename.substring(filename.lastIndexOf(".") + 1))); box.open(); return; } if (new java.io.File(filename).exists()) { MessageBox box = new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL); box.setMessage(createMsg("Overwrite", filename)); if (box.open() == SWT.CANCEL) return; } Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT); shell.setCursor(waitCursor); imageCanvas.setCursor(waitCursor); try { // Save the current image to the specified file. loader.data = new ImageData[] { imageData }; loader.save(filename, filetype); // Update the shell title and file type label, // and use the new file. fileName = filename; shell.setText(createMsg("Analyzer_on", filename)); typeLabel.setText(createMsg("Type_string", fileTypeString(filetype))); } catch (SWTException e) { showErrorDialog("Saving_lc", filename, e); } catch (SWTError e) { showErrorDialog("Saving_lc", filename, e); } finally { shell.setCursor(null); imageCanvas.setCursor(crossCursor); waitCursor.dispose(); } } void menuSaveMaskAs() { if (image == null || !showMask) return; if (imageData.getTransparencyType() == SWT.TRANSPARENCY_NONE) return; animate = false; // stop any animation in progress // Get the user to choose a file name and type to save. FileDialog fileChooser = new FileDialog(shell, SWT.SAVE); fileChooser.setFilterPath(lastPath); if (fileName != null) fileChooser.setFileName(fileName); fileChooser.setFilterExtensions(new String[] { "*.bmp", "*.gif", "*.ico", "*.jpg", "*.png" }); fileChooser.setFilterNames(new String[] { "BMP (*.bmp)", "GIF (*.gif)", "ICO (*.ico)", "JPEG (*.jpg)", "PNG (*.png)" }); String filename = fileChooser.open(); lastPath = fileChooser.getFilterPath(); if (filename == null) return; // Figure out what file type the user wants saved. // We need to rely on the file extension because FileDialog // does not have API for asking what filter type was selected. int filetype = determineFileType(filename); if (filetype == SWT.IMAGE_UNDEFINED) { MessageBox box = new MessageBox(shell, SWT.ICON_ERROR); box.setMessage(createMsg("Unknown_extension", filename.substring(filename.lastIndexOf(".") + 1))); box.open(); return; } if (new java.io.File(filename).exists()) { MessageBox box = new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL); box.setMessage(createMsg("Overwrite", filename)); if (box.open() == SWT.CANCEL) return; } Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT); shell.setCursor(waitCursor); imageCanvas.setCursor(waitCursor); try { // Save the mask of the current image to the specified file. ImageData maskImageData = imageData.getTransparencyMask(); loader.data = new ImageData[] { maskImageData }; loader.save(filename, filetype); } catch (SWTException e) { showErrorDialog("Saving_lc", filename, e); } catch (SWTError e) { showErrorDialog("Saving_lc", filename, e); } finally { shell.setCursor(null); imageCanvas.setCursor(crossCursor); waitCursor.dispose(); } } void menuPrint() { if (image == null) return; try { // Ask the user to specify the printer. PrintDialog dialog = new PrintDialog(shell, SWT.NULL); PrinterData printerData = dialog.open(); if (printerData == null) return; Printer printer = new Printer(printerData); Point screenDPI = display.getDPI(); Point printerDPI = printer.getDPI(); int scaleFactor = printerDPI.x / screenDPI.x; Rectangle trim = printer.ruputeTrim(0, 0, 0, 0); if (printer.startJob(currentName)) { if (printer.startPage()) { GC gc = new GC(printer); int transparentPixel = imageData.transparentPixel; if (transparentPixel != -1 && !transparent) { imageData.transparentPixel = -1; } Image printerImage = new Image(printer, imageData); gc.drawImage(printerImage, 0, 0, imageData.width, imageData.height, -trim.x, -trim.y, scaleFactor * imageData.width, scaleFactor * imageData.height); if (transparentPixel != -1 && !transparent) { imageData.transparentPixel = transparentPixel; } printerImage.dispose(); gc.dispose(); printer.endPage(); } printer.endJob(); } printer.dispose(); } catch (SWTError e) { MessageBox box = new MessageBox(shell, SWT.ICON_ERROR); box.setMessage("Printing_error" + e.getMessage()); box.open(); } } void menuReopen() { if (currentName == null) return; animate = false; // stop any animation in progress resetScrollBars(); resetScaleCombos(); Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT); shell.setCursor(waitCursor); imageCanvas.setCursor(waitCursor); try { loader = new ImageLoader(); long startTime = System.currentTimeMillis(); ImageData[] newImageData; if (fileName == null) { URL url = new URL(currentName); InputStream stream = url.openStream(); newImageData = loader.load(stream); stream.close(); } else { newImageData = loader.load(fileName); } loadTime = System.currentTimeMillis() - startTime; imageDataIndex = 0; displayImage(newImageData[imageDataIndex]); } catch (Exception e) { showErrorDialog("Reloading", currentName, e); } finally { shell.setCursor(null); imageCanvas.setCursor(crossCursor); waitCursor.dispose(); } } void changeBackground() { String background = backgroundCombo.getText(); if (background.equals("White")) { imageCanvas.setBackground(whiteColor); } else if (background.equals("Black")) { imageCanvas.setBackground(blackColor); } else if (background.equals("Red")) { imageCanvas.setBackground(redColor); } else if (background.equals("Green")) { imageCanvas.setBackground(greenColor); } else if (background.equals("Blue")) { imageCanvas.setBackground(blueColor); } else { imageCanvas.setBackground(null); } } /* * Called when the ScaleX combo selection changes. */ void scaleX() { try { xscale = Float.parseFloat(scaleXCombo.getText()); } catch (NumberFormatException e) { xscale = 1; scaleXCombo.select(scaleXCombo.indexOf("1")); } if (image != null) { resizeScrollBars(); imageCanvas.redraw(); } } /* * Called when the ScaleY combo selection changes. */ void scaleY() { try { yscale = Float.parseFloat(scaleYCombo.getText()); } catch (NumberFormatException e) { yscale = 1; scaleYCombo.select(scaleYCombo.indexOf("1")); } if (image != null) { resizeScrollBars(); imageCanvas.redraw(); } } /* * Called when the Alpha combo selection changes. */ void alpha() { try { alpha = Integer.parseInt(alphaCombo.getText()); } catch (NumberFormatException e) { alphaCombo.select(alphaCombo.indexOf("255")); alpha = 255; } } /* * Called when the mouse moves in the image canvas. Show the color of the * image at the point under the mouse. */ void showColorAt(int mx, int my) { int x = mx - imageData.x - ix; int y = my - imageData.y - iy; showColorForPixel(x, y); } /* * Called when a mouse down or key press is detected in the data text. Show * the color of the pixel at the caret position in the data text. */ void showColorForData() { int delimiterLength = dataText.getLineDelimiter().length(); int charactersPerLine = 6 + 3 * imageData.bytesPerLine + delimiterLength; int position = dataText.getCaretOffset(); int y = position / charactersPerLine; if ((position - y * charactersPerLine) < 6 || ((y + 1) * charactersPerLine - position) <= delimiterLength) { statusLabel.setText(""); return; } int dataPosition = position - 6 * (y + 1) - delimiterLength * y; int byteNumber = dataPosition / 3; int where = dataPosition - byteNumber * 3; int xByte = byteNumber % imageData.bytesPerLine; int x = -1; int depth = imageData.depth; if (depth == 1) { // 8 pixels per byte (can only show 3 of 8) if (where == 0) x = xByte * 8; if (where == 1) x = xByte * 8 + 3; if (where == 2) x = xByte * 8 + 7; } if (depth == 2) { // 4 pixels per byte (can only show 3 of 4) if (where == 0) x = xByte * 4; if (where == 1) x = xByte * 4 + 1; if (where == 2) x = xByte * 4 + 3; } if (depth == 4) { // 2 pixels per byte if (where == 0) x = xByte * 2; if (where == 1) x = xByte * 2; if (where == 2) x = xByte * 2 + 1; } if (depth == 8) { // 1 byte per pixel x = xByte; } if (depth == 16) { // 2 bytes per pixel x = xByte / 2; } if (depth == 24) { // 3 bytes per pixel x = xByte / 3; } if (depth == 32) { // 4 bytes per pixel x = xByte / 4; } if (x != -1) { showColorForPixel(x, y); } else { statusLabel.setText(""); } } /* * Set the status label to show color information for the specified pixel in * the image. */ void showColorForPixel(int x, int y) { if (x >= 0 && x < imageData.width && y >= 0 && y < imageData.height) { int pixel = imageData.getPixel(x, y); RGB rgb = imageData.palette.getRGB(pixel); Object[] args = { new Integer(x), new Integer(y), new Integer(pixel), Integer.toHexString(pixel), rgb }; if (pixel == imageData.transparentPixel) { statusLabel.setText(createMsg("Color_at_trans", args)); } else { statusLabel.setText(createMsg("Color_at", args)); } } else { statusLabel.setText(""); } } /* * Called when the Animate button is pressed. */ void animate() { animate = !animate; if (animate && image != null && imageDataArray.length > 1) { animateThread = new Thread("Animation") { public void run() { // Pre-animation widget setup. preAnimation(); // Animate. try { animateLoop(); } catch (final SWTException e) { display.syncExec(new Runnable() { public void run() { showErrorDialog(createMsg("Creating_image", new Integer(imageDataIndex + 1)), currentName, e); } }); } // Post animation widget reset. postAnimation(); } }; animateThread.setDaemon(true); animateThread.start(); } } /* * Loop through all of the images in a multi-image file and display them one * after another. */ void animateLoop() { // Create an off-screen image to draw on, and a GC to draw with. // Both are disposed after the animation. Image offScreenImage = new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight); GC offScreenImageGC = new GC(offScreenImage); try { // Use syncExec to get the background color of the imageCanvas. display.syncExec(new Runnable() { public void run() { canvasBackground = imageCanvas.getBackground(); } }); // Fill the off-screen image with the background color of the // canvas. offScreenImageGC.setBackground(canvasBackground); offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth, loader.logicalScreenHeight); // Draw the current image onto the off-screen image. offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); int repeatCount = loader.repeatCount; while (animate && (loader.repeatCount == 0 || repeatCount > 0)) { if (imageData.disposalMethod == SWT.DM_FILL_BACKGROUND) { // Fill with the background color before drawing. Color bgColor = null; int backgroundPixel = loader.backgroundPixel; if (showBackground && backgroundPixel != -1) { // Fill with the background color. RGB backgroundRGB = imageData.palette .getRGB(backgroundPixel); bgColor = new Color(null, backgroundRGB); } try { offScreenImageGC .setBackground(bgColor != null ? bgColor : canvasBackground); offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width, imageData.height); } finally { if (bgColor != null) bgColor.dispose(); } } else if (imageData.disposalMethod == SWT.DM_FILL_PREVIOUS) { // Restore the previous image before drawing. offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); } // Get the next image data. imageDataIndex = (imageDataIndex + 1) % imageDataArray.length; imageData = imageDataArray[imageDataIndex]; image.dispose(); image = new Image(display, imageData); // Draw the new image data. offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); // Draw the off-screen image to the screen. imageCanvasGC.drawImage(offScreenImage, 0, 0); // Sleep for the specified delay time before drawing again. try { Thread.sleep(visibleDelay(imageData.delayTime * 10)); } catch (InterruptedException e) { } // If we have just drawn the last image in the set, // then decrement the repeat count. if (imageDataIndex == imageDataArray.length - 1) repeatCount--; } } finally { offScreenImage.dispose(); offScreenImageGC.dispose(); } } /* * Pre animation setup. */ void preAnimation() { display.syncExec(new Runnable() { public void run() { // Change the label of the Animate button to "Stop". animateButton.setText("Stop"); // Disable anything we don"t want the user // to select during the animation. previousButton.setEnabled(false); nextButton.setEnabled(false); backgroundCombo.setEnabled(false); scaleXCombo.setEnabled(false); scaleYCombo.setEnabled(false); alphaCombo.setEnabled(false); incrementalCheck.setEnabled(false); transparentCheck.setEnabled(false); maskCheck.setEnabled(false); // leave backgroundCheck enabled // Reset the scale combos and scrollbars. resetScaleCombos(); resetScrollBars(); } }); } /* * Post animation reset. */ void postAnimation() { display.syncExec(new Runnable() { public void run() { // Enable anything we disabled before the animation. previousButton.setEnabled(true); nextButton.setEnabled(true); backgroundCombo.setEnabled(true); scaleXCombo.setEnabled(true); scaleYCombo.setEnabled(true); alphaCombo.setEnabled(true); incrementalCheck.setEnabled(true); transparentCheck.setEnabled(true); maskCheck.setEnabled(true); // Reset the label of the Animate button. animateButton.setText("Animate"); if (animate) { // If animate is still true, we finished the // full number of repeats. Leave the image as-is. animate = false; } else { // Redisplay the current image and its palette. displayImage(imageDataArray[imageDataIndex]); } } }); } /* * Called when the Previous button is pressed. Display the previous image in * a multi-image file. */ void previous() { if (image != null && imageDataArray.length > 1) { if (imageDataIndex == 0) { imageDataIndex = imageDataArray.length; } imageDataIndex = imageDataIndex - 1; displayImage(imageDataArray[imageDataIndex]); } } /* * Called when the Next button is pressed. Display the next image in a * multi-image file. */ void next() { if (image != null && imageDataArray.length > 1) { imageDataIndex = (imageDataIndex + 1) % imageDataArray.length; displayImage(imageDataArray[imageDataIndex]); } } void displayImage(ImageData newImageData) { if (incremental && incrementalThread != null) { // Tell the incremental thread to stop drawing. synchronized (this) { incrementalEvents = null; } // Wait until the incremental thread is done. while (incrementalThread.isAlive()) { if (!display.readAndDispatch()) display.sleep(); } } // Dispose of the old image, if there was one. if (image != null) image.dispose(); try { // Cache the new image and imageData. image = new Image(display, newImageData); imageData = newImageData; } catch (SWTException e) { showErrorDialog("Creating_from" + " ", currentName, e); image = null; return; } // Update the widgets with the new image info. String string = createMsg("Analyzer_on", currentName); shell.setText(string); if (imageDataArray.length > 1) { string = createMsg("Type_index", new Object[] { fileTypeString(imageData.type), new Integer(imageDataIndex + 1), new Integer(imageDataArray.length) }); } else { string = createMsg("Type_string", fileTypeString(imageData.type)); } typeLabel.setText(string); string = createMsg("Size_value", new Object[] { new Integer(imageData.width), new Integer(imageData.height) }); sizeLabel.setText(string); string = createMsg("Depth_value", new Integer( imageData.depth)); depthLabel.setText(string); string = createMsg("Transparent_pixel_value", pixelInfo(imageData.transparentPixel)); transparentPixelLabel.setText(string); string = createMsg("Time_to_load_value", new Long( loadTime)); timeToLoadLabel.setText(string); string = createMsg("Animation_size_value", new Object[] { new Integer(loader.logicalScreenWidth), new Integer(loader.logicalScreenHeight) }); screenSizeLabel.setText(string); string = createMsg("Background_pixel_value", pixelInfo(loader.backgroundPixel)); backgroundPixelLabel.setText(string); string = createMsg("Image_location_value", new Object[] { new Integer(imageData.x), new Integer(imageData.y) }); locationLabel.setText(string); string = createMsg("Disposal_value", new Object[] { new Integer(imageData.disposalMethod), disposalString(imageData.disposalMethod) }); disposalMethodLabel.setText(string); int delay = imageData.delayTime * 10; int delayUsed = visibleDelay(delay); if (delay != delayUsed) { string = createMsg("Delay_value", new Object[] { new Integer(delay), new Integer(delayUsed) }); } else { string = createMsg("Delay_used", new Integer( delay)); } delayTimeLabel.setText(string); if (loader.repeatCount == 0) { string = createMsg("Repeats_forever", new Integer(loader.repeatCount)); } else { string = createMsg("Repeats_value", new Integer( loader.repeatCount)); } repeatCountLabel.setText(string); if (imageData.palette.isDirect) { string = "Palette_direct"; } else { string = createMsg("Palette_value", new Integer( imageData.palette.getRGBs().length)); } paletteLabel.setText(string); string = createMsg("Pixel_data_value", new Object[] { new Integer(imageData.bytesPerLine), new Integer(imageData.scanlinePad), depthInfo(imageData.depth) }); dataLabel.setText(string); String data = dataHexDump(dataText.getLineDelimiter()); dataText.setText(data); // bold the first column all the way down int index = 0; while ((index = data.indexOf(":", index + 1)) != -1) dataText.setStyleRange(new StyleRange(index - INDEX_DIGITS, INDEX_DIGITS, dataText.getForeground(), dataText .getBackground(), SWT.BOLD)); statusLabel.setText(""); // Redraw both canvases. paletteCanvas.redraw(); imageCanvas.redraw(); } void paintImage(PaintEvent event) { Image paintImage = image; int transparentPixel = imageData.transparentPixel; if (transparentPixel != -1 && !transparent) { imageData.transparentPixel = -1; paintImage = new Image(display, imageData); } int w = Math.round(imageData.width * xscale); int h = Math.round(imageData.height * yscale); event.gc.drawImage(paintImage, 0, 0, imageData.width, imageData.height, ix + imageData.x, iy + imageData.y, w, h); if (showMask && (imageData.getTransparencyType() != SWT.TRANSPARENCY_NONE)) { ImageData maskImageData = imageData.getTransparencyMask(); Image maskImage = new Image(display, maskImageData); event.gc.drawImage(maskImage, 0, 0, imageData.width, imageData.height, w + 10 + ix + imageData.x, iy + imageData.y, w, h); maskImage.dispose(); } if (transparentPixel != -1 && !transparent) { imageData.transparentPixel = transparentPixel; paintImage.dispose(); } } void paintPalette(PaintEvent event) { GC gc = event.gc; gc.fillRectangle(paletteCanvas.getClientArea()); if (imageData.palette.isDirect) { // For a direct palette, display the masks. int y = py + 10; int xTab = 50; gc.drawString("rMsk", 10, y, true); gc.drawString(toHex4ByteString(imageData.palette.redMask), xTab, y, true); gc.drawString("gMsk", 10, y += 12, true); gc.drawString(toHex4ByteString(imageData.palette.greenMask), xTab, y, true); gc.drawString("bMsk", 10, y += 12, true); gc.drawString(toHex4ByteString(imageData.palette.blueMask), xTab, y, true); gc.drawString("rShf", 10, y += 12, true); gc.drawString(Integer.toString(imageData.palette.redShift), xTab, y, true); gc.drawString("gShf", 10, y += 12, true); gc.drawString(Integer.toString(imageData.palette.greenShift), xTab, y, true); gc.drawString("bShf", 10, y += 12, true); gc.drawString(Integer.toString(imageData.palette.blueShift), xTab, y, true); } else { // For an indexed palette, display the palette colors and indices. RGB[] rgbs = imageData.palette.getRGBs(); if (rgbs != null) { int xTab1 = 40, xTab2 = 100; for (int i = 0; i < rgbs.length; i++) { int y = (i + 1) * 10 + py; gc.drawString(String.valueOf(i), 10, y, true); gc.drawString(toHexByteString(rgbs[i].red) + toHexByteString(rgbs[i].green) + toHexByteString(rgbs[i].blue), xTab1, y, true); Color color = new Color(display, rgbs[i]); gc.setBackground(color); gc.fillRectangle(xTab2, y + 2, 10, 10); color.dispose(); } } } } void resizeShell(ControlEvent event) { if (image == null || shell.isDisposed()) return; resizeScrollBars(); } // Reset the scale combos to 1. void resetScaleCombos() { xscale = 1; yscale = 1; scaleXCombo.select(scaleXCombo.indexOf("1")); scaleYCombo.select(scaleYCombo.indexOf("1")); } // Reset the scroll bars to 0. void resetScrollBars() { if (image == null) return; ix = 0; iy = 0; py = 0; resizeScrollBars(); imageCanvas.getHorizontalBar().setSelection(0); imageCanvas.getVerticalBar().setSelection(0); paletteCanvas.getVerticalBar().setSelection(0); } void resizeScrollBars() { // Set the max and thumb for the image canvas scroll bars. ScrollBar horizontal = imageCanvas.getHorizontalBar(); ScrollBar vertical = imageCanvas.getVerticalBar(); Rectangle canvasBounds = imageCanvas.getClientArea(); int width = Math.round(imageData.width * xscale); if (width > canvasBounds.width) { // The image is wider than the canvas. horizontal.setEnabled(true); horizontal.setMaximum(width); horizontal.setThumb(canvasBounds.width); horizontal.setPageIncrement(canvasBounds.width); } else { // The canvas is wider than the image. horizontal.setEnabled(false); if (ix != 0) { // Make sure the image is completely visible. ix = 0; imageCanvas.redraw(); } } int height = Math.round(imageData.height * yscale); if (height > canvasBounds.height) { // The image is taller than the canvas. vertical.setEnabled(true); vertical.setMaximum(height); vertical.setThumb(canvasBounds.height); vertical.setPageIncrement(canvasBounds.height); } else { // The canvas is taller than the image. vertical.setEnabled(false); if (iy != 0) { // Make sure the image is completely visible. iy = 0; imageCanvas.redraw(); } } // Set the max and thumb for the palette canvas scroll bar. vertical = paletteCanvas.getVerticalBar(); if (imageData.palette.isDirect) { vertical.setEnabled(false); } else { // indexed palette canvasBounds = paletteCanvas.getClientArea(); int paletteHeight = imageData.palette.getRGBs().length * 10 + 20; // 10 // pixels // each // index // + 20 // for // margins. vertical.setEnabled(true); vertical.setMaximum(paletteHeight); vertical.setThumb(canvasBounds.height); vertical.setPageIncrement(canvasBounds.height); } } /* * Called when the image canvas" horizontal scrollbar is selected. */ void scrollHorizontally(ScrollBar scrollBar) { if (image == null) return; Rectangle canvasBounds = imageCanvas.getClientArea(); int width = Math.round(imageData.width * xscale); int height = Math.round(imageData.height * yscale); if (width > canvasBounds.width) { // Only scroll if the image is bigger than the canvas. int x = -scrollBar.getSelection(); if (x + width < canvasBounds.width) { // Don"t scroll past the end of the image. x = canvasBounds.width - width; } imageCanvas.scroll(x, iy, ix, iy, width, height, false); ix = x; } } /* * Called when the image canvas" vertical scrollbar is selected. */ void scrollVertically(ScrollBar scrollBar) { if (image == null) return; Rectangle canvasBounds = imageCanvas.getClientArea(); int width = Math.round(imageData.width * xscale); int height = Math.round(imageData.height * yscale); if (height > canvasBounds.height) { // Only scroll if the image is bigger than the canvas. int y = -scrollBar.getSelection(); if (y + height < canvasBounds.height) { // Don"t scroll past the end of the image. y = canvasBounds.height - height; } imageCanvas.scroll(ix, y, ix, iy, width, height, false); iy = y; } } /* * Called when the palette canvas" vertical scrollbar is selected. */ void scrollPalette(ScrollBar scrollBar) { if (image == null) return; Rectangle canvasBounds = paletteCanvas.getClientArea(); int paletteHeight = imageData.palette.getRGBs().length * 10 + 20; if (paletteHeight > canvasBounds.height) { // Only scroll if the palette is bigger than the canvas. int y = -scrollBar.getSelection(); if (y + paletteHeight < canvasBounds.height) { // Don"t scroll past the end of the palette. y = canvasBounds.height - paletteHeight; } paletteCanvas.scroll(0, y, 0, py, paletteWidth, paletteHeight, false); py = y; } } /* * Return a String containing a line-by-line dump of the data in the current * imageData. The lineDelimiter parameter must be a string of length 1 or 2. */ String dataHexDump(String lineDelimiter) { if (image == null) return ""; char[] dump = new char[imageData.height * (6 + 3 * imageData.bytesPerLine + lineDelimiter.length())]; int index = 0; for (int i = 0; i < imageData.data.length; i++) { if (i % imageData.bytesPerLine == 0) { int line = i / imageData.bytesPerLine; dump[index++] = Character.forDigit(line / 1000 % 10, 10); dump[index++] = Character.forDigit(line / 100 % 10, 10); dump[index++] = Character.forDigit(line / 10 % 10, 10); dump[index++] = Character.forDigit(line % 10, 10); dump[index++] = ":"; dump[index++] = " "; } byte b = imageData.data[i]; dump[index++] = Character.forDigit((b & 0xF0) >> 4, 16); dump[index++] = Character.forDigit(b & 0x0F, 16); dump[index++] = " "; if ((i + 1) % imageData.bytesPerLine == 0) { dump[index++] = lineDelimiter.charAt(0); if (lineDelimiter.length() > 1) dump[index++] = lineDelimiter.charAt(1); } } String result = ""; try { result = new String(dump); } catch (OutOfMemoryError e) { /* Too much data to display in the text widget - truncate at 4M. */ result = new String(dump, 0, 4 * 1024 * 1024) + "\n ...data dump truncated at 4M..."; } return result; } /* * Open an error dialog displaying the specified information. */ void showErrorDialog(String operation, String filename, Throwable e) { MessageBox box = new MessageBox(shell, SWT.ICON_ERROR); String message = createMsg("Error", new String[] { operation, filename }); String errorMessage = ""; if (e != null) { if (e instanceof SWTException) { SWTException swte = (SWTException) e; errorMessage = swte.getMessage(); if (swte.throwable != null) { errorMessage += ":\n" + swte.throwable.toString(); } } else if (e instanceof SWTError) { SWTError swte = (SWTError) e; errorMessage = swte.getMessage(); if (swte.throwable != null) { errorMessage += ":\n" + swte.throwable.toString(); } } else { errorMessage = e.toString(); } } box.setMessage(message + errorMessage); box.open(); } /* * Open a dialog asking the user for more information on the type of BMP * file to save. */ int showBMPDialog() { final int[] bmpType = new int[1]; bmpType[0] = SWT.IMAGE_BMP; SelectionListener radioSelected = new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { Button radio = (Button) event.widget; if (radio.getSelection()) bmpType[0] = ((Integer) radio.getData()).intValue(); } }; // need to externalize strings final Shell dialog = new Shell(shell, SWT.DIALOG_TRIM); dialog.setText("Save_as"); dialog.setLayout(new GridLayout()); Label label = new Label(dialog, SWT.NONE); label.setText("Save_as"); Button radio = new Button(dialog, SWT.RADIO); radio.setText("Save_as_type_no_compress"); radio.setSelection(true); radio.setData(new Integer(SWT.IMAGE_BMP)); radio.addSelectionListener(radioSelected); radio = new Button(dialog, SWT.RADIO); radio.setText("Save_as_type_rle_compress"); radio.setData(new Integer(SWT.IMAGE_BMP_RLE)); radio.addSelectionListener(radioSelected); radio = new Button(dialog, SWT.RADIO); radio.setText("Save_as_type_os2"); radio.setData(new Integer(SWT.IMAGE_OS2_BMP)); radio.addSelectionListener(radioSelected); label = new Label(dialog, SWT.SEPARATOR | SWT.HORIZONTAL); label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Button ok = new Button(dialog, SWT.PUSH); ok.setText("OK"); GridData data = new GridData(); data.horizontalAlignment = SWT.CENTER; data.widthHint = 75; ok.setLayoutData(data); ok.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { dialog.close(); } }); dialog.pack(); dialog.open(); while (!dialog.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } return bmpType[0]; } /* * Return a String describing how to analyze the bytes in the hex dump. */ static String depthInfo(int depth) { Object[] args = { new Integer(depth), "" }; switch (depth) { case 1: args[1] = createMsg("Multi_pixels", new Object[] { new Integer(8), " [01234567]" }); break; case 2: args[1] = createMsg("Multi_pixels", new Object[] { new Integer(4), "[00112233]" }); break; case 4: args[1] = createMsg("Multi_pixels", new Object[] { new Integer(2), "[00001111]" }); break; case 8: args[1] = "One_byte"; break; case 16: args[1] = createMsg("Multi_bytes", new Integer(2)); break; case 24: args[1] = createMsg("Multi_bytes", new Integer(3)); break; case 32: args[1] = createMsg("Multi_bytes", new Integer(4)); break; default: args[1] = "Unsupported_lc"; } return createMsg("Depth_info", args); } /* * Return the specified number of milliseconds. If the specified number of * milliseconds is too small to see a visual change, then return a higher * number. */ static int visibleDelay(int ms) { if (ms < 20) return ms + 30; if (ms < 30) return ms + 10; return ms; } /* * Return the specified byte value as a hex string, preserving leading 0"s. */ static String toHexByteString(int i) { if (i <= 0x0f) return "0" + Integer.toHexString(i); return Integer.toHexString(i & 0xff); } /* * Return the specified 4-byte value as a hex string, preserving leading * 0"s. (a bit "brute force"... should probably use a loop...) */ static String toHex4ByteString(int i) { String hex = Integer.toHexString(i); if (hex.length() == 1) return "0000000" + hex; if (hex.length() == 2) return "000000" + hex; if (hex.length() == 3) return "00000" + hex; if (hex.length() == 4) return "0000" + hex; if (hex.length() == 5) return "000" + hex; if (hex.length() == 6) return "00" + hex; if (hex.length() == 7) return "0" + hex; return hex; } /* * Return a String describing the specified transparent or background pixel. */ static String pixelInfo(int pixel) { if (pixel == -1) return pixel + " (" + "None_lc" + ")"; else return pixel + " (0x" + Integer.toHexString(pixel) + ")"; } /* * Return a String describing the specified disposal method. */ static String disposalString(int disposalMethod) { switch (disposalMethod) { case SWT.DM_FILL_NONE: return "None_lc"; case SWT.DM_FILL_BACKGROUND: return "Background_lc"; case SWT.DM_FILL_PREVIOUS: return "Previous_lc"; } return "Unspecified_lc"; } /* * Return a String describing the specified image file type. */ String fileTypeString(int filetype) { if (filetype == SWT.IMAGE_BMP) return "BMP"; if (filetype == SWT.IMAGE_BMP_RLE) return "RLE" + imageData.depth + " BMP"; if (filetype == SWT.IMAGE_OS2_BMP) return "OS/2 BMP"; if (filetype == SWT.IMAGE_GIF) return "GIF"; if (filetype == SWT.IMAGE_ICO) return "ICO"; if (filetype == SWT.IMAGE_JPEG) return "JPEG"; if (filetype == SWT.IMAGE_PNG) return "PNG"; return "Unknown_ac"; } /* * Return the specified file"s image type, based on its extension. Note that * this is not a very robust way to determine image type, and it is only to * be used in the absence of any better method. */ int determineFileType(String filename) { String ext = filename.substring(filename.lastIndexOf(".") + 1); if (ext.equalsIgnoreCase("bmp")) { return showBMPDialog(); } if (ext.equalsIgnoreCase("gif")) return SWT.IMAGE_GIF; if (ext.equalsIgnoreCase("ico")) return SWT.IMAGE_ICO; if (ext.equalsIgnoreCase("jpg") || ext.equalsIgnoreCase("jpeg")) return SWT.IMAGE_JPEG; if (ext.equalsIgnoreCase("png")) return SWT.IMAGE_PNG; return SWT.IMAGE_UNDEFINED; } static String createMsg(String msg, Object[] args) { MessageFormat formatter = new MessageFormat(msg); return formatter.format(args); } static String createMsg(String msg, Object arg) { MessageFormat formatter = new MessageFormat(msg); return formatter.format(new Object[] { arg }); }
}
</source>
Image Basics
<source lang="java">
/******************************************************************************
* All Right Reserved. * Copyright (c) 1998, 2004 Jackwind Li Guojie * * Created on 2004-4-21 18:47:54 by JACK * $Id$ * *****************************************************************************/
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class ImageBasics {
Display display = new Display(); Shell shell = new Shell(display); public ImageBasics() { Image image = new Image(shell.getDisplay(), "jexp.gif"); shell.setImage(image); shell.pack(); shell.open(); //textUser.forceFocus(); // Set up the event loop. while (!shell.isDisposed()) { if (!display.readAndDispatch()) { // If no more entries in event queue display.sleep(); } } display.dispose(); } private void init() { } public static void main(String[] args) { new ImageBasics(); }
}
</source>
Rotate and flip an image
<source lang="java">
/*
* This snippet was adapted from org.eclipse.draw2d.ImageUtilities in * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.draw2d/?cvsroot=Tools_Project * by Pratik Shah. * * example snippet: rotate and flip an image * * For a list of all SWT example snippets see * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets */
import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class Snippet139 {
static ImageData rotate(ImageData srcData, int direction) { int bytesPerPixel = srcData.bytesPerLine / srcData.width; int destBytesPerLine = (direction == SWT.DOWN) ? srcData.width * bytesPerPixel : srcData.height * bytesPerPixel; byte[] newData = new byte[srcData.data.length]; int width = 0, height = 0; for (int srcY = 0; srcY < srcData.height; srcY++) { for (int srcX = 0; srcX < srcData.width; srcX++) { int destX = 0, destY = 0, destIndex = 0, srcIndex = 0; switch (direction) { case SWT.LEFT: // left 90 degrees destX = srcY; destY = srcData.width - srcX - 1; width = srcData.height; height = srcData.width; break; case SWT.RIGHT: // right 90 degrees destX = srcData.height - srcY - 1; destY = srcX; width = srcData.height; height = srcData.width; break; case SWT.DOWN: // 180 degrees destX = srcData.width - srcX - 1; destY = srcData.height - srcY - 1; width = srcData.width; height = srcData.height; break; } destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel); srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel); System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel); } } // destBytesPerLine is used as scanlinePad to ensure that no padding is // required return new ImageData(width, height, srcData.depth, srcData.palette, destBytesPerLine, newData); } static ImageData flip(ImageData srcData, boolean vertical) { int bytesPerPixel = srcData.bytesPerLine / srcData.width; int destBytesPerLine = srcData.width * bytesPerPixel; byte[] newData = new byte[srcData.data.length]; for (int srcY = 0; srcY < srcData.height; srcY++) { for (int srcX = 0; srcX < srcData.width; srcX++) { int destX = 0, destY = 0, destIndex = 0, srcIndex = 0; if (vertical) { destX = srcX; destY = srcData.height - srcY - 1; } else { destX = srcData.width - srcX - 1; destY = srcY; } destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel); srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel); System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel); } } // destBytesPerLine is used as scanlinePad to ensure that no padding is // required return new ImageData(srcData.width, srcData.height, srcData.depth, srcData.palette, destBytesPerLine, newData); } public static void main(String[] args) { Display display = new Display(); // create an image with the word "hello" on it final Image image0 = new Image(display, 50, 30); GC gc = new GC(image0); gc.setBackground(display.getSystemColor(SWT.COLOR_RED)); gc.fillRectangle(image0.getBounds()); gc.drawString("hello", 5, 5, true); gc.dispose(); ImageData data = image0.getImageData(); // rotate and flip this image final Image image1 = new Image(display, rotate(data, SWT.LEFT)); final Image image2 = new Image(display, rotate(data, SWT.RIGHT)); final Image image3 = new Image(display, rotate(data, SWT.DOWN)); final Image image4 = new Image(display, flip(data, true)); final Image image5 = new Image(display, flip(data, false)); Shell shell = new Shell(display); // draw the results on the shell shell.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { e.gc.drawText("Original Image:", 10, 10, true); e.gc.drawImage(image0, 10, 40); e.gc.drawText("Left, Right, 180:", 10, 80, true); e.gc.drawImage(image1, 10, 110); e.gc.drawImage(image2, 50, 110); e.gc.drawImage(image3, 90, 110); e.gc.drawText("Flipped Vertical, Horizontal:", 10, 170, true); e.gc.drawImage(image4, 10, 200); e.gc.drawImage(image5, 70, 200); } }); shell.setSize(300, 300); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } image0.dispose(); image1.dispose(); image2.dispose(); image3.dispose(); image4.dispose(); image5.dispose(); display.dispose(); }
}
</source>
Set icons with different resolutions
<source lang="java">
/*
* example snippet: set icons with different resolutions * * For a list of all SWT example snippets see * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets */
import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class Snippet138 {
public static void main(String[] args) { Display display = new Display(); Image small = new Image(display, 16, 16); GC gc = new GC(small); gc.setBackground(display.getSystemColor(SWT.COLOR_RED)); gc.fillArc(0, 0, 16, 16, 45, 270); gc.dispose(); Image large = new Image(display, 32, 32); gc = new GC(large); gc.setBackground(display.getSystemColor(SWT.COLOR_RED)); gc.fillArc(0, 0, 32, 32, 45, 270); gc.dispose(); /* * Provide different resolutions for icons to get high quality rendering * wherever the OS needs large icons. For example, the ALT+TAB window on * certain systems uses a larger icon. */ Shell shell = new Shell(display); shell.setText("Small and Large icons"); shell.setImages(new Image[] { small, large }); /* * No large icon: the OS will scale up the small icon when it needs a * large one. */ Shell shell2 = new Shell(display); shell2.setText("Small icon"); shell2.setImage(small); shell.open(); shell2.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
}
</source>
SWT and Image
<source lang="java">
/* SWT/JFace in Action GUI Design with Eclipse 3.0 Matthew Scarpino, Stephen Holder, Stanford Ng, and Laurent Mihalkovic ISBN: 1932394273 Publisher: Manning
- /
import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.graphics.RGB; public class Ch7_Images {
public static void main(String[] args) { int numRows = 6, numCols = 11, pix = 20; PaletteData pd = new PaletteData(new RGB[] { new RGB(0x00, 0x00, 0x00), new RGB(0x80, 0x80, 0x80), new RGB(0xFF, 0xFF, 0xFF) }); ImageData[] flagArray = new ImageData[3]; for (int frame = 0; frame < flagArray.length; frame++) { flagArray[frame] = new ImageData(pix * numCols, pix * numRows, 4, pd); flagArray[frame].delayTime = 10; for (int x = 0; x < pix * numCols; x++) { for (int y = 0; y < pix * numRows; y++) { int value = (((x / pix) % 3) + (3 - ((y / pix) % 3)) + frame) % 3; flagArray[frame].setPixel(x, y, value); } } } ImageLoader gifloader = new ImageLoader(); ByteArrayOutputStream flagByte[] = new ByteArrayOutputStream[3]; byte[][] gifarray = new byte[3][]; gifloader.data = flagArray; for (int i = 0; i < 3; i++) { flagByte[i] = new ByteArrayOutputStream(); flagArray[0] = flagArray[i]; gifloader.save(flagByte[i], SWT.IMAGE_GIF); gifarray[i] = flagByte[i].toByteArray(); } byte[] gif = new byte[4628]; System.arraycopy(gifarray[0], 0, gif, 0, 61); System.arraycopy(new byte[] { 33, (byte) 255, 11 }, 0, gif, 61, 3); System.arraycopy("NETSCAPE2.0".getBytes(), 0, gif, 64, 11); System.arraycopy(new byte[] { 3, 1, -24, 3, 0, 33, -7, 4, -24 }, 0, gif, 75, 9); System.arraycopy(gifarray[0], 65, gif, 84, 1512); for (int i = 1; i < 3; i++) { System.arraycopy(gifarray[i], 61, gif, 1516 * i + 80, 3); gif[1516 * i + 83] = (byte) -24; System.arraycopy(gifarray[i], 65, gif, 1516 * i + 84, 1512); } try { DataOutputStream in = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(new File( "FlagGIF.gif")))); in.write(gif, 0, gif.length); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
}
</source>
Transfer type to transfer SWT ImageData objects.
<source lang="java">
/**
* Transfer type to transfer SWT ImageData objects. */
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.ByteArrayTransfer; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.TransferData; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; public class ImageTransfer extends ByteArrayTransfer {
private static final String TYPENAME = "imagedata"; private static final int TYPEID = registerType(TYPENAME); private static ImageTransfer _instance = new ImageTransfer(); public static ImageTransfer getInstance() { return _instance; } public void javaToNative(Object object, TransferData transferData) { if (!checkImage(object) || !isSupportedType(transferData)) { DND.error(DND.ERROR_INVALID_DATA); } ImageData imdata = (ImageData) object; try { // write data to a byte array and then ask super to convert to // pMedium ByteArrayOutputStream out = new ByteArrayOutputStream(); DataOutputStream writeOut = new DataOutputStream(out); ImageLoader loader = new ImageLoader(); loader.data = new ImageData[] { imdata }; loader.save(writeOut, SWT.IMAGE_BMP); writeOut.close(); byte[] buffer = out.toByteArray(); super.javaToNative(buffer, transferData); out.close(); } catch (IOException e) { } } public Object nativeToJava(TransferData transferData) { if (!isSupportedType(transferData)) return null; byte[] buffer = (byte[]) super.nativeToJava(transferData); if (buffer == null) return null; ImageData imdata; try { ByteArrayInputStream in = new ByteArrayInputStream(buffer); DataInputStream readIn = new DataInputStream(in); imdata = new ImageData(readIn); readIn.close(); } catch (IOException ex) { return null; } return imdata; } protected String[] getTypeNames() { return new String[] { TYPENAME }; } protected int[] getTypeIds() { return new int[] { TYPEID }; } boolean checkImage(Object object) { return (object != null && object instanceof ImageData); } protected boolean validate(Object object) { return checkImage(object); }
}
</source>