# WARUM wird paintComponent nicht aufgerufen?



## ernst (7. Feb 2010)

Hallo allerseits,
Mit dem Visual-Editor von Netbeans habe ich eine _einfache_ grafische Oberfläche erzeugt.
Dort soll sich von links nach rechts ein Ball bewegen.
Meine Frage:
Warum wird die Methode paintComponent nicht aufgerufen?
Was muß ich machen, damit diese aufgerufen wird?
Wer kann mir helfen? ich komme hier nicht weiter !

mfg
Ernst



```
package packT1;

public class MyJFrame extends javax.swing.JFrame {

    public MyJFrame() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jPanel1.setBackground(new java.awt.Color(255, 255, 102));
        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel1.setLayout(new java.awt.BorderLayout());

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(43, 43, 43)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 308, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(49, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(71, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
//                new MyJFrame().setVisible(true);
            MyJFrame myJFrame = new MyJFrame();
            myJFrame.setSize(700, 700);
            MyJPanel myJPAnel  = new MyJPanel();
            myJFrame.getContentPane().add(myJPAnel);
            myJFrame.setVisible(true); 
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JPanel jPanel1;
    // End of variables declaration

}
```



```
package packT1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class MyJPanel extends javax.swing.JPanel {
    private Timer t;
    private Ball  ball;

    public MyJPanel() {
        initComponents();
        ball = new Ball(this);
        t = new Timer(20,
                new ActionListener() {

                    public void actionPerformed(ActionEvent ae) {
                        System.out.println("Hallo1");
                        myupdate();
                        repaint();
                    }
                });

        t.start();
    }

    public void setTimer(int millis) {
        t.setDelay(millis);
    }


    public int getTimerTime() {
        return t.getDelay();
    }

    public void myupdate() {
        ball.berechnePos();
    }

// ??????????????????????????????????????????????????????????????
// ????  Warum wird dieses paintComponent nicht aufgerufen  ?????
// ??????????????????????????????????????????????????????????????

    public void paintComponent(Graphics g) {
        System.out.println("Wo befindet sich Hallo2");
/*
        super.paintComponent(g);
        Point pos;
        pos = ball.getPos();
        g.drawImage(ball.getImage(), pos.x, pos.y, this);
        System.out.println("Wo befindet sich Hallo2");
*/
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        setLayout(new java.awt.BorderLayout());
    }// </editor-fold>


    // Variables declaration - do not modify
    // End of variables declaration

}
```




```
package packT1;

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Ball {
    // x-Koordinate der Kugel
    private int x;
    // y-Koordinate der Kugel
    private int y;
    // Das Bild der Kugel befindet sich als Datei auf Festplatte
    private BufferedImage bild;
    private MyJPanel myJPanel;

    public Ball(MyJPanel pspielJPanel){
        try {
            myJPanel = pspielJPanel;
            bild = ImageIO.read(new File("meinebilder/ball.png"));
        } catch (IOException ex) {
            System.out.println("Datei existiert nicht:" +ex.toString());
            ex.printStackTrace();
            System.exit(0);
        }
    }


    public BufferedImage getImage() {
        return bild;
    }

    public void berechnePos() {
        if( x < myJPanel.getWidth()){
           x+=3;
        }
        else{
           x=0;
        }
        System.out.println("myJPanel.getWidth()="+myJPanel.getWidth());

    }

    public Point getPos() {
       return new Point(x, y);
    }

}
```


----------



## Gast2 (7. Feb 2010)

Warum sollte es auch???
Du erstellst nirgends ein Objekt von MyJPanel ...


----------



## ernst (7. Feb 2010)

SirWayne hat gesagt.:


> Warum sollte es auch???
> Du erstellst nirgends ein Objekt von MyJPanel ...



Doch Zeile 47 in MyJFRame
MyJPanel myJPAnel  = new MyJPanel();

mfg
Ernst


----------



## icarus2 (7. Feb 2010)

Damit eine Komponente seinen Inhalt neu zeichnet musst du die Methode repaint() aufrufen.

In deinem Fall myJPanel.repaint()


----------



## SlaterB (7. Feb 2010)

Ausgabe erscheint bei mir mit untenstehenden Programm, durch den Timer sehr oft,
habe deins vereinfacht, mit manchem von deinem Code (wie initComponents() in MyPanel)
gehts auch, aber lohnt nicht da weiter zu schauen,

kannst deins nach und nach alles einbauen 


```
public class Test {

	public static void main(String[] args) throws Exception {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				MyJFrame myJFrame = new MyJFrame();
				myJFrame.setSize(700, 700);
				MyJPanel myJPAnel = new MyJPanel();
				myJFrame.getContentPane().add(myJPAnel);
				myJFrame.setVisible(true);
			}
		});

	}
}

class MyJFrame extends JFrame {

}

class MyJPanel extends JPanel {
	private Timer t;

	public MyJPanel() {
		t = new Timer(20, new ActionListener() {

			public void actionPerformed(ActionEvent ae) {
				System.out.println("Hallo1");
				repaint();
			}
		});

		t.start();
	}

	public void paintComponent(Graphics g) {
		System.out.println("Wo befindet sich Hallo2");
	}

}
```


----------



## ernst (7. Feb 2010)

icarus2 hat gesagt.:


> Damit eine Komponente seinen Inhalt neu zeichnet musst du die Methode repaint() aufrufen.
> 
> In deinem Fall myJPanel.repaint()



Wenn ich ab Zeile 21 (siehe Quellcode MyJPanel) in:
public void actionPerformed(ActionEvent ae) {
  System.out.println("Hallo1");
  myupdate();
  repaint();
}

statt
repaint()
schreibe:
myJPAnel.repaint()
bekomme ich eine Fehlermeldung (Variable myJPAnel ist unbekannt)
Außerdem:
Warum reicht nicht - wie bei meinem Quellcode - einfach nur repaint()  ???

mfg
Ernst


----------



## SlaterB (7. Feb 2010)

ok, ich habe es mir mit obigen Code zu leicht gemacht,
es liegt anscheinend doch an initComponents() von MyJFrame, dort wird GroupLayout gesetzt, 
deswegen funktioniert anscheinend das einfache add() des MyPanel nicht, dieses ist nicht in der GUI, 
ein repaint bzw dann das zugehörige paint wird nicht ausgeführt


----------



## ernst (7. Feb 2010)

SlaterB hat gesagt.:


> Ausgabe erscheint bei mir mit untenstehenden Programm, durch den Timer sehr oft,
> habe deins vereinfacht, mit manchem von deinem Code (wie initComponents() in MyPanel)
> gehts auch, aber lohnt nicht da weiter zu schauen,
> 
> kannst deins nach und nach alles einbauen


-------------------------------------
Danke für den Test.
Aber was ist bei mir falsch?
Wo ist mein Denkfehler?

mfg
Ernst


----------



## ernst (7. Feb 2010)

SlaterB hat gesagt.:


> ok, ich habe es mir mit obigen Code zu leicht gemacht,
> es liegt anscheinend doch an initComponents() von MyJFrame, dort wird GroupLayout gesetzt,
> deswegen funktioniert anscheinend das einfache add() des MyPanel nicht, dieses ist nicht in der GUI,
> ein repaint bzw dann das zugehörige paint wird nicht ausgeführt


Was muß ich machen, damit mein repaint ausgeführt wird?

mfg
Ernst


----------



## SlaterB (7. Feb 2010)

wenn du so fragst: denken


z.B. auf Visual irgendwas verzichten und Programmieren lernen,
Lesson: Laying Out Components Within a Container (The Java™ Tutorials > Creating a GUI With JFC/Swing)


----------



## ernst (7. Feb 2010)

SlaterB hat gesagt.:


> wenn du so fragst: denken
> z.B. auf Visual irgendwas verzichten und Programmieren lernen,
> Lesson: Laying Out Components Within a Container (The Java™ Tutorials > Creating a GUI With JFC/Swing)



1) Danke für das Herausfinden des Fehlers.
Mit
public class MyJFrame extends javax.swing.JFrame {
    public MyJFrame() {
        //initComponents();
    }
    ...
}

funktioniert es wieder. Allerdings kann ich dann nicht mehr die Vorzüge des Visual-Editors von Netbeans nutzen.

2) 
Ich will allerdings nicht mehr die Vorzüge des Visual-Editors von Netbeans missen.
Früher hatte ich meine Programm alle von Hand gemacht. Das ist sehr mühselig.
Dein Link weist auf eine Menge Test hin. 
Deswegen: 
Bevor ich das ganze Zeug durchlese frage ich dich, ob du weißt, was ich an initComponents()
ändern muss, dass alles wieder funktioniert?

mfg
Ernst


----------



## SlaterB (7. Feb 2010)

leider weiß ich da nicht weiter,

so komplizierten Code wie

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(71, Short.MAX_VALUE))
        );

kann nur ein Programm automatisch erstellen, jede manuelle Modifikation wäre zum Scheitern verurteilt,
designe deine GUI komplett mit was auch immer und tausche dann evtl. panel342786 durch ein eigenes aus, so dass es an einer korrekt initalisierten Stelle der GUI sitzt


----------



## ernst (7. Feb 2010)

SlaterB hat gesagt.:


> leider weiß ich da nicht weiter,
> 
> so komplizierten Code wie
> 
> ...



---------
1)
Danke für deine Einschätzung.

2) 
Ich habe es mal anders probiert:
Mit Visual-Editor (VE) einen Panel in das JFrame reinziehen (so wie bisher auch).
Dann bekommt dieser Panel automatisch den Namen jPanel1.
Jetzt selbst ein JPanel Form erstellen, Namen vergeben wie z.B: zeichnungJPanel.
und dann im Konstruktor des JFrame anmelden mit:
jPanel1.add(zeichnungJPanel, "Center");
Dann klappt alles.
Ich hatte mich bisher immer gewundert, warum man ein Panel (zeichnungJPanel) in einem Panel (jPanel1)braucht.
Dank deiner Hilfe weiß ich es jetzt.
Wenn ich es kürzer mach (so wie in meinem Versuch), funktioniert es mit dem VE nicht mehr.

mfg
Ernst


----------

