Hallo,
Nachdem mir bei meinem Projekt "Game of Life" schon neulich hier geholfen wurde, bin ich wieder steckengeblieben.
Wenn ich in BlueJ die main()-Methode in der Klasse Logik aufrufe, die die Methode spielen() aufruft, dann läuft das Programm wie es sollte - nach jeder Veränderung des Spielfeldes wird das Spielfeld neu gezeichnet. d.h. man sieht jeden Schritt.
Wenn ich aber erstmal nur die Klasse Logik erzeuge und dann den Button start drücke, registriert dies mein Listener (der in einer separaten Klasse liegt) und ruft ebenfalls die Methode spielen() auf, aber dann wird das Spielfeld erst angezeigt, wenn die Schleife in der Methode spielen() durchgelaufen ist, also nur das Endbild, in meinem Beispiel hier nach 10 Schritten.
Hier ist mein Code, etwas gekürzt:
Klasse Logik, die Hauptklasse:
Klasse Welt, die Zeichenklasse, erbt von JPanel:
Klasse Listener, erbt von MouseAdapter:
Es scheint auch von der Logik her alles richtig zu sein, d.h. das Endbild sieht auch vernünftig aus, aber nur dass man halt keine Animation sieht. Ich hoffe, das Problem lässt sich lösen, ohne irgenwelche Threads verlegen zu müssen... bei anderen Projekten lief es auch so.
Liebe Grüße und vielen Dank, Salmo Salar
Nachdem mir bei meinem Projekt "Game of Life" schon neulich hier geholfen wurde, bin ich wieder steckengeblieben.
Wenn ich in BlueJ die main()-Methode in der Klasse Logik aufrufe, die die Methode spielen() aufruft, dann läuft das Programm wie es sollte - nach jeder Veränderung des Spielfeldes wird das Spielfeld neu gezeichnet. d.h. man sieht jeden Schritt.
Wenn ich aber erstmal nur die Klasse Logik erzeuge und dann den Button start drücke, registriert dies mein Listener (der in einer separaten Klasse liegt) und ruft ebenfalls die Methode spielen() auf, aber dann wird das Spielfeld erst angezeigt, wenn die Schleife in der Methode spielen() durchgelaufen ist, also nur das Endbild, in meinem Beispiel hier nach 10 Schritten.
Hier ist mein Code, etwas gekürzt:
Klasse Logik, die Hauptklasse:
Java:
import javax.swing.JFrame;
import javax.swing.JButton;
import java.util.Random;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JPanel;
public class Logik
{
private JFrame frame;
private Welt welt = new Welt();
public static void main(String args[]) throws InterruptedException {
new Logik().spielen(50, 1000);
}
public Logik()
{
frame = new JFrame("Game of Life");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(515, 580);
Listener audi = new Listener();
audi.setLogik(this);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
welt.addMouseListener(audi);
panel.add(welt,BorderLayout.CENTER);
JPanel buttonPanel = new JPanel(); //hat automatisch FlowLayout()
JButton startButton = new JButton("start");
startButton.addMouseListener(audi);
audi.setStartButton(startButton);
buttonPanel.add(startButton);
JButton endButton = new JButton("end");
endButton.addMouseListener(audi);
audi.setEndButton(endButton);
buttonPanel.add(endButton);
panel.add(buttonPanel, BorderLayout.PAGE_END);
frame.setContentPane(panel);
frame.setVisible(true);
}
public void spielen(int prozent, int anzahlSchritte) throws InterruptedException {
boolean[][] feld = new boolean[100][100];
feld = feldZufälligInitialisieren(prozent);
for (int n = 0; n < anzahlSchritte; n++) {
welt.setFeld(feld);
welt.repaint();
Thread.sleep(150);
feld = nächsteGeneration(feld);
}
}
public boolean[][] feldZufälligInitialisieren(int p){
Random rand = new Random();
boolean[][] neuesFeld = new boolean[100][100];
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
neuesFeld[i][j] = rand.nextInt(100) < p;
}
}
return neuesFeld;
}
private boolean[][] nächsteGeneration(boolean[][] altesFeld){
boolean[][] neuesFeld = new boolean[100][100];
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
int nachbarn = getAnzahlNachbarn(altesFeld, i, j);
if (altesFeld[i][j]) {
neuesFeld[i][j] = (nachbarn == 2) || (nachbarn == 3);
}
else {
neuesFeld[i][j] = nachbarn == 3;
}
}
}
return neuesFeld;
}
public int getAnzahlNachbarn(boolean[][] altesFeld, int x, int y) {
if (x == 0 || x == 99 || y == 0 || y == 99){
return 0; // Die Randfelder sollen leer bleiben
}
int anzahlNachbarn = 0;
for (int i = x - 1; i <= x + 1; i++) {
for (int j = y - 1; j <= y + 1; j++){
if (altesFeld[i][j]){
anzahlNachbarn++;
}
}
}
if (altesFeld[x][y]){
anzahlNachbarn--; // Die Zelle an sich rechnen wir raus.
}
return anzahlNachbarn;
}
}
Klasse Welt, die Zeichenklasse, erbt von JPanel:
Java:
import java.awt.*;
import javax.swing.*;
public class Welt extends JPanel
{
private boolean[][] feld = new boolean[100][100];
public Welt() {
}
public void setFeld(boolean[][] feld){
this.feld = feld;
repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Das Feld
for (int i = 0; i < 100; i++){
for (int j = 0; j < 100; j++) {
if (feld[i][j]) {
g.setColor(java.awt.Color.BLACK);
}
else {
g.setColor(java.awt.Color.WHITE);
}
g.fillRect(i * 5, j * 5, 5, 5);
}
}
}
}
Java:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
public class Listener extends MouseAdapter
{
private JButton startButton;
private JButton endButton;
private Logik logik;
/**
* Constructor for objects of class Listener
*/
public Listener(){
}
public void mouseReleased( MouseEvent e)
{
if(e.getSource() == startButton){
try{
logik.spielen(30,10);
}
catch(Exception ex) {
System.out.println("Ooops, an error occured. Close the program and try again.");
}
}
else if(e.getSource() == endButton) {
System.exit(0);
}
}
public void setStartButton(JButton b){
startButton = b;
}
public void setEndButton(JButton b){
endButton = b;
}
public void setLogik( Logik l){
logik = l;
}
}
Es scheint auch von der Logik her alles richtig zu sein, d.h. das Endbild sieht auch vernünftig aus, aber nur dass man halt keine Animation sieht. Ich hoffe, das Problem lässt sich lösen, ohne irgenwelche Threads verlegen zu müssen... bei anderen Projekten lief es auch so.
Liebe Grüße und vielen Dank, Salmo Salar