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.