I'm trying to create a bunch of the same objects (Grass) with a loop in different spaces. I have a grid and I want it to fill up the entire grid with different colors.
So I have this code so far:
public stage() {
super(null);
cast = new Cast();
cast.setBounds(10, 10, cast.getWidth(), cast.getHeight());
this.add(grid);
for (int i = 0; i <= 19; i++) {
obj = new Object[] {
new Grass (cast.cells[i][i])
};
}
}
This obviously doesn't work and only makes a colored cell in the last spot of the grid. Is there anyway to make a loop for objects in every spot?
Your code is going to create an new Object[1] 20 times. That Array will contain an instance of Grass. Try this instead.
public stage() {
super(null);
cast = new Cast();
cast.setBounds(10, 10, cast.getWidth(), cast.getHeight());
this.add(grid);
Object obj[] = new Object[20];
for (int i = 0; i <= 19; i++) {
obj[i] = new Grass (cast.cells[i][i])l
}
}
}
Related
If you add a int[][] to a list, it will not add the value of the array, but the location of the array. How can I add the value of an array to a list. This is the code (This is just an example and might have small errors in it):
public class Main {
int[][] matrix = new int[2][2];
List<int[2][2]> matrixList = new ArrayList<>();
public static void main(String[] args) {
for(int i = 0; i < 4; i++){
matrixList.add(matrix);
matrix = matrixCalc(matrix);
}
for(int i = 0; i < 4; i++) {
System.out.println(Arrays.deepToString(matrixList.get(i)));
}
public int[][] matrixCalc(int[][] m){
//do various calculations with m
...
return m;
}
}
}
I want the output to have different matrixes that are calculated by the calculate method.
example of out put i want to get:
{{0,1}{5,7}}
{{2,0}{2,4}}
{{8,1}{4,8}}
{{3,3}{7,9}}
output I would get this way (WRONG!)
{{3,3}{7,9}}
{{3,3}{7,9}}
{{3,3}{7,9}}
{{3,3}{7,9}}
EDIT: After OP's comment I removed my entire answer (you can still find a screenshot of it here; or look in the history of the edits).
If I'm not mistaken, you send an empty Array to the method matrixCalc? For the calculations method I need a matrix with the same value as I just put on top of the stack.
In that case it's a bit different, although the problem is still having the same reference to matrix, so we'll have to change this. To copy the data from one 2D-array to a new one (with a new reference), we should make a separate copy-method. In Java there is the Arrays.copyOf-method (or alternatively System.arraycopy) for a 1D-array, but for a 2D-array you should make a method yourself. So your code becomes something like this:
public class Main {
int[][] previousMatrix = new int[2][2];
List<int[2][2]> matrixList = new ArrayList<>();
public static void main(String[] args) {
for(int i = 0; i < 4; i++){
int[][] matrix = matrixCalc(previousMatrix);
matrixList.add(matrix);
previousMatrix = copy2dArray(matrix);
}
for(int i = 0; i < 4; i++) {
System.out.println(Arrays.deepToString(matrixList.get(i)));
}
}
public int[][] matrixCalc(int[][] m){
//do various calculations with m
...
return m;
}
private int[][] copy2dArray(int[][] original){
int[][] copy = new int[original.length][];
for(int i = 0; i < original.length; i++){
copy[i] = Arrays.copyOf(original[i], original[i].length);
}
return copy;
}
}
Alternatively, you could make a new 2D array at the start of your matrixCalc method and fill and return that, instead of the parameter given. But, since I didn't knew what kind of calculations you are doing in your matrixCalc method I can't really give an example of this. It will look something like this:
public int[][] matrixCalc(int[][] m){
int[][] n = new int[2][2];
//do various calculations with m,
//but save the result in n
...
return n;
}
Some background info:
The programm I'm writing uses backtracking. I need to save boardstates into an stack and also add stuff to the board. Here [matrix] stands for the board and [matrixList] for the saved boardstates. When I do calculations I need to have the current board then after I changed something. I need to add the new board on top of the stack and continue changing the new board.
Try with:
public class Main {
int[][] matrix = new int[2][2];
List<int[2][2]> matrixList = new ArrayList<>();
public static void main(String[] args) {
for(int i = 0; i < 4; i++){
matrixList.add(matrixCalc(matrix));
}
for(int i = 0; i < 4; i++) {
System.out.println(Arrays.deepToString(matrixList.get(i)));
}
public int[][] matrixCalc(int[][] m){
int[][] newMatrix = new int[2][2];
... do calc then put results on newMatrix
return newMatrix;
}
}
}
How can I create a two-dimensional array containing ArrayLists? Something like this :
ArrayList<Character>[][] myArray = new ArrayList<Character>[][];
and would it be ok to do the following :
I need to compare the position of some characters with the position of the buildings in my map. Several buildings can belong to the same tile, but one can be drawn in front of the character and the other behind him. This comparison has to be done all the time in the game, with every character.
I am trying to update an array of characters each time a character is moving from one tile to another. Then the render method should look for how many characters, if any, are in a specific tile, and loop over the characters in this tile to draw them in front or behind the buildings.
Something like this :
//init
ArrayList<Character>[][] arrayOfCharacters = new ArrayList<Character>[][];
//each tile in the map
for (int y = 0; y < 9; y++){
for(int x = 9-1; x >= 0; x--){
if ( arrayOfCharacters[y][x].length > 0 ){
for ( int i=0, i< arrayOfCharacters[y][x].length; i++ ){
//compare which building is in front or behind the characters
//then
characterInThisTile = index of each character in arrayOfCharacters[y][x]
spriteBatch.draw(characterInThisTile, x_pos, y_pos, tileWidth, tileHeight);
}
}
}
}
ArrayList<Character>[][] arrayOfCharacters = new ArrayList[9][9];
for(int i=0;i<arrayOfCharacters.length;i++){
for(int i2=0;i2<arrayOfCharacters[i].length;i2++){
arrayOfCharacters[i][i2]=new ArrayList<Character>(20);
}
}
A two dimensional array is an array of arrays - it means that the structure looks something like:
[0,0][0,1][0,2][0,3] -> sub array 1
[1,0][1,1][1,2] -> sub array 2
[2,0][2,1][2,2][2,3][2,4] - sub array 3
Notice how the number of elements in each sub array does not have to be the same. You could create the above array as (I am using integers your type would vary as necessary):
int[][] a = new int[3][]; // The number of sub arrays or the first argument should be defined.
// The number of elements in each sub array need not be known at compile time though
So if had to do the same thing with an ArrayList, an array inside an array would translate to a list within a list. So you could do something like:
ArrayList<ArrayList<Integer>> arrayList = new ArrayList<ArrayList<Integer>>();
Since an ArrayList object can expand dynamically, the structure would be something like:
Row [0] -> [0][1][2]..... // and so on
Row [1] -> [0][1][2]..... // and so on
Row [2] -> [0][1][2]..... // and so on
Entering elements into this would be done very similarly using nested for loops.
You could make a class and then make Objects using that class that stores an ArrayList<Character> as an instance variable.
First make a class that has a instance variable ArrayList<Character>
that also has a getter, setter and constructor.
//Make Objects that will have an ArrayList<Character>
public class ArrayOfChars {
private ArrayList<Character> list;
//Constructor
public arrayOfChars(){
this.list = new ArrayList<Character>();
}
//Getter
public ArrayList<Character> getList(){
return this.list;
}
//Setter
public void setList(ArrayList<Character> list){
this.list = list;
}
}
You can now use this class to make Objects and store that Objects in a 2D array
These Objects can store and ArrayList<Character> that can be used.
public static void main(String[] args) {
ArrayOfChars[][] myLists = new ArrayOfChars[9][9];
//initialize the 2d array so that it is filled with Empty ArrayList<>'s'
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
ArrayOfChars thislist = new ArrayOfChars();
myLists[i][j] = thislist;
}
}
//You can now use it like a 2d array of objects
Here are some ways you can use this 2D-Array of ArrayList<Character>
//Iterate like this
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
myLists[row][col].getList().get(index);
//or
myLists[row][col].setList(list);
}
}
//Add to a list
myLists[2][5].getList().add(new Character('H'));
//Set a list of characters
ArrayList<Character> useThisList = new ArrayList<Character>();
useThisList.add('F');
useThisList.add('G');
useThisList.add('L');
myLists[3][7].setList(useThisList);
}
I'd use list of lists, which is more dynamic.
List<ArrayList<Character>> list =
new ArrayList<ArrayList<Character>>();
I have a very simple question but i can't figure out why I'm having this exception. I'm trying to create a 2-dimensional Array of objects for a sudoku puzzle, but when I'm initializing i'm getting ArrayIndexOutOfBoundsException. Please help, I've read similar questions and it should be working!
Here I'm declaring the grid(2-dimensional array of objects used and constructor):
public class Sudoku extends javax.swing.JFrame {
private int lines;
Cell[][] grid;
public Sudoku() {
initComponents();
grid = new Cell[lines][lines];
So when i'm cliking a button to set the lines(size length) as shown below
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
lines=10;
makeGrid(lines);
}
I'm getting the exception:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
at Sudoku.makeGrid(Sudoku.java:146)
public void makeGrid(int size) {
for(int i=0;i<size;i++)
for(int j=0;j<size;j++) {
146: grid[i][j] = new Cell();
}
}
You should move your grid initialization into the make grid method since in the constructor the member lines is still not initialized with your desired value (default value of int is 0 so you get an empty array and you try to access it afterwards with bigger unallocated bounds)
public void makeGrid(int size) {
this.lines = size; // If you do not need lines anywhere else then it is redundant
grid = new Cell[size][size];
for(int i=0;i<size;i++)
for(int j=0;j<size;j++) {
grid[i][j] = new Cell();
}
}
The problem is that the default value for an int is 0.
So when you create your Sudoku object, grid = new Cell[lines][lines]; is equivalent to grid = new Cell[0][0];
Either change your makeGrid method or provide a size in your constructor.
public void makeGrid(int size) {
this.lines = size;
grid = new Cell[size][size];
for(int i=0;i<size;i++){
for(int j=0;j<size;j++){
grid[i][j] = new Cell();
}
}
}
grid = new Cell[lines][lines]; creates an array of size [0][0] because lines is still 0 when that statement is run.
Whavetever changes you make to lines later on won't affect the array size, which will remain [0][0]...
Simpler example:
int size = 0;
Object[] array = new Object[size];
size = 1;
System.out.println(array.length); //prints 0, not 1
Initialize lines before creation of array. Now you creating array with 0x0 dimensions, because lines is 0 be default.
lines = 10; // Add this line
grid = new Cell[lines][lines];
public void actionPerformed(ActionEvent e){
grid=new JButton[length+20][width+20];
grid1=new JButton[length+20][width+20];
for(int i=0;i<length+2;i++)
{
for(int j=0;j<width+2;j++)
{
grid1[i][j]=grid[i][j];
}
}
for(int i=1;i<length+1;i++)
{
for(int j=1;j<width+1;j++)
{
//final int row = i;
//final int col = j;
int count=0;
if(grid[i][j-1].getBackground() == Color.BLACK);
count++;
if(grid[i][j+1].getBackground()==Color.BLACK)
count++;
if(grid[i-1][j-1].getBackground()==Color.BLACK)
count++;
if(grid[i-1][j].getBackground()==Color.BLACK)
count++;
if(grid[i-1][j+1].getBackground()==Color.BLACK)
count++;
if(grid[i+1][j-1].getBackground()==Color.BLACK)
count++;
if(grid[i+1][j].getBackground()==Color.BLACK)
count++;
if(grid[i+1][j+1].getBackground()==Color.BLACK)
count++;
if(count==3) // exactly three neighbors
{
if(grid[i][j].getBackground()==Color.WHITE)
{
grid1[i][j].setBackground(Color.BLACK); // birth cell
}
}
if(count==2 || count==3) // 2 or 3 neighbors
{
if(grid[i][j].getBackground()==Color.BLACK)
{
grid1[i][j].setBackground(Color.BLACK); // survives
}
}
if(count>=4 || count<=1) //4 or more neighbors, or 1 or less neighbor
{
if(grid[i][j].getBackground()==Color.BLACK)
{
grid1[i][j].setBackground(Color.WHITE); // dies from over-population or isolation
}
}
}
}
for(int i=0;i<length+2;i++)
{
for(int j=0;j<width+2;j++)
{
grid[i][j]=grid1[i][j];
}
}
for(int i=1;i<length+1;i++)
{
for(int j=1;j<width+1;j++)
{
System.out.print(grid[i][j]);
}
System.out.println("\n");
}
}
I am getting a nullpointer exception when I try to display the next generation of conway game of life using a GUI. Please suggest whats wrong with my code. The action performed method is executed when a start button is clicked
The cause of the NullPointerException is this:
grid = new JButton[length+20][width+20];
grid1 = new JButton[length+20][width+20];
This way, you have a 2D-array of JButtons, but it is still full of null values. You have to initialize the individual "cells" in the array:
for (int i = 0; i < length+20; i++) {
for(int j = 0; j < width+20; j++) {
grid1[i][j] = new JButton();
}
}
Also, is the size of the array intentional, or should it be length+2 x width+2 instead, as in your for-loop?
But this is not your actual problem: You create a new buttons-array, and then check the background colors of those newly created buttons. Assuming that grid represents the current state of the game, you are erasing the game state before doing the update. More likely, you have to drop the line grid = new JButton[length+20][width+20]; entirely.
And even this will not work correctly, as the two arrays grid and grid1 will hold the same buttons, so when you change the background color of one, you also change the background color in the backup. With grid1[i][j]=grid[i][j] you just copy the reference to the button to the other array, but do not create a new button. And even if you did, you would have the problem that that new button would not be in the GUI at all.
Instead of storing your game state in the GUI elements, you should rather use two 2D-arrays of booleans (one for the current state, one as backup of the previous state during the state update) and set the background color of the buttons based on those booleans.
I'm working through a JPanel exercise in a Java book. I'm tasked with creating a 5x4 grid using GridLayout.
When I loop through the container to add panels and buttons, the first add() throws the OOB exception. What am I doing wrong?
package mineField;
import java.awt.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class MineField extends JFrame {
private final int WIDTH = 250;
private final int HEIGHT = 120;
private final int MAX_ROWS = 5;
private final int MAX_COLUMNS = 4;
public MineField() {
super("Minefield");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container mineFieldGrid = getContentPane();
mineFieldGrid.setLayout(new GridLayout(MAX_ROWS, MAX_COLUMNS));
// loop through arrays, add panels, then add buttons to panels.
for (int i = 0; i < MAX_ROWS; i++) {
JPanel[] rows = new JPanel[i];
mineFieldGrid.add(rows[i], rows[i].getName());
rows[i].setBackground(Color.blue);
for (int j = 0; j < MAX_COLUMNS; j++) {
JButton[] buttons = new JButton[i];
rows[i].add(buttons[j], buttons[j].getName());
}
}
mineFieldGrid.setSize(WIDTH, HEIGHT);
mineFieldGrid.setVisible(true);
}
public int setRandomBomb(Container con)
{
int bombID;
bombID = (int) (Math.random() * con.getComponentCount());
return bombID;
}
/**
* #param args
*/
public static void main(String[] args) {
//int randomBomb;
//JButton bombLocation;
MineField minePanel = new MineField();
//minePanel[randomBomb] = minePanel.setRandomBomb(minePanel);
}
}
I'm sure I'm over-engineering a simple nested for loop. Since I'm new to Java, please be kind. I'm sure I'll return the favor some day.
JPanel[] rows = new JPanel[i];
i is 0 in the first iteration, which isn't what you want. Make that:
JPanel[] rows = new JPanel[MAX_ROWS];
Also, I think you want to take that completely outside the for loop, since you seem to be using its elements, which would be uninitialised...
This is also wrong:
JButton[] buttons = new JButton[i];
i can be 0 when j is 2 for example, in which case there's no such thing as a buttons[j]. Make them all MAX_* and I think you want to take them out of the loop, since I don't see the point in recreating them at every iteration. Also, you need to instantiate the individual array elements as well.
This part doesn't really make sense:
for (int j = 0; j < MAX_COLUMNS; j++) {
JButton[] buttons = new JButton[i];
rows[i].add(buttons[j], buttons[j].getName());
}
You're creating an array of i JButtons, and trying to add the jth to rows, which makes little sense and won't work if j >= i. You probably meant to do:
JButton[] buttons = new JButton[MAX_COLUMNS];
for (int j = 0; j < MAX_COLUMNS; j++) {
rows[i].add(buttons[j], buttons[j].getName());
}
But the array still doesn't contain any buttons, all you did is initialize it. There's really no reason for the array at all; this actually works:
for (int j = 0; j < MAX_COLUMNS; j++) {
JButton button = new JButton("foo");
rows[i].add(button, button.getName());
}
JPanel[] rows = new JPanel[i];
When i is 0, you create an array with 0 elements. You then try to access that array, but it has no elements in it.
The problem is that your button array is of size i, but j can be larger than i. For instance, the first time through, you are making an empty array here:
JButton[] buttons = new JButton[i];
because i is equal to 0. You then attempt to access it at index 0, which doesn't exist (since the array has no size) and you get your exception. Should you instead be doing something like:
JButton[] buttons = new JButton[MAX_COLUMNS];
That way you will have a button for each array location. Also, you will probably need to initialize the individual buttons - i.e. something like this:
for (int k = 0; k < MAX_COLUMNS; k++) {
buttons[k] = new JButton();
}
(disclaimer: code not tested, but pulled out of you-know-where for example purposes only. There could be typos or unseen bugs.)
Good luck.
It looks like you're creating way too many arrays. You're creating your arrays INSIDE the loops, so instead of creating 5 rows, you're creating 5 rows 5 times, or 25 rows.
The other problem is that you aren't actually creating any objects, only the array to hold the objects. For each object in your array, you need another "button[j] = new JButton()" line.