Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/port80/swt/apps/ImageViewer.java


1   package com.port80.swt.apps;
2   
3   import java.io.InputStream;
4   import java.net.URL;
5   import java.text.MessageFormat;
6   
7   import org.eclipse.swt.SWT;
8   import org.eclipse.swt.SWTException;
9   import org.eclipse.swt.custom.StyledText;
10  import org.eclipse.swt.events.ControlAdapter;
11  import org.eclipse.swt.events.ControlEvent;
12  import org.eclipse.swt.events.DisposeEvent;
13  import org.eclipse.swt.events.DisposeListener;
14  import org.eclipse.swt.events.MouseEvent;
15  import org.eclipse.swt.events.MouseMoveListener;
16  import org.eclipse.swt.events.PaintEvent;
17  import org.eclipse.swt.events.PaintListener;
18  import org.eclipse.swt.events.SelectionAdapter;
19  import org.eclipse.swt.events.SelectionEvent;
20  import org.eclipse.swt.events.ShellAdapter;
21  import org.eclipse.swt.events.ShellEvent;
22  import org.eclipse.swt.graphics.Color;
23  import org.eclipse.swt.graphics.Cursor;
24  import org.eclipse.swt.graphics.Font;
25  import org.eclipse.swt.graphics.GC;
26  import org.eclipse.swt.graphics.Image;
27  import org.eclipse.swt.graphics.ImageData;
28  import org.eclipse.swt.graphics.ImageLoader;
29  import org.eclipse.swt.graphics.RGB;
30  import org.eclipse.swt.graphics.Rectangle;
31  import org.eclipse.swt.layout.GridData;
32  import org.eclipse.swt.layout.GridLayout;
33  import org.eclipse.swt.layout.RowLayout;
34  import org.eclipse.swt.widgets.Button;
35  import org.eclipse.swt.widgets.Canvas;
36  import org.eclipse.swt.widgets.Combo;
37  import org.eclipse.swt.widgets.Composite;
38  import org.eclipse.swt.widgets.Dialog;
39  import org.eclipse.swt.widgets.Display;
40  import org.eclipse.swt.widgets.FileDialog;
41  import org.eclipse.swt.widgets.Label;
42  import org.eclipse.swt.widgets.Menu;
43  import org.eclipse.swt.widgets.MenuItem;
44  import org.eclipse.swt.widgets.MessageBox;
45  import org.eclipse.swt.widgets.Sash;
46  import org.eclipse.swt.widgets.ScrollBar;
47  import org.eclipse.swt.widgets.Shell;
48  import org.eclipse.swt.widgets.Text;
49  
50  import com.port80.eclipse.util.UIUtil;
51  import com.port80.util.Sprint;
52  import com.port80.util.SystemWatch;
53  
54  /**
55   * An image viewer using swt.
56   * 
57   * <li>A GC can be created on an Image and then use it to draw into the Image.</li>
58   * <li>To display very large image, pixel data is loaded into ImageData and then
59   * tiles of the data are used to create Image's for display.</li>
60   * <li>The current development version, for now, this is same as ImageViewer1.</li>
61   * 
62   * @author chrisl
63   */
64  public class ImageViewer {
65  
66    ////////////////////////////////////////////////////////////////////////
67  
68    private static final String NAME = "ImageViewer";
69  
70    private static final String[] IMAGE_SUFFICES =
71      new String[] {
72        "*.bmp; *.gif; *.ico; *.jpg; *.pcx; *.png; *.tif",
73        "*.bmp",
74        "*.gif",
75        "*.ico",
76        "*.jpg",
77        "*.pcx",
78        "*.png",
79        "*.tif" };
80  
81    private static final String[] IMAGE_FILTER_NAMES =
82      new String[] {
83        i18n("All_images") + " (bmp, gif, ico, jpg, pcx, png, tif)",
84        "BMP (*.bmp)",
85        "GIF (*.gif)",
86        "ICO (*.ico)",
87        "JPEG (*.jpg)",
88        "PCX (*.pcx)",
89        "PNG (*.png)",
90        "TIFF (*.tif)" };
91  
92    ////////////////////////////////////////////////////////////////////////
93  
94    private Display fDisplay;
95    private Shell fShell;
96    private Font fFont;
97    private Color fWhiteColor, fBlackColor, fLightColor;
98    private Cursor fCrossCursor;
99    private GC fImageCanvasGC;
100   private Image fImage;
101   private ImageData[] fImageDatas;
102   private ImageData fImageData; // the currently-displayed image data
103   private int fImageDataIndex;
104   private double fScale;
105   private int fX = 0, fY = 0; // Top left corner, used to scroll the image and palette
106   private String fLastPath;
107   private boolean fTransparent, fShowMask;
108   private boolean fIncremental;
109   //
110   private long fLoadTime;
111   private String fFilename;
112   //
113   // Widgets
114   private Combo fScaleCombo;
115   private Canvas fImageCanvas;
116   private Sash fSash;
117   private Label fDataLabel, fStatusLabel;
118   private StyledText fDataText;
119   private Label fInfoLabel;
120   //
121   private boolean isResizing;
122 
123   ////////////////////////////////////////////////////////////////////////
124 
125   public static void main(String[] args) {
126 
127     Display display = new Display();
128     ImageViewer app = new ImageViewer();
129     Shell shell = app.open(display);
130 
131     while (!shell.isDisposed())
132       if (!display.readAndDispatch())
133         display.sleep();
134     display.dispose();
135   }
136 
137   ////////////////////////////////////////////////////////////////////////
138 
139   public Shell open(Display display) {
140 
141     // Create a window and set its title.
142     this.fDisplay = display;
143     this.fShell = new Shell(fDisplay);
144 
145     // Create colors and fonts.
146     fWhiteColor = new Color(display, 255, 255, 255);
147     fBlackColor = new Color(display, 0, 0, 0);
148     fLightColor = new Color(display, 0xd8, 0xd8, 0xd8);
149     fFont = new Font(display, "verdana", 11, 0);
150     fCrossCursor = new Cursor(display, SWT.CURSOR_CROSS);
151 
152     fShell.setText(NAME);
153 
154     // Hook resize and dispose listeners.
155     fShell.addControlListener(new ControlAdapter() {
156       public void controlResized(ControlEvent event) {
157         resizeShell(event);
158       }
159     });
160     fShell.addShellListener(new ShellAdapter() {
161       public void shellClosed(ShellEvent e) {
162         e.doit = true;
163       }
164     });
165     fShell.addDisposeListener(new DisposeListener() {
166       public void widgetDisposed(DisposeEvent e) {
167         dispose();
168       }
169     });
170 
171     // Add a menu bar and widgets.
172     createMenuBar();
173     createWidgets();
174     fShell.pack();
175 
176     // Create a GC for drawing, and hook the listener to dispose it.
177     fImageCanvasGC = new GC(fImageCanvas);
178     fImageCanvas.addDisposeListener(new DisposeListener() {
179       public void widgetDisposed(DisposeEvent e) {
180         disposeImageCanvasGC();
181       }
182     });
183 
184     // Open the window
185     fShell.open();
186     return fShell;
187   }
188 
189   void dispose() {
190     // Clean up.
191     fWhiteColor.dispose();
192     fBlackColor.dispose();
193     fLightColor.dispose();
194     fFont.dispose();
195     fCrossCursor.dispose();
196   }
197 
198   void disposeImageCanvasGC() {
199     fImageCanvasGC.dispose();
200   }
201 
202   Shell getShell() {
203     return fShell;
204   }
205 
206   Display getDisplay() {
207     return fDisplay;
208   }
209 
210   void createWidgets() {
211     // Add the widgets to the shell in a grid layout.
212     GridLayout layout = new GridLayout();
213     layout.marginHeight = 0;
214     layout.numColumns = 2;
215     fShell.setLayout(layout);
216 
217     // Add a composite to contain some control widgets across the top.
218     Composite controls = new Composite(fShell, SWT.NULL);
219     RowLayout rowLayout = new RowLayout();
220     rowLayout.marginTop = 2;
221     rowLayout.marginBottom = 2;
222     rowLayout.spacing = 8;
223     controls.setLayout(rowLayout);
224     controls.setLayoutData(UIUtil.fillCell(1, 1, false, false));
225 
226     // RowLayout is top aligned. To make label text at middle, need to set label height.
227     fInfoLabel = new Label(fShell, SWT.NULL);
228     fInfoLabel.setToolTipText("Image info");
229     fInfoLabel.setText("Image info");
230     fInfoLabel.setLayoutData(UIUtil.fillCell(1, 1, true, false));
231     // Combo to change the x scale.
232     String[] values =
233       {
234         "5 %",
235         "10 %",
236         "25 %",
237         "33 %",
238         "50 %",
239         "75 %",
240         "100 %",
241         "125 %",
242         "133 %",
243         "150 %",
244         "175 %",
245         "200 %",
246         "300 %",
247         "500 %",
248         "750 %",
249         "1000 %",
250         };
251     fScaleCombo = new Combo(controls, SWT.DROP_DOWN);
252     for (int i = 0; i < values.length; i++) {
253       fScaleCombo.add(values[i]);
254     }
255     fScaleCombo.setToolTipText("Scale");
256     fScaleCombo.select(fScaleCombo.indexOf("100 %"));
257     fScaleCombo.addSelectionListener(new SelectionAdapter() {
258       public void widgetSelected(SelectionEvent event) {
259         scaleImage();
260       }
261     });
262 
263     // Canvas to show the image.
264     fImageCanvas = new Canvas(fShell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE);
265     fImageCanvas.setBackground(fWhiteColor);
266     fImageCanvas.setCursor(fCrossCursor);
267     fImageCanvas.setLayoutData(UIUtil.fillCell(15, 2, 1024, 768, true, true));
268     fImageCanvas.addPaintListener(new PaintListener() {
269       public void paintControl(PaintEvent event) {
270         paintImage(event);
271       }
272     });
273     fImageCanvas.addMouseMoveListener(new MouseMoveListener() {
274       public void mouseMove(MouseEvent event) {
275         showColorAt(event.x, event.y);
276       }
277     });
278 
279     // Set up the image canvas scroll bars.
280     ScrollBar horizontal = fImageCanvas.getHorizontalBar();
281     horizontal.setVisible(true);
282     horizontal.setMinimum(0);
283     horizontal.setEnabled(false);
284     horizontal.addSelectionListener(new SelectionAdapter() {
285       public void widgetSelected(SelectionEvent event) {
286         scrollHorizontally((ScrollBar) event.widget);
287       }
288     });
289     ScrollBar vertical = fImageCanvas.getVerticalBar();
290     vertical.setVisible(true);
291     vertical.setMinimum(0);
292     vertical.setEnabled(false);
293     vertical.addSelectionListener(new SelectionAdapter() {
294       public void widgetSelected(SelectionEvent event) {
295         scrollVertically((ScrollBar) event.widget);
296       }
297     });
298 
299     // Label to show status and cursor location in image.
300     fStatusLabel = new Label(fShell, SWT.NULL);
301     fStatusLabel.setText("");
302     fStatusLabel.setLayoutData(UIUtil.fillCell(1, 2, true, false));
303   }
304 
305   Menu createMenuBar() {
306     // Menu bar.
307     Menu menuBar = new Menu(fShell, SWT.BAR);
308     fShell.setMenuBar(menuBar);
309     createFileMenu(menuBar);
310     return menuBar;
311   }
312 
313   void createFileMenu(Menu menuBar) {
314     // File menu
315     MenuItem item = new MenuItem(menuBar, SWT.CASCADE);
316     item.setText("File");
317     Menu fileMenu = new Menu(fShell, SWT.DROP_DOWN);
318     item.setMenu(fileMenu);
319 
320     item = new MenuItem(fileMenu, SWT.NULL);
321     item.setText("&Open");
322     item.setAccelerator(SWT.CTRL + 'O');
323     item.addSelectionListener(new SelectionAdapter() {
324       public void widgetSelected(SelectionEvent event) {
325         openFile();
326       }
327     });
328 
329     item = new MenuItem(fileMenu, SWT.NULL);
330     item.setText("Open &URL");
331     item.setAccelerator(SWT.CTRL + 'U');
332     item.addSelectionListener(new SelectionAdapter() {
333       public void widgetSelected(SelectionEvent event) {
334         openURL();
335       }
336     });
337 
338     new MenuItem(fileMenu, SWT.SEPARATOR);
339 
340     // File -> Exit
341     item = new MenuItem(fileMenu, SWT.NULL);
342     item.setText("Exit");
343     item.addSelectionListener(new SelectionAdapter() {
344       public void widgetSelected(SelectionEvent event) {
345         getShell().close();
346       }
347     });
348 
349     // Test menu
350     item = new MenuItem(menuBar, SWT.CASCADE);
351 
352   }
353 
354   ////////////////////////////////////////////////////////////////////////
355 
356   void openFile() {
357     resetScaleCombo();
358 
359     // Get the user to choose an image file.
360     FileDialog fileChooser = new FileDialog(fShell, SWT.OPEN);
361     if (fLastPath != null)
362       fileChooser.setFilterPath(fLastPath);
363     fileChooser.setFilterExtensions(IMAGE_SUFFICES);
364     fileChooser.setFilterNames(IMAGE_FILTER_NAMES);
365     String filename = fileChooser.open();
366     fLastPath = fileChooser.getFilterPath();
367     if (filename == null)
368       return;
369 
370     Cursor waitCursor = new Cursor(fDisplay, SWT.CURSOR_WAIT);
371     fShell.setCursor(waitCursor);
372     fImageCanvas.setCursor(waitCursor);
373     try {
374       clear();
375       ImageLoader loader = new ImageLoader();
376       // Read the new image(s) from the chosen file.
377       SystemWatch timer = new SystemWatch().start();
378       long startTime = System.currentTimeMillis();
379       fImageDatas = loader.load(filename);
380       fLoadTime = System.currentTimeMillis() - startTime;
381       System.err.println(NAME + ".open(): load time=" + timer.stop().toString());
382       if (fImageDatas.length > 0) {
383         // Cache the filename.
384         fFilename = filename;
385 
386         // Display the first image in the file.
387         fImageDataIndex = 0;
388         displayImage(fImageDatas[fImageDataIndex]);
389         resetScrollBars();
390       }
391     } catch (SWTException e) {
392       showErrorDialog(i18n("Loading_lc"), filename, e);
393     } finally {
394       fShell.setCursor(null);
395       fImageCanvas.setCursor(fCrossCursor);
396       waitCursor.dispose();
397     }
398   }
399 
400   void openURL() {
401     resetScaleCombo();
402 
403     // Get the user to choose an image URL.
404     TextPrompter textPrompter = new TextPrompter(fShell, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
405     textPrompter.setText(i18n("OpenURLDialog"));
406     textPrompter.setMessage(i18n("EnterURL"));
407     String urlname = textPrompter.open();
408     if (urlname == null)
409       return;
410 
411     Cursor waitCursor = new Cursor(fDisplay, SWT.CURSOR_WAIT);
412     fShell.setCursor(waitCursor);
413     fImageCanvas.setCursor(waitCursor);
414     try {
415       clear();
416       URL url = new URL(urlname);
417       InputStream stream = url.openStream();
418       ImageLoader loader = new ImageLoader();
419       // Read the new image(s) from the chosen file.
420       long startTime = System.currentTimeMillis();
421       fImageDatas = loader.load(stream);
422       fLoadTime = System.currentTimeMillis() - startTime;
423       if (fImageDatas.length > 0) {
424         fFilename = null;
425         // Display the first image in the file.
426         fImageDataIndex = 0;
427         displayImage(fImageDatas[fImageDataIndex]);
428         resetScrollBars();
429       }
430     } catch (Exception e) {
431       showErrorDialog(i18n("Loading_lc"), urlname, e);
432     } finally {
433       fShell.setCursor(null);
434       fImageCanvas.setCursor(fCrossCursor);
435       waitCursor.dispose();
436     }
437   }
438 
439   void displayImage(ImageData newImageData) {
440     // Dispose of the old image, if there was one.
441     if (fImage != null)
442       fImage.dispose();
443 
444     try {
445       // Cache the new image and imageData.
446       fImage = new Image(fDisplay, newImageData);
447       fImageData = newImageData;
448     } catch (SWTException e) {
449       showErrorDialog(i18n("Creating_from") + " ", fFilename, e);
450       fImage = null;
451       return;
452     }
453 
454     // Update the widgets with the new image info.
455     String string = createMsg(i18n("Analyzer_on"), fFilename);
456     fShell.setText(string);
457 
458     fInfoLabel.setText(
459       fFilename
460         + ": w="
461         + fImageData.width
462         + ", h="
463         + fImageData.height
464         + ", depth="
465         + fImageData.depth
466         + Sprint.f(" (%.2f)", fLoadTime / 1000f));
467     fImageCanvas.redraw();
468   }
469 
470   void paintImage(PaintEvent event) {
471     if (true)
472       System.err.println(
473         NAME
474           + ".paintImage(): event="
475           + event.x
476           + ","
477           + event.y
478           + ","
479           + event.width
480           + ","
481           + event.height
482           + ", fX,fY="
483           + fX
484           + ","
485           + fY);
486     if (fImageData == null)
487       return;
488     int w = fImageData.width;
489     int h = fImageData.height;
490     event.gc.drawImage(fImage, 0, 0, w, h, fX + fImageData.x, fY + fImageData.y, w, h);
491   }
492 
493   /*
494    * Called when the mouse moves in the image canvas.
495    * Show the color of the image at the point under the mouse.
496    */
497   void showColorAt(int mx, int my) {
498     if (fImage == null)
499       return;
500     int x = mx - fImageData.x - fX;
501     int y = my - fImageData.y - fY;
502     showColorForPixel(x, y);
503   }
504 
505   /*
506    * Set the status label to show color information
507    * for the specified pixel in the image.
508    */
509   void showColorForPixel(int x, int y) {
510     if (x >= 0 && x < fImageData.width && y >= 0 && y < fImageData.height) {
511       int pixel = fImageData.getPixel(x, y);
512       RGB rgb = fImageData.palette.getRGB(pixel);
513 
514       Object[] args =
515         { new Integer(x), new Integer(y), new Integer(pixel), Integer.toHexString(pixel), rgb };
516       if (pixel == fImageData.transparentPixel) {
517         fStatusLabel.setText(createMsg("Color at transparent pixel: ", args));
518       } else {
519         fStatusLabel.setText(Sprint.f("Color at: %d,%d=%06x").a(x).a(y).a(pixel).end());
520       }
521     } else {
522       fStatusLabel.setText("");
523     }
524   }
525 
526   /*
527    * Called when a mouse down or key press is detected
528    * in the data text. Show the color of the pixel at
529    * the caret position in the data text.
530    */
531   void showColorForData() {
532   }
533 
534   ////////////////////////////////////////////////////////////////////////
535 
536   /*
537    * Called when the image canvas' horizontal scrollbar is selected.
538    */
539   void scrollHorizontally(ScrollBar scrollBar) {
540     if (fImage == null)
541       return;
542     Rectangle canvasBounds = fImageCanvas.getClientArea();
543     int width = (int) Math.round(fImageData.width);
544     int height = (int) Math.round(fImageData.height);
545     if (width > canvasBounds.width) {
546       // Only scroll if the image is bigger than the canvas.
547       int x = -scrollBar.getSelection();
548       if (x + width < canvasBounds.width) {
549         // Don't scroll past the end of the image.
550         x = canvasBounds.width - width;
551       }
552       fImageCanvas.scroll(x, fY, fX, fY, width, height, false);
553       fX = x;
554     }
555   }
556 
557   /*
558    * Called when the image canvas' vertical scrollbar is selected.
559    */
560   void scrollVertically(ScrollBar scrollBar) {
561     if (fImage == null)
562       return;
563     Rectangle canvasBounds = fImageCanvas.getClientArea();
564     int width = (int) Math.round(fImageData.width);
565     int height = (int) Math.round(fImageData.height);
566     if (height > canvasBounds.height) {
567       // Only scroll if the image is bigger than the canvas.
568       int y = -scrollBar.getSelection();
569       if (y + height < canvasBounds.height) {
570         // Don't scroll past the end of the image.
571         y = canvasBounds.height - height;
572       }
573       fImageCanvas.scroll(fX, y, fX, fY, width, height, false);
574       fY = y;
575     }
576   }
577 
578   /*
579    * Called when the ScaleX combo selection changes.
580    */
581   void scaleImage() {
582     try {
583       String text = fScaleCombo.getText();
584       int index = text.indexOf(' ');
585       fScale = Float.parseFloat(text.substring(0, index)) / 100;
586     } catch (NumberFormatException e) {
587       fScale = 1;
588       fScaleCombo.select(fScaleCombo.indexOf("100 %"));
589     }
590     if (fImage == null)
591       return;
592     // Scale image to a new buffer.
593     fImageData = fImageDatas[fImageDataIndex];
594     if (fScale != 1) {
595       fImageData =
596         fImageData.scaledTo(
597           (int) Math.round(fImageData.width * fScale),
598           (int) Math.round(fImageData.height * fScale));
599     }
600     resizeScrollBars();
601     fX = -fImageCanvas.getHorizontalBar().getSelection();
602     fY = -fImageCanvas.getVerticalBar().getSelection();
603     displayImage(fImageData);
604   }
605 
606   // Reset the scale combos to 1.
607   void resetScaleCombo() {
608     fScale = 1;
609     fScaleCombo.select(fScaleCombo.indexOf("100 %"));
610   }
611 
612   // Reset the scroll bars to 0.
613   void resetScrollBars() {
614     if (fImage == null)
615       return;
616     fX = 0;
617     fY = 0;
618     resizeScrollBars();
619     fImageCanvas.getHorizontalBar().setSelection(0);
620     fImageCanvas.getVerticalBar().setSelection(0);
621   }
622 
623   void resizeScrollBars() {
624     // Set the max and thumb for the image canvas scroll bars.
625     ScrollBar horizontal = fImageCanvas.getHorizontalBar();
626     ScrollBar vertical = fImageCanvas.getVerticalBar();
627     Rectangle canvasBounds = fImageCanvas.getClientArea();
628     int width = (int) Math.round(fImageData.width);
629     if (width > canvasBounds.width) {
630       // The image is wider than the canvas.
631       // Set selection such as to keep top left corner of the image stationary.
632       int x = horizontal.getSelection() * width / horizontal.getMaximum();
633       horizontal.setEnabled(true);
634       horizontal.setMaximum(width);
635       horizontal.setSelection(x);
636       horizontal.setThumb(canvasBounds.width);
637       horizontal.setPageIncrement(canvasBounds.width);
638     } else {
639       // The canvas is wider than the image.
640       horizontal.setEnabled(false);
641       if (fX != 0) {
642         // Make sure the image is completely visible.
643         fX = 0;
644         fImageCanvas.redraw();
645       }
646     }
647     int height = (int) Math.round(fImageData.height);
648     if (height > canvasBounds.height) {
649       // The image is taller than the canvas.
650       // Set selection such as to keep top left corner of the image stationary.
651       vertical.setEnabled(true);
652       vertical.setMaximum(height);
653       vertical.setThumb(canvasBounds.height);
654       vertical.setPageIncrement(canvasBounds.height);
655     } else {
656       // The canvas is taller than the image.
657       vertical.setEnabled(false);
658       if (fY != 0) {
659         // Make sure the image is completely visible.
660         fY = 0;
661         fImageCanvas.redraw();
662       }
663     }
664   }
665 
666   void resizeShell(ControlEvent event) {
667     if (isResizing)
668       return;
669     if (fImage == null || fShell.isDisposed())
670       return;
671     isResizing = true;
672     resizeScrollBars();
673     isResizing = false;
674   }
675 
676   void clear() {
677     fImageDatas = null;
678     fImageData = null;
679     if (fImage != null)
680       fImage.dispose();
681     fImage = null;
682   }
683 
684   ////////////////////////////////////////////////////////////////////////
685 
686   /*
687    * Open an error dialog displaying the specified information.
688    */
689   void showErrorDialog(String operation, String filename, Exception e) {
690     MessageBox box = new MessageBox(fShell, SWT.ICON_ERROR);
691     String message = createMsg(i18n("Error"), new String[] { operation, filename });
692     String errorMessage = "";
693     if (e != null) {
694       if (e instanceof SWTException) {
695         SWTException swte = (SWTException) e;
696         errorMessage = swte.getMessage();
697         if (swte.throwable != null) {
698           errorMessage += ":\n" + swte.throwable.toString();
699         }
700       } else {
701         errorMessage = e.toString();
702       }
703     }
704     box.setMessage(message + errorMessage);
705     box.open();
706   }
707 
708   /*
709    * Return a String describing the specified image file type.
710    */
711   static String fileTypeString(int filetype) {
712     if (filetype == SWT.IMAGE_BMP)
713       return "BMP";
714     if (filetype == SWT.IMAGE_GIF)
715       return "GIF";
716     if (filetype == SWT.IMAGE_ICO)
717       return "ICO";
718     if (filetype == SWT.IMAGE_JPEG)
719       return "JPEG";
720     if (filetype == SWT.IMAGE_PNG)
721       return "PNG";
722     return i18n("Unknown_ac") + ": " + filetype;
723   }
724 
725   static String createMsg(String msg, Object arg) {
726     MessageFormat formatter = new MessageFormat(msg);
727     return formatter.format(new Object[] { arg });
728   }
729 
730   static String i18n(String str) {
731     return str;
732   }
733 
734   ////////////////////////////////////////////////////////////////////////
735 
736   class TextPrompter extends Dialog {
737     String message = "";
738     String result = null;
739     Shell dialog;
740     Text text;
741     public TextPrompter(Shell parent, int style) {
742       super(parent, style);
743     }
744     public TextPrompter(Shell parent) {
745       this(parent, SWT.APPLICATION_MODAL);
746     }
747     public String getMessage() {
748       return message;
749     }
750     public void setMessage(String string) {
751       message = string;
752     }
753     public String open() {
754       dialog = new Shell(getParent(), getStyle());
755       dialog.setText(getText());
756       dialog.setLayout(new GridLayout());
757       Label label = new Label(dialog, SWT.NULL);
758       label.setText(message);
759       label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
760       text = new Text(dialog, SWT.SINGLE | SWT.BORDER);
761       GridData data = new GridData(GridData.FILL_HORIZONTAL);
762       data.widthHint = 300;
763       text.setLayoutData(data);
764       Composite buttons = new Composite(dialog, SWT.NONE);
765       GridLayout grid = new GridLayout();
766       grid.numColumns = 2;
767       buttons.setLayout(grid);
768       buttons.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
769       Button ok = new Button(buttons, SWT.PUSH);
770       ok.setText(i18n("OK"));
771       data = new GridData();
772       data.widthHint = 75;
773       ok.setLayoutData(data);
774       ok.addSelectionListener(new SelectionAdapter() {
775         public void widgetSelected(SelectionEvent e) {
776           result = text.getText();
777           dialog.dispose();
778         }
779       });
780       Button cancel = new Button(buttons, SWT.PUSH);
781       cancel.setText(i18n("Cancel"));
782       data = new GridData();
783       data.widthHint = 75;
784       cancel.setLayoutData(data);
785       cancel.addSelectionListener(new SelectionAdapter() {
786         public void widgetSelected(SelectionEvent e) {
787           dialog.dispose();
788         }
789       });
790       dialog.setDefaultButton(ok);
791       dialog.pack();
792       dialog.open();
793       while (!dialog.isDisposed()) {
794         if (!getDisplay().readAndDispatch())
795           getDisplay().sleep();
796       }
797       return result;
798     }
799   }
800 
801   ////////////////////////////////////////////////////////////////////////
802 
803 }