Mac OS X Remote Install via Disc Target Mode

Problem: Leider ist das Superdrive von meinem MacBook Pro scheinbar schon etwas mitgenommen.. denn die Leopard-CD (normal, kein OEM) wollte er nicht mehr lesen – der iMac aber schon. 😐 Dafür aber die mitgelieferte DVD, nur war das noch Tiger (10.4). Was tun?

Die Problemlösung ist die gleiche, wenn man ein ganz kaputtes Superdrive hat.

Idee 1: Remote Install oder in deutsch: Entfernte Installation

Dieses Feature wurde mit der Einführung des Macbook Airs in Leopard integriert – okay, fein, den Host könnte der iMac spielen. Leider scheint das entweder nicht funktionieren oder aber es funktioniert tatsächlich nur mit dem Macbook Air 🙁 Geht nicht. Schade

Idee 2: Die Leopard-DVD vom iMac

Ja, geniale Idee.. nur (leider) sind die mitgelieferten DVDs allesamt OEM-Versionen, die jeweils nur für die Produktreihe funktionieren. Also mit anderen Worten: Einen anderen iMac kann ich Leopard installieren, für ein anderes Macbook hätt ich ein(en) Tiger im Angebot.. ach menno 🙁

Idee 2.5: Disc Target Mode

Nachdem die Installation der iMac-Leopard-DVD auf dem Macbook Pro die Installation verweigerte, kam mir eine Blitzidee: Targetmode. Damit startet man das Target (also das Macbook) in einen besonderen Bootstatus; zeitgleich verbindet man den Target mit dem Hostrechner (Mac) und kann von dort auf die Platten zugreifen (vgl. externe Platten). Da man bei einem Mac auf externe Platten wie die eigene zugreifen kann, kann man auch installieren. Und wenn man für den Host auch eine gültige Installations-CD hat (oder ein funktionierendes Laufwerk)… *freu*

Tatsache, man nehme also die Boot-DVD des Hosts (hier iMac), mit der man „booten & installieren darf“. Als Zielmedium wählt man aber die Platte aus, die auf dem Target liegt – sehr einfach an dem Symbol eines externen Datenträgers zu erkennen. Nicht vergessen, vor dem nächsten Neustart die Rechner alle auszumachen, Kabel raus.. neu starten.. und voila. 🙂

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