Grafikdateien laden und anzeigen (Java): Unterschied zwischen den Versionen
(→Laden von Bildern für AWT-Applikationen) |
(→Laden von Grafikdateien in Swing) |
||
Zeile 85: | Zeile 85: | ||
=Laden von Grafikdateien in Swing= | =Laden von Grafikdateien in Swing= | ||
In Swing haben die Java-Erfinder von Sun eine sehr leistungsfähige Klasse für das Einlesen von Grafikdaten aus unterschiedlichen Quellen entwickelt, die auch die Anwendung in Applets und Applikationen vereinheitlicht. | In Swing haben die Java-Erfinder von Sun eine sehr leistungsfähige Klasse für das Einlesen von Grafikdaten aus unterschiedlichen Quellen entwickelt, die auch die Anwendung in Applets und Applikationen vereinheitlicht. | ||
+ | ==Varianten zum Einbinden von Grafiken== | ||
+ | Viele Wege führen bekanntlich nach Rom, so auch beim erfolgreichen Laden und Anzeigen von Grafikdateien in Java.<br> | ||
+ | ===ImageIcon=== | ||
+ | '''javax.swing.ImageIcon''' ist eine konkrete Implementierung des '''Icon'''-Interfaces, welches grundlegende Methoden für die Arbeit mit Icons oder Abbildungen definiert.<br> | ||
+ | Das Laden der Bilder wird im Hintergrund bereits mit dem '''java.awt.Mediatracker''' überwacht, so dass die Bilder auf jeden Fall im Speicher sind, bevor sie gezeichnet werden.<br> | ||
+ | Der Konstruktor von ImageIcon erwartet die Übergabe des Speicherortes bzw. den Namen der zu ladenen Datei in Form eines Strings, eines Images oder einer URL. | ||
==JApplets== | ==JApplets== | ||
In Swing-Applets kann für das effiziente Einlesen von Grafikdaten die Klasse javax.imageio.ImageIO verwendet werden.<br> | In Swing-Applets kann für das effiziente Einlesen von Grafikdaten die Klasse javax.imageio.ImageIO verwendet werden.<br> |
Version vom 4. Oktober 2011, 16:07 Uhr
Dieser Beitrag wird derzeit noch bearbeitet. Der Text ist deshalb unvollständig und kann Fehler oder ungeprüfte Aussagen enthalten. |
Häufig möchte man aus verschiedenen Gründen Grafikdateien, wie Icons, Eyecatcher oder Fotos in Java-Programme einbinden. Im Folgenden soll anhand von Code-Beispielen gezeigt werden, wie unter verschiedenen Bedingungen und GUI-Schnittstellen (AWT/Swing) Grafiken eingebunden werden können.
Inhaltsverzeichnis
Laden von Grafikdateien im AWT
Im AWT, welches die Standard-Schnittstelle für die Entwicklung grafischer Benutzeroberflächen bis zur Veröffentlichung von Java 1.2 war, wird das Einlesen von Grafikdaten in Applets und Applikationen unterschiedlich gehandhabt. Bis auf den gleichen Namen der benutzten Methode zum Einlesen, müssen hier verschiedene Konzepte angewendet werden.
Applets
Laden von Bildern für Applets
Da Applets auf einem Webserver gespeichert sind und nach dem Laden in den Browser externe Resourcen wie Bilder ebenfalls aus dem Internet nachladen, werden die URLs (Quellenanzeiger) der Resourcen meist ausgehend vom URL des Applets angegeben. Das heißt: getCodeBase() liefert den URL des Applets im Internet. Und davon ausgehend kann nun der exakte Pfad zu unserem Bild angegeben werden.
<code=java> Image image = getImage(getCodeBase(),"Bild.jpg"); </code=java>
Einfache Applet-Klassen
Die einfachste Variante, eine Grafik in ein Applet (AWT) einzubinden ist, sie von der URL einzulesen und in der paint()-Methode direkt auf die Appletfläche zu zeichnen.
<code=java>import java.awt.*; import java.applet.*;
public class PictureApplet extends Applet {
private Image image;
public void init() { image = getImage(getCodeBase(),"Bild.jpg"); }
public void paint(Graphics g) { super.paint(g); if(image != null) { g.drawImage(image, 0, 0, this); } }
}</code=java>
Diese Variante ist aber wenig effizient und häufig kommt es vor, dass kein Bild ausgegeben wird, obwohl der URL und der Pfad zum Bild stimmen. Das Einlesen des Bildes dauert hier bei größeren und/oder mehreren Dateien etwas länger, so dass die paint()-Methode schon ausgeführt wird, obwohl das Laden des Bildes noch nicht abgeschlossen ist. In der Java-Konsole würde in diesem Fall eine NullPointerException ausgegeben werden, wenn image nicht auf null geprüft werden würde.
Einsatz des MediaTrackers
Um sicher zu stellen, dass ein Bild erst dann auf ein Applet gezeichnet wird, wenn es wirklich vollständig geladen wurde, bedient man sich der Klasse java.awt.MediaTracker, welche das Laden der Dateien in einem extra Thread überwacht und die Kontrolle ans Programm zurückgibt, wenn die Bilder geladen wurden.
<code=java>import java.awt.*; import java.applet.*;
public class PictureApplet extends Applet {
private Image image; private MediaTracker tracker;
public void init() { tracker = new MediaTracker(this);
image = getImage(getCodeBase(),"Bild.jpg"); //Laden des Bildes anstoßen
tracker.addImage(image, 0); //Image an den MediaTracker zur Überwachung übergeben
try { tracker.waitForAll(); //auf alle zu ladenden Dateien warten } catch (InterruptedException e) { e.printStackTrace(); //Fehlerausgabe auf der Java-Konsole } }
public void paint(Graphics g) { super.paint(g); if(image != null) { g.drawImage(image, 0, 0, this); } }
}</code=java>
AWT-Applikationen
Laden von Bildern für AWT-Applikationen
Anwendungen, welche das AWT als GUI-Schnittstelle anwenden, greifen auf die Klasse java.awt.Toolkit zurück, um Bilder zu laden <code=java> Image image = Toolkit.getDefaultToolkit().getImage("picture.jpg"); </code=java> Auch hier empfiehlt sich zusätzlich der Einsatz von MediaTracker, wie wir das bereits beim obigen Applet gesehen haben.
Laden von Grafikdateien in Swing
In Swing haben die Java-Erfinder von Sun eine sehr leistungsfähige Klasse für das Einlesen von Grafikdaten aus unterschiedlichen Quellen entwickelt, die auch die Anwendung in Applets und Applikationen vereinheitlicht.
Varianten zum Einbinden von Grafiken
Viele Wege führen bekanntlich nach Rom, so auch beim erfolgreichen Laden und Anzeigen von Grafikdateien in Java.
ImageIcon
javax.swing.ImageIcon ist eine konkrete Implementierung des Icon-Interfaces, welches grundlegende Methoden für die Arbeit mit Icons oder Abbildungen definiert.
Das Laden der Bilder wird im Hintergrund bereits mit dem java.awt.Mediatracker überwacht, so dass die Bilder auf jeden Fall im Speicher sind, bevor sie gezeichnet werden.
Der Konstruktor von ImageIcon erwartet die Übergabe des Speicherortes bzw. den Namen der zu ladenen Datei in Form eines Strings, eines Images oder einer URL.
JApplets
In Swing-Applets kann für das effiziente Einlesen von Grafikdaten die Klasse javax.imageio.ImageIO verwendet werden.
Wie einfach ihre Benutzung ist, werden wir im Anschluss demonstrieren.
Einfache JApplet-Klassen
Zeichnen auf einen Container (JPanel), welcher dem JApplet als Hintergrund hinzugefügt wird: <code=java> import javax.swing.*; import javax.imageio.*; import java.awt.*; import java.net.*; import java.io.*;
public class PictureApplet extends JApplet {
private Image image, background;
public void init() { setContentPane(new MyContentPane());
try { image = ImageIO.read(new URL(getCodeBase(), "Bild.jpg")); background = ImageIO.read(new URL(getCodeBase(), "/hintergruende/Hintergrund.jpg")); } catch(IllegalArgumentException iae) {
JOptionPane.showMessageDialog(this, "Grafikdatei nicht gefunden!");
} catch(IOException ioe) {
JOptionPane.showMessageDialog(this, "Fehler beim Einlesen der Grafikdatei!");
} }
private class MyContentPane extends JPanel {
public void paintComponent(Graphics g) { super.paintComponent(g); if(image != null) { g.drawImage(image, 0, 0, this); } } }
}</code=java>
Link: Einbinden von Applets in HTML-Dateien
Applets in Jar-Dateien
Wenn sich das Applet gemeinsam mit der zu ladenden Grafik in einer Jar-Datei zusammengefasst wurden, muss die Grafik über den ClassLoader ins Applet geladen werden.
Zeichnen auf einen Container (JPanel), welcher dem JApplet als Hintergrund hinzugefügt wird: <code=java> import javax.swing.*; import javax.imageio.*; import java.awt.*; import java.net.*; import java.io.*;
public class PictureApplet extends JApplet {
private Image image, background;
public void init() { setContentPane(new MyContentPane());
try { image = ImageIO.read(getClass().getResource("Bild.jpg")); background = ImageIO.read(getClass().getResource("hintergruende/Hintergrund.jpg")); } catch(IllegalArgumentException iae) {
JOptionPane.showMessageDialog(this, "Grafikdatei nicht gefunden!");
} catch(IOException ioe) {
JOptionPane.showMessageDialog(this, "Fehler beim Einlesen der Grafikdatei!");
} }
private class MyContentPane extends JPanel {
public void paintComponent(Graphics g) { super.paintComponent(g); if(image != null) { g.drawImage(image, 0, 0, this); } } }
}</code=java>
Das Applet-Tag in der HTML-Datei muss jetzt angepasst werden, damit der Browser weiß, wo sich das Applet befindet.
Link: Applet-Tag für Jar-Dateien
Swing-Applikationen
Auch Swing-Applikationen werden im Allgemeinen in Jar-Archiven zusammengefasst. Diese lassen sich auf jedem System per Doppelklick starten, oder per Webstart über das Internet laden.
Hier also nun die Variante für eine Applikation. Auffällig ist, dass sich der Code des Panels gegenüber dem Applet nur leicht, der Code zum Laden der Bilder aber gar nicht verändert hat.
<code=java>
import javax.swing.*;
import javax.imageio.*;
import java.awt.*;
import java.net.*;
import java.io.*;
public class PicturePanel extends JPanel {
private Image image, background; public PicturePanel() { try { image = ImageIO.read(getClass().getResource("Bild.jpg")); background = ImageIO.read(getClass().getResource("hintergruende/Hintergrund.jpg")); } catch(IllegalArgumentException iae) { JOptionPane.showMessageDialog(this, "Grafikdatei nicht gefunden!"); } catch(IOException ioe) { JOptionPane.showMessageDialog(this, "Fehler beim Einlesen der Grafikdatei!"); } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if(image != null) { g.drawImage(image, 0, 0, this); } }
} </code=java>
Das Ganze kann nun in einem Fenster angezeigt werden: <code=java> import javax.swing.*;
public class PictureFrame {
public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame f = new JFrame("Bildbetrachter"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new PicturePanel()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } }); }
} </code=java>