# warteschleife in swing applet



## florian89 (20. Mrz 2007)

ich hab folgendes applet geschrieben, indem ein see gemalt wird und in diesem see blasen aufsteigen. see ist gemalt, blase auch. die steigen jetzt nur leider viel zu schnell auf. ich habe versucht eine einfach for schleife einzubauen, die lässt jedoch alles neu malen, nich nur die blasen, was dazu führt, dass das programm nur länger lädt. hier der quell code:

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;

public class LakeNyos1 extends JFrame
{
  public LakeNyos1()
  {
    super("LAKE NYOS");
    setTitle("Lake Nyos");
    setSize(1000,1000);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MapPane LakeNyos1 = new MapPane();
    Container content = getContentPane();
    content.add(LakeNyos1);
    setVisible(true);
  }
      public static void main(String[] arguments)
    {
        LakeNyos1 frame = new LakeNyos1();
    }
}
class MapPane extends JPanel
{
  public void See(Graphics comp)
  {
    Graphics2D comp2D = (Graphics2D)comp;
    comp2D.setColor(Color.white);
    Rectangle2D.Float background = new Rectangle2D.Float(
    0F, 0F, (float)getSize().width, (float)getSize().height);
    comp2D.fill(background);
    // den see zeichnen
    comp2D.setColor(Color.black);
    GeneralPath fl = new GeneralPath();
    fl.moveTo(0F,300F);
    fl.lineTo(10F,300F);
    fl.lineTo(15F,290F);
    fl.lineTo(18F,290F);
    fl.lineTo(23F,280F);
    fl.lineTo(26F,275F);
    fl.lineTo(50F,275F);
    fl.lineTo(50F,275F);
    fl.lineTo(100F,273F);
    fl.lineTo(150F,270F);
    fl.lineTo(200F,275F);
    fl.lineTo(210F,315F);
    fl.lineTo(215F,315F);   //Beginn des Sees
    fl.lineTo(225F,350F);
    fl.lineTo(235F,400F);
    fl.lineTo(250F,430F);
    fl.lineTo(270F,440F);
    fl.lineTo(320F,450F);
    fl.lineTo(380F,460F);
    fl.lineTo(440F,460F);
    fl.lineTo(500F,450F);
    fl.lineTo(550F,440F);
    fl.lineTo(570F,410F);
    fl.lineTo(585F,380F);
    fl.lineTo(595F,350F);
    fl.lineTo(605F,315F);  //Ende des Sees
    fl.lineTo(630F,310F);
    fl.lineTo(700F,305F);
    fl.lineTo(750F,315F);
    fl.lineTo(850F,315F);
    fl.lineTo(920F,305F);
    fl.lineTo(1000F,295F);
    fl.lineTo(1000F,295F);
    fl.lineTo(920F,305F);
    fl.lineTo(850F,315F);
    fl.lineTo(750F,315F);
    fl.lineTo(700F,305F);
    fl.lineTo(630F,310F);
    fl.lineTo(605F,315F);
    fl.lineTo(595F,350F);
    fl.lineTo(585F,380F);
    fl.lineTo(570F,410F);
    fl.lineTo(550F,440F);
    fl.lineTo(500F,450F);
    fl.lineTo(440F,460F);
    fl.lineTo(380F,460F);
    fl.lineTo(320F,450F);
    fl.lineTo(270F,440F);
    fl.lineTo(250F,430F);
    fl.lineTo(235F,400F);
    fl.lineTo(225F,350F);
    fl.lineTo(215F,315F);
    fl.lineTo(210F,315F);
    fl.lineTo(200F,275F);
    fl.lineTo(150F,270F);
    fl.lineTo(100F,273F);
    fl.lineTo(26F,275F);
    fl.lineTo(23F,280F);
    fl.lineTo(18F,290F);
    fl.lineTo(15F,290F);
    fl.moveTo(0F,300F);
    fl.lineTo(10f,300F);
    fl.closePath();
    comp2D.draw(fl);
  }
  public void fuelleSee(Graphics comp)
  {
    Graphics2D comp2D = (Graphics2D)comp;
    // See mit Wasser füllen
    comp2D.setColor(Color.blue);
    GeneralPath sl = new GeneralPath();
    sl.moveTo(215F,320F);
    sl.lineTo(225F,350F);
    sl.lineTo(235F,400F);
    sl.lineTo(250F,430F);
    sl.lineTo(270F,440F);
    sl.lineTo(320F,450F);
    sl.lineTo(380F,460F);
    sl.lineTo(440F,460F);
    sl.lineTo(500F,450F);
    sl.lineTo(550F,440F);
    sl.lineTo(570F,410F);
    sl.lineTo(585F,380F);
    sl.lineTo(595F,350F);
    sl.lineTo(605F,320F);

    comp2D.fill(sl);
  }
  public void blasen(Graphics comp)
  {
     int y = 450;
     while ( y>320)
     {
      for (int i = 0; i <100000; i++);
      y = y- 1;
      Graphics2D comp2D = (Graphics2D)comp;
      // CO2 Blasen zeichnen
      comp2D.setColor(Color.white);
      BasicStroke pen2 = new BasicStroke();
      comp2D.setStroke(pen2);
      Ellipse2D.Float e1 = new Ellipse2D.Float(380,y,4,4);
      comp2D.fill(e1);

     }
  }
  public void menschen(Graphics comp)
  {
    Graphics2D comp2D = (Graphics2D)comp;
    comp2D.setColor(Color.black);
    GeneralPath ss = new GeneralPath();
    ss.moveTo(25F,275F);
    ss.lineTo(31F,265F);
    ss.lineTo(37F,275F);
    ss.lineTo(31F,265F);
    ss.lineTo(31F,255F);
    ss.lineTo(25F,250F);
    ss.lineTo(31F,255F);
    ss.lineTo(37F,250F);
    ss.lineTo(31F,255F);
    ss.lineTo(31F,265F);
    ss.lineTo(25F,275F);
    ss.closePath();
    comp2D.draw(ss);
    BasicStroke pen2 = new BasicStroke();
    comp2D.setStroke(pen2);
    Ellipse2D.Float em = new Ellipse2D.Float(27,246,8,8);
    comp2D.fill(em);
  }
  public void paintComponent(Graphics comp)
  {
    See(comp);
    fuelleSee(comp);
    blasen(comp);
    menschen(comp);
  }
}
```


ich hoffe ihr könnt mir helfen. ich benötige eine schleife die die blasen langsam und ansehbar aufsteigen lässt.
danke im vorraus.


----------



## Marco13 (20. Mrz 2007)

Blasen. So'n Schweinkram. Naja. Hab jetzt nicht den ganzen Code gelesen, aber prinzipiell solltest du irgendwo

```
try
{
    Thread.sleep(20); // Millsekunden
}
catch (InterruptedException e)
{
    e.printStackTrace();
}
```
einfügen können. Nach Möglichkeit nicht in der paint-Methode, sondern z.B. in der Klasse/Methode, die die Bewegung der Blasen steuert. (Das sollte NICHT in der 'blasen'-Methode gemacht werden!)


----------



## florian89 (20. Mrz 2007)

danke, ich probiers morgen gleich mal aus


----------



## florian89 (20. Mrz 2007)

so, ich das jetzt mal ausprobiert. also sieht jetzt so aus.

```
public void blasen(Graphics comp)
  {

      Graphics2D comp2D = (Graphics2D)comp;
      // CO2 Blasen zeichnen
      comp2D.setColor(Color.white);
      BasicStroke pen2 = new BasicStroke();
      comp2D.setStroke(pen2);
      Ellipse2D.Float e1 = new Ellipse2D.Float(380,y,4,4);
      comp2D.fill(e1);
  }

  public void warten()
  {
    try
     {
     Thread.sleep(40); // Millsekunden
     }
     catch (InterruptedException e)
    {
    e.printStackTrace();
    }

  }
  public void aufsteigen()
  {
    while ( y >320)
    {
     y = y - 1;
     warten();
    }
  }
  public void paintComponent(Graphics comp)
  {
    y = 450;
    See(comp);
    fuelleSee(comp);
    menschen(comp);
    aufsteigen();
    blasen(comp);
  }
}
```

hab den ganzen unwichtigen kram jetzt ma wegegelassen. wenn ich das applet starte wartet er die angebene zeit, bevor er irgendwas zeichnet. ich muss das problem irgendwie beseitigen, aber ich bekomm das einfach net hin. 
bitte, is wichtig


----------



## SlaterB (20. Mrz 2007)

was soll denn aufsteigen bedeuten?
darin wird doch ganz alleine die ganze Zeit gewartet ohne das zwischendurch was passiert

so kann es nicht gehen, was soll 'ich bekomm das einfach net hin' bedeuten?

wenn du ein Hans bauen willst, aber nie anfängst zu bauen sondern vorher in einer Warteschleife bist,
dann gibt es nur einen Tipp: befinde dich NICHT vorher die ganze Zeit in einer Schleife 

edit: komisches Beispiel, ich weiß


----------



## Marco13 (20. Mrz 2007)

Sorry    meine Aussage
_Nach Möglichkeit nicht in der paint-Methode, sondern z.B. in der Klasse/Methode, die die Bewegung der Blasen steuert. (Das sollte NICHT in der 'blasen'-Methode gemacht werden!)_
von vorhin war natürlich nicht präzise genug, wenn man nicht sowieso schon weiß, worum es geht.

Es ist NICHT entscheidend, in welcher _Methode_ das Warten gemacht wird, sondern von welchem *Thread* es gemacht wird. 

Wenn das Warten in der paint-Methode gemacht wird (oder in einer Methode, die von paint aus aufgerufen wird), dann wird das Warten IMMER vom EventDispatchThread gemacht - und genau DAS darf eben nicht sein, weil der EventDispatchThread für das Zeichnen verantwortlich ist.

Mal sinngemäß wie das gemeint war:

```
class XXX 
    public void starteBlasenBewegung()
    {
        Thread t = new Thread(new Runnable()
        {
            public void run() // Entspricht deiner "aufsteigen"-Methode
            {
                while ( y >320)
                {
                     y = y - 1;
                     repaint();
                     warten();
                }
            }
        });
        t.start();
    }

  public void warten()
  {
    try
     {
     Thread.sleep(40); // Millsekunden
     }
     catch (InterruptedException e)
    {
    e.printStackTrace();
    }

   ....
}
```

Jetzt sorgt der Thread, der in starteBlasenBewegung angelegt wird, dafür, dass immer 
- y verringert wird
- ein Neuzeichnen ausgelöst wird
- einen augenblick gewartet wird

D.h. wenn du irgendwo starteBlasenBewegung aufrufst (z.B. am Ende des Konstruktors), dann sollte sich da was tun.


----------



## florian89 (20. Mrz 2007)

also muss ich ne neue class erstellen und diese dann in der main methode bzw. in der methode "LakeNyos" aufrufen?


----------



## Marco13 (20. Mrz 2007)

Nein, das XXX war nur, weil ich nicht nachsehen wollte, wie deine Klasse hieß :roll: Die beschriebene Methode kann (und muß, wenn du sie genau so übernehmen willst) in deine Hauptklasse, also *rumscroll* *nachguck* in die Klasse "LakeNyos1".


----------



## florian89 (20. Mrz 2007)

ich weiß ich nerve ein bisschen, aber ich bin halt nich so der programmierer.  ich habe informatik als schulfach und habe, weil ich nicht so schlecht bin, als 5. Prüfungskomponente im Abitur halt informatik gewählt. deswegen ist es so wichtig, dass ich das programm fertig bekomme. mein lehrer is nicht ganz so gut in java, deswegen kann der mir auch nich helfen.

so zur vorgeschichte


----------



## Marco13 (20. Mrz 2007)

Sobald du (mich) nervst, wird (von mir) keine Antwort mehr kommen. Der Umkehrschluß gilt aber nicht. (Man kann ja auch mal vergessen zu antworten, oder eine Rückfrage übersehen).


----------



## florian89 (20. Mrz 2007)

ok, ich habe des jetzt mal so gebastelt: 

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;

public class LakeNyos1 extends JFrame
{
    int y;
    Graphics comp;
   public void blasen()
   {
      Graphics2D comp2D = (Graphics2D)comp;
      // CO2 Blasen zeichnen
      comp2D.setColor(Color.white);
      BasicStroke pen2 = new BasicStroke();
      comp2D.setStroke(pen2);
      Ellipse2D.Float e1 = new Ellipse2D.Float(380,y,4,4);
      comp2D.fill(e1);
   }
    public void starteBlasenBewegung()
    {
        Thread t = new Thread(new Runnable()
        {
            public void run() // Entspricht deiner "aufsteigen"-Methode
            {
                while ( y >320)
                {
                     y = y - 1;
                     repaint();
                     warten();
                }
            }
        });
        t.start();
    }

  public void warten()
  {
    try
     {
     Thread.sleep(40); // Millsekunden
     }
     catch (InterruptedException e)
    {
    e.printStackTrace();
    }
   }

  public LakeNyos1()
  {
    super("LAKE NYOS");
    setTitle("Lake Nyos");
    setSize(1000,1000);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MapPane LakeNyos1 = new MapPane();
    Container content = getContentPane();
    content.add(LakeNyos1);
    setVisible(true);
  }
      public static void main(String[] arguments)
    {
        LakeNyos1 frame = new LakeNyos1();
    }

  
}
```

