# paint-Methode aufrufen



## andi11 (25. Jan 2016)

Hallo zusammen,
ich befasse mich erst seit kurzen mit Java und verstehe nicht wann jeweils die Methode “paint“ aufgerufen wird. Bisher habe ich das unten stehende Programm erstellt. Mit dem Debugger sehe ich, dass „paint“ bei Aufruf von „this.setVisible(true);“  ausgeführt wird. Warum? Zudem wird es 2 Mal hintereinander ausgeführt.
Des Weiteren möchte ich die „paint“-Methode in eine neue Klasse legen und dann von außen aufrufen. Wie funktioniert das? Ich habe es bereits mit repaint() versucht, aber es hat nicht funktioniert.

--------------------------

```
package Pack1;

public class Start {
   public static Fenster Fenster;

   public static void main(String[] args) throws Exception{    
     Fenster = new Fenster();
     Fenster.FensterErstellen();
     Fenster.ButtonErstellen();
   }
}
```

-------------------------

```
package Pack1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Fenster extends JFrame implements ActionListener{
   private JButton VonLinks1;
   private JButton VonLinks2;
   private JButton VonRechts;
   private JButton Schliessen;  
  
   public Fenster () {
     super("Test");
   }

   public void FensterErstellen() {
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     this.setSize(1000,800);
     this.setLayout(null);
     this.setVisible(true);
   }
    
   public void ButtonErstellen () {    
     VonRechts = new JButton("Von rechts");
     VonRechts.setBounds(72, 700, 160, 40);
     VonRechts.addActionListener(this);
     add(VonRechts);
    
     VonLinks1 = new JButton("Von links1");
     VonLinks1.setBounds(304, 700, 160, 40);
     VonLinks1.addActionListener(this);
     add(VonLinks1);
    
     VonLinks2 = new JButton("Von links2");
     VonLinks2.setBounds(536, 700, 160, 40);
     VonLinks2.addActionListener(this);
     add(VonLinks2);
    
     Schliessen = new JButton("Schließen");
     Schliessen.setBounds(768, 700, 160, 40);
     Schliessen.addActionListener(this);
     add(Schliessen);    
   }

   public void paint (Graphics g){
     super.paint(g);
     g.setColor(new Color(100,100,250));
     g.fillRect(50, 50, 100, 100);
     System.out.println("paint");
   }

   @Override
   public void actionPerformed(ActionEvent arg0) {
     // TODO Auto-generated method stub    
   }
}
```


----------



## Joose (25. Jan 2016)

andi11 hat gesagt.:


> ... verstehe nicht wann jeweils die Methode “paint“ aufgerufen wird. Bisher habe ich das unten stehende Programm erstellt. Mit dem Debugger sehe ich, dass „paint“ bei Aufruf von „this.setVisible(true);“  ausgeführt wird. Warum?



Weil du ja sagst er soll das Fenster sichtbar machen, dazu muss er was zeichnen. Irgendwo in den Java Klassen wird dann eben die "paint" Methode aufgerufen. 



andi11 hat gesagt.:


> Zudem wird es 2 Mal hintereinander ausgeführt.



Wieso 2x hintereinander? Nur weil du dazwischen keine andere Ausgabe hast? Heißt ja nur das dazwischen keine andere Ausgabe passiert 
Aber nicht das es direkt hintereinander aufgerufen wird.



andi11 hat gesagt.:


> Des Weiteren möchte ich die „paint“-Methode in eine neue Klasse legen und dann von außen aufrufen. Wie funktioniert das? Ich habe es bereits mit repaint() versucht, aber es hat nicht funktioniert.



Was heißt du willst diese Methode in eine andere Klasse legen? Wozu? Was erhoffst du dir davon?


----------



## kneitzel (25. Jan 2016)

Separation of Concerns - pack Dinge immer da hin, wo es hin gehört und Trenne Dinge, die nicht zusammen gehören.

Du hast ein JFrame - wo soll das Malen des Fensters hin gehören, wenn nicht in die vom JFrame abgeleitete Klasse?

