# Problem mit JApplet bzw Applet



## Guest (8. Sep 2007)

Hallo,

ich wollte mich ein bisschen mit Applets und kleinen Animationen beschäftigen. Hab mit Hilfe eines Tutorials folgenden Code geschrieben:


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


public class Ball extends JApplet implements Runnable
{
	// Initialisierung der Variablen
	int x;	
	int y;	
	int d;

	public void init()
	{
            x = 0;
            y = 80;
            d = 30; 
	}

	public void start ()
	{
		Thread th = new Thread (this);
		th.start ();
	}

	public void stop()
	{

	}

	public void destroy()
	{

	}

	public void run ()
	{
		while (true)
		{
			x ++;
			repaint();

			try
			{
				Thread.sleep (20);
			}
			catch (InterruptedException ex)
			{
			}

		}
	}


	public void paint (Graphics g)
	{
		g.setColor  (Color.blue);
                g.fillOval (x,y,d,d);
	}

}
```

Das ist also ein einfacher ausgefüllter Kreis der sich von links nach rechts bewegt. Wenn man das Applet ausführt dann zieht der Ball jedoch den Kreis "hinter sich mit" (sozusagen nen Schatten mit sich zieht). Das heisst die repaint() bzw die update() löscht das Bild nicht. Nach stundenlangen versuchen und googlen bin ich dann drauf gekommen das wenn man das 


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

public class Ball extends JApplet implements Runnable
```

durch 


```
import java.applet.*;
import java.awt.*;

public class Ball extends Applet implements Runnable
```

ersetzt, dieser Schatten weggeht.

Warum gibt es da zwischen Applet und JApplet nen unterschied ? Warum löscht die update() das Bild bei JApplet nicht und wie kann ich es evtl "manuell" löschen ?

Danke für eure Hilfe


----------



## Wildcard (8. Sep 2007)

Geh am besten wieder zur ursprünglichen Variante mit JApplet zurück und änder paint:

```
public void paint (Graphics g)
   {
      //im Falle von Applet wird dadruch lediglich der Hintergrund gereinigt
      super.paint(g);
      g.setColor  (Color.blue);
                g.fillOval (x,y,d,d);
   }
```

Besser wäre es noch, nicht direkt auf das Applet zu zeichnen, sondern auf eine JComponent oder JPanel.
Bei Swing überschreibst du dann statt paint die paintComponent. update solltest du bei Swing gar nicht überschreiben.


----------



## Guest (8. Sep 2007)

Dankeschön hat gefunzt!

Noch ne dumme Frage hinterher: Warum sollte man auf das Panel zeichnen und nicht direkt aufs Applet ?


----------



## Wildcard (8. Sep 2007)

Weil man sich direkt angewöhnen sollte paintComponent statt paint zu überschreiben und dazu wird eine lightweight Komponente wie JPanel oder JComponent benötigt (weil ein Applet kein paintComponent hat).


----------



## Guest (8. Sep 2007)

alle guten Dinge sind 3:

1. ok, die Erklärung ist ja einleuchtend nur ist damit die Frage nicht beantwortet. Auf die Gefahr hin dich zu nerven: Ich versteh nicht warum "man sich das angewöhnen soll". Worin besteht mein Vorteil mit einer lightweight component zu arbeiten und damit die paintComponent() benutzen zu "dürfen/können"... 

2. mir fehlt noch das Verständnis ( wie man wohl leicht merkt  ) ..kann man das so vereinfacht sagen?:

paint() -> AWT 
repaint (AWT) -> update() -> paint()

paintComponent() -> Swing
repaint (Swing) -> paintComponent()

3. Danke !  :wink:


----------



## Wildcard (9. Sep 2007)

1. so einfach ist das gar nicht zu beantworten, auch deshalb, weil es nicht falsch ist direkt in einem Frame zu zeichnen.
Das Problem ist aber, das ein Frame ein komplexes Konstrukt aus Dekorator, Rahmen, Fläche und verschiedenen Ebenen ist.
Paint beeinflußt die gesamte Komponente, und deren Kindern, während paintComponent nur die Komponente selbst zeichnen muss und sich um nichts anderes kümmerst.
Der Scope bleibt also auf das nötigste reduziert. 
Weiterhin ist es in realen Anwendungen meistens auch gar nicht sinnvoll direkt auf den Frame zu zeichnen, da ein Programm mit Zeichenfläche üblicherweise auch reguläre Widgets enthält. Daher wird der Zeichenbereich i.d.R. in einer eigenen Komponete 'isoliert'.

2. Mach dir nicht zu viele Gedanken darüber. Du musst nur wissen das du in paintComponent zeichnen kannst und das nach repaint() irgendwann die paintComponent aufgerufen wird. Der Rest kommt von selbst  :wink:


----------

