Jump to content

Game of Life GUI

namarino
Go to solution Solved by fizzlesticks,

This is what I've got. Unfortunately, the grid still does not resize with the window...really sorry to keep bothering you. Maybe my program design sucks or something.

You need to save the panel as an instance variable and get the width/height inside your drawGrid method then use those new values to calculate a new boxWidth. 

Hey guys, I'm programming conway's game of life with a GUI. I'm to the point right now where I have a grid and I've gotten java to recognize that I'm clicking. I'm running into a problem though. Here is my Grid class.

import java.awt.Graphics;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;public class Grid extends MouseAdapter{	private boolean[][] grid;	private int rows;	private int columns;	private int boxWidth;	private int panelHeight;	private int panelWidth;		public Grid(int panelHeight, int panelWidth){		rows = 30;		columns = 30;		grid = new boolean[rows][columns];		this.panelHeight = panelHeight;		this.panelWidth = panelWidth;		this.boxWidth = panelWidth / grid.length;	}		public Grid(){			}		public void drawGrid(Graphics g){		for(int x = 0; x <= grid.length; x++){			g.drawLine(x * boxWidth, 0,  x * boxWidth, panelHeight);		}				for(int x = 0; x <= grid.length; x++){			g.drawLine(0, x * boxWidth, panelWidth, x * boxWidth);		}					}		public void mouseReleased(MouseEvent event){		System.out.print("Clicked! ");                System.out.print(panelHeight);			}}

So essentially I have a constructor that initializes all my instance variable here and another constructor for my mouseHandler on my panel. The problem that I'm having is that anytime I click and it runs the code inside mouseReleased, the instance variable are printed as 0, even though I obviously initialized them. Can someone please help me with this? If you need the rest of my code, just let me know. I didn't want to put it all up there because I didn't want it to overwhelm you. haha Thanks a lot guys!

Link to comment
Share on other sites

Link to post
Share on other sites

Are you sure you didn't initialize them to 0?

 

Yeah I'm positive. The program wouldn't work if they were 0.

Link to comment
Share on other sites

Link to post
Share on other sites

Are you sure you didn't initialize them to 0?

 

Do you want to look at the rest of the code?

Link to comment
Share on other sites

Link to post
Share on other sites

Do you want to look at the rest of the code?

Yea, gunna need to see the rest.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

Yea, gunna need to see the rest.

public class Application {	public static void main(String[]args){		Window window;				window = new Window(10, 10, 500, 500);	}}import java.awt.BorderLayout;import javax.swing.JFrame;public class Window extends JFrame{	private static final long serialVersionUID = 1L;		public Window(int x, int y, int width, int height){				setLocation(x, y);		setSize(width, height);		setLayout(new BorderLayout());				Panel panel = new Panel();				setVisible(true);				add(panel, BorderLayout.CENTER);				setDefaultCloseOperation(EXIT_ON_CLOSE);	}}import java.awt.Graphics;import java.awt.event.MouseListener;import javax.swing.JPanel;//embodies a panel to be added to the window public class Panel extends JPanel {		private static final long serialVersionUID = 1L;	private int width;	private int height;		public Panel(){		Grid handler;				handler = new Grid();				addMouseListener(handler);	}		public void paintComponent(Graphics g){		super.paintComponent(g);				width = this.getWidth();		height = this.getHeight();						Grid grid = new Grid(height, width);		grid.drawGrid(g);	}}import java.awt.Graphics;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;//embodies the grid that will be added to the panelpublic class Grid extends MouseAdapter{	private boolean[][] grid;	private int rows;	private int columns;	private int boxWidth;	private int panelHeight;	private int panelWidth;		public Grid(int panelHeight, int panelWidth){		rows = 30;		columns = 30;		grid = new boolean[rows][columns];		this.panelHeight = panelHeight;		this.panelWidth = panelWidth;		this.boxWidth = panelWidth / grid.length;	}			public Grid(){			}		public void drawGrid(Graphics g){		for(int x = 0; x <= grid.length; x++){			g.drawLine(x * boxWidth, 0,  x * boxWidth, panelHeight);		}				for(int x = 0; x <= grid.length; x++){			g.drawLine(0, x * boxWidth, panelWidth, x * boxWidth);		}	}		public void mouseClicked(MouseEvent event){		System.out.print("Clicked! ");	}}
Link to comment
Share on other sites