frage jetzt:  wie und wo rufe ich die blasen und die blasenbewegung auf


----------



## Marco13 (20. Mrz 2007)

Ja, das war's schon fast. Habs einfach mal in dein erstes Programm eingefügt. 
y darf halt nichtmehr in der Methode stehen.


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;

public class LakeNyos1 extends JFrame
{
  public LakeNyos1()
  {
    super("LAKE NYOS");
    setTitle("Lake Nyos");
    setSize(1000,1000);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MapPane LakeNyos1 = new MapPane();
    Container content = getContentPane();
    content.add(LakeNyos1);
    setVisible(true);
    LakeNyos1.starteBlasenBewegung(); //--------------------------------------------------------------------- Aufruf
  }
      public static void main(String[] arguments)
    {
        LakeNyos1 frame = new LakeNyos1();
    }
}
class MapPane extends JPanel
{
  private int y = 450; //-------------------------------------------------------------------------- y steht jetzt hier
  public void See(Graphics comp)
  {
    Graphics2D comp2D = (Graphics2D)comp;
    comp2D.setColor(Color.white);
    Rectangle2D.Float background = new Rectangle2D.Float(
    0F, 0F, (float)getSize().width, (float)getSize().height);
    comp2D.fill(background);
    // den see zeichnen
    comp2D.setColor(Color.black);
    GeneralPath fl = new GeneralPath();
    fl.moveTo(0F,300F);
    fl.lineTo(10F,300F);
    fl.lineTo(15F,290F);
    fl.lineTo(18F,290F);
    fl.lineTo(23F,280F);
    fl.lineTo(26F,275F);
    fl.lineTo(50F,275F);
    fl.lineTo(50F,275F);
    fl.lineTo(100F,273F);
    fl.lineTo(150F,270F);
    fl.lineTo(200F,275F);
    fl.lineTo(210F,315F);
    fl.lineTo(215F,315F);   //Beginn des Sees
    fl.lineTo(225F,350F);
    fl.lineTo(235F,400F);
    fl.lineTo(250F,430F);
    fl.lineTo(270F,440F);
    fl.lineTo(320F,450F);
    fl.lineTo(380F,460F);
    fl.lineTo(440F,460F);
    fl.lineTo(500F,450F);
    fl.lineTo(550F,440F);
    fl.lineTo(570F,410F);
    fl.lineTo(585F,380F);
    fl.lineTo(595F,350F);
    fl.lineTo(605F,315F);  //Ende des Sees
    fl.lineTo(630F,310F);
    fl.lineTo(700F,305F);
    fl.lineTo(750F,315F);
    fl.lineTo(850F,315F);
    fl.lineTo(920F,305F);
    fl.lineTo(1000F,295F);
    fl.lineTo(1000F,295F);
    fl.lineTo(920F,305F);
    fl.lineTo(850F,315F);
    fl.lineTo(750F,315F);
    fl.lineTo(700F,305F);
    fl.lineTo(630F,310F);
    fl.lineTo(605F,315F);
    fl.lineTo(595F,350F);
    fl.lineTo(585F,380F);
    fl.lineTo(570F,410F);
    fl.lineTo(550F,440F);
    fl.lineTo(500F,450F);
    fl.lineTo(440F,460F);
    fl.lineTo(380F,460F);
    fl.lineTo(320F,450F);
    fl.lineTo(270F,440F);
    fl.lineTo(250F,430F);
    fl.lineTo(235F,400F);
    fl.lineTo(225F,350F);
    fl.lineTo(215F,315F);
    fl.lineTo(210F,315F);
    fl.lineTo(200F,275F);
    fl.lineTo(150F,270F);
    fl.lineTo(100F,273F);
    fl.lineTo(26F,275F);
    fl.lineTo(23F,280F);
    fl.lineTo(18F,290F);
    fl.lineTo(15F,290F);
    fl.moveTo(0F,300F);
    fl.lineTo(10f,300F);
    fl.closePath();
    comp2D.draw(fl);
  }
  public void fuelleSee(Graphics comp)
  {
    Graphics2D comp2D = (Graphics2D)comp;
    // See mit Wasser füllen
    comp2D.setColor(Color.blue);
    GeneralPath sl = new GeneralPath();
    sl.moveTo(215F,320F);
    sl.lineTo(225F,350F);
    sl.lineTo(235F,400F);
    sl.lineTo(250F,430F);
    sl.lineTo(270F,440F);
    sl.lineTo(320F,450F);
    sl.lineTo(380F,460F);
    sl.lineTo(440F,460F);
    sl.lineTo(500F,450F);
    sl.lineTo(550F,440F);
    sl.lineTo(570F,410F);
    sl.lineTo(585F,380F);
    sl.lineTo(595F,350F);
    sl.lineTo(605F,320F);

    comp2D.fill(sl);
  }







