# Applet immer wieder neu laden - Problem



## lcv (3. Nov 2009)

Hallo, 
ich habe mal wieder drei kleiner Probleme. Ich habe ein Applet mit mehreren Bildern drinnen. Die Bilder sind animiert. 

Es fährt quasi ein Auto von oben nach unteren. 

Problem 1: Wie kann ich es machen, dass das auto komplett aus dem Bild verschwindet.
Und nicht ein Teil stehen bleibt. Ich habe innerhalb des Applet ein großes Bild. Quasi ein Hintergrund mit Straßen. Es soll nun so sein. Wenn die kleinen Bilder zb ein Auto, diesen Hintergrund verlässt. Soll es nicht mehr angezeigt werden!
Wie kann ich das realisieren

Problem 2: In der Paint Methode werden alle Bilder gezeichnet. Es sind also immer alle Bilder angezeigt. Wie kann ich es machen, dass ich Bilder wieder unsichtbar mache. Also sowas wie Visible(false) setzen!


Problem 3: Wie ist es möglich das Applet immer wieder neu zu starten? Das Auto fährt quasi einmal über den Bildschirm. Es soll aber unendlich oft fahren, bis das Fenster geschlossen wird. Wie ist das möglich?

Danke 
 und liebe Grüße, 
LCV

Anbei einen Auszug aus meinem bisherigen Quelltext


```
import java.awt.event.*;
import java.applet.Applet;
import java.util.EventListener;


import java.awt.*;
import javax.swing.*;
import java.util.Random;


import java.awt.*;


public class Zebrastreifen extends JApplet {
    private Random zufallszahl;   
    Image bild;
    Image auto;
    Image auto2;
    Image fussgaenger1;
    Image fussgaenger2;
    Image fussgaenger3;
    int y = 550;
    int k = 110;
    int o = 160;
    int x = 240;
    int z = 90;
    int e = 100;
    int h = 650;
    int i = 310;
    int m = 310;
    int n = 100;
    @Override
    public void init() {
        bild = getImage(getCodeBase(), "bild.jpg");
        auto = getImage(getCodeBase(), "auto.gif");
        auto2 = getImage(getCodeBase(), "auto2.gif");
        fussgaenger1 = getImage(getCodeBase(), "fussgaenger1.gif");
        fussgaenger2 = getImage(getCodeBase(), "fussgaenger2.gif");
        fussgaenger3 = getImage(getCodeBase(), "fussgaenger3.gif");
        JRadioButton c1 = new JRadioButton("Keine Fussgänger", true);
        JRadioButton c2;
        c2 = new JRadioButton("Ein Fussgänger");
        JRadioButton c3;
        c3 = new JRadioButton("Zwei Fussgänger");
        JRadioButton c4;
        c4 = new JRadioButton("Zufällige Wiedergabe");
        ButtonGroup bg = new ButtonGroup();
        bg.add(c1);
        bg.add(c2);
        bg.add(c3);
        bg.add(c4);
        JPanel p = new JPanel() {
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(bild, 5, 100, this);
                g.drawImage(auto, x, y, this);

                 g.drawImage(auto2, o, k, this);
                 g.drawImage(fussgaenger1, z, e, this);
                g.drawImage(fussgaenger2, i, h, this);
                g.drawImage(fussgaenger3, m, n, this);

            }
        };
        getContentPane().add(p);
        p.add(c1);
        p.add(c2);
        p.add(c3);
        p.add(c4);
        p.setSize(50, 50);
        p.setVisible(true);
        if (c1.isSelected()) {
            generator();
            fussgaengereinsohnezebra();
            fussgaengerzweiohnezebra();
            fussgaengerdreiohnezebra();
        } else if (c2.isSelected()) {
            
          
        } else {
            
        }
    }
    
    
       public void generator()
    {
        zufallszahl= new Random();
        
        if (zufallszahl.nextInt()%2 == 0)
        {
            autofahrenoben();
        }
        else
        {   
           autofahrenunten();
        }
    }
    
    
    public void autofahrenunten() {
        new Thread(new Runnable() {
            public void run() {
                while (y > 110) {
                   
                    y = y - 1;
                    repaint();
                    try {
                        Thread.sleep(3);
 
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                
            }
            }
        }).start();
    }
    
      public void autofahrenoben() {
        new Thread(new Runnable() {
            public void run() {
                while (k < 550) {
                   
                    k = k + 1;
                    repaint();
                    try {
                        Thread.sleep(3);
 
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                
            }
            }
        }).start();
    }
    
    
    
    
    public void fussgaengereinsohnezebra() {
        new Thread(new Runnable() {
            public void run() {
                while (e > 0) {
                    
                    e = e + 1;
                    repaint();
                    try {
                        Thread.sleep(10);
 
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            
            }
        }).start();
    }
    
    
    @Override
    public String getAppletInfo() {
        return "Title: Test   \nAuthor: Test   \n";
    }
}
```


