Bild in JPanel nicht angezeigt

JustinSane

Mitglied
Hallo!

hab jetzt schon länger in Foren, tutorials, oracle usw gesucht, aber leider zu meinem Problem keine wirkliche Lösung gefunden.

Es geht grundsätzlich darum, dass ich ein Panel habe, dass sich aus 2 weiteren Panels zusammen setzt (alles Swing-Komponenten). Im oberen Panel werden meine Buttons dargestellt und im unteren soll ein Bild angezeigt werden. (soll ein einfaches Bildbearbeitungsprogramm werden)
Die App soll dann aus diesem Panel bestehen und wenn ein Bild geöffnet wird, die Methode initImg(img) aufgerufen werden.
Das Problem ist nun jedoch das, dass mein Bild einfach nicht gemalen wird.

Der Quellcode des Jpanels ist

Java:
public class ImageEditingPanel extends javax.swing.JPanel {

    private boolean pictureLoaded;
    private float displayedHeight;
    private float displayedWidth;
    private int horCenter;
    private int vertCenter;
    private float imgWidth;
    private float imgHeight;
    private Image img;
    private boolean crop;
    private Rectangle rect;
    private Image originalImg;
    private float[] displayedSizes = new float[2];
    private DisplayImage displayImg;
    private ObserveImageChanges changeObserver;
    private ArrayList<Image> undo;
    private ArrayList<Image> redo;
    private boolean init;

    public ImageEditingPanel() {
        initComponents();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (!init) {
            initComponents();
            init = true;
        }
        if (pictureLoaded) {
            horCenter = editingPanel.getWidth() / 2 - (int) displayedWidth / 2;
            vertCenter = editingPanel.getHeight() / 2 - (int) displayedHeight / 2;
            g.drawImage(img, horCenter, vertCenter, (int) displayedWidth, (int) displayedHeight, this);
        }
        if (crop) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(Color.red);
            g2.setStroke(new BasicStroke(5));
            g2.draw(rect);
            CropImageShape cropImgShape = new CropImageShape(this);
            this.addMouseListener(cropImgShape);
            this.addMouseMotionListener(cropImgShape);
        }
    }

    public void initImage(Image img) {
        this.originalImg = img;
        this.img = originalImg;
        imgWidth = img.getWidth(this);
        imgHeight = img.getHeight(this);
        displayImg = new DisplayImage(img, editingPanel);
        displayedSizes = displayImg.resize2WindowHeight();
        displayedWidth = displayedSizes[0];
        displayedHeight = displayedSizes[1];
        changeObserver = new ObserveImageChanges(img);
        undo = changeObserver.getUndo();
        redo = changeObserver.getRedo();
        pictureLoaded = true;
        redrawImg(img);
    }

    public Image resetChanges() {
        return originalImg;
    }

    public void redrawImg(Image img) {
        changeObserver.observeImageChanges(img);
        this.img = img;
        this.repaint();
    }
 
Du machst das ja viel zu kompliziert, die ganzen Observer brauchst du nicht mehr, das ist ein relikt aus vergangener Zeit (ich glaub das hing mit Applets und dem langsamen Internet zusammen).
Hast du z.B schonmal überprüft ob pictureLoaded auch true wird?
 
ja, das mit den Observern habe ich auch schon herausgefunden, aber in dem Tutorial, das ich gelesen habe, steht, dass man die Observer nicht braucht, aber angeben muss. Also habe ich entweder null oder wie von Netbeans vorgeschlagen gleich this genommen.

Zu der zweiten Frage: Ja, wird true! und das Image wird auch richtig geladen. Erhalte die gesamten Bildinformationen, wenn ich sie mir ausgeben lasse und auch die richtige Größe.
Damit kann es meiner Meinung nicht zu tun haben, glaube eher, dass ich das Bild vielleicht wieder sofort übermale?!
 
Hmm da würde nur ein KSKB Aufklärung schaffen. Du könntest auch mal dem Panel eine andere Hintergrundfarbe geben, damit du siehtst wie groß es ist und was übermalt wird.
 
habe ich ebenfalls schon versucht! Das Panel wird auch richtig angezeigt und hin und wieder bei einer Interaktion (zB drücken eines Buttons) auch das Bild ganz kurz, aber es verschwindet sofort wieder... Deshalb auch meine Idee, dass es sofort wieder übermalen wird. Aber eigentlich, wenn man den Code betrachtet wird ja das Panel zuerst gezeichnet und dann erst das Bild darüber gezeichnet, oder?
 
hat keiner eine Idee woran es liegen könnte, dass mein Bild nach dem Bruchteil einer Sekunde wieder verschwindet?
Finde in anderen Threads mit dem gleichen Problem überall nur, dass die Leute die paintComponent() nicht bzw. falsch überschreiben. Aber bei mir müsste sie doch passen, oder?
 
Zeichne dein Bild doch erst in ein BUfferedImage und zeichne das dann in dein Panel.
Ich kann den fehler bei dir jetzt auch nicht direkt entdecken, is halt viel zeugs im code, der mMn nicht sein müsste.

wenn du manipulationen am Bild vornimmst, würde ich immer den "Umweg"über das BufferedImage gehen und in der paintComponent wirklich nur das Bild draufpinseln.

Ist auch vom Code her eleganter.

Gruß Vanny

Java:
private BufferedImage createDrawImg(int x, int y){
BufferedImage bi = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(deinBild, 0, 0, x, y);
g2d.dispose();
}

public void paintComponent(Graphics g){
super.paintComponent(g);
BufferedImage img = createDrawImg(10, 10);//dieser Schritt ist nicht nötig, gient aber der Übersicht in diesem Beispiel
g.drawImage(img, 0, 0, 10, 10)
}

//is jetzt so im Forum getippt, wenn ich was vergessen haben sollte sagt bescheid ;P
 
Zuletzt bearbeitet von einem Moderator:
[ot]ich würde ja 100 imaginäre JaFo-Talers darauf wetten, dass wenn du die
[java=30] //init = true;[/code]
auskommentierst, dein Bild angezeigt wird.[/ot]
 
@jgh gut, dass du nicht wirklich darauf gewettet hast, die Taler wären sonst jetzt weg! 😉

Das Problem war wirklich, dass es anscheinend daran gelegen ist, dass ich ein Image und nicht ein BufferedImage zeichnen lassen wollte! Also vielen Dank an vanny für den super Tipp! Glaube ich hätte sonst ewig herumgesucht und keinen Fehler entdeckt...

Hat aber irgendwer von euch auch eine Erklärung dafür, warum das Bild nur als BufferedImage gezeichnet wurde und nicht als Image? Habe diesbezüblich nirgends eine Erklärung gefunden, würde mich aber doch irgendwie interessieren 🙂
 

Zurück
Oben