Die Image Factory ermöglicht die Erzeugung von Images oder Buffered Images.
Die Schnittstelle `IImageFactory’ hat die folgenden Methoden:
IImage createImage(File file); IImage createImage(URL url); IImage createImage(IFactory<InputStream> inputStream); IBufferedImage createBufferedImage(int width, int height);
Eine Instanz erhält man vom Toolkit mit Hilfe der folgenden Methode:
IImageFactory getImageFactory();
Die Schnittstelle IImage
hat die folgenden
Methoden:
Dimension getSize(); void initialize(); void dispose(); boolean isDisposed(); void addDisposeListener(IDisposeListener listener); void removeDisposeListener(IDisposeListener listener);
Ein IImage
ist von
IImageConstant
abgeleitet, und kann somit überall verwendet werden, wo Image
Konstanten verwendet werden können.[25]
Wird ein Image (oder Buffered Image) von der Image Factory erzeugt, wird es automatisch in der Image Registry registriert, und ist somit für die Verwendung in Widgets unmittelbar verfügbar.
Das native Image (z.B.
org.eclipse.swt.graphics.Image
) wird erst
erzeugt, wenn es einem Widget zugewiesen, oder die Methode
getSize()
oder
initialize()
aufgerufen wurde. Wird das
Image mehrfach (für unterschiedliche Widgets) verwendet, wird
trotzdem nur eine native Image Instanz erzeugt.
Wird die dispose()
Methode auf dem Image
aufgerufen, wird das Image automatisch aus der
Image Registry entfernt
und das zugehörige native Image disposed, falls es bereits
initialisiert wurde. Das gleiche passiert, wenn auf der
Image Registry die
Methode unRegisterImage(...)
für das Image
aufgerufen wird. In beiden Fällen führen anschließend alle
Operation auf dem Image (außer
isDisposed()
) zu einem Fehler.
Images können in jedem beliebigen Thread erzeugt werden. Für
Images, welche explizit außerhalb des Ui Thread geladen werden
sollen, sollte man darauf achten, dass
ohne expliziten Aufruf der Methode
initialize()
nur ein
Image Handle erzeugt wird,
und das eigentliche Laden erst bei der ersten Verwendung im UI
Thread stattfindet.
Die Schnittstelle IBufferedImage
ist von
IImage
abgeleitet. Zusätzlich zu den
geerbten Methoden hat ein Bufferd Image die folgende weitere
Methode:
IGraphicContext getGraphicContext();
Ein Buffered Image liefert einen Graphic Context zum Zeichnen des Bildes.
Das
ImageIconSnipped
zeigt die Verwendung eines Images in Verbindung mit einem
Icon Widget:
1 public final class ImageIconSnipped implements IApplication { 2 3 @Override 4 public void start(final IApplicationLifecycle lifecycle) { 5 6 //create the root frame 7 final IFrame frame = Toolkit.createRootFrame( 8 BPF.frame("Image Icon Snipped"), 9 lifecycle); 10 frame.setLayout(FillLayout.get()); 11 12 //create a scroll composite 13 final IScrollComposite container = frame.add(BPF.scrollComposite()); 14 container.setLayout(FillLayout.get()); 15 16 //create a image from url 17 String url = "http://www.jowidgets.org/docu/images/widgets_hierarchy_1.gif"; 18 final IImage image = ImageFactory.createImage(UrlFactory.create(url)); 19 20 //use the icon widget to display the image 21 final IIcon imageIcon = container.add(BPF.icon(image)); 22 23 //remove the icon on double click from its container to test dispose 24 imageIcon.addMouseListener(new MouseAdapter() { 25 @Override 26 public void mouseDoubleClicked(final IMouseButtonEvent mouseEvent) { 27 imageIcon.dispose(); 28 container.layoutLater(); 29 } 30 }); 31 32 //dispose the image if it was removed from its container 33 imageIcon.addDisposeListener(new IDisposeListener() { 34 @Override 35 public void onDispose() { 36 image.dispose(); 37 //CHECKSTYLE:OFF 38 System.out.println("DISPOSED IMAGE"); 39 //CHECKSTYLE:ON 40 } 41 }); 42 43 //set the root frame visible 44 frame.setVisible(true); 45 } 46 }
Das image
wird auf einem
Icon Widget gesetzt (Zeile
21). Auf dem Icon Widget wird ein Listener registriert,
welcher dieses bei einem Doppeklick aus seinem Container
entfernt, wodurch es disposed wird.
In Zeile 16 bis 18 könnte man zum Beispiel auch das Folgende schreiben, um das Image aus einem File einzulesen:
1 //create a image from file 2 final String path = "C:/projects/jo-widgets/trunk/docu/images/widgets_hierarchy_1.gif"; 3 final IImage image = ImageFactory.createImage(new File(path));
Das
ImageCanvasSnipped
zeigt die Verwendung eines Images in Verbindung mit einem
Canvas:
1 public final class ImageCanvasSnipped implements IApplication { 2 3 @Override 4 public void start(final IApplicationLifecycle lifecycle) { 5 6 //create the root frame 7 final IFrame frame = Toolkit.createRootFrame(BPF.frame("Image Canvas Snipped"), lifecycle); 8 frame.setLayout(FillLayout.get()); 9 10 //create a scroll composite 11 final IScrollComposite container = frame.add(BPF.scrollComposite()); 12 container.setLayout(FillLayout.get()); 13 14 //create a image from url 15 final String url = "http://www.jowidgets.org/docu/images/widgets_hierarchy_1.gif"; 16 final IImage image = ImageFactory.createImage(UrlFactory.create(url)); 17 18 //use a canvas to display the image 19 final ICanvas canvas = container.add(BPF.canvas()); 20 21 //set the preferred size of the canvas to the image size 22 canvas.setPreferredSize(image.getSize()); 23 24 //add a paint listener to draw the image and an arrow 25 canvas.addPaintListener(new IPaintListener() { 26 @Override 27 public void paint(final IPaintEvent event) { 28 final IGraphicContext gc = event.getGraphicContext(); 29 30 //draw the image 31 gc.drawImage(image); 32 33 //draw with green color 34 gc.setForegroundColor(Colors.GREEN); 35 36 //define a polygon that shapes an arrow 37 final Point p1 = new Point(438, 205); 38 final Point p2 = new Point(464, 205); 39 final Point p3 = new Point(464, 199); 40 final Point p4 = new Point(486, 211); 41 final Point p5 = new Point(464, 223); 42 final Point p6 = new Point(464, 217); 43 final Point p7 = new Point(438, 217); 44 final Point[] polygon = new Point[] {p1, p2, p3, p4, p5, p6, p7, p1}; 45 46 //fill the polygon 47 gc.fillPolygon(polygon); 48 } 49 }); 50 51 //set the root frame visible 52 frame.setVisible(true); 53 } 54 }
Das Image wird mit Hilfe eine Canvas gezeichnet (Zeile 31). Anschließend wird auf der Grafik ein grüner Pfeil, welcher durch ein Polygon definiert wird, gezeichnet (Zeile 47). Die folgende Abbildung zeigt das Ergebnis:
Das
BufferedImageSnipped
zeigt die Verwendung eines
Buffered Image:
1 public final class BufferedImageSnipped implements IApplication { 2 3 @Override 4 public void start(final IApplicationLifecycle lifecycle) { 5 6 //create the root frame 7 final IFrameBluePrint frameBp = BPF.frame("Buffered Image Snipped"); 8 final IFrame frame = Toolkit.createRootFrame(frameBp, lifecycle); 9 frame.setSize(300, 200); 10 frame.setBackgroundColor(Colors.WHITE); 11 frame.setLayout(FillLayout.builder().margin(10).build()); 12 13 //create a arrow buffered image 14 final IBufferedImage image = createArrowImage(); 15 16 //create a label using the buffered image as icon 17 frame.add(BPF.label().setIcon(image).setText("Hello world")); 18 19 //set the root frame visible 20 frame.setVisible(true); 21 } 22 23 private static IBufferedImage createArrowImage() { 24 //create a buffered image 25 final IBufferedImage image = ImageFactory.createBufferedImage(52, 26); 26 final IGraphicContext gc = image.getGraphicContext(); 27 28 //use anti aliasing 29 gc.setAntiAliasing(AntiAliasing.ON); 30 31 //define a polygon that shapes an arrow 32 final Point p1 = new Point(0, 6); 33 final Point p2 = new Point(26, 6); 34 final Point p3 = new Point(26, 0); 35 final Point p4 = new Point(48, 12); 36 final Point p5 = new Point(26, 24); 37 final Point p6 = new Point(26, 18); 38 final Point p7 = new Point(0, 18); 39 final Point[] polygon = new Point[] {p1, p2, p3, p4, p5, p6, p7, p1}; 40 41 //use white background for the image 42 gc.setBackgroundColor(Colors.WHITE); 43 gc.clear(); 44 45 //draw with green color 46 gc.setForegroundColor(Colors.GREEN); 47 48 //fill the polygon 49 gc.fillPolygon(polygon); 50 51 return image; 52 } 53 }
Die folgende Abbildung zeigt das Ergebnis:
[25]
Hier macht es sich besonders unangenehm bemerkbar, dass
der Name IImageConstant
und nicht
IImageKey
gewählt wurde, da ein
IImage
nicht zwingend eine Konstante
sein muss und das dispose()
explizit
zum Vertrag gehört.