I want to Fill a 2D-Array with Javafx Labels in Which I can change the Text when I click it.
This is my actual Code but it's returning a NullPointer Exception.
Blockquote
`public static Label[][] initWelt() {
Label[][] welt = new Label[DIM1][DIM2];
for (int x = 1; x < welt.length - 1; x++) {
for (int y = 1; y < welt.length - 1; y++) {
if (Math.random() > 0.4) {
welt[x][y].setText("X");
}
else{
welt[x][y].setText(" ");
}
}
}
return welt;
}`
it's returning a NullPointer Exception.
The only thing the below code does is initialise a two-dimensional array, it doesn't populate the two-dimensional array, hence the NullPointerException occurs.
Label[][] welt = new Label[DIM1][DIM2];
Basically you can't call this:
welt[x][y].setText("X");
without populating the two-dimensional array with object references.
to overcome the problem first populate the two dimensional array, something like below:
Label[][] welt = new Label[DIM1][DIM2];
for(int i = 0; i < DIM1; i++){
for(int j = 0; j < DIM2; j++){
welt[i][j] = new Label();
}
}
then you can proceed with your current task at hand.
so now your code becomes like this:
public static Label[][] initWelt() {
Label[][] welt = new Label[DIM1][DIM2];
for(int i = 0; i < DIM1; i++){ //populate the array
for(int j = 0; j < DIM2; j++){
welt[i][j] = new Label();
}
}
for (int x = 0; x < DIM1; x++) {
for (int y = 0; y < DIM2; y++) {
if (Math.random() > 0.4) {
welt[x][y].setText("X");
}
else{
welt[x][y].setText(" ");
}
}
}
return welt;
}
Note - personally I think it would be better to refactor the current method and insert the code that populates the two-dimensional array in a different method.
Related
sorry I don't know how title this question but I am having an issue with assigning data to a new multidimentional array, do something and then retrieve the old data.
In my case I am trying to loop through JTextFields, assign all current data specifically the colour to a new multidimentional array. Then I want to do a search and change the background colour of found textfields.
Now I have a reset button that I would like the old colours that are now in the new multidimentional array to be assigned back to the fields. The issue I am having is that the new multidimentional array has updated after the search with the new colours. I really appreciate if someone can point me to the right direction.
Here is my code:
public JTextField[][] fields = new JTextField[totalX][totalY];
public JTextField[][] newFields = new JTextField[totalX][totalY];
if (e.getSource() == btnFind || e.getSource() == txtSearch)
{
// Make a copy of fields before selecting everything
for(int t = 0; t < totalX; t++){
for(int r = 0; r < totalY; r++){
newFields[t][r] = fields[t][r];
}
}
findStudentRecord();
// when looping though newFields[x][y] here it is already updated to the current colour
}
if (e.getSource() == btnReset)
{
for(int x = 0; x < totalX; x++){
for(int y = 0; y < totalY; y++){
fields[x][y].setText(newFields[x][y].getText());
fields[x][y].setBackground(newFields[x][y].getBackground());
// have tried this one but doesn't work
if(newFields[x][y].getBackground() == Color.green){
fields[x][y].setBackground(Color.green);
System.out.print(fields[x][y].getText() + "\n");
}
}
}
}
Here is the findStudentRecord()
public void findStudentRecord()
{
boolean found = false;
String strFind = txtSearch.getText();
for(int x = 0; x < totalX; x++){
for(int y = 0; y < totalY; y++){
if(fields[x][y].getText().equalsIgnoreCase(strFind))
{
found = true;
}
}
}
if (found)
{
for (int x = 0; x < totalX; x++)
{
for(int y = 0; y < totalY; y++){
if(fields[x][y].getText().equalsIgnoreCase(strFind))
{
fields[x][y].setBackground(new Color(255,217,200));
}
}
}
txtSearch.setText(txtSearch.getText() + " ...Found.");
}
else
{
txtSearch.setText(txtSearch.getText() + " ...Not Found.");
}
}
You have to create a new JTextField and add the relevant data:
newFields[t][r] = new javax.swing.JTextField();
newFields[t][r].setText(fields[t][r].getText());
newFields[t][r].setColumns(fields[t][r].getColumns());
// any other property you want to transfer
I have an array of buttons declared as a class variable that is added to a gridPane. When I try to remove the buttons of the array from the gridPane the event handler is being recognized but the node is not being removed.
Any ideas of how to accomplish this?
for(int i = 0; i < Rows; i++) {
for(int j = 0; j < Cols; j++) {
bArray = new Button[Rows][Cols];
bArray[i][j] = new Button();
bArray[i][j].setMinSize(20,20);
bArray[i][j].setMaxSize(25,25);
gridBoard.setVgap(1); //vertical gap in pixels
gridBoard.add(bArray[i][j], j, i);
bArray[i][j].setOnMouseClicked(e->checkNeighbors());
}
}
// Local Method
public static void checkNeighbors() {
// This print out statement is met, but the removal does not occur
System.out.println("Action is called");
gridBoard.getChildren().remove(bArray[0][1]);
gridBoard.getChildren().remove(bArray[0][2]);
gridBoard.getChildren().remove(bArray[0][3]);
}
You are overriding bArray in each iteration and the only valid references that are left at the end of the for loops are from [Rows][0] to [Rows][Cols].
As an example if Rows = 4 and Cols = 4, that would be that at the end the only valid references are [3][0], [3][1], [3][2] and [3][3], and you are trying to remove [0][1], [0][2], [0][3].
You should move the initialization of bArray before the loops start.
bArray = new Button[rows][cols];
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
bArray[i][j] = new Button();
// ......
}
Want to write the diagonal of an 2-dimensional array (n*n Matrix) into an one-dimensional array.
1 2 3
4 5 6 => 1 5 9
7 8 9
public int[] getDiagonalFromArray(int[][] two_d_array){
int[] diagonal_array = new int[two_d_array[0].length];
int k=0;
for (int i = 0; i < two_d_array[0].length; i++) {
for (int j = 0; j < two_d_array[1].length; j++) {
for (int l = 0; l < two_d_array[0].length; l++) {
diagonal_array[k]=two_d_array[i][j];} //HERE SHOULD BE THE ERROR... HOW DO I CYCLE THROUGH THE 1dim "diagonal_array"?
}
}
return diagonal_array;
}
This method delivers wrong values.
This method of mine works, but just Prints the diagonale, instead of putting it into an 1dim array.
public void getDiagonal(int[][] two_d_array){
//int[] diagonal_array = new int[two_d_array[0].length];
for (int i = 0; i < two_d_array[0].length; i++) {
for (int j = 0; j < two_d_array[1].length; j++) {
if (i==j) System.out.print(two_d_array[i][j]+" ");
}
}
}
Where is the logical difference? I tried the if-clause on the first method, but it raises the "outofbound"-Exception.
Thanks in advance.
Why do you need more than one loop?
for (int i = 0; i < two_d_array[0].length; i++) {
diagonal_array[i]=two_d_array[i][i];
}
Seems to be enough to me.
If your matrix has the same width and height, this is a solution:
public int[] getDiagonal(int[][] two_d_array){
int[] diagonal_array = new int[two_d_array.length];
for (int i = 0; i < two_d_array.length; i++) {
diagonal_array[i] = two_d_array[i][i];
}
return diagonal_array;
Here, I consider principal diagonal elements to be the set of elements , where n & m are the number of rows and the number of columns (per row?) respectively.
Thus, the number of diagonal elements is never greater than min(numOfRows, numOfColumns).
And so, you can always try:
public int[] getDiagonalFromArray(int[][] 2DArray){
int[] diagonalArray = new int[Math.min(2DArray.length, 2DArray[0].length]);
int k=0;
for (int i = 0; i < 2DArray.length && k < diagonalArray.l length; ++i) {
for (int j = 0; j < 2DArray[i].length && k < diagonalArray.l length; ++j) {
if (i == j) {
diagonalArray[k++]=2DArray[i][j];
}
}
}
return diagonalArray;
}
Threw in some bounds checks for good measure.
Your input matrix must at be at least rectangular (square makes most sense), otherwise, the code will behave unreliably.
This is the same as #Andreas' answer, but I sacrifice performance and brevity here for the sake of understanding.
I need a method that given input 2D array {{1,2},{3,4}} and (int)row=2; (int)column = 3, will produce a concatenated 2D array {{1,2,1,2,1,2}{3,4,3,4,3,4}}.
My attempt was to use a nested for loop to expand them both horizontally and and vertically, but was unsuccessful. This is what I have so far:
int row = 2;
int column = 5;
int count = 0;
int[][] list = {{12,3},{3,4}};
int [][] renewed = new int[row*list.length][column*list[0].length];
for (int l = 0; l<list.length; l++) {
for (int k = 0; k<renewed.length; k+= list.length) {
renewed[l+k] = list[l];
}
}
System.out.println(Arrays.deepToString(renewed));
}
}
^This produces list[][] expanded vertically, for the first column
int row = 2;
int column = 4;
int[][] list = {{12,3},{3,4}};
int [][] renewed = new int[row*list.length][column*list[0].length];
for (int i = 0; i<list[0].length; i++) {
for (int j = 0; j<renewed[0].length; j+=list[0].length) {
renewed[0][j+i] = list[0][i];
}
}
System.out.println(Arrays.toString(renewed[0]));
}
^This produces list[][] expanded horizontally, for the first row;
So how can I concatenate these two methods in order to produce a method that expands BOTH horizontally and vertically?
I think the easiest way is to iterate over every position in the new array and use the remainder operator % to get the right entry of the original.
int[][] list = {{1,2},{3,4}};
int row = 2;
int column = 5;
int [][] renewed = new int[row*list.length][column*list[0].length];
for (int i = 0; i < renewed.length; i++) {
for (int j = 0; j < renewed[0].length; j++) {
renewed[i][j] = list[i % list.length][j % list[0].length];
}
}
System.out.println(Arrays.deepToString(renewed));
I have two arrays that I create like this:
public int GameBoard[][] = new int[30][14];
public int DirectionMap[][] = new int[30][14];
I then initialize the arrays like this:
for (int i = 0; i < GameBoard.length; i++)
{
for (int j = 0; j < GameBoard[i].length; j++)
{
GameBoard[i][j] = 0;
}
}
... //Same for DirectionMap
When I run the function:
DirectionMap = AStar(GameBoard);
To render the pathfinding map that my units will follow, DirectionMap is correctly set to the values generated based on my GameBoard. However GameBoard is set to the result as well. When I run the application in Debug Mode within Eclipse, I can see that the ID's of the two arrays are the same. For some reason they seem to be pointing to the memory space. My AStar function does not modify the GameBoard array at all. The only reference to it is int retVal[][] = GameBoard;
My function prototype is public int[][] AStar(int[][] Board); and it returns the int[][] retVal.
I have no idea why I cannot change the values of DirectionMap without GameBoard following. I have never had any issues like this before.
Any ideas are really appreciated. Thanks for your help.
public int[][] AStar(int[][] Board)
{
int retVal[][] = Board;
//Initialize All Needed Lists
int width = retVal.length;
int height = retVal[0].length;
int goalX = 0;
int goalY = 0;
//List<Node> fieldInfo = new ArrayList<Node>();
Node fieldArray[][] = new Node[width][height];
for (int i = 0; i < fieldArray.length; i++)
{
for (int j = 0; j < fieldArray[i].length; j++)
{
fieldArray[i][j] = new Node(i, j);
if (retVal[i][j] == 2)
{
fieldArray[i][j].setOpen(1);
fieldArray[i][j].setDirection(10); //Set as target
goalX = i;
goalY = j;
}
if (retVal[i][j] == 1)
{
fieldArray[i][j].setOpen(0);
fieldArray[i][j].setDirection(9); //Set as wall
}
}
}
//Add AStar Algorithm Here
for (int i = 0; i < fieldArray.length; i++)
{
for (int j = 0; j < fieldArray[i].length; j++)
{
if (fieldArray[i][j].getDirection() == 0)
{
//Occurs when node was never reached
int dX = i - goalX;
int dY = j - goalY;
if (dX < 0)
dX = -dX;
if (dY < 0)
dY = -dY;
if (dY > dX)
fieldArray[i][j].setDirection(1);
else
{
if (i > goalX)
fieldArray[i][j].setDirection(7);
if (i < goalX)
fieldArray[i][j].setDirection(3);
}
}
}
}
for (int i = 0; i < fieldArray.length; i++)
{
for (int j = 0; j < fieldArray[i].length; j++)
{
retVal[i][j] = fieldArray[i][j].getDirection();
}
}
return retVal;
}
Remember when you are passing an object to methods you are actually passing a copy of reference. So when you initialise retVal[][] = Board; you actually point Board using another reference retVal. And you are returning the same reference to DirectionMap. Hence same id's for Board and DirectionMap. Consider array copy instead.
I can see that the ID's of the two arrays are the same. For some
reason they seem to be pointing to the memory space
The int[] array in Java has 0's as default values.
int[] x = new int[2];
System.out.println(x[0]); // prints 0
System.out.println(x[1]); // prints 0
The only reference to it is int retVal[][] = GameBoard;
Java arrays are objects. If at any point you are setting array = array, you are setting one reference to point to the same object as the other.