Der Inhalt kann woanders erstellt werden, das ist egal. Da ist evtl. der Vergleich mit der Textausgabe hilfreich:
Die Ausgabe ist da, wo sie hin gehört. Also z.B. die Funktion println auf dem Stream der hinter System.out steckt. Was angezeigt wird, ist in den eigentlichen Objekten drin. Eine Klasse hat z.B. eine Funktion toString.

So kannst du auch Dinge trennen. Dann hast Du Objekte, die wissen, wie sie dargestellt werden können, aber die eigentliche Darstellung übernimmt das JFrame.

Der Vergleich mit dem Stream hinkt etwas, denn Du hast bei Swing nicht die aktive Darstellung wie beim System.out.println, sondern Du hast halt die typische Window-Applikation mit Event-Loop und darüber wird ein Fenster aufgefordert sich zu malen. Du änderst also nur Inhalte und triggerst dann das neumalen. Daher hat man oft eine Zweiteilung: Ein Objekt mit Daten und ein Objekt zum Anzeigen. Und diese sind über ein Binding miteinander verbunden ...

Hoffe, dass hat jetzt nicht nur verwirrt.


----------



## andi11 (27. Jan 2016)

Ich sehe teilweise, dass mit paintComponent gearbeitet wird und dieses in eine separate Klasse gelegt wird mit der Vererbung der Klasse JPanel (extends JPanel). Ich habe ja schon JFrame vererbt, ich kann ja nicht 2 Klassen vererben. Deshalb lege ich „paint“ in eine neue Klasse und rufe sie an irgendeiner Stelle von meiner Klasse „Fenster „auf.
An welcher Stelle genau soll ich die neue Klasse „Zeichen“ aufrufen.
Ich habe es wie folgt versucht, aber es hat nicht funktioniert.

------------------------------------
Aufruf mit
Zeichnen Zeichnen = new Zeichnen ()

---------------------------------

```
package Pack1;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;


public class Zeichnen extends JPanel {

   public void paintComponent (Graphics g){
     super.paintComponent(g);
     g.setColor(new Color(100,100,250));
     g.fillRect(50, 50, 100, 100);  
  }  
}
```


----------



## Joose (27. Jan 2016)

Einfach nur ein Objekt dieser Klasser erstellen reicht nicht, du musst es natürlich noch deinem JFrame hinzufügen.

```
frame.add(new Zeichnen());
```


----------



## andi11 (27. Jan 2016)

Leider will es nicht funktionierten. Bitte schau dir nochmal den Programmcode an und korrigiere ihn.


```
package Pack1;

public class Start {

   public static Fenster Fenster;

   public static void main(String[] args) throws Exception{
   
     Fenster = new Fenster();
     Fenster.FensterErstellen();
     Fenster.ButtonErstellen();
   }
}
```
-------------------------------------------------------

```
package Pack1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Fenster extends JFrame implements ActionListener{

   private JButton VonLinks1;
   private JButton VonLinks2;
   private JButton VonRechts;
   private JButton Schliessen; 
 
   public Fenster () {
     super("Test");
   }

   public void FensterErstellen() {
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     this.setSize(1000,800);
     this.setLayout(null);
     this.setVisible(true);
   }
   
   public void ButtonErstellen () {
   
     VonRechts = new JButton("Von rechts");
     VonRechts.setBounds(72, 700, 160, 40);
     VonRechts.addActionListener(this);
     add(VonRechts);
   
     VonLinks1 = new JButton("Von links1");
     VonLinks1.setBounds(304, 700, 160, 40);
     VonLinks1.addActionListener(this);
     add(VonLinks1);
   
     VonLinks2 = new JButton("Von links2");
     VonLinks2.setBounds(536, 700, 160, 40);
     VonLinks2.addActionListener(this);
     add(VonLinks2);
   
     Schliessen = new JButton("Schließen");
     Schliessen.setBounds(768, 700, 160, 40);
     Schliessen.addActionListener(this);
     add(Schliessen);
   
     this.add(new Zeichnen());
   }

   @Override
   public void actionPerformed(ActionEvent arg0) {
     // TODO Auto-generated method stub
   
   }
}
```
-------------------------------------------------------

```
package Pack1;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Zeichnen extends JPanel {

   public void paintComponent (Graphics g){
     super.paintComponent(g);
     g.setColor(new Color(100,100,250));
     g.fillRect(50, 50, 100, 100);
 
  } 
}
```


