views:

484

answers:

3

Within this program, we need to create an 8x8 grid of "LifeCell" widgets. The instructor did not mention that the widgets had to be an object of Shape so I went ahead and used the GridLayout class. The GridLayout class works fine (as well as I know, since there is no visual aid to confirm.) The object of the program is to play the Game of Life where a user can click on one of the LifeCell widgets and toggle between states being 'alive' or 'dead.

My question relies heavily on getting the cells to be painted. It could be a problem with my code, but I am not 100% sure.

Program2.java

public class Program2 extends JPanel implements ActionListener {
private LifeCell[][] board; // Board of life cells.
private JButton next; // Press for next generation.
private JFrame frame; // The program frame.

public Program2() {
 // The usual boilerplate constructor that pastes the main
 // panel into a frame and displays the frame. It should
 // invoke the "init" method before packing the frame
 frame = new JFrame("LIFECELL!");
 frame.setContentPane(this);
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 this.init();
 frame.pack();
 frame.setVisible(true);
}
    public void init() {
 // Create the user interface on the main panel. Construct
 // the LifeCell widgets, add them to the panel, and store
 // them in the two-dimensional array "board". Create the
 // "next" button that will show the next generation.
 LifeCell[][] board = new LifeCell[8][8];
 this.setPreferredSize(new Dimension(600, 600));
 this.setBackground(Color.white);
 this.setLayout(new GridLayout(8, 8));
    // here is where I initialize the LifeCell widgets
 for (int u = 0; u < 8; u++) {
  for (int r = 0; r < 8; r++) {
   board[u][r] = new LifeCell(board, u, r);
   this.add(board[u][r]);
   this.setVisible(true);

  }
 }

LifeCell.java

 public class LifeCell extends JPanel implements MouseListener {
   private LifeCell[][] board; // A reference to the board array.
   private boolean alive;      // Stores the state of the cell.
   private int row, col;       // Position of the cell on the board.
   private int count;          // Stores number of living neighbors.

   public LifeCell(LifeCell[][] b, int r, int c) {
       // Initialize the life cell as dead.  Store the reference
       // to the board array and the board position passed as
       // arguments.  Initialize the neighbor count to zero.
       // Register the cell as listener to its own mouse events.
       this.board = b;
       this.row = r;
       this.col = c;
       this.alive = false;
       this.count = 0;
       addMouseListener(this);
   }

and here is the paintComponent method:

   public void paintComponent(Graphics gr) {
       // Paint the cell.  The cell must be painted differently
       // when alive than when dead, so the user can clearly see
       // the state of the cell.
           Graphics2D g = (Graphics2D) gr;
           super.paintComponent(gr);
           g.setPaint(Color.BLUE);
   }

I do not need the exact solution to fix it, but I am at wits end trying to get it to work.

Thanks.

EDIT:

I added more segment of Program2.java class, I can check back tomorrow I am heading off to bed, I appreciate all the help guys.

EDIT #2:

My real confusion gets to when I populate my frame with an 8x8 GridLayout each individual "cell" for lack of better words is of type LifeCell. How can I paint each LifeCell different colors? If that makes any sense at all to you guys, I can try to revise it as much as I can. And camickr, I will look at that website, thank you.

Assignment can be found here to avoid any and all confusion regarding my question and/or the code snippet.

+2  A: 

JPanel has no default preferred size or visible content. you'll need to add some kind of visible component (eg JLabel) or give it a preferred size.

besides this, your layout should work if you've set it up as follows:

JFrame frame = new JFrame();
Container cp = frame.getContentPane();
cp.setLayout(new GridLayout(8, 8));
for (int i = 0; i < 8; i++)
    for (int j = 0; j < 8; j++)
        cp.add(new JLabel(i + "-" + j));
frame.pack();
frame.setVisible(true);
pstanton
I have done something similar to make sure populating my `GridLayout` works, but when I tried to see if I could color in each cell, it wasn't working because I can't color a JLabel :(
Anthony Forloney
You can paint with JLabels. The trick is that by default the opaque property is false. You need to call setOpaque(true) first, then call setBackground(Color.BLUE).
Devon_C_Miller
I am anxious now to go home and try it out. Thank you.
Anthony Forloney
+1  A: 

Why do you even have a paintComponent() method for your LifeCell? There is no need to do custom painting. You can change the background color of any component by using:

setBackground( Color.BLUE )

Other than that your question makes no sense to me. First you state you need to use a Shape object, but I don't see a Shape object anywhere in your code, so why did you confuse the question by mentioning that?

I really don't understand your question and we don't have enough of your code to provide any real suggestions.

If you need more help post your SSCCE showing the problem.

camickr
The instructor did *not* mention that the widgets had to be an object of Shape
pstanton
Well, I read the question wrong, which leads to me point, why post unnecessary information to confuse us. I would never think to use a Shape to solve this problem so I don't know why the OP mentioned it. :)
camickr
I only mentioned Shape for the fact that my problem relies on coloring the cell with a mouseclick, I am trying to see if `fill` would work, but it needs to take a `Shape` argument, so I was wondering if the `GridLayout` I used, should have been just 8x8 Rectangle2D objects.
Anthony Forloney
We have to follow a standard skeleton code by the instructor, I can post the link for the assignment above and see if you guys can get a better sense at what I am talking about
Anthony Forloney
+1  A: 

alt text

You're in the right track.

If you want to use an existing component ( such as a JPanel, JLabel, JButton etc ) it it much better that you honor what the component already does, and just parametrize what is needed.

So in your case you're using a JPanel, this ( and other JComponents ) have a background property that you can change. So, instead of trying to paint the component your self ( which is what is failing right now ) just set that value and let the paint paint itself.

You can add a "getLifeColor" which return different colors depending on the cell state:

   private Color getLifeColor() {
       return this.alive?liveColor:deadColor;
   }

And then just have the cell painting the background with this color:

  public void paintComponent(Graphics gr) {
       setBackground( getLifeColor() );
       super.paintComponent( gr );
  }

After that you just have to set the state of the cell to live or dead and the component will appear with the corresponding color:

alt text

Here's the short self contained correct example ( SSCCE ) of the code you posted + the live/dead color usage. I think you can continue from there.

OscarRyz
Thank you very much, that is along the lines of what I was going to try when I got home, I appreciate all the help you guys have done.
Anthony Forloney