Swing Animation - VM beendet nicht

bile

Mitglied
Tag auch...

ich hab momentan ein kleines Problem... es geht um eine Conways Game of Life Simulation, bei der man sich erst durch ein paar Menus klickt, eine Startkonfiguration lädt und dann startet...

Grundlegender Aufbau:

- Ein paar JFrames, die sich gegenseitig aufrufen und visible resp. invisible setzten als Menu...
- Dann per JFileChooser die Startkonfiguration wählen...
- Dann wird ein neues JFrame angezeigt, welches ein JPanel mit überschriebener paint() Funktion enthält (nennen wir die Instanz area).

und dann vermutlich hier das Problem:
- ich starte einen neuen Thread und rufe darin die runMachine() - Methode von area auf:

area.setVisible(true);
Java:
Thread t = new Thread() {
  public void run() {
    area.runMachine();
  }
};
t.start();

die runMachine()-Methode macht nichts anderes als folgendes (wobei frame = das JFrame, das area beinhaltet):
Java:
public void runMachine() {
 while(frame.isVisible()) {
  calculateNextRound();
  SwingUtilities.invokeLater( new Runnable() {
   public void run() {
    area.repaint();
   }
  });
 }
}

Die Animation funktioniert auch ohne sichtbare Probleme. Wenn ich nun aber das JFrame schliesse (EXIT_ON_CLOSE), dann wird die VM nicht abgewürgt und es bleibt mir irgend ein Zombie-Thread im TaskManager hängen....

Ich weiss, dass Swing nicht Thread-save ist... aber falls irgendwer grad eine Mr.-Obvious-Idee dazu hat, woran es liegen könnte, würd ich mich gerne belehren lassen...

Danke
.bile
 
Ich würde nen windowClosing Listener implementieren und damit ein boolean flag setzen. In deinem Thread fragst du dann das boolean flag ab, statt auf den frame zuzugreifen.
 
okay, zeja, das tönt gut.

also etwas in der Art:

also in area
private volatile boolean showing inklusive getter und setter.
und für frame:

Java:
...

frame.addWindowListener(new WindowListener() {
  ...
 @Override
 public void windowClosing(WindowEvent e) {
   area.setShowing(false);
 }
...
});

und dann in der Loop:

Java:
public void runMachine() {
 while(isShowing) {
  calculateNextRound();
  SwingUtilities.invokeLater( new Runnable() {
   public void run() {
    area.repaint();
   }
  });
 }
}

..so müsste die runMachine()-Funktion verlassen werden, sobald das Fenster geschlossen wird... und dann? Thread.stop() ist ja deprecated und nach meinem Verständnis werden Threads, die aus ihrer run()-Methode zurück kommen oder nicht mehr referenziert werden abgeschossen, oder? Oder muss ich noch einen interupt auslösen?
 
Der Thread hört auf zu laufen wenn er aus der Endlosschleife raus ist, ja.

Ein interrupt benötigst du nur wenn du den Thread schlafen legst oder in einem wait bist.
 
okay... werde ich vermutlich in einem zweiten Schritt benötigen, um das Tempo zu regulieren..
dann würde ich in windowClosing() also einfach noch t.interrupt() aufrufen...

Gut, danke, ich probiers am Abend aus und poste dann die Lösung und schliesse das Thema wenn's klappt.

Gruss
.bile
 

Neue Beiträge

Zurück