简体   繁体   中英

Stuck on Java Swing Project: Conway's Game of Life

I have been working on this for about four hours now. I have all the logic down pat, the timer works, keyboard and mouse input works, but the paintComponent method isn't called to draw the updates! I am not experienced with these sort of real time applications, so it could be anything causing this not to work. Any help would be appreciated!

gamemain.java :

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;

public class gamemain extends JPanel {

public static boolean paused = true;
public static JFrame gui;
public static JPanel panel;

static int[][] worldsize = new int[1000][1000];
static world playspace = new world(worldsize);

static Timer timer = new Timer(250, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {

        System.out.println("Debug: timer ticked");
        playspace.updateWorldState();
        panel.repaint();

    }

});

@Override
public void paintComponent(Graphics g) {

    super.paintComponent(g);
    System.out.println("Hit painter");
    g.drawString("Test", 50, 50);

    for(int i = 0; i < 999; i++) {
        for(int j = 0; j < 999; i++) {
            if(playspace.getWorldStateAt(i, j) == 1) {
                g.drawRect(i, j, 1, 1);
            }
        }
    }

}

public static class listener implements KeyListener {

    @Override
    public void keyTyped(KeyEvent e) {

        if(e.getKeyChar() == ' ') {
            if(paused) {
                timer.start();
                paused = false;
                System.out.println("Unpaused");
            }
            else {
                timer.stop();
                paused = true;
                System.out.println("Paused");
            }
        }

    }

    @Override
    public void keyPressed(KeyEvent e) {
        // unused

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // unused

    }

}

public static class mouselistener implements MouseListener {

    @Override
    public void mouseClicked(MouseEvent e) {

        int x, y;
        x = e.getX();
        y = e.getY();
        playspace.placeCell(x, y);

    }

    @Override
    public void mousePressed(MouseEvent e) {
        // unused

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // unused

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // unused

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // unused

    }

}

public static void main(String[] args) throws InterruptedException {

    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    gui = new JFrame();
    gui.setTitle("Game of Life");
    gui.setSize(1000, 1000);
    gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel = new JPanel();
    panel.addKeyListener(new listener());
    panel.addMouseListener(new mouselistener());
    panel.setBackground(Color.WHITE);
    panel.setOpaque(true);
    Container pane = gui.getContentPane();
    pane.add(panel);
    gui.setVisible(true);
    panel.requestFocus();
        }
    });


}


}

world.java

public class world {

int[][] worldstate = new int[1000][1000];

public world(int[][] world) {

    for(int i = 0; i < 1000; i++) { // make all cells dead
        for(int j = 0; j < 1000; j++) {

            world[i][j] = 0;

        }
    }

    this.worldstate = world;

}

public int getWorldStateAt(int i, int j) {

    return this.worldstate[i][j];

}

public void placeCell(int x, int y) {

    this.worldstate[x][y] = 1;

}

public void updateWorldState() {

    int n1,n2,n3,n4,n5,n6,n7,n8,total; // all possible buddies of a cell

    for(int i = 1; i < 999; i++) { // go to each cell
        for(int j = 1; j < 999; j++) {

            n1 = this.worldstate[i-1][j];
            n2 = this.worldstate[i][j-1];
            n3 = this.worldstate[i-1][j-1];
            n4 = this.worldstate[i+1][j];
            n5 = this.worldstate[i][j+1];
            n6 = this.worldstate[i+1][j+1];
            n7 = this.worldstate[i+1][j-1];
            n8 = this.worldstate[i-1][j+1];

            total = n1 + n2 + n3 + n4 + n5 + n6 + n7 + n8; // add them up

            if(total < 2 && (this.worldstate[i][j] == 1)) { // rule 1

                this.worldstate[i][j] = 0;

            }

            if(total > 3 && (this.worldstate[i][j] == 1)) { //rule 3

                this.worldstate[i][j] = 0;

            }

            if((total == 3) && (this.worldstate[i][j] == 0)) { //rule 4

                this.worldstate[i][j] = 1;

            }

        }
    }

}

}

paintComponent is never been called because gamemain is never actually added to anything capable of displaying.

Your first task would be to remove the reliance on static

Something perhaps more like...

public class gamemain extends JPanel {

    public boolean paused = true;

    int[][] worldsize = new int[1000][1000];
    world playspace = new world(worldsize);

    Timer timer = new Timer(250, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

            System.out.println("Debug: timer ticked");
            playspace.updateWorldState();
            repaint();

        }

    });

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        System.out.println("Hit painter");
        g.drawString("Test", 50, 50);

        for(int i = 0; i < 999; i++) {
            for(int j = 0; j < 999; i++) {
                if(playspace.getWorldStateAt(i, j) == 1) {
                    g.drawRect(i, j, 1, 1);
                }
            }
        }

    }

    //...

    public static void main(String[] args) throws InterruptedException {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame gui = new JFrame();
                gui.setTitle("Game of Life");
                gui.setSize(1000, 1000);
                gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                gamemain panel = new gamemain();
                panel.addKeyListener(new listener());
                panel.addMouseListener(new mouselistener());
                panel.setBackground(Color.WHITE);
                panel.setOpaque(true);
                Container pane = gui.getContentPane();
                pane.add(panel);
                gui.setVisible(true);
                panel.requestFocus();
            }
        });


    }

}

I'd then focus on having the ability to pass more information to the gamemain class, like the worldszie and world properties for example.

I'd also consider using the Key Bindings API over KeyListener , it will help solve the focus related issues with KeyListener

I'd also recommend having a look at Code Conventions for the Java Programming Language - it will make it easier for other people to read your code and for you to read theirs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM