# paintComponent in JPanel in JFrame



## Azubi96 (13. Dez 2014)

Ich arbeite derzeit an einem kleinen Java Spiel. Ein Snake Spiel um genauer zu sein. Dabei verfolge ich folgendes Konzept:
Ich habe eine Surface Klasse, welche direkt in der main-Methode initialisiert wird.
Die Surface Klasse enthält die gesamte Oberfläche und fängt alle Aktionen vom Benutzer auf (KeyListener)
In der Surface Klasse initialisiere ich ein Snake Objekt. Dieses Snake Objekt erbt von keiner Klasse.

Zu meinem Problem: Wie man es vom Snake kennt, frisst dieser irgendwelche Objekte, und wird danach grösser. Und diese Objekte (bei mir Diamanten) anzuzeigen, habe ich die paintComponent Methode in meiner Surface Klasse implementiert. Jedoch schein diese noch nicht zu funktionieren. Sobald ich ein repaint() einsetzt, scheint die Schlange unterhalb des JPanels zu sein. Und ist nur noch zu sehen, wenn sich

Und natürlich noch Code, um das Ganze zu verdeutlichen:

```
public Surface(int width, int height)
	{
	    this.width = width;
	    this.height = height;
	    // Create the JFrame
	    jframe.setSize(width, height);
            jframe.setResizable(false);
	    jframe.setLayout(null);
	    jframe.add(this); // Add the JPanel to the JFrame
	    jframe.setVisible(true);
		
	    // Create the JPanel
	    setLayout(new BorderLayout());
	    setBounds(0, 0, 400, 400);
	    setBackground(Color.DARK_GRAY);
				
	    // Add the KeyListener
	    addKeyListener(this);
	    setFocusTraversalKeysEnabled(true);
	    setFocusable(true);
	    requestFocusInWindow();
	}

    @Override
    public void paintComponent(Graphics g){
	    super.paintComponent(g);
	    g.drawRect(50, 50, 40, 40);
	    g.setColor(Color.RED);
	    repaint();
    }
```

Und ausserdem. Hier erstelle ich meine Schlange (und ja, ich habe absichtlich Buttons gewählt  )

```
private void createSnake()
    {
    	snakeButtonx[0] = 100; //Sets the starter position of the snake
        snakeButtony[0] = 150;
        JButton tempButton; //temporary Button for adding button to the Snake
        
        // Initially the snake has small length 3
	    for (int i = 0; i < sizeSnake; i++) 
	    {
	    	snakeButton[i] = new JButton("" + i);
	    	snakeButton[i].setEnabled(false); // Disable the buttons so you cant click it
	        
	        tempButton = snakeButton[i];
	        Surface.jframe.add(tempButton);
	
	        
	        snakeButton[i].setBounds(snakeButtonx[i], snakeButtony[i], 10, 10);
	        snakeButtonx[i + 1] = snakeButtonx[i] - 10;
	        snakeButtony[i + 1] = snakeButtony[i];
	    }
    }
```

Hier noch 2 kleine Screenshots:
Ohne paintComponent




Mit paintComponent. Die Schlange ist nun nur noch zu sehen, wenn man auf dem JFrame ist.




Ich hoffe ihr seid nicht zu streng mit mir, da ich recht neu in der Programmierung bin ^^


----------



## Androbin (13. Dez 2014)

Azubi96 hat gesagt.:


> Dieses Snake Objekt erbt von keiner Klasse.


Doch, von Object!

Ach ja, dein Problem sollte sich ganz einfach mit "JFrame#setContentPane" lösen lassen.

PS. Wovon wird Surface eigentlich abgeleitet?
PPS. Die richtige Antwort lautet hier "JComponent", und nicht "JPanel".


----------



## Azubi96 (13. Dez 2014)

Androbin hat gesagt.:


> Doch, von Object!
> 
> Ach ja, dein Problem sollte sich ganz einfach mit "JFrame#setContentPane" lösen lassen.
> 
> ...



Erstmal danke für deine Antwort.
Also theoretisch müsste ich doch einfach 
	
	
	
	





```
jframe.setContentPane(this);
```
 am Ende meines Konstruktors schreiben. Scheint jedoch trotzdem nicht ganz zu funktionieren. Oder liege ich dabei falsch?

PS: Warum wird eigentlich paintComponent nicht richtig ausgeführt? Ich sehe nur die Umrisse, obwohl ich die Farbe rot gesetzt habe.


----------



## Androbin (13. Dez 2014)

Azubi96 hat gesagt.:


> PS: Warum wird eigentlich paintComponent nicht richtig ausgeführt? Ich sehe nur die Umrisse, obwohl ich die Farbe rot gesetzt habe.


Es gibt zwei Arten von Methoden in Graphics:
1. Graphics#draw*(...): Es werden nur die Umrisse gezeichnet
2. Graphics#fill*(...): Es wird (welche Form auch immer) ausgefüllt


----------



## Azubi96 (13. Dez 2014)

Androbin hat gesagt.:


> Es gibt zwei Arten von Methoden in Graphics:
> 1. Graphics#draw*(...): Es werden nur die Umrisse gezeichnet
> 2. Graphics#fill*(...): Es wird (welche Form auch immer) ausgefüllt



Perfekt
Jetzt stellt sich eigentlich nur noch die Frage, wie genau ich diese Buttons nun aufs JPanel bekomme


----------



## Androbin (13. Dez 2014)

Azubi96 hat gesagt.:


> Perfekt
> Jetzt stellt sich eigentlich nur noch die Frage, wie genau ich diese Buttons nun aufs JPanel bekomme


JPanel#add( JButton );
JButton#setBounds( ... );


----------



## Azubi96 (13. Dez 2014)

Androbin hat gesagt.:


> JPanel#add( JButton );
> JButton#setBounds( ... );



Danke dir. Hat auch perfekt funktioniert
Noch die letzte Frage:
Wie würde es aussehen wenn ich die Buttons von einer anderen Klasse (Snake), welche von Surface erbt, zum JPanel hinzufügen wollte. Sprich: Surface erbt von JPanel. Snake erbt von Surface. 
Würde es dann nicht einfach heißen


```
super.add(testButton);
testButton.setBounds(100, 100, 10, 10);
```


----------



## Androbin (14. Dez 2014)

Azubi96 hat gesagt.:


> Surface erbt von JPanel. Snake erbt von Surface.


Ergo ==> Snake erbt von JPanel



Azubi96 hat gesagt.:


> Würde es dann nicht einfach heißen ...


Ja, allerdings kannst du das "super" weglassen [sofern du "add" nicht überschrieben hast]


----------

