# Menu als Thread



## Schinken (27. Apr 2006)

Ich hab schon vieles ausprobiert und nichts klappt. Hab die Lust verloren weiter selber zu suchen, vielleicht könnte 
mir jemand helfen. Die Methode "titelAnim" müsste in einem Thread ablaufen damit ich sie später abrufen kann
nachdem ein Intro gelaufen ist. Hab schon einige mal probiert das als Thread zu machen aber er kommt 
mit der Grafik nicht klar.



```
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Thread;
import java.awt.image.ImageObserver;

public class Projekt extends Applet implements MouseMotionListener, MouseListener
{
  Image imageSchrift, backgroundImage;
  Image Menu1, Menu2, Menu3, Menu4;
  int xposSchrift = 0;
  int xpos2=0;
  
  //Double Buffer
  private Image dbImage;
  private Graphics dbg;

  int backImageWidth = 848;
  int backImageHeigh = 478;

  public void init()
  {
    Menu1 = getImage(getCodeBase(), "Menu1.gif");
    Menu2 = getImage(getCodeBase(), "Menu3.gif");
    this.addMouseMotionListener(this);
    this.addMouseListener(this);
    resize(848, 478);
  }

  public void start(){}
  public void stop(){}
  public void destroy(){}

  public void paint (Graphics g)
  {
     backgroundImage = getImage (getCodeBase(), "title.jpg");
     imageSchrift = getImage (getCodeBase (), "schrift.gif");

     titelAnim(g);
  }

  public void mouseDragged (MouseEvent e){}
  
  public void mouseMoved (MouseEvent e)
  {
    int xPosMenu1 = ((this.getWidth()/2) - (Menu1.getWidth(this)/2));
    int yPosMenu1 = ((this.getHeight()/2) - Menu1.getHeight(this));
    int xPosMenu2 = ((this.getWidth()/2) - (Menu2.getWidth(this)/2));
    int yPosMenu2 = ((this.getHeight()/2) - Menu2.getHeight(this) + 50);
    
    if(e.getX() > xPosMenu1 && e.getY() > yPosMenu1 && e.getX() < xPosMenu1 + Menu1.getWidth(this) && 
                       e.getY() < yPosMenu1 + Menu1.getHeight(this))
    {
      Menu1 = getImage(getCodeBase(), "Menu2.gif");
      repaint();
    } else {
      Menu1 = getImage(getCodeBase(), "Menu1.gif");
      repaint();
    }
   
    if(e.getX() > xPosMenu2 && e.getY() > yPosMenu2 && e.getX() < xPosMenu2 + Menu2.getWidth(this) && 
                         e.getY() < yPosMenu2 + Menu2.getHeight(this))
    {
      Menu2 = getImage(getCodeBase(), "Menu4.gif");
      repaint();
    } else {
      Menu2 = getImage(getCodeBase(), "Menu3.gif");
      repaint();
    }
  }
  
  public void titelAnim(Graphics g)
  {
    while (backImageHeigh > 150)
    {
      g.drawImage(backgroundImage, 0, 0, this);
      g.drawImage(imageSchrift, xposSchrift, 0, backImageWidth, backImageHeigh, this);
      backImageWidth = backImageWidth - 35;
      backImageHeigh = backImageHeigh - 20;
      xposSchrift = xposSchrift + 17;

      repaint();

      StopThread(15);
    };
    
      g.drawImage(backgroundImage, 0, 0, this);
      g.drawImage(imageSchrift, xposSchrift, 0, backImageWidth, backImageHeigh, this);
      g.drawImage(Menu1, ((this.getWidth()/2)-(Menu1.getWidth(this)/2)) , ((this.getHeight()/2) - Menu1.getHeight(this)), this);
      g.drawImage(Menu2, ((this.getWidth()/2) - (Menu2.getWidth(this)/2)), ((this.getHeight()/2) - Menu2.getHeight(this)) + 50, this);
  }
  
  public void StopThread(int StopZeit)
  {
    try
    {
      Thread.sleep(StopZeit);
    } catch (InterruptedException e) {}
  }
  
  public void update (Graphics g)
  {
    // Initialisierung des DoubleBuffers
    if (dbImage == null)
    {
      dbImage = createImage (this.getSize().width, this.getSize().height);
      dbg = dbImage.getGraphics ();
    }

    // Bildschirm im Hintergrund löschen
    dbg.setColor (getBackground ());
    dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

    // Auf gelöschten Hintergrund Vordergrund zeichnen
    dbg.setColor (getForeground());
    paint (dbg);

    g.drawImage (dbImage, 0, 0, this);
  }
  
  public void mouseClicked (MouseEvent e){}
  public void mouseEntered (MouseEvent e){}
  public void mouseExited (MouseEvent e){}
  public void mousePressed (MouseEvent e){}
  public void mouseReleased (MouseEvent e){}
}
```


----------



## Leroy42 (5. Mai 2006)

Da du noch keine Antwort bekommen hast, versuche ich es mal


```
public void paint (Graphics g)
  {
     backgroundImage = getImage (getCodeBase(), "title.jpg");
     imageSchrift = getImage (getCodeBase (), "schrift.gif");

     titelAnim(g);
  }
```


```
public void titelAnim(Graphics g) 
  { 
    while (backImageHeigh > 150) 
    { 
      g.drawImage(backgroundImage, 0, 0, this);
      ...
      repaint(); 
      StopThread(15); 
    };
    
      g.drawImage(backgroundImage, 0, 0, this); 
      ...
  };
```

