2D-Grafik PNG Bild per Graphics auf JPanel

reschiram

Mitglied
Hey Leute,

Ich versuche seit circa ne Woche nen Problem zu lösen wobei selbst google mir nicht helfen konnte🙁.
Java:
JPanel Kontinent = new JPanel();
 
    public KontinentEditor(Main main,Planet planet){
        Main = main;
        Planet = planet;     
        design();
     
        main.Fenster.setSize(1580, 1000);     
        main.Fenster.add(TeileListe.ScrollPane);
             
        Kontinent.setBounds(225, 125, 1430,880);
        main.Fenster.add(Kontinent);
        Kontinent.setLayout(null);
        Kontinent.setVisible(true);
        Kontinent.setOpaque(true);

            Kontinent.getGraphics().drawImage(new ImageIcon("./Data/Sea.png").getImage(),0,0,null);
    }
(Wenn ihr noch mehr vom Code sehen wollt sagt bescheid)

Das Problem ist: Das Bild das ich auf das JPanel setzte erscheid für ca. ne millisekunde da es kurz blau wird aber dann verschwindet es.
Das Bild ist exat an der Stelle ("./Data/Sea.png" | Windows Explorer sagt (F:\My Games\Game\Data\Sea.png) aber da die .jar in F:\My Games\Game ist das das gleiche).
Aufruf der Methode Repaint für JFrame und Kontinent helfen beide dabei nicht.

Die Methode design fügt nur JButtons,JTextfields etc. hinzu ohne extra graphics.

Oh und es gibt natürlich keine Fehlermeldung 🙁
 
Ich versuche seit circa ne Woche nen Problem zu lösen wobei selbst google mir nicht helfen konnte
Komisch. Googlen nach "java paint png on jpanel" gibt mehrere hilfreiche Treffer, die auch noch Hintergrundwissen vermitteln.
Kontinent.getGraphics().drawImage(new ImageIcon("./Data/Sea.png").getImage(),0,0,null);
So wird in Swing NICHT gezeichnet. Kurzfassung: Du holst die den Graphics2D der Component, zeichnest da was drauf, und das nächste mal, wenn die Komponente neu gezeichnet werden muss (z. B. weil sie verdeckt war und dan wieder sichtbar wurde), ist der Zauber verschwunden.
Langfassung mit Hintergrundwissen:http://www.java-forum.org/thema/zeichnen-in-swing-tutorial.146458/
 
Ja es ist richtig das man zu dem Thema fiel auf Google findet allerdings nur in diesem Format:
Java:
public void paintComponent(Graphics g) {
          super.paintComponent(g);
          if (this.icon != null) {
              g.drawImage(icon.getImage(), 0, 0, this);
          }
      }
Ich versuche es aber ohne extra dafür eine neue Klasse erstellen zu müssen. Dazu (so wie ich es oben geschrieben habe) findet man nichts deratiges bei Google(1,2 Seite).
Und was ich mich auch frage wo ist der Unterscheid ist ob ich jetzt in der Klasse den Aufruf stehen habe oder außerhalb(meines Wissens nach ist da nämlich keiner).
Es ist richtig das wenn Komponente neu gezeichnet werden muss der "Zauber" (XD) verschwindet,allerdings passiert nach dem Kontient.getGraphics().draw... nichts mehr und zweitens würde der Aufruf repaint() den "Zauber" wiederherstellen tut es aber nicht.
 
Du kannst beim Kontinent die Methode während der Instantiierung überschreiben, dann brauchst keine neue Klasse erstellen.

Java:
JPanel Kontinent;
    
    public KontinentEditor(Main main,Planet planet){
       // dein code
    
        ImageIcon icon = new ImageIcon("./Data/Sea.png");
        Kontinent = new JPanel() {
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (icon != null) {
                    g.drawImage(icon.getImage(), 0, 0, this);
                }
            }
        };

       // rest von deinem code        
    }
 
Hey,
erstmal danke für die ganzen Vorschläge und sorry das ich so lange gebraucht habe.
repaint sorgt dafür das paint bzw. paintComponent erneut aufgerufen wird
Ah okey danke das wusste ich nicht, nur ist es so das das Image (der "Zauber") nicht verschwinden sollte, da die Komponente ja nach dem "Zauber" nichts tut/nichts mit ihr passiert.
Danke XyMorgan das hat super funktioniert 🙂 könntest du mir nur einmal noch den Unterschied zwischen dem was du da stehen hast und dem was ich da stehen hatte erklaren? Its ja doch imprinzip der selbe Aufruf (Kontinent.getGraphics().drawImage(new ImageIcon("./Data/Sea.png").getImage(), 0, 0, this)😉
 
Danke XyMorgan das hat super funktioniert 🙂 könntest du mir nur einmal noch den Unterschied zwischen dem was du da stehen hast und dem was ich da stehen hatte erklaren? Its ja doch imprinzip der selbe Aufruf (Kontinent.getGraphics().drawImage(new ImageIcon("./Data/Sea.png").getImage(), 0, 0, this)😉
Seine Variante überschreibt, wie die 10 Mal in diesem Thread genannte paintComponent-Methode. Das GraphicsObjekt wird sozusagen "intern" bereitgestellt und alles läuft smoth.
mit .getGraphics() greifst du aktiv und "gewalttätig" ein und holst dir, ohne zu Fragen ein Graphics-Objekt. Zudem kommt, dass wenn du das einmal aufrufst es nur ein einziges mal gezeichnet wird.
Wenn man die paintComponent() überschreibt, wird das Bild jedesmal gezeichnet, wenn es sein muss: d.h. auch wenn das Betriebsystem sagt: hey da ist was überdeckt worden, zeichne neu!

Außerdem ... ist dieses Denken:

Ich versuche es aber ohne extra dafür eine neue Klasse erstellen zu müssen.
Falsch!
Man sollte so viel wie möglich versuchen, Klassen nur eine einzige Aufgabe zu geben. Obiger Code von XyMorgan funktioniert zwar, ist allerdings nicht zu empfehlen. Solche Konstrukte sind sehr schlecht lesbar und ich denke er hat den Code nur gepostet, um deiner Voraussetzung gerecht zu werden.

Und noch was: ImageIcon ist nett, wenn es darum geht ein Bild als Komponente darzustellen. Wenn du es aber nur zeichnen lassen willst, ist ein BufferedImage die bessere Wahl.
 
Obiger Code von XyMorgan funktioniert zwar, ist allerdings nicht zu empfehlen. Solche Konstrukte sind sehr schlecht lesbar und ich denke er hat den Code nur gepostet, um deiner Voraussetzung gerecht zu werden.

100% agree, wobei wenn es nur eine Stelle ist ....... 🙂

Und noch was: ImageIcon ist nett, wenn es darum geht ein Bild als Komponente darzustellen. Wenn du es aber nur zeichnen lassen willst, ist ein BufferedImage die bessere Wahl.

Sehe ich auch so, wobei natürlich ImageIcon den Charm hat, dass das Bild geladen wird. Sonst musst nen eigenen Loader nehmen und/oder Umwandeln. Wenn man solche GUIs öfter baut, ist es sicher nicht verkehrt Bilder selber zu laden. ImageIcon ist halt auch nicht wirklich für sowas gedacht.
 

Zurück
Oben