---
title: 'Inselraus: Die Schnittstelle Icon und eigene Icons zeichnen'
url: 'https://tutego.de/blog/javainsel/2013/02/inselraus-die-schnittstelle-icon-und-eigene-icons-zeichnen'
markdown: 'https://tutego.de/blog/javainsel/2013/02/inselraus-die-schnittstelle-icon-und-eigene-icons-zeichnen.md'
date: '2013-02-24'
description: 'Bei einer genauen Betrachtung fällt auf, dass ImageIcon eine Implementierung der Schnittstelle Icon ist und dass die JLabel-Klasse ein Icon-Objekt erwartet und nicht speziell ein Argument vom Typ ImageIcon. Das heißt aber: Wir können auch eigene Icon-Objekte zeichnen. Dazu müssen wir nur drei spezi…'
taxonomy:
  category:
    - Swing
---

# Inselraus: Die Schnittstelle Icon und eigene Icons zeichnen

![Illustration einer tropischen Insel mit Palmen und einem hohen Berg](https://tutego.de/blog/javainsel/user/themes/tutego/images/insel-cover.jpg)# Java Blog für Programmierer

[Java Blog für Programmierer](https://tutego.de/blog/javainsel/)

## Inselraus: Die Schnittstelle Icon und eigene Icons zeichnen

24.02.2013 · [Christian Ullenboom](https://tutego.de/blog/javainsel/author/admin/)

Bei einer genauen Betrachtung fällt auf, dass ImageIcon eine Implementierung der Schnittstelle Icon ist und dass die JLabel-Klasse ein Icon-Objekt erwartet und nicht speziell ein Argument vom Typ ImageIcon. Das heißt aber: Wir können auch eigene Icon-Objekte zeichnen. Dazu müssen wir nur drei spezielle Methoden von Icon implementieren: die Methode `paintIcon(…)` und ferner zwei Methoden, die die Dimensionen angeben.

```
interface interface javax.swing.Icon
```

- `int getIconWidth()`Liefert die feste Breite eines Icons.
- `int getIconHeight()`Liefert die feste Höhe eines Icons.
- `void paintIcon(Component c, Graphics g, int x, int y)`Zeichnet das Icon an die angegebene Position. Der Parameter Component wird häufig nicht benutzt. Er kann jedoch eingesetzt werden, wenn weitere Informationen beim Zeichnen bekannt sein müssen, wie etwa die Vorder- und Hintergrundfarbe oder der Zeichensatz.

Die folgende Klasse zeigt die Verwendung der Icon-Schnittstelle. Das eigene Icon soll einen einfachen roten Kreis mit den Ausmaßen 20 × 20 Pixel besitzen:

```java

class CircleIcon implements Icon {

  @Override public void paintIcon( Component c, Graphics g, int x, int y )  {
    g.setColor( Color.red );
    g.fillOval( x, y, getIconWidth(), getIconHeight() );
  }

  @Override public int getIconWidth() {
    return 20;
  }

  @Override public int getIconHeight() {
    return 20;
  }
}
```

Wir überschreiben die drei erforderlichen Methoden, sodass ein Icon-Objekt der Größe 20 × 20 Pixel entsteht. Als Grafik erzeugen wir einen gefüllten roten Kreis. Dieser kann als Stopp-Schaltfläche verwendet werden, ohne dass wir eine spezielle Grafik verwenden müssen. Für die Grafik stehen uns demnach 400 Pixel zur Verfügung – genau `getIconWidth()` mal `getIconHeight()` –, und alle nicht gefüllten Punkte liegen transparent auf dem Hintergrund. Dies ist auch typisch für leichtgewichtige Komponenten. Über das Component-Objekt können wir weitere Informationen herausholen, wie etwa den aktuellen Zeichensatz oder die darstellende Vaterkomponente.

Um das eigene Icon auf ein JLabel zu setzen, lässt sich die Icon-Implementierung entweder im Konstruktor übergeben oder später über `setIcon(Icon)`:

```java

JLabel circle = new JLabel( new CircleIcon() );
```

**Was die Typen Icon und Image verbindet**

Vielleicht wird der eine oder andere sich schon überlegt haben, ob nun ImageIcon eine ganz eigene Implementierung neben der Image-Klasse ist oder ob beide miteinander verwandt sind. Das Geheimnis ist, dass ImageIcon die Icon-Schnittstelle implementiert, aber auch ImageIcon intern die Image-Klasse nutzt. Sehen wir uns das einmal im Detail an: Ein ImageIcon ist serialisierbar. Also implementiert es die Schnittstelle Serializable. Im Konstruktor kann ein `URL`-Objekt oder ein `String` mit einer `URL` stehen. Hier wird einfach `getImage(…)` vom Toolkit aufgerufen, um sich eine Referenz auf das Image-Objekt zu holen. Eine geschützte Methode `loadImage(Image)` wartet nun mithilfe eines MediaTrackers auf das Bild. Nachdem dieser auf das Bild gewartet hat, setzt er die Höhe und Breite, die sich dann über die Icon-Methoden abfragen lassen. Doch ein richtiges Icon muss auch `paintIcon(…)` implementieren. Hier verbirgt sich nur die `drawImage(…)`-Methode.

Kommen wir noch einmal auf die Serialisierbarkeit der ImageIcon-Objekte zurück. Die Klasse implementiert dazu die privaten Methoden `readObject(…)` und `writeObject(…)`. Der Dateiaufbau ist sehr einfach. Breite und Höhe befinden sich im Datenstrom, und anschließend existiert ein `Integer`-Feld mit den Pixelwerten. In `readObject(…)` liest `s.defaultReadObject()` – wobei s der aktuelle ObjectInputStream ist – das Feld wieder ein, und über die Toolkit-Methode `createImage(…)` wird die Klasse MemoryImageSource genutzt, um das Feld wieder zu einem Image-Objekt zu konvertieren. Umgekehrt ist es genauso einfach. `writeObject(…)` schreibt die Breite und Höhe und anschließend das Ganzzahl-Feld mit den Farbinformationen, das es über einen PixelGrabber bekommen hat.

Kategorien: [Swing](https://tutego.de/blog/javainsel/category/swing/)

[← Alle Beiträge](https://tutego.de/blog/javainsel/)

---

## Navigation

- Previous: [Inselraus: Zeichensatz eines Swing-Labels ändern](https://tutego.de/blog/javainsel/2013/02/inselraus-zeichensatz-eines-swing-labels-ndern.md)
- Next: [Inselraus: Bilder auf AbstractButton-basierten Swing-Schaltflächen je nach Zustand ändern](https://tutego.de/blog/javainsel/2013/02/inselraus-bilder-auf-abstractbutton-basierten-swing-schaltflchen-je-nach-zustand-ndern.md)
