0

Before we start this is not a duplicate. If you think it is please link a solution. I'm super new to Java and JavaFX.

As the title says, when keycode.A is pressed, I want to change the colour of an arc node.

Main.java

public class Main extends Application {


@Override
public void start(Stage primaryStage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("/sample/menu.fxml"));
    Scene scene = new Scene(root, 700, 400);

    primaryStage.setScene(scene);
    primaryStage.show();


}

MenuController

public class MenuController implements Initializable{

@FXML
private StackPane parentContainer;
@FXML
private AnchorPane anchorRoot;
@FXML
private Button btnGo;

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {

}

@FXML
private void keyFrameAnimation(MouseEvent mouseEvent) throws IOException {

    Parent root2 = FXMLLoader.load(getClass().getResource("/sample/maingame.fxml"));
    Scene scene = btnGo.getScene();
    root2.translateXProperty().set(scene.getWidth());
    parentContainer.getChildren().add(root2);

    Timeline timeLine = new Timeline();
    KeyValue kv = new KeyValue(root2.translateXProperty(), 0, Interpolator.EASE_IN);
    KeyFrame kf = new KeyFrame(Duration.seconds(1), kv);
    timeLine.getKeyFrames().add(kf);
    timeLine.setOnFinished(event -> {
        parentContainer.getChildren().remove(anchorRoot);
    });
    timeLine.play();

}

}

GameController

public class GameController implements Initializable {

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {

}

@FXML
private Arc arc;

@FXML
private void controlArc(KeyEvent event) throws IOException{
    Scene scene = arc.getScene();
    scene.setOnKeyPressed(ke -> {
        if (ke.getCode() == KeyCode.A) {
            arc.setFill(Color.BLUE);

        }
    });
}

FXML

menu.fxml

<StackPane fx:id="parentContainer" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.MenuController">
   <children>
      <AnchorPane fx:id="anchorRoot" prefHeight="400.0" prefWidth="381.0">
         <children>
            <Button fx:id="btnGo" layoutX="425.0" layoutY="167.0" mnemonicParsing="false" onMouseClicked="#keyFrameAnimation" text="Button" />
         </children>
      </AnchorPane>
   </children>
</StackPane>

maingame.fxml

<AnchorPane fx:id="anchorRoot2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"  prefHeight="400.0" prefWidth="700.0" style="-fx-background-color: black;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.GameController">

<children>
   <Arc fx:id="arc" fill="#fff91f" layoutX="312.0" layoutY="170.0" length="270.0" "radiusX="21.0" radiusY="18.0" startAngle="45.0" stroke="BLACK" strokeType="INSIDE" type="ROUND" />
</children>
</AnchorPane>

When the setOnKeyPressed() method is ran from the KeyFrameAnimation() method, the keycode is printed. However, it gives nullPointerException when trying to change colour of the arc.

When the setOnKeyPressed() method is ran from the GameController as it is in the code above, nothing happens.

I think maybe it's because im not loading the GameController? or am I way off?

TIA!

  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it). Please debug your code to find the location and variable that is `null`, then work your way through the code to find the missing initialization. – M. le Rutte Sep 24 '19 at 08:45

1 Answers1

3

There are multiple things to consider in this question: Firstly, there is a typo error in maingame.fxml

length="270.0" "radiusX="21.0"

which is an extra " just before radiusX. Not sure whether you fixed this.

Secondly, it would be more clear to us if you provide the stacktrace of NullPointerException to figure out where it is happening.

Thirdly, who is calling controlArc() method in GameController.java? As of now I couldnt find any code calling this method.

Lastly, to make it work, you need to move the code from controlArc() to initialize() method. which will be something like

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    Scene scene = arc.getScene();
    scene.setOnKeyPressed(ke -> {
        if (ke.getCode() == KeyCode.A) {
            arc.setFill(Color.BLUE);

        }
    });
}

At this stage you wil be encountering the NullPointerException, as scene will be null in initialize method. to fix this, the code should be changed to ..

public class GameController implements Initializable {

    @FXML
    private Arc arc;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        // Adding events to scene once it is loaded.
        arc.sceneProperty().addListener((obs, old, scene) -> {
            scene.setOnKeyPressed(ke -> {
                if (ke.getCode() == KeyCode.A) {
                    arc.setFill(Color.BLUE);
                }
            });
        });
    }
}
Sai Dandem
  • 8,229
  • 11
  • 26
  • Cool. That worked! So i needed to initialize the varibale and add a listener to update a node's property? Does that mean all the key events go in the intizialize method? –  Sep 25 '19 at 11:31
  • You can set events only if the node/scene is initialized. As you will not get scene by just merely loading the fxml, we listen for the scene to get loaded and when loaded we add the events. – Sai Dandem Sep 25 '19 at 22:30