0

while creating an application using JavaFX i faced a little problem - elements in my array are somehow not updating with changes which are made on these elements. On the start I want to point - dont pay attention on structure and model of my app - I already know It is not good and I changed it but i still dont understand why my problem existed. This how initialization of my array look like:

public class GameBoardAI implements IGameModel{


Random rand = new Random();
int currentPlayer = 1;
TicTacViewController tacController = new  TicTacViewController();
Button[] buttonss = new Button[]{ tacController.btn1, tacController.btn2, tacController.btn3, tacController.btn4, 
        tacController.btn5, tacController.btn6, tacController.btn7, tacController.btn8, tacController.btn9};  

The problem is, that when I am creating the array of buttons, buttons are not connected to the view yet, so they are still nulls. And when I am trying to invoke some methods on my buttons inside I encounter a problem:

public void switchPlayer() {
if(currentPlayer == 1)
{              
    currentPlayer=2;
    buttonss[rand.nextInt(9)].fire();

}
if(currentPlayer == 2)
    currentPlayer = 1;

}

You can see here, that I am trying to get some random button, from array of buttons i created in instance variable. Here is the part of code, when buttons are located inside TicTacViewController:

    public class TicTacViewController implements Initializable
{

@FXML
private Label lblPlayer;

@FXML
private Button btnNewGame;

@FXML
private GridPane gridPane;

private static final String TXT_PLAYER = "Player: ";
private IGameModel game = new GameBoard();
@FXML
public Button btn1;
@FXML
public Button btn2;
@FXML
public Button btn3;
@FXML
public Button btn4;
@FXML
public Button btn5;
@FXML
public Button btn6;
@FXML
public Button btn7;
@FXML
public Button btn8;
@FXML
public Button btn9;

As i understood, the problem is, that when I am creating the array as instance variable, mu buttons are still null - they are not connected to the view yet. But here happens some strange thing: When I am putting array initialization inside a switchPlayer method instead of doing this as instance variable - everything is working correctly. So it seems like when I am creating array while invoking a method buttons are already connected to the view and there is no problems. And it ruins my knowledge about reference variables - why it is not working when we are creating array as instance variable? Because i thought that even if we have a reference variables inside a array - when we will change this reference variables, they will be also changed in our array. To be more specific - even if when we are initalizing an array and buttons are not connected to the view yet, they are connecting afterwards - so when we are invoking a switchPlayer method butttons should be already connected to the view - but compiler is telling me that they are null. Can someone explain me what is the problem here? Why while invoking a method buttons are still null, as they were in array creation even if they were connected to the view afterwards?

schemaboi
  • 561
  • 4
  • 9
  • References in other languages may work that way but in java a "reference" just contains the info where to find an object on the heap. This location behaves as a value type. When you create your array `tacController.btn1` ect. doesn't store "a way to find the object" but evaluates `tacController.btn1` and creates a copy of the memory address which at that time is still `null`. – fabian Oct 23 '18 at 09:35

1 Answers1

1

Java is a pass-by-value language. Object type variables are not object pointers, they merely hold a object reference (i.e. memory address). Example:

String str = "Hello"; // A String type variable holding reference of "Hello" string
String str2 = str; // Variable "str2" now copies the reference of "str"
String str2 = "World"; // Variable "str2" changes the reference it holds to the string "World" (in other word, it is being replaced)

It is frequently confused because the follow is valid:

List<String> foo = new ArrayList<>(); // Let foo hold the reference of an empty arraylist
List<String> bar = foo; // Let bar hold the reference that is held by foo
bar.add("hello");
System.out.println(foo); // Prints "[hello]"

This is working because bar has copied the object reference of the ArrayList from foo, so any manipulation to the ArrayList via bar will be reflected by foo, since they both hold the same object reference.

Back to your question. If tacController has not loaded the FXML file, all the Button references will be null. So what you are doing is to copy the null references and keep these null references in the array. Therefore, you will never be able to access the actual Button objects.

Jai
  • 7,616
  • 2
  • 17
  • 43