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.