I'm trying to loop through all of the rows in a column in a jTable at the moment I can get it to loop through a column but it only gives me the first 5 values and it also gives me a strange output.
here is the code:
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// Button to Start
Object[] columnData = new Object[jTable1.getColumnCount()];
Object[] rowData = new Object [jTable1.getRowCount()];
for (int i = 0; i < jTable1.getColumnCount(); i++) {
columnData[i] = jTable1.getValueAt(i, 4);
System.out.println(Arrays.toString(columnData));
}
here is the output:
I think you are using your column iteration as the row number in your code. jTable1.getValue(i, 4) has parameters row, column in that order. If you only have five columns, you will only get five values.
Try changing the loop to count through the rows and select the 5th column.
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// Button to Start
Object[] columnData = new Object[jTable1.getRowCount()]; // One entry for each row
Object[] rowData = new Object [jTable1.getRowCount()];
for (int i = 0; i < jTable1.getRowCount(); i++) { // Loop through the rows
// Record the 5th column value (index 4)
columnData[i] = jTable1.getValueAt(i, 4);
}
System.out.println(Arrays.toString(columnData));
Okay, so I need to print 10 rows from 1 to 10 and 15 columns in every row from 1 to 15 with lines in between numbers. The second subroutine runs on its own, but only prints 0's and the first subroutine is me trying to give value to rows and columns, but I know I'm doing it very wrong. Any help is appreciated
static int ROWS = 10;
static int COLUMNS = 15;
static int[][] myArray = new int[10][15];
static int i; // loops through the number of rows
static int j; // loops through the number of columns
static int num1 = 0;
static int num2 = 0;
public static void vlueArray() {
for (i = 1; i < ROWS; i++) {
myArray[i][j]= num1++;
for (j = 1; j < COLUMNS; j++) {
myArray[i][j] = num2++;
System.out.print(myArray[i][j]);
}
System.out.println("");
}
}
public static void display2DArray() {
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLUMNS; j++) {
System.out.print(myArray[i][j] + " | ");
}
System.out.println("");
System.out.println("_____________________________________________________________");
}
}
you have not initialized elements in array and that is why you are getting zero displayed because int values are always initialized by the compiler even if you don't initialize them. The default value of int is 0.
Initialize your 2D array like this:
int[][] myArray = new int[10][15]{{2,3},{3,5},..........};
Hope this helps.
There are two issues here. First, you don't have very good syntax, while the way you have this set up does work, let me give you a couple of tips about settings this up, and then we can fix your problem fairly easily.
Some general rules here:
You don't have to initialize loop variables in the class variables, just initialize them in the loop structure (I'll show you this below).
Use the ROW and COLUMN in declaring your array, it helps make sure the array length values are the same throughout.
Your loop for creating the values in vlueArray is incorrect. I'll show you some correct formatting for placing these values below.
When you array is initialized, each place in the array (if it is an integer array) is automatically given a value of zero. You can change this, but since the first method doesn't run correctly, printing the values in the array without changing them will give the array of zeros.
Now, it seems like you want to just have 1 - 15 on 10 different rows. To do this, you only need one variable, so my response code will only have one variable, but if this isn't what you want, I'd be glad to help you get a different setup.
So now that you have a little bit of background information, let's get you some working code.
static int ROWS = 10; //Your row count.
static int COLUMNS = 15; //Your column count.
static int num = 0; //Our number.
//Using the constants to make sure rows and columns values match everywhere.
static int[][] myArray = new int[ROWS][COLUMNS];
public static void fillArray() {
//Initializing the loop variables in the loop is the common practice.
//Also, since the first index is zero, the loop needs to start at 0, not 1.
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
//If you want 0 - 14, use `num++`.
//If you want 1-15, use `++num`.
myArray[i][j] = num++;
}
num = 0; //This sets num back to zero after cycling through a whole row.
}
//Your display method works just fine.
public static void display2DArray() {
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLUMNS; j++) {
System.out.print(myArray[i][j] + " | ");
}
System.out.println("");
System.out.println("_____________________________________________________________");
}
I'm currently trying to figure out how to add values into a full 2d array. Any help would be appreciated.
This is what i currently have.
public static ObjectA[][] addValue(ObjectA value, ObjectA[][] oldArray)
{
//Creates a new array with an extra row
ObjectA[][] newArray = new ObjectA[oldArray.length +1][oldArray[0].length]
for (int i= 0 ; i < newArray.length; i++)
{
for (int ii = 0; ii <= newArray[0].length; ii++)
{
// when the index exceeds the oldArray
// it will add the value to the newArray
if (i <= oldArray.length)
{
newArray[i][ii] = oldArray[i][ii];//copies all values into newArray
}
else
{
newArray[i][ii] = value; //adds value to the last row
}
}
}
return newArray;
}
What I currently have done is input a value to the new row however the method is going to be called multiple times to add more than one value. Which mean it's going to create multiple rows rather than adding to the next available column.
EDIT:
mistyped the data type the array and value are suppoed to be objects.
First, your code throws an IndexOutOfBoundsException. Here is why:
Consider the if (i <= oldArray.length) clause. Say, oldArray.length is 3. When i = 3, newArray[i][ii] = oldArray[i][ii] line seeks the oldArray[3][ii] elements but there are no such elements. All the possible elements of oldArray is oldArray[0][ii], oldArray[1][ii] and oldArray[2][ii], since counting starts with 0 in programming.
Second, I didn't get the point of adding another row for each next value. If you're not going to add a set of values to each row, then, why do you consider expanding number of rows?
This is a typical situation when you need to make a tradeoff between element access complexity and complexity of adding new column
If you need fast column adding without new structure allocation you should use LinkedList as a storage of rows and call list.add(row) every time you need to add a new column so your code will look like:
public static void addValue(int value, LinkedList<int[]> list) {
int[] row_you_need_to_add = new int[list.get(0).length];
for (int i = 0; i < list.get(0).length; i++) {
row_you_need_to_add[i] = value;
}
list.add(row_you_need_to_add);
}
As 2D Array is an Array which consist of an array within an Array. So at every index of 2D array there is another array is present and has a specific size.
public static ObjectA[][] addValue(ObjectA value, ObjectA[][] oldArray) {
ObjectA[][] newArray = new ObjectA[oldArray.length +1][oldArray[0].length]
for (int i= 0 ; i < newArray.length; i++) {
for (int ii = 0; ii <= newArray[0].length; ii++) {
// when the index exceeds the oldArray
// it will add the value to the newArray
if (i <= oldArray.length) {
newArray[i][ii] = oldArray[i][ii];//copies all values into newArray
} else {
newArray[i][ii] = value; //adds value to the last row
}
}
}
return newArray;
}
I want to store several 2d array positions in an ArrayList and I've set it up like so:
ArrayList<Integer> playedValues = new ArrayList<Integer>();
playedValues.add(dataArray[0][1]);
playedValues.add(dataArray[0][2]); //example of adding 2d array positions
int size = playedValues.size(); //get size of ArrayList
int gridIndex = playedValues.get(size - 1); //trying to set gridIndex to dataArray[0][2]
cell.setCell(0, gridIndex); //this is where the error occurs
//trying to pass gridIndex to here
public void setCell(int value, int gridIndex) {
gridIndex = value;
}
My issue is when I try and pass gridIndex as a parameter to setCell, I get a NullPointerException.
The method I'm passing it to seems to work fine in my tests, so I assume gridIndex is not being set properly. How do I make playedValues store dataArray[][] itself instead of the information dataArray[][] holds?
The solution you were looking for
After talking with you in chat, we determined that you were making a Sudoku game, and you wanted to store moves, and be able to undo those moves.
You have the board stored as sudokuGrid which is a 2d int array. You need to be able to make changes to certain cells (row, column). You also need to be able to store moves, (row, column), and in order. Then you can use both of these features together, and allow your users to undo their moves.
Let's focus on making changes to a cell first.
Undo'ing a move
We can write a method that takes in a row and a column, and changes the value of the cell at (row, column) back to 0. (Undo-ing a move).
We should be able to call this method like so:
int testRow = 4, testColumn = 1;
undoMove(testRow, testColumn, sudokuGrid);
Of course, later we'll use row's and column's from previous moves, but we need to be able to test right now. The undoMove method will be written like so:
public void undoMove(int row, int column, int[][] board) {
board[row][column] = 0;
}
It's very important that we pass in sudokuGrid to undoMove. Otherwise, undoMove wouldn't be able to make permanent changes to the game board. You can read the link I gave farther below for more information on why you are able to make changes to sudokuGrid.
Now, we need to focus on how we can store moves.
Storing moves
We have a few options available, but the easiest in my opinion, would be to make an ArrayList and store Move's in it. Of course, Java hasn't defined Move's for us. We will have to make our own class to define a Move.
If you're unfamiliar with making classes, you can learn the basics here, and here.
Here's what our Move class might look like:
class Move {
int row, column;
public Move(int row, int column) {
this.row = row;
this.column = column;
}
}
public void undoMove(int row, int column, int[][] board) {
board[row][column] = 0;
}
This simply says that each Move will have a row, a column.
We can now store the row and column of the cell where each move was played.
Now we can make an ArrayList to hold our Move's:
ArrayList<Move> moves = new ArrayList<Move>();
We can make a Move object each time that a user makes a move like so:
// You'll need to get the row and column
// before you make the Move object
Move currentMove = new Move(row, column);
Now anytime we want to undo a move, we can simply do this:
Move moveToUndo = moves.get( moves.size() - 1 );
undoMove(moveToUndo.row, moveToUndo.column, sudokuGrid);
moves.remove( moves.size() - 1 );
Now all together!
class Move {
int row, column;
public Move(int row, int column) {
this.row = row;
this.column = column;
}
}
public void undoMove(int row, int column, int[][] board) {
board[row][column] = 0;
}
// Later on, in your game loop method
ArrayList<Move> moves = new ArrayList<Move>();
// Adding moves
// In your program, you'll get the row and column from what
// the user types in or clicks on.
int row = 1, column = 7;
moves.add( new Move(row, column) );
row = 6, column = 8;
moves.add( new Move(row, column) );
// Undo'ing moves
Move moveToUndo = moves.get( moves.size() - 1 );
undoMove(moveToUndo.row, moveToUndo.column, sudokuGrid);
moves.remove( moves.size() - 1 );
You could even re-write the undoMove method to take in a Move, rather than a row and a column, and that would look very clean. You could also write a method undoLastMove that would automate some of this process.
Fixing your ArrayList problem
I'm not quite sure what you intend to use the ArrayList playedValues for, so I have to make a somewhat educated guess that you want to have an ArrayList hold arrays, not single values.
That is very simple to do!
Your current declaration:
ArrayList<Integer> playedValues = ArrayList<Integer>();
Sets up playedValues to hold Integer or int values. To instead set up playedValues to hold arrays of int's, do this:
ArrayList<Integer[]> playedValues = ArrayList<Integer[]>();
Then playedValues will store arrays of Integer's or int's.
You can use the ArrayList like so:
ArrayList<Integer[]> playedValues = ArrayList<Integer[]>();
int[] arrayOne = {1, 2, 3, 4, 5};
// Adding arrays to the list
playedValues.add(arrayOne);
// Iterating through all arrays in playedValues
for(int i = 0; i < playedValues.size(); i++) {
int[] currentArray = playedValues.get(i);
// Then, of course, you can loop over each array like normal:
for(int j = 0; j < currentArray.length; j++) {
System.out.println(
"Array #" + i + " - Element #" + j + " = " + currentArray[i][j]
);
}
}
There's an even better way!
If you're using an ArrayList the same way as you would a 2d array, but you still want all of the flexibility and features of an ArrayList, then do this:
ArrayList<ArrayList<Integer>> playedValues = ArrayList<ArrayList<Integer>>();
That sets up playedValues to be an ArrayList which holds ArrayLists which hold int's. Very similar to using int[][] which uses an array that holds arrays that hold ints'.
The above code can be implemented with this new ArrayList of ArrayLists, like so:
ArrayList<ArrayList<Integer>> playedValues = ArrayList<ArrayList<Integer>>();
int[] arrayOne = {1, 2, 3, 4, 5};
// Adding values to the playedValues
playedValues.add( Arrays.asList(arrayOne) );
// Iterating through all values in playedValues
for(int i = 0; i < playedValues.size(); i++) {
for(int j = 0; j < playedValues.get(i).size(); j++) {
System.out.println(
"Row #" + i + " - Column #" + j + " = " + playedValues.get(i).get(j)
);
}
}
If you wanted to store, maybe a 9x9 grid, you could easily do that like this:
ArrayList<ArrayList<Integer>> playedValues = ArrayList<ArrayList<Integer>>();
int[] sampleRow = {0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int i = 0; i < 9; i++) {
playedValues.add( Arrays.asList(sampleRow) );
}
But, should you use ArrayList?
I don't see a huge need for using an ArrayList here. When I see the code you have and read what you are trying to do, I immediately think 2d array.
There isn't anything in your code, or my answer, that can't be done with a 2d array. It may make things simpler too. The only issue, is if you need to dynamically add arrays. A 2d array can't do that.
Here is the same implementation as above, with a 2d array:
// 100 for rows and columns was chosen arbitrarily.
int[][] playedValues = new int[100][100];
int[] arrayOne = {1, 2, 3, 4, 5};
int[] arrayTwo = {1337, 9001, 1111111, 22222, 33333, 444, -1, -123, 246};
// Adding arrays to the list
playedValues[0] = arrayOne;
playedValues[1] = arrayTwo;
// Iterating through all arrays in playedValues
for(int i = 0; i < playedValues.length; i++) {
for(int j = 0; j < playedValues[i].length; j++) {
System.out.println(
"Array #" + i + " - Element #" + j + " = " + currentArray[i][j]
);
}
}
And the setCell method:
public void setCell(int value, int row, int column, int[][] grid) {
grid[row][column] = value;
}
Fixing the setCell method
If we have an ArrayList which stores arrays of int's, we can change a certain cell with this implementation:
// Making a call to set the cell in the 1st row at the 4th column, to 0
setCell(0, 1, 4, playedValues);
public void setCell(int value, int row, int column, ArrayList<Integer[]> grid) {
int[] rowArray = grid.get(row);
rowArray[column] = value;
}
Original Error
The problem isn't with gridIndex, it's with cell.
You can get a NullPointerException from an int, since all int's have default/null values of 0 in Java. See the documentation here, here, here, and this post's answers, for proof of this.
So the problem isn't with the setCell method, it's with your cell variable. The NullPointerException is being thrown because cell is null, not anything you pass to setCell.
Why setCell didn't originally work
It is true, as pointed out by other answers, that the method setCell won't actually do anything noticeable. This is because Java is pass by value, not pass by reference. You can read this post for a detailed explanation.
What this means behind the scenes, is that whatever actual number values you pass to setCell as value and gridIndex, setCell will have the values of, but not the references.
This code:
int gridIndex = 10, myValue = 2;
setCell(myValue, gridIndex);
will call setCell and pass the values of gridIndex and myValue, which are 10 and 2. The setCell method never sees the actual variables gridIndex and myValue, setCell has no reference to those variables, it only ever sees the values 10 and 2.
This can be confusing because the values are stored in variables within setCell, the variables you specify to be the parameter names (int value, int gridIndex), but these variables, are not the variables you passed to setCell. See this code:
public static void main(String[] args) {
int gridIndex = 10, myValue = 9999;
setCell(myValue, gridIndex);
System.out.println(gridIndex);
}
public static void setCell(int value, int gridIndex) {
// In here, value is NOT the same variable, myValue, that
// we passed in. Just the same, gridIndex, is not the same
// variable that we passed in from main.
// In here, value and gridIndex have the SAME VALUES
// as the variables we pass in, but they are not the same
// variables. They are newly made variables, with the same values.
}
Also look at this code:
public static void main(String[] args) {
setCell(10, 9999);
System.out.println(gridIndex);
}
public static void setCell(int value, int gridIndex) {
gridIndex = value;
}
We didn't pass a variable to setCell, but inside setCell we changed the variable gridIndex to be equal to value. Will this tell Java that the new value of the number 9999 should really be 10? Of course not. We aren't changing what was passed in, we are changing variables that hold the values that were passed in.
An easy way to think about what is happening, is to remember that whenever you use an int variable in Java, you could replace the variable name with the value it holds, and the code would remain exactly the same.
Take this code for example:
int gridIndex = 10, myValue = 9999;
setCell(myValue, gridIndex);
an equilivant code is:
setCell(10, 9999);
And as we just saw above, of course we can't change the value of 10 or 9999. We can't just decide that numbers are equal other numbers. Of course we can change the numbers that are held in int's, but there aren't any int variables being delivered to setCell, only number values like 10 or 9999.
public void setCell(int value, int gridIndex) {
gridIndex = value;
}
The above code does nothing. It takes two arguments, and locally sets one of the arguments to the other. Then since both of the variables were declared within the function, they are both gone when it exits.
Since this method just sets gridIndex, why not just set it directly?
gridIndex = 0;
EDIT: example of why this doesn't work.
I tried this in my IDE - it is exactly the same setCell method you have.
public static void main(String[] args) {
int gridIndex = 10;
setCell(0, gridIndex);
System.out.println(gridIndex);
}
public static void setCell(int value, int gridIndex) {
gridIndex = value;
}
The console prints 10, because setCell does nothing. It doesn't set the value of gridIndex, it doesn't edit any variables. It does nothing, because the only values it changes are values which are declared in its signature, and which are lost when the method exits as a result.
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];