----------



## kneitzel (28. Jan 2016)

Wenn Du ein eigenes Panel hast, dann musst Du da - so wie für jedes Control, dass Du hinzugefügt hast, doch die Position und Größe setzen. Sprich: So wie du für die anderen Controls setBounds aufgerufen hast, musst Du dies auch für Deine Klasse Zeichnen machen.

Für Dein Verständnis: Du hast da halt jetzt ein eigenes, neues Control "Zeichnen" erstellt. Und das musst Du natürlich so wie jedes Control verwenden.

Konrad


----------



## Joose (28. Jan 2016)

@andi11 Bitte deinen Code immer in Code-Tags posten, danke! 
[java] /* dein code hier */ [/java]


----------



## andi11 (28. Jan 2016)

Also setze ich jetzt wie folgt "setBounds" ein, aber es funktioniert nicht, warum?



```
package Pack1;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Zeichnen extends JPanel {

   public void paintComponent (Graphics g){
     super.paintComponent(g);
   
     this.setBounds(50, 50, 100, 100);
     g.setColor(new Color(100,100,250));
     g.fillRect(50, 50, 100, 100);
 
  } 
}
```

Ist das so richtig mit dem Code-Tag?


----------



## kneitzel (28. Jan 2016)

Also ich mache nicht viel auf Clientseite aber setBounds gibt die Position im Parent an. Aber beim Malen gelten die Koordinaten des controls selbst. Damit malst Du jetzt ausserhalb des sichtbaren Bereiches.

Wäre jetzt zumindest meine Vermutung....


----------



## Joose (29. Jan 2016)

andi11 hat gesagt.:


> Ist das so richtig mit dem Code-Tag?



Ja  du kannst aber "/*" und "*/ weglassen da dies als Code Kommentar interpretiert wird
Habs mal wegeditiert


----------



## andi11 (29. Jan 2016)

Kann mir das vielleicht mal jemand genauer erklären, wann ich im sichtbaren und wann im nicht sichtbaren Bereich arbeite.


----------



## andi11 (1. Feb 2016)

Hallo zusammen,
ich habe immer noch Probleme mit paintComponent (siehe folgendes Beispiel).
Warum wird das Rechteck nicht gezeichnet? 
Habe außerdem JFrame in JApplet geändert, da ich ein Applet erstellen will.


```
package Pack1;   

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;

public class StartNeu extends JApplet{

   private JPanel p;
   private JButton VonLinks1;
   private JButton VonLinks2;
   private JButton VonRechts;
   private JButton Schliessen;
   
   public void init(){

     setSize(1000,800);
     p = new JPanel();
     p.setLayout(null);
     this.setContentPane(p);
     
     VonRechts = new JButton("Von rechts");
     VonLinks1 = new JButton("Von links1");
     VonLinks2 = new JButton("Von links2");
     Schliessen = new JButton("Schließen");
     
     add(VonRechts);
     add(VonLinks1);
     add(VonLinks2);
     add(Schliessen);
     
     VonRechts.setBounds(72, 750, 160, 40);
     VonLinks1.setBounds(304, 750, 160, 40);
     VonLinks2.setBounds(536, 750, 160, 40);
     Schliessen.setBounds(768, 750, 160, 40);
     
     Zeichnen = new Zeichnen();
     this.getContentPane().add(Zeichnen);
     this.setVisible(true);
   }

----------------------------
package Pack1;

import java.awt.*;
import java.awt.Graphics;
import javax.swing.JPanel;


public class Zeichnen extends JPanel {

   
   public Zeichnen ()
   {
   }
   
   public void paintComponent (Graphics g){
     
     super.paintComponent(g);
     g.setColor(new Color(100,100,250));
     g.fillRect(50, 50, 100, 100);
  }   
}
```


----------



## andi11 (1. Feb 2016)

Hallo zusammen,
um die unterschiedlichen Möglichkeiten kennenzulernen würde mich außerdem interessieren, wie das ganze aussehen muss, wenn die Methode "paintComponent" in die Klasse "StartNeu" gelegt wird. Gibt es auch eine Möglichkeit ohne die paintComponent Methode zu zeichnen?


----------

