# Repaint() in Methode



## Kaiser Karlos (20. Feb 2007)

nommal Ich 

warum funkt die repaint() Anweißung nicht wenn ich die Methode "ZeichnungAktualisieren()" aufrufe?
Es funktioniert wenn ichs ins paintComponent selber schreibe allerdings muss ich nur selten den Jframe aktualisieren dass das unötige Belastung wäre und mein Programm verlangsamen würde.


```
package schiffeversenken;

import javax.swing.*;
import java.awt.Graphics;
import java.awt.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;


/**
 *
 * @author user
 */

public class zeichneWelt extends JPanel {

    private JFrame Jframe;
    Graphics g;
    String title = "src/Grafiken/master.jpg";
    BufferedImage bild;                             //hier noch die arrays deklarieren
    static int zeichneSchiff[][];                               //jedesmal bei veränderungen hier aktualisieren
                                                    //dann mit repaint() des ganze aufm JFrane aktualisieren
     
               
    protected void paintComponent(Graphics g)
   {
        super.paintComponent(g);
        System.out.println( this.zeichneSchiff[1][1]+" im paintComponent");   
        zeicheneHintergrund(g);                    //ab hier alles was es zum zeichnen gibt
        zeichneSchiff Schiff = new zeichneSchiff(); //Objekt für Abbildung von Schiffen       
        Schiff.zeichne(g, zeichneSchiff);              //zeichneSchiff wir array: schiffe[][] übergeben
                                           //alles jedesmal in 2 Dimensionale arrays stecken :)
                                                  
   } 
    
    protected void zeicheneHintergrund(Graphics g){
       g.drawImage(bild,0,20,this);
       System.out.println("x: "+bild.getWidth(this)); 
       
    }
    
    public zeichneWelt(){                      //Konstruktor ; Läd Hintergrundbild
        try{
          bild = ImageIO.read(new File(title));
        }catch(IOException ioe){
          ioe.printStackTrace();
        }
        //this.zeichneSchiff = new int[6][4];  
    }
    
    
    public static void main() {               //main läd JFrame     
             //String []args
             JFrame f = new JFrame();
             f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
             f.setSize(500, 700);
             f.setContentPane(new zeichneWelt() );
             f.setVisible(true);
    }
    
    protected void ZeichnungAktualisieren() {
       repaint();
    }
    

    
}
```
danke schommal


----------



## Wildcard (20. Feb 2007)

Gewöhn dir mal richtige Benennung an:
Klassen groß, Methoden klein


			
				Kaiser Karlos hat gesagt.:
			
		

> warum funkt die repaint() Anweißung nicht wenn ich die Methode "ZeichnungAktualisieren()" aufrufe?


repaint funktioniert.
Liegt also eher an deinem Aufruf.
btw: repaint in paintComponent führt zu Endlosrekursion


----------



## Gast (20. Feb 2007)

^^also ich will über mein Hauptprogramm irgendwann mal den JFrame neu aktualisieren weil sich variblen geändert haben usw. Ich hab mir das so vorgestellt dass ich dann "ZeichnungAktualisieren()" aufrufe und mit repaint() mein Jframe neu gezeichnet wird. Funktioniert jedoch nicht. Es geschieht nichts (nur wenn ich das Fenster minimiere und neu öffne wird alles aktualisiert).


----------



## Wildcard (20. Feb 2007)

Der Code lässt nicht auf die Ursache schließen.
repaint tut jedenfalls das was es soll.


----------



## Gast (20. Feb 2007)

ne tuts nicht des macht garnix. ich kanns genausogut weglassen aber ich muss die paintComponent irgendwie aktualisieren


----------



## Wildcard (20. Feb 2007)

Das ist mir jetzt echt zu dumm.
Wenn du mir nicht glaubst kann ich dir auch nicht helfen.


----------



## Wildcard (20. Feb 2007)