  //------------------------------------------------------------------- blasen geändert, 2 Methoden eingefügt -->


  public void blasen(Graphics comp)
  {
      Graphics2D comp2D = (Graphics2D)comp;
      // CO2 Blasen zeichnen
      comp2D.setColor(Color.white);
      BasicStroke pen2 = new BasicStroke();
      comp2D.setStroke(pen2);
      Ellipse2D.Float e1 = new Ellipse2D.Float(380,y,4,4);
      comp2D.fill(e1);
  }


    public void starteBlasenBewegung()
    {
        Thread t = new Thread(new Runnable()
        {
            public void run() // Entspricht deiner "aufsteigen"-Methode
            {
                while ( y >320)
                {
                     y = y - 1;
                     repaint();
                     warten();
                }
            }
        });
        t.start();
    }

  public void warten()
  {
    try
     {
     Thread.sleep(40); // Millsekunden
     }
     catch (InterruptedException e)
    {
    e.printStackTrace();
    }
   }

  //------------------------------------------------------------------- blasen geändert, 2 Methoden eingefügt --<




  public void menschen(Graphics comp)
  {
    Graphics2D comp2D = (Graphics2D)comp;
    comp2D.setColor(Color.black);
    GeneralPath ss = new GeneralPath();
    ss.moveTo(25F,275F);
    ss.lineTo(31F,265F);
    ss.lineTo(37F,275F);
    ss.lineTo(31F,265F);
    ss.lineTo(31F,255F);
    ss.lineTo(25F,250F);
    ss.lineTo(31F,255F);
    ss.lineTo(37F,250F);
    ss.lineTo(31F,255F);
    ss.lineTo(31F,265F);
    ss.lineTo(25F,275F);
    ss.closePath();
    comp2D.draw(ss);
    BasicStroke pen2 = new BasicStroke();
    comp2D.setStroke(pen2);
    Ellipse2D.Float em = new Ellipse2D.Float(27,246,8,8);
    comp2D.fill(em);
  }
  public void paintComponent(Graphics comp)
  {
    See(comp);
    fuelleSee(comp);
    blasen(comp);
    menschen(comp);
  }
}
```


----------



## florian89 (20. Mrz 2007)

eyh man danke, du hast mir sowas von den arsch gerettettetetet!!!!!!!!!!!!!!!! vielen dank. echt man


----------