Link to post
Share on other sites

In your panel class you're creating a new Grid every time you redraw and not giving it a width or height. You should pass your panel class the width and height to make the grid and make handler an instance variable with those dimensions and use that grid in the paintComponent instead of remaking it every time.

 

Also since you don't need it you should delete the default constructor from Grid so these types of things don't happen.

 

edit: Sorry, I mean your not passing "handler" a width or height which is the one your mouseAdapter is attached to.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

In your panel class you're creating a new Grid every time you redraw and not giving it a width or height. You should pass your panel class the width and height to make the grid and make handler an instance variable with those dimensions and use that grid in the paintComponent instead of remaking it every time.

 

Also since you don't need it you should delete the default constructor from Grid so these types of things don't happen.

Would you mind writing that out for me? This is not a school assignment or anything, just for fun.

Link to comment
Share on other sites

Link to post
Share on other sites

Would you mind writing that out for me? This is not a school assignment or anything, just for fun.

Nope, sorry can't do that.

But if you'd like to give it a try here's what to do.

 

Start in Panel by making "handler" an instance variable like width and height.

Next add width and height parameters to the Panel constructor just like you have in the Grid class and pass the width and height to the Grid constructor.

Then in paintComponent don't create a new grid and instead of grid.drawGrid(g); call handler.drawGrid(g);

In Window pass width and height to panel just like you did with grid.

And finally in Grid, delete the method public Grid()

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

Nope, sorry can't do that.

But if you'd like to give it a try here's what to do.

 

Start in Panel by making "handler" an instance variable like width and height.

Next add width and height parameters to the Panel constructor just like you have in the Grid class and pass the width and height to the Grid constructor.

Then in paintComponent don't create a new grid and instead of grid.drawGrid(g); call handler.drawGrid(g);

In Window pass width and height to panel just like you did with grid.

And finally in Grid, delete the method public Grid()

Unfortunately, that didn't work. It doesn't display the grid like it did before. It's throwing an exception. The width and height instance variable in panel are intended to be the panel width and height. When I'm making a new grid in paintComponent, I am passing the panel width and panel height.

Link to comment
Share on other sites

Link to post
Share on other sites

Unfortunately, that didn't work. It doesn't display the grid like it did before. It's throwing an exception. The width and height instance variable in panel are intended to be the panel width and height. When I'm making a new grid in paintComponent, I am passing the panel width and panel height.

What is the exception? 

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

What is the exception? 

Well I kind of figured it out. So basically when you make a new Panel, it runs the code in the constructor first. And since the panel doesn't exist yet, the height and width are 0. So what I did was give the constructor 2 parameters and passed in the height and width of the window (as you suggested) instead of the height and width of the panel. I kind of wish I could pass the height and width of the panel, but I'm not really sure how I could do that without restructuring my program.

Link to comment
Share on other sites

Link to post
Share on other sites

Well I kind of figured it out. So basically when you make a new Panel, it runs the code in the constructor first. And since the panel doesn't exist yet, the height and width are 0. So what I did was give the constructor 2 parameters and passed in the height and width of the window (as you suggested) instead of the height and width of the panel. I kind of wish I could pass the height and width of the panel, but I'm not really sure how I could do that without restructuring my program.

Instead of setting the size of the window with setSize, after passing the width and height to panel, in the panel constructor call 

setPreferredSize(new Dimension(width, height));

then back in the window constructor after adding the panel to the frame call 

this.pack(); 

This will make the window resize to whatever's in it and allow you to set the panel size to whatever you want. 

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

Instead of setting the size of the window with setSize, after passing the width and height to panel, in the panel constructor call 

setPreferredSize(new Dimension(width, height));

then back in the window constructor after adding the panel to the frame call 

this.pack(); 

This will make the window resize to whatever's in it and allow you to set the panel size to whatever you want. 

Aha! that works. The only thing is that I need to use the height and width in some calculations when I click the mouse. And the way that works, the height and width remain at the size I set them and don't change when I resize the window. Any suggestions?

Link to comment
Share on other sites

Link to post
Share on other sites

Aha! that works. The only thing is that I need to use the height and width in some calculations when I click the mouse. And the way that works, the height and width remain at the size I set them and don't change when I resize the window. Any suggestions?

