Geladenes Bild wird nicht in JPanel angezeigt

sum41

Mitglied
Hallo,

da ich mich schon zu tode gesucht habe und nichts passendes gefunden habe, was mein Problem lösen könnte, poste ich es hier einfach mal:

Über einen Button wird ein JFileChooser aufgerufen, mit dem ein Bild geladen werden kann.
Dieses Bild soll dann in das dafür vorgesehene JPanel gezeichnet werden.

Es scheint, dass einfach die GUI (das Panel) nach dem Klick auf den entsprechenden Button und dem anschließendem Auswählen des Bildes einfach nicht neu gezeichnet zu werden.

Lasse ich das Ganze in einer anderen "Testklasse" bei der Initialisierung laufen, funktioniert es.

Innere Klasse, die das Bild laden und zeichnen soll:
Java:
class HoleBild extends JPanel {

        private String imageURL;
        private BufferedImage pic;
        

        private HoleBild() {
            getImageURL();

        }

        private String getImageURL() {

            JFileChooser chooser = new JFileChooser();
            FileNameExtensionFilter filter = new FileNameExtensionFilter(
                    "JPG & GIF Images", "jpg", "gif");
            chooser.setFileFilter(filter);
            int returnVal = chooser.showOpenDialog(this);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                imageURL = chooser.getSelectedFile().getAbsolutePath();
            }
            return imageURL;
        }

        @Override
        public void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;

            try {
                File f = new File(imageURL);
                if (!f.canRead()) {
                    JOptionPane.showMessageDialog(EditProdukt.this, "Bild kann nicht geladen werden.");
                }

                pic = ImageIO.read(f);
                g2.drawImage(pic, 20, 20, this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
Hier soll das Bild in das Panel eingefügt werden:
(Das Panel bleibt aber leer!)
Java:
JPanel produktPicPanel1 = new JPanel();
    private void addFurtherComponents(){
                HoleBild hb = new HoleBild();
                produktPicPanel1.add(hb);
                produktPicPanel1.validate();
                produktPicPanel1.repaint();
                jPanel1.repaint();
    }
Button, der die Klasse aufruft und das Panel neu zeichnen soll:
Java:
private void btnChooseImageActionPerformed(java.awt.event.ActionEvent evt) {                                               

        addFurtherComponents();
    }
 
So wie ich das sehe, lässt du dir zwar den Pfad geben aber du machst nichts damit. Die getImageUrl()-Methode läuft sozusagen leer.
 
Stimmt. Der unnütze return Wert hat mich verwirrt. Mein Fehler. 🙂

lass dir mal mit Sysouts jeden Schritt und sein Ergebnis bestätigen.
 
Der Pfad der Datei wird über den FileChooser korrekt angezeigt.

Wenn ich mit aber den Pfad des File-Objekts mit f.getPath() geben lassen will, bleibt dies leer.
Ich vermute also, dass die paintComponent-Methode nicht aufgerufen wird.
Woran kann das liegen?
 
Ich verstehe viele Dinge deines Programms nicht.

Zum Beispiel deine Vermutung die paintComponent-Methode würde nicht aufgerufen, kannst du selbst schnell verifizieren, indem du darin einen Breakpoint setzt.

Weiterhin ist klar, das die paintComponent auch aufgerufen wird, BEVOR du irgendwas mit FileChoosers machst. Ich sehe keinen Code, der darauf reagiert.

Warum du überhaupt ein Bild in paintComponent malst, ist mir ebenfalls unklar. Ich würde ein JLabel nehmen und dieses auf dem JPanel platzieren.
 
Ich habe nun das Zeichnen des Bildes in eine neue Klasse ausgelagert.
Das Bild wird nun als ein JLabel zurückgegeben.
Java:
public class DrawImage extends JPanel{
    
    private String imageURL;
    private JLabel label;
    BufferedImage pic;
    
    public DrawImage(){
        getImageURL();
    }
    
    @Override
    public void paintComponent(Graphics g){
         Graphics2D g2 = (Graphics2D) g;
         File f = new File(imageURL);
        try {
            pic = ImageIO.read(f);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(g2.drawImage(pic, 20, 20, this)){
                  System.out.println("ZEICHNEN OK");
              }else{
                  System.out.println("FEHLER BEIM ZEICHNEN DES BILDES");
              }
    }
    
     public String getImageURL(){
       
       JFileChooser chooser = new JFileChooser();
    FileNameExtensionFilter filter = new FileNameExtensionFilter(
        "JPG & GIF Images", "jpg", "gif");
    chooser.setFileFilter(filter);
    int returnVal = chooser.showOpenDialog(this);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
           /*System.out.println("You chose to open this file: " +
                chooser.getSelectedFile().getName());*/
           imageURL = chooser.getSelectedFile().getAbsolutePath();
          
        }
        return imageURL;
   }
     
     public JLabel getImage(){
         return label = new JLabel(new ImageIcon(imageURL));
     }
}

Im eigentlichen JPanel sitzt der Button, der die Klasse "DrawImage" aufrufen soll und das Bild auf das Panel "produktPicPanel1" zeichnen soll:
Java:
private void btnChooseImageActionPerformed(java.awt.event.ActionEvent evt) {                                               
        DrawImage di = new DrawImage();
        
        produktPicPanel1.add(di.getImage());
    }

In der Klasse "DrawImage" wird die paintComponent nicht durchlaufen und auch die getImage() nicht?
 
Zuletzt bearbeitet:
Ich glaube du hast mich falsch verstanden.

Hier mal meine kleine Demo

Java:
import java.awt.BorderLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class HoleBild extends JPanel {
	private JButton ladeBild;
	private JLabel bild;

	public HoleBild(final JFrame frame) {
		setLayout(new BorderLayout());
		ladeBild = new JButton("lade bild...");
		add(ladeBild, BorderLayout.NORTH);
		ladeBild.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					JFileChooser fc = new JFileChooser();
					if (fc.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
						File selectedFile = fc.getSelectedFile();
						URL resource = selectedFile.toURI().toURL();
						ImageIcon imageIcon = new ImageIcon(resource);
						bild.setIcon(imageIcon);
						frame.pack();
					}
				} catch (HeadlessException e1) {
					e1.printStackTrace();
				} catch (MalformedURLException e1) {
					e1.printStackTrace();
				}
			}
		});
		bild = new JLabel();
		add(bild, BorderLayout.CENTER);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Bild");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new HoleBild(frame));
		frame.pack();
		frame.setVisible(true);
	}
}
 

Zurück
Oben