----------



## Chumax (3. Nov 2009)

zum Beispiel mit einer schleife die so lange läuft, bis sie beendet wird.


----------



## lcv (3. Nov 2009)

Ja das hatte ich mir für das eine Problem auch schon gedacht: Ich weiß nur nicht genau wo ich die Schleife hinmachen soll! Kommt die um die gesamte init methode oder wie?
Danke für die schnelle Antwort!
Gruß
LCV


----------



## lcv (4. Nov 2009)

Kann mir einer weiter helfen? Besonders das unsichtbarmachen nach einer Animation ist sehr wichtig und das durchgängig ausführen! Wäre echt super!
Vielen Dank


----------



## darkeye2 (5. Nov 2009)

ich würde vorschlagen, auf den rand deines hintergrundes einfach einen eventlistener zu  machen, und sobald das auto diesen überquert einfach auto löschen,  oder einfacher, wenn du weißt, wie lang die strecke ist oder wie lange das auto braucht, einfach ne schleife, die überprüft, ob strecke zurückgelegt wurde.


----------



## Spacerat (5. Nov 2009)

Animationen realisiert man mit mindestens einem Thread und DoubleBuffering. Innerhalb des Threads ruft man ständig [c]repaint()[/c] auf.
Applets verfügen über die Methoden [c]init()[/c], [c]start()[/c], [c]stop()[/c] und [c]destroy()[/c]. Diese werden vom Browser je nach bedarf aufgerufen.
Wie die Methodenamen schon andeuten, hat jede davon eine Bestimmte Aufgabe:
1. Init: Initialisiert das Applet. In dieser Methode lädt man Grafiken, Clips usw. und instanziert evtl. Threads, welche für Animationen verwendet werden sollen.
2. Start: Hier kann man die vorher instanzierten Threads und/oder Clips erstmalig ([c]<thread>.start()[/c]) bzw. erneut starten ([c]<thread>.notify()[/c]. Erst nach dem Aufruf von [c]start()[/c] wird [c]update()[/c] unddadurch [c]paint()[/c] aufgerufen.
3. Stop: Hält das Applet (vorübergehend) an. Threads und/oder Clips können hier mit einem entsprechenden [c]<thread>.wait()[/c]-Konstrukt angehalten werden.
4. Destroy: Das Applet wird zerstört. In dieser Methode sollte man alle verwendeten Ressourcen (geladene Grafiken und Clips) wieder freigeben. Das bedeutet man setzt alle Referenzen der verwendeten Objekte auf *null*, damit sie vom GC gesehen werden. Threads und Clips müssen vorher beendet werden ([c]<thread>.interrupt()[/c] bzw. [c]<clip>.stop()[/c]).


----------



## Marco13 (5. Nov 2009)

DoubleBuffering braucht man hier nicht, JPanel ist schon doubleBuffered.

Das unsichtbarmachen... Ja, diese variablen sind natürlich besch*** benannt, aber du wirst sowas machen können wie

```
class Soundso
{
    private boolean autoSichtbar = true;

   ...
         // In der paintComponent-Methode vom JPanel, wo die Bilder gemalt werden:
        if (autoSichtbar) g.drawImage(auto2, o, k, this);
```


Um das Auto unsichtbar zu machen, dann einfach
autoSichtbar = false;
repaint();
machen.


----------



## Spacerat (5. Nov 2009)

@Marco13: Mit dem DB hast du natürlich recht. Steht da wohl auch nur, weil's 'ne Standardantwort für Animationen ist.
Für alle Animationen genügt hier ein einziger Thread. Wichtig ist das Timing bzw. ein korrekt getimetes Positionieren der Bilder. Dazu legt man eine Zeitspanne in ms und einen Startpunkt sowie einen Endpunkt fest, in welcher eine Bewegung ablaufen soll. Über folgende Formel erhalten wir die prozenual abgelaufene Zeit der Animation:
	
	
	
	





```
double percent = System.currentTimeMillis() % animTime / (double) animTime;
```
Mit diesem Wert, dem Start- und dem Endpunkt kann man für eine Lineare Bewegung über das 1. Polynom (oder Polynom 1. Grades) den Punkt errechnen, an welchem die Grafik gezeichnet werden soll.
	
	
	
	





```
point.x = start.x + (int) ((end.x - start.x) * percent);
point.y = start.y + (int) ((end.y - start.y) * percent);
```
So verfährt man dann mit allen animierten Grafiken.


----------



## lcv (9. Nov 2009)

Hey, 
vielen Dank für die tollen Beiträge. 
Problem 1 und 2 habe ich damit lösen können! Mit dieser Variable die Lösung ist perfekt für mein Problem. 
Zu meinem 3 Problem (durchgängig das Applet immer wieder neu Aufrufen. Also dass das Auto durchgängig fährt) habe ich noch nicht ganz hinbekommen! Wenn ich das richtig verstanden habe, geht das mit den Methoden, die ein Applet zur Verfügung stellt. 
Also destroy, start und init. Aber wo ruf ich die auf und brauche ich nochwas? 
Danke für die tolle Hilfe.
Gruß
LCV


----------



## L-ectron-X (9. Nov 2009)

lcv hat gesagt.:


> Also destroy, start und init. Aber wo ruf ich die auf und brauche ich nochwas?


Im Normalfall ist es nicht nötig, die Methoden des Applet-Lebenszykluses explizit aufzurufen. Der Browser ruft sie zum festgelegten Zeitpunkt auf.
Du musst nur diese Zeitpunkte kennen, also wann er eine bestimmte Methode aufrufen wird.

Edit: Um dein Auto aber ständig durch's Applet fahren zu lassen setzt du in der start()-Methode eine Schleife oder startest einen weiteren Thread, der sich unabhängig vom Geschehen im Applet ums "Autofahren" kümmert.


----------



## lcv (9. Nov 2009)

Ok. Also hab jetzt mal ne Start Methode bei mir rein gemacht. In welcher Form mach ich da jetzt ne schleife. Eine Endlosschliefe? Hängt sich das dann nicht auf? Und wie mach ich dass der Wert komplett zurückgesetzt wird? Also wie neu aufrufen dann!

Ich hab jetzt folgendes:

public void start(){
        while(end == 0) {

        }

    }

Mach ich da nun ein Aufruf von destroy oder init oder so?

Und wie mache ich für die Schliefe eine Abbruchbedingung in der Form wenn das Fenster geschlossen wird!

Vielen Dank
Gruß
LCV


----------



## Marco13 (9. Nov 2009)

```
public void start()
{
    Thread t = new Thread(new Runnable()
    {
        public void run()
        {
            while (end == 0)  { ... }
        }
    }
    t.start();
}

// Und ggf. noch
public void destroy()
{
    super.destroy();
    end = 1;
}
// da müßt' ich aber erst schauen ob das nötig ist... Vermutlich nicht...
```


----------



## lcv (9. Nov 2009)

Ok das hab ich verstanden. Das einzige ist nun... in die while da muss ich ja einen befehl noch rein machen. der alle werte quasi zurück setzt und das applet quasi wie neu startet! Mach ich das nun mit init? oder setzte ich da die einzelnen Variablen zurück oder gibts da einen extra Befehl für?

Vielen Dank und Gruß
LCV


----------



## L-ectron-X (9. Nov 2009)

Marco13 hat gesagt.:
			
		

> ```
> super.destroy();
> ```


Eigendlich brauchst du den super-Aufruf schon nicht. Die Implementierungen in Applet sind leer.


----------



## lcv (9. Nov 2009)

Ok. Ja das geht ja dann wahrscheinlich automatisch wenn die Methode im Applet selber leer ist. Oder?
Jetzt ist nur noch die Frage wie ich das in der While Schleife machen soll!??!

Dankeschön!!


----------



## L-ectron-X (9. Nov 2009)

Wenn bspw. dein Auto aus dem oberen Anzeigebereich herausgefahren ist, musst du die Werte für die Koordinaten z.B. auf den unteren Anzeigebereich zurücksetzen.
Das machst du, in dem du nach jedem Zeichendurchgang die Bedingungen (if) abfragst.
Sind sie erfüllt, setzt du die Werte, die du in privaten Instanzvariablen hältst, zurück.


----------



## Spacerat (9. Nov 2009)

Zumindest ist in der Destroy-Methode ein [c]end = 1[/c] (besser man verwendet dazu boolsche Werte) nötig, damit sich der Thread beendet. Der Thread muss sich von selbst beenden können, da ein Applet zwar einen Thread starten, nicht jedoch per[c]interrupt()[/c] wieder anhalten kann. In der while-Schleife könntest du z.B. die Prozentualwerte der Fussgänger und Autos berechnen und festlegen ob sie gerade sichtbar oder unsichtbar sein sollen. Ferner muss dort [c]repaint()[/c] aufgerufen werden.


----------



## lcv (9. Nov 2009)

In die while Schleife müssen ja eigentlich die Wert von den Variablen zurückgesetzt werden. Also die Koordinaten. 
Ich hatte jetzt versucht allen Variablen darin die Startwerte wieder zuzuweisen. 
Das ging aber nicht. Also Repaint hab ich auch schon drin aufgerufen. Aber irgendwie ging das auch noch nicht richig. 
So ganz ist mir das noch nicht klar. Ich werde nun nochmal mir das anschauen.
Trotzdem freue ich mich über jede Idee und jeden Hinweis.  Soweit ich was herausgefunden habe, melde ich mich wieder! 
Danke


----------



## lcv (9. Nov 2009)

Hier nochmal mein Quelltext der beiden Methoden. Das habe ich bis jetzt:


```
public void start(){
      Thread t = new Thread(new Runnable()
    {
        public void run()
        {
              autoSichtbar = false;
              autoSichtbar2 = false;
              fussganger1Sichtbar = false;
              fussganger2Sichtbar = false;
              fussganger3Sichtbar = false;
              y = 550;
              k = 110;
              o = 160;
              x = 240;
              z = 90;
              e = 100;
              h = 650;
              i = 310;
              m = 310;
              n = 100;
            while (end == 0)  {
            repaint();
           
            }
        }
    });
    t.start();
        
    }
    
    
        public void destroy()
        {
          
            end = 1;
        }
```


----------



## L-ectron-X (10. Nov 2009)

In der run()-Methode werden jetzt bei jedem Schleifendurchlauf deine Startwerte gesetzt.
Du sollestst die Startwerte zu Beginn der start()-Methode setzen. Dazu am besten eine weitere private Methode schreiben, die das erledigt und die du immer wieder aufrufen kannst.
In der run()-Methode deines Threads lässt du das Auto mit jedem neuen Schleifendurchgang ein Stück weiter fahren, indem du die Koordinaten veränderst und repaint() aufrufst. Danach prüfst du, ob sich die Koordinaten noch im sichtbaren Bereich befinden und setzt sie ggf. auf die Startwerte zurück.


----------



## lcv (10. Nov 2009)

Das habe ich jetzt versucht gehabt. Da ging plötzlich gar nix mehr. Und nix war mehr animiert. Wie mach ich das denn jetzt? Ist echt wichtig. Muss doch irgendwie gehen, dass es mehrmals durchlaufen wird? Mit der extra Methode ging das irgendwie nicht. Hab ne neue Methode public void werteSetzen() gemacht und da die Werte zugewiesen und einen Methodenaufruf in die Start methode in die While ( end == 0) Schliefe gemacht??! Oder ist das falsch! ???:L  ???:L  
Danke! :toll:


----------



## Spacerat (10. Nov 2009)

Man hab' ich Zeit...:lol:
	
	
	
	





```
import java.applet.Applet;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;

public class AnimApplet
extends Applet
{
	private static final long serialVersionUID = 1L;
	private static final String[] names = {
		"bild1.gif",
		"bild2.gif",
		"bild3.gif",
		"bild4.gif",
		"bild5.gif",
	};
	private static final Point[] startPoints = {
		new Point(4, 5),
		new Point(18, 100),
		new Point(200, 10),
		new Point(50, 50),
		new Point(100, 100),
	};
	private static final Point[] endPoints = {
		new Point(200, 200),
		new Point(118, 10),
		new Point(20, 100),
		new Point(100, 100),
		new Point(50, 50),
	};
	private static final long[] deltaTimes = {
		100000,
		3000,
		10000,
		5000,
		500,
	};
	private static final Component c;
	private static final MediaTracker mt;
	private static int cnt = 0;

	static
	{
		c = new Component()
		{
			private static final long serialVersionUID = -8883857847456903994L;
		};
		AccessController.doPrivileged(new PrivilegedAction<Void>()
		{
			public Void run()
			{
				try {
					Field appContextField = Component.class.getDeclaredField("appContext");
					appContextField.setAccessible(true);
					appContextField.set(c, null);
				} catch (NoSuchFieldException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				return null;
			}
		});
		mt = new MediaTracker(c);
	}

	private final Collection<MovingObject> objects = new ArrayList<MovingObject>();
	private Thread animator;
	private boolean running, paused;
	private BufferedImage second;

	@Override
	public void init()
	{
		Point start, end;
		// Einlesen der Daten...
		// Normalerweise über getParameter()...
		// Zur Demonstration mal eben statisch
		for(int n = 0; n < names.length; n++) {
			start = startPoints[n];
			end = endPoints[n];
			objects.add(new MovingObject(getImage(getDocumentBase(), names[n]), start, end, deltaTimes[n]));
		}
		// Animationsthread instanzieren...
		animator = new Thread()
		{
			@Override
			public void run()
			{
				while(running) {
					if(!paused) {
						repaint();
						synchronized(this) {
							try {
								wait(20); // für 50 FPS
							} catch(InterruptedException e) {
								running = false;
							}
						}
					}
				}
				animator = null;
			}
		};
		// ...und pausiert starten
		running = paused = true;
		animator.start();
	}

	@Override
	public void start()
	{
		// Animationsthread starten
		paused = false;
	}

	@Override
	public void stop()
	{
		// animationsthread pausieren
		paused = true;
	}

	@Override
	public void destroy()
	{
		// Animationsthread beenden (lassen)
		running = false;
		// Objekte freigeben
		objects.clear();
	}

	@Override
	public void update(Graphics g)
	{
		if(second == null || second.getWidth() != getWidth() || second.getHeight() != getHeight()) {
			second = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT);
		}
		Graphics g2 = second.getGraphics();
		g2.clearRect(0, 0, getWidth(), getHeight());
		paint(g2);
		g.drawImage(second, 0, 0, this);
	}

	@Override
	public void paint(Graphics g)
	{
		for(MovingObject o : objects) {
			o.paint(g);
		}
	}

	public static final BufferedImage track(Image source, int type)
	{
		int id = cnt++;
		mt.addImage(source, id);
		try {
			mt.waitForID(id);
		} catch(InterruptedException e) {
			// nothing;
		}
		BufferedImage rc = new BufferedImage(source.getWidth(c), source.getHeight(c), type);
		rc.getGraphics().drawImage(source, 0, 0, c);
		return rc;
	}
}

final class MovingObject
extends BufferedImage
{
	private int x, y;
	private long runningTime, startTime;
	private final Point start, delta;
	private final long deltaTime;

	public MovingObject(BufferedImage i, Point start, Point end, long deltaTime)
	{
		super(i.getWidth(), i.getHeight(), i.getType());
		if(start == null || end == null) {
			throw new IllegalArgumentException("any parameter may not be null");
		}
		if(deltaTime < 20) {
			throw new IllegalArgumentException("deltaTime has to be larger than 20");
		}
		getGraphics().drawImage(i, 0, 0, null);
		this.start = start;
		delta = (Point) end.clone();
		x = start.x;
		y = start.y;
		delta.x -= x;
		delta.y -= y;
		startTime = -1;
		this.deltaTime = deltaTime;
	}

	public MovingObject(Image i, Point start, Point end, long deltaTime)
	{
		this(AnimApplet.track(i, BufferedImage.TRANSLUCENT), start, end, deltaTime);
	}

	public void paint(Graphics g)
	{
		if(g == null) {
			return;
		}
		if(startTime < 0) {
			startTime = System.currentTimeMillis();
		}
		g.drawImage(this, x, y, null);
		runningTime = (System.currentTimeMillis() - startTime) % deltaTime;
		float percent = (float) runningTime / (float) deltaTime;
		x = start.x + (int) (delta.x * percent);
		y = start.y + (int) (delta.y * percent);
	}
}
```
Hoffe du kannst damit was anfangen... geht zwar auch anders, aber im Grossen und Ganzen ist das ein Ansatz.


----------



## lcv (11. Nov 2009)

Puh das sieht aber ganz schön kompliziert aus. Im großen und ganzen ist mir das schon klar. Aber welche Teile muss ich jetzt genau bei mir einbauen?
Es hängt irgendwie an der Umsetzung! Vielen dank für die Hilfe!
LG, LCV


----------



## Spacerat (11. Nov 2009)

Wenn du so willst, brauchst du eigentlich nur die Klasse MovingObject in etwas abgeänderter Form:
	
	
	
	





```
public final class MovingObject
extends BufferedImage
{
	private int x, y;
	private long runningTime, startTime;
	private float anim;
	private final Point start, delta;
	private final long deltaTime, stillTime;

	public MovingObject(BufferedImage i, Point start, Point end, long deltaTime, long stillTime)
	{
		super(i.getWidth(), i.getHeight(), i.getType());
		if(start == null || end == null) {
			throw new IllegalArgumentException("any parameter may not be null");
		}
		if(deltaTime < 20) {
			throw new IllegalArgumentException("deltaTime has to be larger than 20");
		}
		if(stillTimeTime < 0 || stillTime >= deltaTime - 20) {
			throw new IllegalArgumentException("stillTime has to be smaller than deltaTime");
		}
		getGraphics().drawImage(i, 0, 0, null);
		this.start = start;
		delta = (Point) end.clone();
		x = start.x;
		y = start.y;
		delta.x -= x;
		delta.y -= y;
		startTime = -1;
		this.deltaTime = deltaTime;
		this.stillTime = stillTime;
	}

	public int getX()
	{
		return x;
	}

	public int getY()
	{
		return y;
	}

	public boolean isAnimating()
	{
		return anim < 1.0f;
	}

	public synchronized void move()
	{
		if(startTime < 0) {
			startTime = System.currentTimeMillis();
		}
		runningTime = (System.currentTimeMillis() - startTime) % deltaTime;
		float percent = (float) runningTime / (float) deltaTime;
		anim = (float) runningTime / (float) deltaTime - stillTime;
		if(anim > 1.0f) {
			anim = 1.0f;
		}
		x = start.x + (int) (delta.x * anim);
		y = start.y + (int) (delta.y * anim);
	}
}
```
in der [c]paint()[/c]-Methode des Applets kann es dann wie folgt gezeichnet werden:
	
	
	
	





```
public void paint(Graphics g)
{
	// mo ist eine Instanz von MovingObject
	if(mo.isAnimating()) {
		g.drawImage(mo, mo.getX(), mo.getY(), this);
		mo.move();
	}
}
```
@Edit: Ungetestet: Verzögerungszeit hinzugefügt.


----------



## lcv (12. Nov 2009)

Wieso brauche ich das denn? die Animaiton funktioniert doch schon? Ich will doch nur immer wieder neu laden!?!! Wie geht das denn? Ich versteh es einfach nicht.


----------



## Spacerat (12. Nov 2009)

Dann versteh' ich's nicht. Wieso willst du denn das Applet unbedingt neu laden wollen? Die Animation läuft kontinuierlichdurch und startet dann von alleine neu. Normalerweise überlässt man den Ladevorgang dem Browser. Nach dem  ein Lebens-Zyklus (init, start, stop oder destroy) des Applets von dem Browser gestartet wurde, belässt man das Applet in diesem. Ok, vllt. kann man noch eine Verzögerung in das MovingObject einbauen, in welchen das Ding nicht sichtbar ist, aber es ist wircklich nicht nötig, das Applet neu zu laden.
@Edit:  Der Aufruf der Move-Methode gehört natürlich ausserhalb, unter die If-Abfrage...


----------

