Java-Swing-Komponenten als Bild / Snapshot

Für unsere Anwendung (ähm, halt Diplomarbeit ftw!) wollte ich eine Export-als-Bild-Funktion für die Anzeige des aktuellen Graphen einbauen. Dabei handelt es sich um eine JComponent, die über das JUNG-Framework dargestellt wird.

Während jetzt Apple-Benutzer leichtfertig über dieses Feature lachen können, ist dies für Hauptzielgruppe der Anwendung (also Windowsbenutzer) eine sinnvolle Funktion. Es hat sicherlich wenig Sinn, umständlich einen Komplett-Screenshot anfertigen zu müssen.. viel einfacher kann das Programm das ja selbst machen.
Es gibt eine Reihe von Suchtreffern in Google, die durchaus lesenswert sind.

Die Grundidee ist, dass man sich selbst ein Graphics-Objekt erstellt und dann die JComponent darauf arbeiten lässt. Im Falle von Swing ist dies idR vom Framework vorgegeben (nämlich für den Bildschirm), hier aber wollen wir ja ein eigenes Bild haben. Die Höhe und Breite ist in den meisten Fällen von der Komponente zu erfragen.
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

Anschließend brauchen wir das zugehörige Graphics-Objekt, denn damit arbeiten die Paint-Methoden. Clue Nummer 1: Man könnte in Versuchung kommen, und einfach getGraphics() zu nehmen – ist ja auch naheliegend. Tatsächlich erstellt das aber auch nur ein Graphics-Objekt, während createGraphics() ein Graphics2D-Objekt erstellt. Und in den meisten Fällen braucht man das auch.
Graphics2D g = bi.createGraphics();

Anschließend muss man sich entscheiden, welche Zeichenroutine man anstoßen will. Es gibt prinzipiell folgende Möglichkeiten: paint(Graphics), paintComponent(Graphics) und paintAll(Graphics). Sofern paintComponent() ausreicht, diese nutzen. Im Falle des JUNG-Graphen mit verschiedenen Subelementen und eigenem Renderer funktioniert jedoch nur paintAll(Graphics) auf allen System zuverlässig. Während paint(Graphics) unter MacOS und Linux noch funktioniert, produziert es unter Windows unschöne Ergebnisse.

Anschließend kann man mit dem statischen Aufruf ImageIO.write(bi, "png", file); das gesamte Bild als — hier PNG — speichern. Achtung: Dies ist eine JavaSE6-Klasse, in den Vorgängern benötigt man dann den Umweg über FileStream & Co.

[1] jung.sourceforge.net
[2] java.sun.com

Java: Nativer Dateidialog unter MacOS X

Definitiv in der Kategorie: „Was ich schon immer mal wissen wollte..“

Wenn man mit Java Swing ein JFileChooser verwendet, so sieht der unter MacOS X alles andere als schön aus – und nativ ist er sowieso nicht. Was ich nicht wusste: Apple hat das AWT-Pendant FileDialog nativ implementiert (oder nachgebaut?). Gewusst wie – darauf gekommen bin ich auch nur, weil ich einfach mal gesucht habe.

Edit: Wie es aussieht, sieht der FileDialog auch unter Windows besser als sein Swing-Pendant aus. Wie sieht das mit den anderen System aus?