When you make a Grid you give it the current size of the panel, then inside Grid you use the panelWidth and panelHeight variables you have. This is one of the reasons you need to have grid be an instance variable instead of making a new one every time you redraw the window, you should never be calling panel.getWidth/Height (at least not in what you're trying to do now.)

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

When you make a Grid you give it the current size of the panel, then inside Grid you use the panelWidth and panelHeight variables you have. This is one of the reasons you need to have grid be an instance variable instead of making a new one every time you redraw the window, you should never be calling panel.getWidth/Height (at least not in what you're trying to do now.)

But if I don't call getWidth(), then the grid won't resize with window. It will stay a constant size.

Link to comment
Share on other sites

Link to post
Share on other sites

But if I don't call getWidth(), then the grid won't resize with window. It will stay a constant size.

Ahh ok sorry, I read it as not changing was what you wanted to do. 

In that case you will need to pass the panel to the grid's constructor and save it as an instance variable and instead of saving the panelWidth and panelHeight call panel.getWidth/Height whenever you need it.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

Ahh ok sorry, I read it as not changing was what you wanted to do. 

In that case you will need to pass the panel to the grid's constructor and save it as an instance variable and instead of saving the panelWidth and panelHeight call panel.getWidth/Height whenever you need it.

Oh ok so scrap the panelHeight/width and replace them with an object of panel. And then when I need the height and width of the panel, I just call panel.width/height. Is that right?

Link to comment
Share on other sites

Link to post
Share on other sites

Oh ok so scrap the panelHeight/width and replace them with an object of panel. And then when I need the height and width of the panel, I just call panel.width/height. Is that right?

yup, that's right. You'll also need to keep recalculating the boxWidth in case the size changed.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

yup, that's right. You'll also need to keep recalculating the boxWidth in case the size changed.

Alright cool, thanks a lot man, I really appreciate your help!

Link to comment
Share on other sites

Link to post
Share on other sites

yup, that's right. You'll also need to keep recalculating the boxWidth in case the size changed.

Hey sorry to bother you again. So basically I tried making an object of Panel in the grid class, but basically what happens is that it falls into a never ending loop of constructors. So basically in Panel, it makes a grid object, and then inside the grid constructor, it makes a new panel and then it goes on forever. So how do I prevent that from happening?

Link to comment
Share on other sites

Link to post
Share on other sites

Hey sorry to bother you again. So basically I tried making an object of Panel in the grid class, but basically what happens is that it falls into a never ending loop of constructors. So basically in Panel, it makes a grid object, and then inside the grid constructor, it makes a new panel and then it goes on forever. So how do I prevent that from happening?

Don't make a new panel. Add a panel parameter to the Grid constructor then where you make the Grid pass "this" for the panel.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

Don't make a new panel. Add a panel parameter to the Grid constructor then where you make the Grid pass "this" for the panel.

import java.awt.Graphics;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;//embodies the grid that will be added to the panelpublic class Grid extends MouseAdapter{	private boolean[][] grid;	private int rows;	private int columns;	private int boxWidth;	private int panelHeight;	private int panelWidth;		public Grid(int panelHeight, int panelWidth, Panel panel){		rows = 30;		columns = 30;		grid = new boolean[rows][columns];		this.panelHeight = panel.getHeight();		this.panelWidth = panel.getWidth();		this.boxWidth = panel.getHeight() / grid.length;	}		public void drawGrid(Graphics g){		for(int x = 0; x <= grid.length; x++){			g.drawLine(x * boxWidth, 0,  x * boxWidth, panelHeight);		}				for(int x = 0; x <= grid.length; x++){			g.drawLine(0, x * boxWidth, panelWidth, x * boxWidth);		}	}		public void mouseClicked(MouseEvent event){		System.out.print("Clicked! ");		System.out.print(panelHeight);	}}

This is what I've got. Unfortunately, the grid still does not resize with the window...really sorry to keep bothering you. Maybe my program design sucks or something. 

Link to comment
Share on other sites

Link to post
Share on other sites

This is what I've got. Unfortunately, the grid still does not resize with the window...really sorry to keep bothering you. Maybe my program design sucks or something.

You need to save the panel as an instance variable and get the width/height inside your drawGrid method then use those new values to calculate a new boxWidth. 

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

You need to save the panel as an instance variable and get the width/height inside your drawGrid method then use those new values to calculate a new boxWidth. 

Aha! I got it! Thanks so much, I really do appreciate your help.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×