JPanel als JPG - weisse Fläche

feldmarv

Mitglied
Rettendes Java Forum =)

Ihr konntet mir schon sehr sehr viel helfen bezüglich meinen Java Problemen.
Ich habe nun mein Zeichnungsprogramm schon bald fertig und versuche mit mir der Methode die Zeichnungsfläche (JPanel) als JPG auf dem Desktop sichern zu können. Wenn ich nun die folgende Methode, die ich aus einem anderen Forum habe versuche einzubauen klappt eigentlich alles. Die grösse des Panels wird übernommen. Aber die JPG Datei hat nur die Farbe des Hintergrunds. Die Objekte die gezeichnet wurden erscheinen nicht?

Java:
	String fileName = "comet01.jpg"; 
        float quality = 0.9f; 

        int w = pan2.getWidth(); 
        int h = pan2.getHeight(); 
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
        Graphics2D big2d = bi.createGraphics(); 

        pan2.paint(big2d); 

        try { 
            FileOutputStream fos = new FileOutputStream(new File(fileName)); 
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos); 
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi); 
            param.setQuality(quality, false); 
            encoder.setJPEGEncodeParam(param); 
            encoder.encode(bi); 
        } catch (Exception ex) { 
            ex.printStackTrace(); 
        }
 
Zuletzt bearbeitet:
Wenn alles von der paint-Methode aus gezeichnet wird, könnte das ungefähr so gehen, aber es ist ein bißchen hakelig (man sollte auch SwingUtilities (Java Platform SE 6) verwenden können, aber das hat ein paar kramfige Eigenschaften). Ist das Panel zum Zeitpunkt des Zeichnens sichtbar auf dem Bildschirm? Mit Robot einen Screenshot machen wäre ggf. einfacher, kann aber auch unerwünschte Effekte haben, mit paint(g) ist's eigentlich besser (wenn's funktioniert 😉). Ein KSKB wäre gut. Vielleicht wenigstens etwas mehr code aus dem Zeichenpanel (paint und paintComponent und so). Wenn du irgendwo getGraphics auf einer Component aufrufst, hast du ein Problem 😉 (Auf dem bufferedImage ist es OK!!!)
 
vielen dank für den input.
es sieht so aus bei mir. In der GUI klasse werden dinge mit den maus funktionen gezeichnet. In der Painter klasse werden diese in eine Arraylist speichert (die koordinaten) und alle 24stel sekunden frisch gezeichnet.
Die Gui klasse erbt von der klasse LINIE in der die Koordinaten und die g.drawLine() methode definiert sind. Somit sitzt die paint methode eigentlich auch in der klasse LINIE.

Ja das JPanel ist zum Zeitpunkt des Zeichnens sichtbar.
 
In der Painter klasse werden diese in eine Arraylist speichert (die koordinaten) und alle 24stel sekunden frisch gezeichnet.

Wieso alle 24stel sekunden? Zeichnest du deine Graphikobjekte von ausserhalb durch übergeben der Graphics auf dein Panel drauf oder wie? Erscheint mir ein bisschen suboptimal und würde erklären warum es nicht hinhaut.
 
Wieso alle 24stel sekunden? Zeichnest du deine Graphikobjekte von ausserhalb durch übergeben der Graphics auf dein Panel drauf oder wie? Erscheint mir ein bisschen suboptimal und würde erklären warum es nicht hinhaut.

da ich java anfänger bin verstehe ich nicht ganz was du meinst. aber ich glaube es geht in diese richtung. Ich übergebe das graphics objekt in einen Thread der dann alles 24stel sekunden neu zeichnet.

Was wäre hier eine schlaue Lösung?
 
Nein ist es nicht. Du musst deine Objekte nicht bei jedem Frame (im Sinne von fps -Frame pro Sekunde) oder so jedes mal neu Zeichnen. Das macht Java ganz von alleine. Du solltest nur in deiner Paint methode auf die Graphics deines Panels zeichnen, Java ruft paint selbständig auf, sobald was neues zu zeichnen ist (z.b wenn sich die Größe ändert oder ein anderes Fenster drübergeschoben wird). Ein manuelles Zeichnen alle paar millisekunden ist schätze ich auch performancemäßig Horror.
Mein Ansatz für dein Problem wäre, eine Klasse BildPanel die von JPanel erbt. Der gibst du deine Arraylist mit den Objekten und überschreibst die paintComponent Methode dort.
 
Vielen Dank für die ausführliche Antwort. Werde mir diesen Ratschlag zu herzen nehmen und dies später so umsetzen.
Im Moment habe ich das Problem mit einem "Robot" gelöst. Ich fertige einfach einen Screenshot des Zeichenpanels an und speichere diesen. Die Qualität ist nicht die beste 😛

Java:
public void takeSnapShot(JPanel fenster){  
		 try {
	           java.awt.Robot robot = new java.awt.Robot();                 
	           BufferedImage img = robot.createScreenCapture(new    Rectangle(fenster.getLocationOnScreen().x,fenster.getLocationOnScreen().y,
	                fenster.getWidth(),fenster.getHeight()));            		
	            		
	            ImageIO.write(img, "png", new File("speichern.png"));
	            		}
	            		catch (Exception ex) {System.out.println(ex);
	            		}
	            		
	            		}
 
Ein PNG sollte eigentlich verlustfrei (d.h. mit "voller" Qualität) gespeichert werden.
(Ich wollte übrigens oben andeuten, dass er eben auch jeden x-Beliebigen anderen Bildschirminhalt abfotografieren würde, wenn z.B. ein anderes Fenster vor dem eigenen ist.. aber das nur nebenbei)
 

Neue Themen


Zurück
Oben