# Swing Komponente als Bild speichern



## Kamairo (31. Mai 2011)

Moin,

ich versuch im Moment einen Screenshot einer Swing Komponente als Bild zu speichern, momentan hab ich folgendes:


```
private void ActionSave(){
		int w = pgg.MainViewerPanel.getWidth();
		int h = pgg.MainViewerPanel.getHeight();
		String filename;

		BufferedImage image = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics = image.createGraphics();
		pgg.MainViewerPanel.paintAll(graphics);						
		graphics.dispose();
		
		FileDialog saveDi = new FileDialog(pgg,"Bild speichern...",FileDialog.SAVE);
		saveDi.setVisible(true);
		filename = saveDi.getDirectory();
		filename += saveDi.getFile(); 		
			            
		try {
		   	 ImageIO.write(image, "jpeg", new File(filename));
		} catch (IOException ex) {
		   	 System.out.println("error");
		 }
		}
```

Das funktioniert für normale Swing Komponenten auch einwandfrei, allerdings muss ich nen Screenshot aus einer Swing Komponente speichern, die von nem Plugin kommt. Das Plugin heißt View3D und basiert auf dem Visualization Tool Kit (VTK).
Hier ist die Dokumentation
Es geht dabei um die Klasse "ViewerPanel", die von Swing Komponenten erbt.
Gibts ne andere möglichkeit von Swing Komponenten Screenshots zu machen, als die oben, die evtl funktionieren könnte?

Btw "pgg" ist die Instanz meiner GUI Klasse.


----------



## Marco13 (1. Jun 2011)

Das Hauptproblem dürfte sein, dass der VTKCanvas keine Swing-Component ist, sondern ein nativer Canvas, in den mit OpenGL reingerendert wird.
Man könnte schauen, ob es im VTK Möglichkeiten gibt, den Inhalt eines solchen Canvas abzugreifen, irgendwas, was in Richtung glReadPixels geht (oder besser: Eine direkt vom VTK angebotene Funktion), aber eine API-Doku zum Java-VTK bzw. VTKCanvas hab' ich jetzt auf die Schnelle nicht gefunden (und den Code auch nicht)


----------



## Kamairo (1. Jun 2011)

Ja alles klar exakt das hab ich mir auch schon so gedacht, ja es gibt ne methode bei vtk komponenten die heißt .getCanvas() mhh okay ich such da mal


----------



## Kr0e (1. Jun 2011)

Ansonsten die absolute holzhammer Methode (Sofern du nicht 30 mal pro Sekunde ein Bild erstellen willst): Screenshot vom Desktop machen und als Clip die absoluten Screenkoordinaten deiner Komponente angeben. Mit der klasse Robot kann man Screenshots machen...


----------



## Kamairo (1. Jun 2011)

Die Holzhammer Methode gefällt mir ganz gut, Problem is nur:

Die absoluten Screenkoordinaten variieren ja je nach dem ob der benutzer das fenster verschiebt oder nicht, kann man sowas aus nem JFrame auslesen? Iwie sowas wie getLocation?

edit: ahh gefunden getLocationOnScreen()

edit: ja perfekt die Holzhammer Methode funktioniert einwandfrei  hab allerdings nochmal schnell ne andere frage: Wie kriege ich das hin, dass im FileDialog nur die extension .jpg erlaubt wird und falls der benutzer sie nicht eingiebt angehängt wird?


----------



## Kr0e (1. Jun 2011)

Manchmal sind die einfachsten und scheinbar "unprofessionellen" Lösungen die Besten 

Wegen dem FileDialog: Du kannst mit setFileFilter mal rumexperimentieren und natürlich die Doku von JFileChooser lesen, da dürften solche Fälle beschrieben werden...


----------



## Kamairo (1. Jun 2011)

Alles klar besten Dank!


----------



## Michael... (2. Jun 2011)

Ich vermute mal, dass wenn Du wenn der Inhalt der Komponente per OpenGL reingerendert wird, wird auch die "Hammermethode" nicht weiterhelfen.
Aber das lässt sich ja schnell feststellen, in dem man versucht mit der Screenshot Funktion des Betriebssystems einen Screenshot zu machen.


----------



## Kr0e (2. Jun 2011)

Warum sollte das nicht gehen ? Es wird vom Bildschirminhalt ein Foto gemacht und das ist ja der Bildschirminhalt


----------



## Marco13 (2. Jun 2011)

Es gibt Fälle, wo SO direkt in den Grafikspeicher gerendert wird, dass man keinen Screenshot machen kann (bei einigen Videoplayern - das geht so weit, dass ein Video manchmal sogar z.B. auf dem Bildschirm eines Laptops angezeigt wird, aber nicht auf dem angeschlossenen Beamer :autsch: Spaß bei Präsentationen  ). Aber bei normalem OpenGL sollte das nicht der Fall sein.


----------



## Kr0e (2. Jun 2011)

Ich kenn solche Fälle auch, aber meist hat das doch mit dem Treiber und nicht mit dem ausführenden Prorgamm zu tun, oder ? ATI-Treiber sind da ein gutes Beispiel... Dort kann man einstellen, ob bei mehreren Bildschirmen auch Videoinhalt angezeigt werden soll oder nicht. Ich verstehe allerdings nicht, warum man Videoinhalt nicht anzeigen lassen sollte... Bei NVidiatreibern gibt es solche sinnfreien Einstellungen garnicht erst^^


----------



## Marco13 (2. Jun 2011)

Ich kenn' mich mit Hardwaredetails da nicht aus, aber ich glaube, dass das auch mit Performance zu tun haben kann: Unter bestimmten Bedingungen können da wohl irgendwelche Datentransfers über irgendwelche langsamen Busse oder so vermieden werden, aber... ist nur .. nichtmal Halb- sondern höchstens Viertelwissen


----------