Das ist ja nur noch verwurschtelt  :autsch: 
Bei jedem Aufruf von paint (z.B. automatisch durch das System) lädst du deine Bilder
unnötigerweise erneut; die ersten beiden Zeilen gehören in die init-Methode. Danach reichst
du die Aufgabe des Zeichnens an die Methode titelAnim weiter, was ja auch ok ist.

Innerhalb der while-Schleife rufst du repaint() auf, was ja eine Aufforderung an den
*E*vent*D*ispatch*T*hread ist, erneut die paint-Methode aufzurufen, was
ja nun überhaupt keinen Sinn macht, es sei denn du willst eine Endlosschleife erzeugen.
Dazu reicht aber ein einmaliger Aufruf von repaint() am Ende aller Aktionen.

Der Aufruf von StopThread ist auch überflüssig, genauso wie die gesamte while-Schleife.

Denn in der Schleife überzeichnest du ja jedesmal das, was vorher gezeichnet wurde
und das zuletzt gezeichnete wird erneut durch die Aktionen hinter der Schleife überschrieben.
 :shock: 

Schließlich bleibt mir der tiefere Sinn deiner Leeranweisung und der Leerdeklarition
ziemlich verborgen ( :bae: )

Ich vermute mal das du die grundlegenden Ablauffolgen einer GUI noch nicht kennst
und versuchst, das Timing deiner Zeichnungen selbst zu übernehmen.

Beschreib doch mal, was genau du eigentlich vorhast; dann können wir dir hier
sicher weiterhelfen.


BTW: Was, bitte schön, hat das Ganze mit Menüs zu tun  :shock:


----------



## Schinken (6. Mai 2006)

ok, das mit dem aufruf in der init methode hab ich geändert, danke für den tipp. 


```
public void titelAnim(Graphics g)
  {
    while (backImageHeigh > 150)
    {
      g.drawImage(backgroundImage, 0, 0, this);
      g.drawImage(imageSchrift, xposSchrift, 0, backImageWidth, backImageHeigh, this);
      backImageWidth = backImageWidth - 35;
      backImageHeigh = backImageHeigh - 20;
      xposSchrift = xposSchrift + 17;

      repaint();

      StopThread(15);
    };
   
      g.drawImage(backgroundImage, 0, 0, this);
      g.drawImage(imageSchrift, xposSchrift, 0, backImageWidth, backImageHeigh, this);
      g.drawImage(Menu1, ((this.getWidth()/2)-(Menu1.getWidth(this)/2)) , ((this.getHeight()/2) - Menu1.getHeight(this)), this);
      g.drawImage(Menu2, ((this.getWidth()/2) - (Menu2.getWidth(this)/2)), ((this.getHeight()/2) - Menu2.getHeight(this)) + 50, this);
  }
```

der obige code sorgt dafür das die überschrift vom menu (Spielname) verkleinert wird. das soll folgendermaßen aussehen. ein intro kommt davor was am ende dann den spielnamen zeigt und dann ins menu übergeht, also der spielname immer kleiner wird und ein stück nach oben rutscht und der code da oben sorgt für die animation deshalb die while schleife mit repaint und das stopthread um die animation bisschen langsamer ablaufen zu lassen. wenn der spielnamen dann oben angekommen ist kommt unten das menu mit "Spiel starten" etc., deshalb auch das repaint in der while schleife.

mein problem ist nun das ich es nicht schafe das menu solange zu verbergen oder verstecken zusammen mit der mouseover funktion bis das intro vorbei ist. ich weiß einfach nicht wie man ein thread aus dem queltext erstellt um den teil einzufrieren.


----------



## Leroy42 (6. Mai 2006)

Schinken hat gesagt.:
			
		

> um den teil einzufrieren.


 :shock: Wer oder was soll da eingefroren werden  :shock: 

Aber immerhin verstehe ich jetzt was du vorhast.
Die Thread-Überschrift "Menü als Thread" war mehr als verwirrend,
da du ja keine richtigen Menüs meintest sonder deine Bilder Menu heißen.

Hier mal die richtige Vorgehensweise:

```
private boolean introLäuft;

	public void init() {
		introLäuft = true;
		new Thread(new Runnable() {
			public void run() {
				while (introLäuft) {
					repaint();
					try {Thread.sleep(15);} catch (InterruptedException e) {}
				}
			}}).start();
	}
	
	public void paint(Graphics g) {
		if (introLäuft)
			intro(g);
		else {
			g.drawImage(backgroundImage, 0, 0, this); 
			g.drawImage(imageSchrift, xposSchrift, 0, backImageWidth, backImageHeigh, this); 
			g.drawImage(Menu1, ((this.getWidth()/2)-(Menu1.getWidth(this)/2)) , ((this.getHeight()/2) - Menu1.getHeight(this)), this); 
			g.drawImage(Menu2, ((this.getWidth()/2) - (Menu2.getWidth(this)/2)), ((this.getHeight()/2) - Menu2.getHeight(this)) + 50, this); 
		}
	}
	
	void introLäuft(Graphics g) {
		g.drawImage(backgroundImage, 0, 0, this); 
		g.drawImage(imageSchrift, xposSchrift, 0, backImageWidth, backImageHeigh, this); 
		backImageWidth = backImageWidth - 35; 
		backImageHeigh = backImageHeigh - 20; 
		xposSchrift = xposSchrift + 17;
		introLäuft = backImageHeigh > 150;
	}
```

Ich kann dir jetzt leider nicht mehr erklären, wie das ganze funktioniert,
auch habe ich es nicht compiliert.

Aber vielleicht können dir mit dem Ansatz dann ja andere weiterhelfen.

Noch ein schönes WE


----------



## Schinken (7. Mai 2006)

ich habs hingekriegt, danke für den ansatz.


----------

