Grafik

SWT stellt eine robuste Grafiksteuerkomponente zur Verfügung, mit der in Fensterobjekten Grafik gezeichnet werden kann und Images angezeigt werden können. Hierdurch ist es häufig nicht einmal erforderlich, eine Programmierung für die Grafikschnittstelle vorzunehmen, da die Fensterobjekte das Zeichnen von Symbolen, Text und anderen Daten für Sie übernehmen. Wenn Ihre Anwendung angepasste Grafik verwendet oder Sie ein angepasstes gezeichnetes Fensterobjekt implementieren, müssen Sie jedoch einige Grundlagen über Zeichnungsobjekte in SWT kennen.

Grafikkontext

Der Grafikkontext GC ist der zentrale Punkt für die Grafikunterstützung von SWT. Seine API beschreibt alle Zeichnungsfunktionen in SWT.

Ein GC kann für das Zeichnen auf einem Steuerelement (dies ist der häufigste Fall) oder für das Zeichnen auf einem Image, einer Anzeige oder einem Drucker verwendet werden. Beim Zeichnen auf einem Steuerelement müssen Sie den GC verwenden, der Ihnen im Zeichnungsereignis des Steuerelements zur Verfügung gestellt wird. Beim Zeichnen auf einem Image, einer Anzeige oder einem Drucker müssen Sie einen entsprechend konfigurierten GC erstellen (und nach seiner Verwendung wieder freigeben).

Sobald der GC vorliegt, können Sie seine Attribute (z. B. Farbe, Zeilenlänge und Schriftart) festlegen, die die Darstellung der Grafik steuern, die im GC gezeichnet wird.

Die API-Referenz zu GC beschreibt die vollständige Palette der Grafikfunktionen.

Schriftarten

Die Klassen Font und FontData werden verwendet, wenn Schriftarten in SWT bearbeitet werden.

FontData beschreibt die Merkmale einer Schriftart. Sie können eine Klasse FontData erstellen, indem Sie einen Schriftartnamen, eine Darstellung und die Größe angeben. Die Klasse FontData enthält eine API zum Abfragen dieser Attribute. Da FontData keine Betriebssystemressourcen zuordnet, müssen Sie diese Klasse nach ihrer Verwendung nicht freigeben.

Die Klasse Font ist das eigentliche Grafikobjekt, das eine in der Zeichnungs-API verwendete Schriftart darstellt. Eine Klasse Font erstellen Sie für ein Objekt Display, indem Sie Display und FontData für die gewünschte Schriftart angeben. Sie können eine Klasse Font auch nach ihrem Wert für FontData abfragen.

Eine Klasse Font muss freigegeben werden, wenn sie nicht mehr verwendet wird.

Farben

Farben haben Ähnlichkeit mit Schriftarten. Sie erstellen eine Klasse Color für ein Objekt Display, indem Sie die RGB-Werte der gewünschten Farbe angeben. Eine Farbe muss freigegeben werden, wenn sie nicht mehr verwendet wird.

Mit der Methode getSystemColor für ein Objekt Display können Sie die vordefinierten Systemfarben für die Betriebssystemplattform abfragen. Farben, die mit dieser Methode abgerufen werden, sollten nicht entfernt werden.

Das Farbmodell wird unter SWT-Farbmodell ausführlich erläutert.

Images

Die Klassen Image, ImageData und ImageLoader werden bei der Bearbeitung von Images in SWT verwendet.

Die Klasse ImageData beschreibt die tatsächlichen Pixel im Image und verwendet die Klasse PaletteData, um die im Image verwendeten Farbwerte zu beschreiben. ImageData ist eine einheiten- und plattformunabhängige Beschreibung für ein Image.

ImageLoader lädt und speichert Klassen ImageData in unterschiedlichen Dateiformaten. Gegenwärtig unterstützt SWT das Laden und Speichern der Imageformate BMP (Windows-Bitmap), ICO (Windows-Symbol), JPEG, GIF und PNG.

Die Klasse Image ist das eigentliche Grafikobjekt für das Image, das in der Zeichnungs-API verwendet wird. Sie erstellen ein Image für ein bestimmtes Objekt Display. Images können auf unterschiedlichen Wegen erstellt werden:

Unabhängig davon, wie Sie die Klasse Image erstellt haben, müssen Sie immer dafür sorgen, dass sie entfernt wird.

Lebenszyklus von Grafikobjekten

Die meisten Grafikobjekte, die beim Zeichnen in SWT verwendet werden, ordnen Ressourcen im zu Grunde liegenden Betriebssystem zu und müssen explizit entfernt werden. Die bereits an früherer Stelle erläuterte Faustregel gilt auch in diesem Fall. Falls Sie zur Erstellung einen Konstruktor verwendet haben, müssen Sie das Objekt entfernen. Haben Sie auf andere Weise auf das Objekt zugegriffen, muss es nicht entfernt werden.

