{"id":1834,"date":"2013-02-24T11:56:37","date_gmt":"2013-02-24T09:56:37","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=1834"},"modified":"2013-02-24T11:59:36","modified_gmt":"2013-02-24T09:59:36","slug":"inselraus-die-schnittstelle-icon-und-eigene-icons-zeichnen","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2013\/02\/inselraus-die-schnittstelle-icon-und-eigene-icons-zeichnen\/","title":{"rendered":"Inselraus: Die Schnittstelle Icon und eigene Icons zeichnen"},"content":{"rendered":"<p>Bei einer genauen Betrachtung f\u00e4llt 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\u00dft aber: Wir k\u00f6nnen auch eigene Icon-Objekte zeichnen. Dazu m\u00fcssen wir nur drei spezielle Methoden von Icon implementieren: die Methode paintIcon(\u2026) und ferner zwei Methoden, die die Dimensionen angeben.<\/p>\n<p>interface interface javax.swing.Icon<\/p>\n<ul>\n<li>int getIconWidth()<br \/>\nLiefert die feste Breite eines Icons.<\/li>\n<li>int getIconHeight()<br \/>\nLiefert die feste H\u00f6he eines Icons.<\/li>\n<li>void paintIcon(Component c, Graphics g, int x, int y)<br \/>\nZeichnet das Icon an die angegebene Position. Der Parameter Component wird h\u00e4ufig nicht benutzt. Er kann jedoch eingesetzt werden, wenn weitere Informationen beim Zeichnen bekannt sein m\u00fcssen, wie etwa die Vorder- und Hintergrundfarbe oder der Zeichensatz.<\/li>\n<\/ul>\n<p>Die folgende Klasse zeigt die Verwendung der Icon-Schnittstelle. Das eigene Icon soll einen einfachen roten Kreis mit den Ausma\u00dfen 20 \u00d7 20 Pixel besitzen:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass CircleIcon implements Icon {\r\n\r\n  @Override public void paintIcon( Component c, Graphics g, int x, int y )  {\r\n    g.setColor( Color.red );\r\n    g.fillOval( x, y, getIconWidth(), getIconHeight() );\r\n  }\r\n\r\n  @Override public int getIconWidth() {\r\n    return 20;\r\n  }\r\n\r\n  @Override public int getIconHeight() {\r\n    return 20;\r\n  }\r\n}\r\n<\/pre>\n<p>Wir \u00fcberschreiben die drei erforderlichen Methoden, sodass ein Icon-Objekt der Gr\u00f6\u00dfe 20 \u00d7 20 Pixel entsteht. Als Grafik erzeugen wir einen gef\u00fcllten roten Kreis. Dieser kann als Stopp-Schaltfl\u00e4che verwendet werden, ohne dass wir eine spezielle Grafik verwenden m\u00fcssen. F\u00fcr die Grafik stehen uns demnach 400 Pixel zur Verf\u00fcgung \u2013 genau getIconWidth() mal getIconHeight() \u2013, und alle nicht gef\u00fcllten Punkte liegen transparent auf dem Hintergrund. Dies ist auch typisch f\u00fcr leichtgewichtige Komponenten. \u00dcber das Component-Objekt k\u00f6nnen wir weitere Informationen herausholen, wie etwa den aktuellen Zeichensatz oder die darstellende Vaterkomponente.<\/p>\n<p>Um das eigene Icon auf ein JLabel zu setzen, l\u00e4sst sich die Icon-Implementierung entweder im Konstruktor \u00fcbergeben oder sp\u00e4ter \u00fcber setIcon(Icon):<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nJLabel circle = new JLabel( new CircleIcon() );\r\n<\/pre>\n<p><strong>Was die Typen Icon und Image verbindet<\/strong><\/p>\n<p>Vielleicht wird der eine oder andere sich schon \u00fcberlegt 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(\u2026) vom Toolkit aufgerufen, um sich eine Referenz auf das Image-Objekt zu holen. Eine gesch\u00fctzte Methode loadImage(Image) wartet nun mithilfe eines MediaTrackers auf das Bild. Nachdem dieser auf das Bild gewartet hat, setzt er die H\u00f6he und Breite, die sich dann \u00fcber die Icon-Methoden abfragen lassen. Doch ein richtiges Icon muss auch paintIcon(\u2026) implementieren. Hier verbirgt sich nur die drawImage(\u2026)-Methode.<\/p>\n<p>Kommen wir noch einmal auf die Serialisierbarkeit der ImageIcon-Objekte zur\u00fcck. Die Klasse implementiert dazu die privaten Methoden readObject(\u2026) und writeObject(\u2026). Der Dateiaufbau ist sehr einfach. Breite und H\u00f6he befinden sich im Datenstrom, und anschlie\u00dfend existiert ein Integer-Feld mit den Pixelwerten. In readObject(\u2026) liest s.defaultReadObject() \u2013 wobei s der aktuelle ObjectInputStream ist \u2013 das Feld wieder ein, und \u00fcber die Toolkit-Methode createImage(\u2026) wird die Klasse MemoryImageSource genutzt, um das Feld wieder zu einem Image-Objekt zu konvertieren. Umgekehrt ist es genauso einfach. writeObject(\u2026) schreibt die Breite und H\u00f6he und anschlie\u00dfend das Ganzzahl-Feld mit den Farbinformationen, das es \u00fcber einen PixelGrabber bekommen hat.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bei einer genauen Betrachtung f\u00e4llt 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\u00dft aber: Wir k\u00f6nnen auch eigene Icon-Objekte zeichnen. Dazu m\u00fcssen wir nur drei spezielle Methoden von Icon implementieren: die Methode paintIcon(\u2026) und ferner zwei Methoden, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[10],"tags":[],"class_list":["post-1834","post","type-post","status-publish","format-standard","hentry","category-swing"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1834","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=1834"}],"version-history":[{"count":2,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1834\/revisions"}],"predecessor-version":[{"id":1836,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1834\/revisions\/1836"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=1834"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=1834"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=1834"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}