Java/SWT JFace Eclipse/Image

Материал из Java эксперт
Перейти к: навигация, поиск

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>