-2

Is it possible to create an array of JavaFX objects that can be accessed.

Currently I have:

    @FXML
    private CheckBox pc1,pc2,pc4,pc8,pc16,pc32,pc64,pc128,pc256,pc512,pc1024,pc2048;

    private final CheckBox[] pcController = {pc1,pc2,pc4,pc8,pc16,pc32,pc64,pc128,
                                             pc256,pc512,pc1024,pc2048};

I am trying to access these objects and flip the check box based on the value in a different array as such:

    

    boolean[] bits = getBits();

    for(int i =0; i<pcController.length;i++){
        pcController[i].setSelected(bits[i]);
    }

I get the error:

Cannot invoke "javafx.scene.control.CheckBox.setSelected(boolean)" because "this.pcController[i]" is null ...

Edit: So I can get the system to semi-work if I instantiate the array inside a method.

Ellis Thompson
  • 408
  • 6
  • 18
  • 1
    [mcve] please.. – kleopatra Sep 06 '21 at 22:34
  • @kleopatra that is MRE... you create a JavaFX project and put in what I described and it willl produce the same error. Another user was able to provide an answer. This comment is just unhelpful. – Ellis Thompson Sep 07 '21 at 19:22
  • _your_ problem = _your_ task to provide that example: as-is, your question is just unhelpful to future readers (though the answer certainly is ;) – kleopatra Sep 07 '21 at 22:12

1 Answers1

6

The following things happen1, in this order, when an FXMLLoader loads an FXML file:

  1. The FXMLLoader parses the file
  2. The FXMLLoader creates object instances corresponding to instance elements in the FXML file, and sets properties on those objects corresponding to property elements in the FXML file.
  3. If there is a fx:controller attribute on the root element, the FXMLLoader creates an instance of the specified class
  4. The FXMLLoader initializes any @FXML-annotated fields in the controller with the corresponding elements whose fx:id matches the field name.
  5. If the controller has an initialize() method, it is invoked.

In your code, you declare your array and initialize it inline:

@FXML
private CheckBox pc1,pc2,pc4,pc8,pc16,pc32,pc64,pc128,pc256,pc512,pc1024,pc2048;

private final CheckBox[] pcController = {pc1,pc2,pc4,pc8,pc16,pc32,pc64,pc128,
                                         pc256,pc512,pc1024,pc2048};

This means the array will be assigned its value when the controller is created, which is in step 3 above. Since the 12 CheckBoxs will not have been initialized yet (because that happens in step 4), you will create an array with 12 null values.

Instead, initialize the array in the initialize() method:

public class MyController {

    @FXML
    private CheckBox pc1,pc2,pc4,pc8,pc16,pc32,pc64,pc128,pc256,pc512,pc1024,pc2048;

    private final CheckBox[] pcController ;

    @FXML
    private void initialize() {
        pcController = new CheckBox[]{pc1,pc2,pc4,pc8,pc16,pc32,pc64,pc128,
                                             pc256,pc512,pc1024,pc2048};
    }

    // ...
}

(1) This is not a complete list of the FXMLLoader lifecycle, but it suffices to explain what is happening in this case.

SedJ601
  • 12,173
  • 3
  • 41
  • 59
James_D
  • 201,275
  • 16
  • 291
  • 322