```
zeichneSchiff Schiff = new zeichneSchiff(); //Objekt für Abbildung von Schiffen       
        Schiff.zeichne(g, zeichneSchiff);
```
Und warum erzeugst du dir bei jedem neuzeichnen ein neues Schiff?  :autsch:


----------



## Gast (20. Feb 2007)

naja des ist ne Klasse die alle Schiffe zeichnet die es gibt.
Aber des repaint() funktioniert wirklich im Programm nicht. Ich will ja die paintComponent aktualisieren ( so wie wenn mann das Fenster minimiert und dann wieder öffnet ) aber mit repaint funktioniert das so irgendwie nicht


----------



## Wildcard (20. Feb 2007)

Als Folge von repaint wird paintComponent aufgerufen und das funktioniert auch.


----------



## Gast (20. Feb 2007)

ich hab jetzt mal zum ode das dazugefügt:

    protected void ZeichnungAktualisieren() {
        System.out.println("repaint"); 
       repaint();
    }

bei jedem Aufruf der funktion wird repaint() ausgeführt denn man im kann im Output "repaint" 6 mal erkennen
doch das Bild verändert sich nicht

ich hab das mit dem Code getestet:

 public int schiffe[][];

  public void start(){
      this.schiffe = new int[6][4];
      schiffe[1][1]= 0;  
      schiffe[1][2]= 100; 
      zeichneWelt.zeichneSchiff = schiffe;

      System.out.println(schiffe[1][1]+"im start");
      zeichneWelt neuezeichnung = new zeichneWelt();  
      neuezeichnung.zeichneSchiff = schiffe;
      neuezeichnung.main();

      for(int i=0; i < 6; i++){
          System.out.println("im for variable i: "+i);
          schiffe[1][1]= i*5;
          zeichneWelt.zeichneSchiff = schiffe; 
          neuezeichnung.ZeichnungAktualisieren();
         try {
             Thread.sleep(1000);
             } 
         catch (InterruptedException e){
             }

       }
  }

ich weiß nicht warum die repaint nicht funktioniert irgendeiner eine Idee?


----------



## Lim_Dul (20. Feb 2007)

Ganz einfach, du arbeitest im Swing-Thread und blockierst damit die gesamt GUI. Du musst für solche Sachen wie deine Berechnungen einen eigenen Thread starten.


----------



## Gast (21. Feb 2007)

welche meinst du genau und wie?


----------



## Marco13 (21. Feb 2007)

Von wo aus rufst du denn "start" auf? (Lass mich raten: Im actionPeformed eines Buttons?)

@Wildcard: repaint in paintComponent führt nicht zu einer Endlosrekursion (d.h. kein StackOverflowError oder so) aber dazu, dass der Thread, der paintet, sich bei jedem painten selbst die Aufgabe gibt, neu zu painten - dass nennt man dann das "Hornbach-Prinzip": "Es gibt immer was zu tun" :wink:

Und noch @Kaiser Karlos: Swing "optimiert" die Aufrufe von repaint. Wenn du z.B. sowas machst wie

```
for (int i=0; i<100; i++) repaint();
```
dann wird zwar 100 mal repaint aufgerufen, aber u.U. nur EINmal neu gezeichnet, weil Swing erkennt, dass die Aufrufe so dicht aufeinader folgen, dass sich dazwischen nicht viel getan haben kann. (Etwas vereinfacht)


----------



## Wildcard (21. Feb 2007)

Marco13 hat gesagt.:
			
		

> @Wildcard: repaint in paintComponent führt nicht zu einer Endlosrekursion (d.h. kein StackOverflowError oder so) aber dazu, dass der Thread, der paintet, sich bei jedem painten selbst die Aufgabe gibt, neu zu painten - dass nennt man dann das "Hornbach-Prinzip": "Es gibt immer was zu tun" :wink:


Ist klar. Das ist schon eine (indirekte)Endlosrekursion, bei der es aber auf Grund der Queue nicht zum Stack Overflow kommt.


----------

