2D-Grafik paint-Methode wird zu oft ausgeführt

krgewb

Top Contributor
Ich möchte zwei Bilder (AlbDonauKreis_t.png und BadenBaden_t.png) zeichnen.
In dem Code ist die Zeile
Java:
System.out.println("Huhu");
Anhand der Ausgabe erkenne ich, dass die paint-Methode viermal aufgerufen wird.
Ich habe bereits erfahren, dass man niemals etwas in die paint-Methode schreiben sollte. Ich weiß jedoch nicht, wie ich es sonst machen soll.

Java:
package de.uebung;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Hauptfenster extends JFrame {
    private static final long serialVersionUID = 1L;
    Container zeichenpane;
    Bildpanel bildpanel;

    public Hauptfenster() {

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setTitle("BW");

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setTitle("BW");
        this.setSize(650, 650);

        bildpanel = new Bildpanel(this);
        zeichenpane = this.getContentPane();
        zeichenpane.setLayout(new FlowLayout(FlowLayout.LEADING));
        zeichenpane.add(bildpanel);

        this.pack();
        this.setVisible(true);
    }

}

class Bildpanel extends JPanel {
    private static final long serialVersionUID = 1L;

    private Image bild01;
    private Image bild02;
    private int breite = 500;
    private int hoehe = 565;

    private String trenner = System.getProperty("file.separator");

    private String pfad = "";
    private String dateiname01 = "";
    private String dateiname02 = "";

    private Hauptfenster haupt;

    public Bildpanel(Hauptfenster haupt) {
        this.haupt = haupt;
        this.setPreferredSize(new Dimension(500, 565));

        pfad += this.getClass().getClassLoader().getResource("").getPath();
        pfad += trenner + "de" + trenner + "weingartenvideos" + trenner + "bilder" + trenner;

        dateiname01 = pfad + "AlbDonauKreis_t.png";

        System.out.println(dateiname01);

        if (dateiname01.length() != 0) {

            // Imageobjekt erzeugen
            bild01 = this.getToolkit().getImage(dateiname01);

            // Ladevorgang starten
            boolean prepared = this.prepareImage(bild01, this);

            if (prepared == true)
                System.out.println("Bild01 fertig");
            else
                System.out.println("Bild01 nicht fertig");
        }

        dateiname02 = pfad + "BadenBaden_t.png";

        if (dateiname02.length() != 0) {
            bild02 = this.getToolkit().getImage(dateiname02);
            boolean prepared = this.prepareImage(bild02, this);

            if (prepared == true)
                System.out.println("Bild02 fertig");
            else
                System.out.println("Bild02 nicht fertig");
        }

    }

    // Zeichnen der Bilder
    @Override
    public void paint(Graphics g) {

        // Konvertierung Garphicsobjekt nach Java2D
        Graphics2D g2d = (Graphics2D) g;

        System.out.println("Huhu");

        // Bild nur zeichnen, wenn eine Bilddatei angegeben ist
        if (dateiname01.length() != 0) {

            try {
                // warten, sonst wird ERROR nicht korrekt erkannt
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // Bild zeichnen
            g2d.drawImage(bild01, 0, 0, breite, hoehe, this);
        } else {
            System.out.println("Leerer Dateiname");
        }

        if (dateiname02.length() != 0) {

            try {
                // warten, sonst wird ERROR nicht korrekt erkannt
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // Bild zeichnen
            g2d.drawImage(bild02, 0, 0, breite, hoehe, this);
        }

        haupt.pack();

    }

}

class Hauptprogramm {

    public static void main(String[] args) {
        Hauptfenster haupt = new Hauptfenster();
        haupt.bildpanel.repaint();
    }

}
 
Zuletzt bearbeitet:
Was soll denn passieren bzw. was ist dein Problem damit?
Wenn ich es nun erweitere und 40 Bilder reintue kommt es zu einer Exception
Code:
Exception in thread "Image Fetcher 3" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferInt.<init>(Unknown Source)
    at java.awt.image.Raster.createPackedRaster(Unknown Source)
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown Source)
    at sun.awt.image.ImageRepresentation.createBufferedImage(Unknown Source)
    at sun.awt.image.ImageRepresentation.setPixels(Unknown Source)
    at sun.awt.image.ImageDecoder.setPixels(Unknown Source)
    at sun.awt.image.PNGImageDecoder.sendPixels(Unknown Source)
    at sun.awt.image.PNGImageDecoder.produceImage(Unknown Source)
    at sun.awt.image.InputStreamImageSource.doFetch(Unknown Source)
    at sun.awt.image.ImageFetcher.fetchloop(Unknown Source)
    at sun.awt.image.ImageFetcher.run(Unknown Source)
 
1) Erbe nicht von JFrame
2) Erbe von JPanel oder JComponent, überschreibe die paintComponent(Graphics g)-Methode. (und rufe die paintComponenet(g) von der super-Klasse als erstes auf...)
3) Lade deine Bilder nicht mit Toolkit, sondern mit ImageIO: https://docs.oracle.com/javase/8/docs/api/javax/imageio/ImageIO.html
4) Schreibe niemals Thread.sleep in die paint-Methoden!
5) Schreibe sonst keine Logik in paintMethoden.
6) dateiname01.length() != 0 ist unnötig, wenn der Code dateiname01 = pfad + "AlbDonauKreis_t.png"; darübersteht.
(Dort wird String-Länge geprüft ~ NICHT Dateigröße oder soetwas.)
 
Zuletzt bearbeitet:
Danke! Ich habe es nun mit ImageIO gemacht. Die PNG-Dateien werden jedoch nicht angezeigt. Bei BMP- und JPG-Dateien funktioniert es problemlos. Ich brauche aber PNG wegen der Transparenz.
 

Zurück
Oben