dalva
dalva

Reputation: 55

Having an issue with javafx objects losing reference once they're put into an array

So I'm trying to modify some circles in my controller class, and i've linked the circles to my fxml file circles but when i try to add them to a circle array for easy management, they seem to lose their reference. For example I have:

@FXML
private Circle circle1 = new Circle();

public void addNumber(ActionEvent event){
circle1.setLayoutX(355.0);
circle1.setLayoutY(100.0);
circle1.setVisbility(true);
}

The above method successfully makes a circle pop up in the given coordinates. However the following doesnt work:

@FXML
private Circle circle1 = new Circle();

@FXML
private Circle[] c = {circle1};

public void addNumber(ActionEvent event){
c[0].setLayoutX(355.0);
c[0].setLayoutY(100.0);
c[0].setVisbility(true);
}

This doesn't work! Tried array tried arraylist tried linkedlist, the reference to circle1 just gets lost. I'm a noob at JAVAFX so this might be a simple fix but i've tried to research a bit, tried different implementations to get it to work and i cant seem to find the solution. Any help would be much appreciated!

Upvotes: 0

Views: 389

Answers (2)

Benjamin Gale
Benjamin Gale

Reputation: 13177

This SSCCE should provide enough information to get you started.

Given the following FXML file:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>


<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" 
      prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" 
      xmlns:fx="http://javafx.com/fxml/1" 
      fx:controller="yourapplication.FXMLDocumentController">

    <children>
        <Button layoutX="22.0" layoutY="31.0" mnemonicParsing="false" 
         onAction="#addNumber" text="Button" />

        <Circle fx:id="circle1" fill="DODGERBLUE" layoutX="56.0" layoutY="118.0" 
                radius="34.0" stroke="BLACK" strokeType="INSIDE" visible="false" />
    </children>
</Pane>

And the following controller code:

public class FXMLDocumentController {

    @FXML
    private Circle circle1;
    private Circle[] c;

    public void initialize() {
        c = new Circle[] { circle1 };
    }

    public void addNumber(ActionEvent event) {
        c[0].setLayoutX(355.0);
        c[0].setLayoutY(100.0);
        c[0].setVisible(true);
    }
}

you should get the results you desire.

Notes:

  • Use the FXML annotation to bind your variables to elements of the same name within your FXML file.
  • An FXML annotation is not required for variables that are not defined in the FXML file.
  • I don't think primitives such as arrays can be defined FXML.
  • the reference to the circle should be set in the initialize method as this is called after the variable is bound to the element in the FXML file.
  • if you mark a Node variable with the FXML annotation you don't need to set a reference in the controller code as this will be overwritten when the FXML file is loaded (which is the root of your problem, see Tomsontoms answer).

Upvotes: 1

tomsontom
tomsontom

Reputation: 5897

You are creating an instance in a field marked with @FXML this wrong, this field is overwritten when the FXML is loaded. This is also the reason the array stuff does not work because the element in the array is never attached to the Scenegraph

Upvotes: 2

Related Questions