如何修复 "Null PointerException" 更改 KeyPressed 节点的填充颜色时

How to fix "Null PointerException" When changing the fill color of a node on KeyPressed

在我们开始之前,这不是重复的。如果你认为是请link解决。我是 Java 和 JavaFX 的超级新手。

正如标题所说,当按下keycode.A时,我想改变一个圆弧节点的颜色。

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();


}

菜单控制器

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();

}

}

游戏控制器

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>

setOnKeyPressed()方法从KeyFrameAnimation()方法变成运行时,打印键码。但是,它在尝试更改弧的颜色时给出 nullPointerException

setOnKeyPressed() 方法是来自 GameController 的 运行 时,就像在上面的代码中一样,没有任何反应。

我想可能是因为我没有加载 GameController?还是我跑题了?

TIA!

在这个问题中有很多事情需要考虑: 首先,maingame.fxml

有错别字
length="270.0" "radiusX="21.0"

这是一个额外的 ",就在 radiusX 之前。不确定你是否修复了这个问题。

其次,如果您提供 NullPointerException 的堆栈跟踪以找出它发生的位置,我们会更清楚。

第三,谁在GameController.java中调用controlArc()方法?截至目前,我找不到任何调用此方法的代码。

最后,要使其正常工作,您需要将代码从 controlArc() 移至 initialize() 方法。类似于

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

        }
    });
}

在此阶段您将遇到 NullPointerException,因为场景在初始化方法中将为 null。要解决此问题,应将代码更改为 ..

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);
                }
            });
        });
    }
}