0

I'm trying to write the game of life. However, no matter how hard I try, I can't seem to add Cell components onto the frame with the buttons. They do appear if I make a new frame and add them, but even so, I can't seem to add more than one component.

So I how I add the components to the frame with all the stuff on it and how do I add multiple components? Thanks!

Here's my code:

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class Visuals extends JFrame implements ActionListener{ 

    private static Board b;
    private GameOfLife g;
    private JButton nextGen;
    private JButton random;

    public Visuals(Board b){
        super("The Game of Life");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        JPanel panel=new JPanel();
        nextGen = new JButton("Next Generation");
        panel.add(nextGen);
        nextGen.addActionListener(this);

        random = new JButton("Random");
        panel.add(random);
        random.addActionListener(this);
        this.add(panel);

        this.setSize(800, 700);
        this.setVisible(true);


        /*for(int i=0, yShift=80; i<b.getRow(); i++, yShift+=20){
            for (int j=0, xShift=30; j<b.getCol(); j++, xShift+=20){
                Cell c= new Cell(xShift,yShift,i,j);
                this.add(c);
            }
        }*/
        Cell c= new Cell(100,100,1,1);
        Cell d= new Cell(200,200,1,1);
        this.add(c);
        this.add(d);

        JFrame frame=new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 700);
        frame.setVisible(true);

        frame.add(c);
        frame.add(d);

    }

    public void paint(Graphics g){
        super.paint(g);
        for(int i=0, yShift=80; i<b.getRow(); i++, yShift+=20){
            for (int j=0, xShift=30; j<b.getCol(); j++, xShift+=20){    
                if(b.getSpot(i, j)==1){
                    g.setColor(Color.red);
                    g.fillRect(xShift, yShift, 10, 10);
                }
                else{
                    g.setColor(Color.white);
                    g.fillRect(xShift, yShift, 10, 10);
                }
            }   
        }
    }   

    public static void main(String[] cnbe){
        b= new Board (30,30);
        Visuals v = new Visuals(b);
    }

    public void actionPerformed(ActionEvent event) {
        Object cause = event.getSource();
        if(cause == nextGen){
            GameOfLife g=new GameOfLife(b);
            g.nextGeneration();
            System.out.println(g);
            this.repaint();
        }
        if(cause == random){
            GameOfLife g=new GameOfLife(b);
            g.random();
            System.out.println(g);
            this.repaint();
        }   
    }

    public class Cell extends JComponent{
        int row;
        int col;
        int x;
        int y;
        Rectangle r;

        public Cell(int x, int y, int row, int col){
            r= new Rectangle(x,y,10,10);
                this.row=row;
                this.col=col;
                this.x=x;
                this.y=y;

        }   


        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            g.drawString("DRAW ME",200,200);
            Graphics2D g2= (Graphics2D) g;
            g2.setColor(Color.green);
            r= new Rectangle(x,y,100,100);
            g2.fill(r);

            /*if(b.getSpot(row, col)==1){

                g.setColor(Color.red);
                g.fillRect(x, y, 10, 10);
            }
            else{

                g.setColor(Color.white);
                g.fillRect(x, y, 10, 10);
            }*/
        }

        class MousePressListener implements MouseListener{

            public void mousePressed(MouseEvent event) {
                /*int x= event.getX();
                int y= event.getY();
                if(x>r.getX() && x<r.getX()+10 && y>r.getY() && y<r.getY()+10){
                    if(b.getSpot(row, col)==1){
                        b.setSpot(row, col, 0);
                        repaint();
                    }
                    else{
                        b.setSpot(row, col, 1);
                        repaint();
                    }
                }*/
            }

            public void mouseReleased(MouseEvent arg0) {
            }
            public void mouseClicked(MouseEvent arg0) {
            }
            public void mouseEntered(MouseEvent arg0) {
            }
            public void mouseExited(MouseEvent arg0) {
            }

        }


    }

}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 3
    You're having a conflict with the frames layout manager. A `JFrame` will use a `BorderLayout` by default, each time you add a new component to the frame, it's replacing what ever you added before it (into the center position). Take a look at [A Visual Guide to Layout Managers](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) and [Using Layout Managers](http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html). – MadProgrammer Dec 04 '12 at 00:19
  • Also, a component can only belong to a single container, so when you add your cells to the first frame and then add the to the second frame, they are begin removed from the first frame – MadProgrammer Dec 04 '12 at 00:19
  • 2
    Why does this code use more than one frame? See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/a/9554657/418556) – Andrew Thompson Dec 04 '12 at 01:02

1 Answers1

0

You have an issue with Layout Managers. Each time you add a component to the JFrame you overwrite what was already there. I'm not too familiar with Game of Life, but I don't think you want your cells to be JComponents. You can represent your board as an array of booleans, representing the alive and dead state, so your Visual constructor becomes:

public Visuals(Board b) {
    super("The Game of Life");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Container container = getContentPane(); // 1
    JPanel panel = new JPanel(new FlowLayout()); // 2
    nextGen = new JButton("Next Generation");
    panel.add(nextGen);
    nextGen.addActionListener(this);

    random = new JButton("Random");
    panel.add(random);
    random.addActionListener(this);
    container.add(panel); // 3

    setSize(800, 700);
    setVisible(true);

}

In your Board class you would represent the board as an array:

public class Board{
    private boolean[][] board;

    public Board(int x, int y) {

        board = new boolean[x][y];
    }
}

Then in the nextGeneration method of your GameOfLife class, perform whatever calculations you're doing and set the true/false (or alive/dead) state of the positions on the Board.

Your Visuals.paint method then becomes something like:

public void paint(Graphics g) {
    super.paint(g);
    for (int i = 0, yShift = 80; i < b.getRow(); i++, yShift += 20) {
        for (int j = 0, xShift = 30; j < b.getCol(); j++, xShift += 20) {
            if (b.isAlive(i, j)) {
                g.setColor(Color.red);
                g.fillRect(xShift, yShift, 10, 10);
            } else {
                g.setColor(Color.white);
                g.fillRect(xShift, yShift, 10, 10);
            }
        }
    }
}

iaAlive is just returning the value of the board array at that position:

public boolean isAlive(int i, int j) {
    return board[i][j];
}

But like I say, I'm not familiar with the game.

Robert
  • 325
  • 1
  • 3
  • 12
  • Thanks everyone, I solved my problem with a GridLayout, so I don't even have to worry about the x and y of my components. BTW Robert, I used JComponents to add mouse listers to them. – user1874103 Dec 04 '12 at 22:41