Swing JPanel Bild einfügen

Hatsi09

Aktives Mitglied
Hallo,

habe mehrere Beiträge zu dem Thema hier gelesen und versucht den Fehler zu finden, aber es funktioniert nicht. Mein Code lautet:
habe mir eine Klasse PicturePanel geschrieben wie folgend;
Code:
class PicturePanel extends JPanel {
   private Image image;
 
   public PicturePanel(String bild) {
      super(new GridBagLayout());

      try {
         image = ImageIO.read(getClass().getResource(bild));
      }
      catch(IllegalArgumentException iae) {
         JOptionPane.showMessageDialog(this, "Grafikdatei nicht gefunden!\n"+iae.getMessage());
      }
      catch(IOException ioe) {
         JOptionPane.showMessageDialog(this, "Fehler beim Einlesen einer Grafikdatei!\n"+ioe.getMessage());
      }
   }
 
   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if(image != null) { //Bild muss im Speicher liegen, sonst wird nichts gezeichnet
         g.drawImage(image, 0, 0, this);
      }
   }
}

In der Klasse, wo ich das haben will, erstelle ich dann ein Object der Klasse:
Code:
stimmenIcon.setLayout(new FlowLayout());
PicturePanel picture = new PicturePanel("Piccolo.png");
stimmenIcon.add(picture);

stimmenIcon ist hierbei ein JPanel, dass ich bereits eingebaut habe, und in diesem das Bild angezeigt werden soll.
Allerdings bleibt dieses JPanel leer, wenn ich die Befehle ausführe.
Was mach ich falsch, verzweifle langsam 😱

Vielen Dank für eure Hilfe
 
Wenn Du bei den Code-Tags angibst, dass es sich um Java-Code handelt, dann wird das hier auch schön bunt 🙂

Jetzt zum Problem. Ein JPanel ist als Container für weitere Komponenten gedacht. Die bevorzugte Größe des Containers wird in der Regel vom LayoutManager anhand des Inhalts berechnet.

Dein PicturePanel hat keinen Inhalt, folglich keine bevorzugte Größe. Da das FlowLayout des stimmenIcon-Containers Komponenten nicht vergrößert, hat Dein PicturePanel am Ende keine Größe.

Es gibt also zwei Möglichkeiten:
1. füge Komponenten hinzu oder
2. setze eine bevorzugte Größe.

Im Fall von 2 stellt sich mir aber die Frage nach der Sinnhaftigkeit Deiner Klasse, denn um ein Bild anzuzeigen, kann ein JLabel verwendet werden:

Java:
ImageIcon icon = new ImageIcon(getClass().getResource("Piccolo.png"));
JLabel picture = new JLabel(icon);
stimmenIcon.add(picture);
 
ja habe zwei Packages, habe aber dieses Bild in beiden, da ich mir schon dachte, dass es Probleme gibt, wenn das in einem anderen Package ist
(vllt. kannst du mir verraten, wie ich da ein Bild aus einem anderen Package einfüge?)
 
Indem Du den Packagenamen angibst: getResource("/org/javaforum/hatsi09/bilder/Piccolo.png"), wobei org.javaforum.hatsi09.bilder natürlich das Package ist. Probier das mal in der Form.
 
jetzt ist die Exception weg, aber es wird immer noch nix angezeigt

habe jetzt einfach mal am Ende pack() hingeschrieben, jetzt wird mir das Bild angezeigt, allerdings 2mal nebeneinander und es zerhaut mir das Layout 🙁
 
Zuletzt bearbeitet:
Wie erstellst Du denn das Fenster inkl. der Komponenten? Kannst Du mal den relevanten Code zwischen Code-Tags ([code=Java]Dein Code[/code]) hier rein kopieren?
 
den Code willst du nicht sehen, dass sind knapp 2000 Zeilen Code, weil das eine große GUI ist, unterteil in 7 TabbedPane und diese haben wieder unterKomponeten ich suche dir mal die relevanten Stellen raus, dauert aber ein bisschen
 
Also hier mal zusammengestellt:
Java:
stimmenIcon = new javax.swing.JPanel();
...
javax.swing.GroupLayout stimmenIconLayout = new javax.swing.GroupLayout(stimmenIcon);
        stimmenIcon.setLayout(stimmenIconLayout);
        stimmenIconLayout.setHorizontalGroup(
            stimmenIconLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        stimmenIconLayout.setVerticalGroup(
            stimmenIconLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 193, Short.MAX_VALUE)
        );
...
pack();

Ich hoffe ich hab alles. Und dann halt die Methode von oben:
Java:
private void konzertStimmenitemSetzen(java.awt.event.ItemEvent evt) {                                         
        String item = konzertStimmenauswahl.getSelectedItem().toString();
        String bild = "";
        switch(item)
        {
            case "Piccolo" : bild = "/material/Piccolo.png";
                             break;
        }
        stimmenIcon.setLayout(new FlowLayout());
        ImageIcon icon = new ImageIcon(getClass().getResource(bild));
        JLabel picture = new JLabel(icon);
        stimmenIcon.add(picture);
        pack();
    }

Also das pack() am Ende, habe ich erst jetzt hinzugefügt, das führt dazu, dass das Bild angezeigt wird, allerdings 2x nebeneinander und zerschießt mir das Layout
 
OK, erst einmal das Wichtigste: es scheint, dass Du in einem EventListener bei jedem Auftreten eines Ereignisses Deinem stimmenIcon ein JLabel hinzufügst. Füg stattdessen das JLabel einmalig Deinem Contaner hinzu und verwende in Deinem EventListener JLabel#setIcon.

Dann: das stimmenIconLayout kannst Du Dir vermutlich sparen, wenn Du es später durch ein FlowLayout ersetzt.

Wesentlich interessanter ist das switch: das sollte ganz entfallen. Das kann im besten Fall dadurch geschehen, dass der Listeneintrag ein Objekt ist, das seine Ressource kennt. Auch möglich wäre eine Map.
 

Neue Themen


Zurück
Oben