Erstellen

Grafikobjekte wie beispielsweise Grafikkontexte, Schriftarten, Farben und Images werden im Betriebssystem zugeordnet, sobald das Objekt erstellt wird. Die beabsichtigte Verwendung der Grafikobjekte bestimmt demnach, wann diese erstellt werden sollten.

Grafikobjekte, die in einer Anwendung intensiv eingesetzt werden, können Sie zu dem Zeitpunkt erstellen, an dem Sie die Fensterobjekte erstellen. Dies erfolgt in der Regel bei Farben und Schriftarten. In anderen Fällen ist es besser, wenn die Grafikobjekte während der Verarbeitung erstellt werden. Sie können beispielsweise einen Grafikkontext in einer der Ereignissteuerroutinen für das Fensterobjekt erstellen, um bestimmte Berechnungen auszuführen.

Wenn Sie ein angepasstes Fensterobjekt implementieren, ordnen Sie normalerweise Grafikobjekte im Konstruktor zu, falls Sie diese immer verwenden. Sie könnten sie während der Verarbeitung zuordnen, wenn sie nicht ständig verwendet werden oder von dem Status eines bestimmten Attributs abhängig sind.

Zeichnen

Nachdem Sie die Grafikobjekte zugeordnet haben, können Sie mit dem Zeichnen beginnen. Das Zeichnen sollten Sie immer in einer entsprechenden Listener-Funktion vornehmen. Es gibt seltene Fälle (insbesondere bei der Implementierung von angepassten Fensterobjekten), in denen Sie das Zeichnen vornehmen, während Sie auf ein anderes Ereignis reagieren. Hiervon wird jedoch generell abgeraten. Wenn Sie glauben, das Zeichnen während der Verarbeitung eines anderen Ereignisses vornehmen zu müssen, sollten Sie zunächst versuchen, die Methode redraw zu verwenden, die ein weiteres Zeichnungsereignis im Betriebssystem generiert. Das Zeichnen außerhalb der Methode "paint" beeinträchtigt Plattformoptimierungen und kann sogar Programmfehler verursachen, wenn die Ereigniswarteschlange eine entsprechende Anzahl von anstehenden Zeichnungsereignissen enthält.

Wenn Sie ein Zeichnungsereignis empfangen, wird ein vorkonfigurierter GC für das Zeichnen im Fensterobjekt zur Verfügung gestellt. Dieser GC darf nicht entfernt werden! Dies liegt daran, dass Sie ihn nicht selbst erstellt haben.

Alle anderen Grafikobjekte müssen während der Verarbeitung des Ereignisses (oder im voraus) zugeordnet werden. Der folgende Ausschnitt basiert auf dem Beispiel org.eclipse.swt.examples.HelloWorld5. Die Farbe Rot wurde während der Erstellung des Fensterobjekts bereits zugeordnet und kann daher hier verwendet werden.

shell.addPaintListener(new PaintListener () {
    public void paintControl(PaintEvent event){
        GC gc = event.gc;
        gc.setForeground(red);
        Rectangle rect = event.widget.getClientArea();
        gc.drawRectangle(rect.x + 10, rect.y + 10, rect.width - 20, rect.height - 20);
        gc.drawString(resHello.getString("Hello_world"), rect.x + 20, rect.y + 20);
    }
});

Entfernen

Alle von Ihnen zugeordneten Grafikobjekte müssen nach ihrer Verwendung entfernt werden.

Der Zeitpunkt der Freigabe ist davon abhängig, wann Sie das Objekt erstellt haben. Wird ein Grafikobjekt im Rahmen der Erstellung eines Fensterobjekts erstellt, sollten Sie generell eine Listener-Funktion für das Freigeben im Fensterobjekt hinzufügen und das Grafikobjekt freigeben, wenn das Fensterobjekt freigegeben wird. Falls Sie ein Objekt während der Verarbeitung des Zeichnens erstellen, sollten Sie es freigeben, sobald das Zeichnen beendet ist.

Der nächste Code-Ausschnitt zeigt eine leicht abgewandelte Version der Listener-Funktion für das Zeichnen. In diesem Beispiel wird die Farbe Rot während des Zeichnens zugeordnet und freigegeben.

shell.addPaintListener(new PaintListener () {
    public void paintControl(PaintEvent event){
        GC gc = event.gc;
        Color red = new Color(event.widget.getDisplay(), 0xFF, 0, 0);
        gc.setForeground(red);
        Rectangle rect = event.widget.getClientArea();
        gc.drawRectangle(rect.x + 10, rect.y + 10, rect.width - 20, rect.height - 20);
        gc.drawString(resHello.getString("Hello_world"), rect.x + 20, rect.y + 20);
        red.dispose();
    }
});