使用 JavaFX 切换场景时出现 InvocationTargetException

Posted

技术标签:

【中文标题】使用 JavaFX 切换场景时出现 InvocationTargetException【英文标题】:InvocationTargetException while switching scenes with JavaFX 【发布时间】:2017-09-11 21:06:32 【问题描述】:

我正在使用 JavaFX 并使用 .fxml 文件和相关的控制器类,在场景之间移动并具有按钮等功能。

我的 MainMenuController 关注我正在开发的游戏的菜单。 MainController 与我要加载的游戏板有关。但是每当我按下“启动游戏”按钮时,我都会收到这些错误:

javafx.fxml.LoadException: 
/C:/.../bin/client/ui/Main.fxml

cause: java.lang.NullPointerException
where: 
/C:/.../bin/client/ui/Main.fxml

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Node.fireEvent(Unknown Source)
at javafx.scene.control.Button.fire(Unknown Source)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Scene$MouseHandler.process(Unknown Source)
at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source)
at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(Unknown Source)
at com.sun.javaenter code herefx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.notifyMouse(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
... 49 more

Caused by: java.lang.NullPointerException: Root cannot be null
at javafx.scene.Scene.<init>(Unknown Source)
at javafx.scene.Scene.<init>(Unknown Source)
at client.ui.MainMenuController.handleButtonAction(MainMenuController.java:251)
... 58 more

对我来说,似乎是 MainController 导致了问题,并且 因此阻止 Main.fxml 加载。

这是 MainMenuController 的方法,其中“launchGame”应该切换到以 Main.fxml 为根的新场景(last else if(...) 指令):

@FXML
private void handleButtonAction(ActionEvent e) 
Stage stage = null;
Parent root = null;
try 

  if (e.getSource() == leaveBrowserButton) 
    stage = (Stage) leaveBrowserButton.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("PlayGameSelection.fxml"));
  
  if (e.getSource() == connect1Button) 
    stage = (Stage) connect1Button.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("Lobby.fxml"));
    StartUI.getClient().connect(0);
  
  if (e.getSource() == connect2Button) 
    StartUI.getClient().connect(1);
  
  if (e.getSource() == connect3Button) 
    StartUI.getClient().connect(2);
  
  if (e.getSource() == playGame) 
    stage = (Stage) playGame.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("PlayGameSelection.fxml"));
   else if (e.getSource() == login) 
    stage = (Stage) login.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("MainMenu.fxml"));
   else if (e.getSource() == createProfile) 
    stage = (Stage) createProfile.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("CreateNewPlayer.fxml"));
   else if (e.getSource() == goToMainMenu) 
    stage = (Stage) goToMainMenu.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("MainMenu.fxml"));
   else if (e.getSource() == goToCreateNewPlayer) 
    stage = (Stage) goToCreateNewPlayer.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("CreateNewPlayer.fxml"));
   else if (e.getSource() == backToLogin) 
    stage = (Stage) backToLogin.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("Login.fxml"));
   else if (e.getSource() == manageProfile) 
    stage = (Stage) manageProfile.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("ManagePlayer.fxml"));
   else if (e.getSource() == backToGame) 
    stage = (Stage) backToGame.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("Main.fxml"));
   else if (e.getSource() == backToMain || e.getSource() == goBackButton) 
    stage = (Stage) backToMain.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("MainMenu.fxml"));
   else if (e.getSource() == playLocalGame) 
    stage = (Stage) playLocalGame.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("Browser.fxml"));
   else if (e.getSource() == launchGame) 
    stage = (Stage) launchGame.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource("Main.fxml"));
    StartGameMessage startGame =
        new StartGameMessage(StartUI.getClient().getGamestate().whosTurnIsIt(), false, 0);
    StartUI.getClient().addMessage(startGame);
   else 
    stage = (Stage) playGame.getScene().getWindow();
    root = FXMLLoader.load(getClass().getResource(e.getClass().getName()));
  
 catch (Exception e1) 
  System.out.println(e1.getMessage());
  System.out.println(e1);
  System.out.println("cause: " + e1.getCause());
  System.out.println("where: " + e1.getLocalizedMessage());
  System.out.println(e1.getStackTrace());


Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();

我在 Main.fxml 文件中将控制器设置为 MainController,所以我看不到那里有问题:

<AnchorPane fx:id="anchorPane" prefHeight="720.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.ui.MainController">

这里是我的 MainController:

package client.ui;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;

import client.domain.DevelopmentCard;
import client.domain.NobleTile;
import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Glow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
import networkcommunication.domain.ActionTakeThreeTokens;
import networkcommunication.domain.ActionTakeTwoTokens;
import server.application.GameController;

public class MainController implements Initializable, Repaintable 

  @FXML
  protected ImageView top1;
  @FXML
  protected ImageView top2;
  @FXML
  protected ImageView top3;
  @FXML
  protected ImageView top4;
  @FXML
  protected ImageView center1;
  @FXML
  protected ImageView center2;
  @FXML
  protected ImageView center3;
  @FXML
  protected ImageView center4;
  @FXML
  protected ImageView bottom1;
  @FXML
  protected ImageView bottom2;
  @FXML
  protected ImageView bottom3;
  @FXML
  protected ImageView bottom4;
  @FXML
  protected ImageView tokenRed7;
  @FXML
  protected ImageView tokenBlack7;
  @FXML
  protected ImageView tokenBlue7;
  @FXML
  protected ImageView tokenYellow5;
  @FXML
  protected ImageView tokenGreen7;
  @FXML
  protected ImageView tokenWhite7;
  @FXML
  protected ImageView noble1;
  @FXML
  protected ImageView noble2;
  @FXML
  protected ImageView noble3;
  @FXML
  protected ImageView noble4;
  @FXML
  protected ImageView noble5;
  @FXML
  protected ImageView reserve1;
  @FXML
  protected ImageView reserve2;
  @FXML
  protected ImageView reserve3;
  @FXML
  protected ImageView buy1;
  @FXML
  protected AnchorPane anchorPane;

  @FXML
  protected ImageView currentPosition;

  @FXML
  protected VBox buyBox;
  @FXML
  protected Button reserve;
  @FXML
  protected Button buy;
  @FXML
  protected Button goToGameMenu;
  @FXML
  protected Button playGame;
  @FXML
  protected Button playLocalGame;
  @FXML
  protected Button backToMain;
  @FXML
  protected Text counterGameYellowToken;
  @FXML
  protected Label yellowGameLabel;
  @FXML
  protected Label blackGameLabel;
  @FXML
  protected Label blueGameLabel;
  @FXML
  protected Label greenGameLabel;
  @FXML
  protected Label whiteGameLabel;
  @FXML
  protected Label redGameLabel;
  @FXML
  protected Label yellowOwnLabel;
  @FXML
  protected Label blackOwnLabel;
  @FXML
  protected Label blueOwnLabel;
  @FXML
  protected Label greenOwnLabel;
  @FXML
  protected Label whiteOwnLabel;
  @FXML
  protected Label redOwnLabel;
  @FXML
  protected CheckBox checkBox;
  @FXML
  protected ColorAdjust colorConstant = new ColorAdjust();
  @FXML
  protected ImageView optionPreviewCard;
  @FXML
  protected HBox buyHbox;

  private int[] counter;
  private int[] saveInt = new int[] 0, 0, 0, 0, 0, 0;
  private int[] saveForThree = new int[] 0, 0, 0, 0, 0, 0;
  private int[] saveSpecificTokens = new int[] 0, 0, 0, 0, 0, 0;
  private int[] previousCounter = new int[] 0, 0, 0, 0, 0, 0;
  private Image forReserve;
  protected List<ImageView> devCardsLevelO;
  protected List<ImageView> devCardsLevelOO;
  protected List<ImageView> devCardsLevelOOO;
  protected List<ImageView> yellowTokens;
  protected List<ImageView> blackTokens;
  protected List<ImageView> redTokens;
  protected List<ImageView> blueTokens;
  protected List<ImageView> greenTokens;
  protected List<ImageView> whiteTokens;
  protected List<ImageView> nobleTilesImgV;
  protected List<DevelopmentCard> devCards1;
  protected List<DevelopmentCard> devCards2;
  protected List<DevelopmentCard> devCards3;
  protected List<NobleTile> nobleTiles;
  private List<Label> pressableTokens = new ArrayList<>();
  private List<Label> ownTokens = new ArrayList<>();
  @FXML
  protected Label player2view;
  @FXML
  protected SplitPane enemySplitPane;
  @FXML
  protected ImageView enemyReserve1;
  @FXML
  protected ImageView enemyReserve2;
  @FXML
  protected ImageView enemyReserve3;
  @FXML
  protected HBox enemyReserveBox;

  @FXML
  public void changeTokenCount(MouseEvent e) throws IOException 
    pressableTokens.addAll(
        Arrays.asList(blackGameLabel, whiteGameLabel, redGameLabel, greenGameLabel, blueGameLabel));
    ownTokens.addAll(
        Arrays.asList(blackOwnLabel, whiteOwnLabel, redOwnLabel, greenOwnLabel, blueOwnLabel));
    for (int cycle = 0; cycle < pressableTokens.size(); cycle++) 
      if (e.getSource() == pressableTokens.get(cycle) && counter[cycle] < 2) 

        previousCounter = counter.clone();
        counter[cycle]++;
        pressableTokens.get(cycle).setText("x" + Integer.toString(5 - counter[cycle]));
        ownTokens.get(cycle).setText("x" + Integer.toString(counter[cycle]));
        if (counter[cycle] == 2 && lastEntryPosition() == cycle) 
          System.out.println("I just pressed x" + pressableTokens.get(cycle).getId() + " twice!");
        
        if (counter[cycle] == 2) 
          pressableTokens.get(cycle).setDisable(true);
        
        if (tookThreeDifferentTokens()) 
          System.out.println("I just took three tokens");
          ActionTakeThreeTokens tookThree = new ActionTakeThreeTokens(
              StartUI.getClient().getGamestate().whosTurnIsIt(), saveSpecificTokens);
          StartUI.getClient().addMessage(tookThree);
          System.out.println(Arrays.toString(saveSpecificTokens));
          saveSpecificTokens = new int[] 0, 0, 0, 0, 0, 0;
        
        System.out.println("I just pressed: " + pressableTokens.get(cycle).getId());
        break;
      
    

    for (

        int i = 0; i < 4; i++) 
      setBrightness(devCardsLevelO.get(i), -0.2);
      setBrightness(devCardsLevelOO.get(i), -0.2);
      setBrightness(devCardsLevelOOO.get(i), -0.2);
      colorConstant.setBrightness(-0.2);

      if (devCards1.get(i).getPriceDiamond() <= counter[2]
          && devCards1.get(i).getPriceEmerald() <= counter[4]
          && devCards1.get(i).getPriceSapphire() <= counter[5]
          && devCards1.get(i).getPriceRuby() <= counter[3]
          && devCards1.get(i).getPriceOnyx() <= counter[1]) 
        setBrightness(devCardsLevelO.get(i), 0.35);
      
      if (devCards2.get(i).getPriceDiamond() <= counter[2]
          && devCards2.get(i).getPriceEmerald() <= counter[4]
          && devCards2.get(i).getPriceSapphire() <= counter[5]
          && devCards2.get(i).getPriceRuby() <= counter[3]
          && devCards2.get(i).getPriceOnyx() <= counter[1]) 
        setBrightness(devCardsLevelOO.get(i), 0.35);
      
      if (devCards3.get(i).getPriceDiamond() <= counter[2]
          && devCards3.get(i).getPriceEmerald() <= counter[4]
          && devCards3.get(i).getPriceSapphire() <= counter[5]
          && devCards3.get(i).getPriceRuby() <= counter[3]
          && devCards3.get(i).getPriceOnyx() <= counter[1]) 
        setBrightness(devCardsLevelOOO.get(i), 0.35);
      
    
    System.out.println("counter: " + Arrays.toString(counter) + "\tpreviousCounter: "
        + Arrays.toString(previousCounter) + "\tsaveThree: " + Arrays.toString(saveForThree)
        + "\tYou took those different tokens: " + Arrays.toString(saveSpecificTokens));
    System.out.println("");
  

  @FXML
  public void manageCardClick(MouseEvent e) throws IOException 
    if (e.getSource() == reserve) 
      setReserveImage(forReserve);
      buyBox.setVisible(false);
      counter[0]++;
      yellowGameLabel.setText("x" + Integer.toString(4 - counter[0]));
      yellowOwnLabel.setText("x" + Integer.toString(counter[0]));
     else if (e.getSource() == buy) 
      setBuyImage(forReserve);
      buyBox.setVisible(false);
      blackGameLabel
          .setText("x" + Integer.toString(5 - counter[1] + devCards1.get(1).getPriceOnyx()));
      blackOwnLabel.setText("x" + Integer.toString(counter[1] - devCards1.get(1).getPriceOnyx()));
      redGameLabel
          .setText("x" + Integer.toString(5 - counter[3] + devCards1.get(1).getPriceRuby()));
      redOwnLabel.setText("x" + Integer.toString(counter[3] - devCards1.get(1).getPriceRuby()));
      blueGameLabel
          .setText("x" + Integer.toString(5 - counter[5] + devCards1.get(1).getPriceSapphire()));
      blueOwnLabel
          .setText("x" + Integer.toString(counter[5] - devCards1.get(1).getPriceSapphire()));
      greenGameLabel
          .setText("x" + Integer.toString(5 - counter[4] + devCards1.get(1).getPriceEmerald()));
      greenOwnLabel
          .setText("x" + Integer.toString(counter[4] - devCards1.get(1).getPriceEmerald()));
      whiteGameLabel
          .setText("x" + Integer.toString(5 - counter[2] + devCards1.get(1).getPriceDiamond()));
      whiteOwnLabel
          .setText("x" + Integer.toString(counter[2] + devCards1.get(1).getPriceDiamond()));
    
  

  private int lastEntryPosition() 
    int out = -1;
    for (int i = 0; i < counter.length; i++) 
      if (counter[i] - previousCounter[i] != 0) 
        out = i;
        break;
      
    
    System.out.println("Position: " + out);
    return out;
  

  private boolean tookThreeDifferentTokens() 
    int countToThree = 0;
    for (int i = 0; i < counter.length; i++) 
      if (counter[i] - saveForThree[i] != 0) 
        countToThree++;
      
    
    System.out.println(countToThree);
    if (countToThree == 3) 
      for (int j = 0; j < counter.length; j++) 
        saveSpecificTokens[j] = counter[j] - saveForThree[j];
      
      saveForThree = counter.clone();
      return true;
     else 
      return false;
    
  

  @FXML
  protected void handleButtonAction(ActionEvent e) throws IOException 
    Stage stage;

    Parent root;

    if (e.getSource() == goToGameMenu) 
      stage = (Stage) goToGameMenu.getScene().getWindow();
      root = FXMLLoader.load(getClass().getResource("GameMenu.fxml"));
     else 
      stage = (Stage) playGame.getScene().getWindow();
      root = FXMLLoader.load(getClass().getResource("Main.fxml"));
    

    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();

  

  public void hideImgView(ImageView imgV) 
    imgV.setVisible(false);
  

  public void selectDevCard(ImageView imgV) 
    if (imgV.getScaleX() == 1.0) 
      imgV.setEffect(new Glow(0.7));
      imgV.setScaleX(1.15);
      imgV.setScaleY(1.15);
     else 
      DropShadow shadow = new DropShadow();
      imgV.setEffect(shadow);
      imgV.setScaleX(1.0);
      imgV.setScaleY(1.0);
    
  

  public void setReserveImage(Image im) throws IOException 
    if (reserve1.getImage() == null) 
      reserve1.setImage(im);
      setNewCard();
     else if (reserve2.getImage() == null) 
      reserve2.setImage(im);
      setNewCard();
     else if (reserve3.getImage() == null) 
      reserve3.setImage(im);
      setNewCard();

     else 
      Stage warning = new Stage();
      Parent root = FXMLLoader.load(getClass().getResource("Warning.fxml"));
      Scene warningScene = new Scene(root);
      warning.setScene(warningScene);
      warning.show();
      PauseTransition delay = new PauseTransition(Duration.seconds(5));
      delay.setOnFinished(e -> warning.close());
      delay.play();
    

  

  public void setBuyImage(Image im) 
    ImageView buyView = new ImageView(optionPreviewCard.getImage());
    buyView.fitHeightProperty().bind(buyHbox.heightProperty());
    buyView.setPreserveRatio(true);
    buyHbox.getChildren().add(buyView);
    setNewCard();
  

  public void setImageEffect(ImageView imageView, double brightness) 
    ColorAdjust colorAdjust = new ColorAdjust();
    colorAdjust.setBrightness(brightness);
    imageView.addEventFilter(MouseEvent.MOUSE_ENTERED, e -> imageView.setEffect(colorAdjust));
    imageView.addEventFilter(MouseEvent.MOUSE_EXITED, e -> imageView.setEffect(colorConstant));
  

  public void setBrightness(ImageView imageView, double brightness) 
    ColorAdjust colorAdjust = new ColorAdjust();
    colorAdjust.setBrightness(brightness);
    imageView.setEffect(colorAdjust);
  

  private void setNewCard() 
    for (int i = 0; i < 4; i++) 
      if (devCardsLevelO.get(i).getImage() == null) 
        devCardsLevelO.get(i)
            .setImage(new Image(this.getClass().getResourceAsStream(devCards1.get(4).getPath())));
      
      if (devCardsLevelOO.get(i).getImage() == null) 
        devCardsLevelOO.get(i)
            .setImage(new Image(this.getClass().getResourceAsStream(devCards2.get(4).getPath())));
      
      if (devCardsLevelOOO.get(i).getImage() == null) 
        devCardsLevelOOO.get(i)
            .setImage(new Image(this.getClass().getResourceAsStream(devCards3.get(4).getPath())));
      
    
  

  @Override
  public void initialize(URL location, ResourceBundle resources) 
    StartUI.getRepaintThread().addInterface(this);
    this.counter = new int[6];
    this.saveInt = new int[6];
    for (int i = 0; i < this.counter.length; i++) 
      this.counter[i] = 0;
      this.saveInt[i] = 0;
    

    this.devCardsLevelO = new ArrayList<ImageView>();
    this.devCardsLevelOO = new ArrayList<ImageView>();
    this.devCardsLevelOOO = new ArrayList<ImageView>();
    this.yellowTokens = new ArrayList<ImageView>();
    this.blackTokens = new ArrayList<ImageView>();
    redTokens = new ArrayList<ImageView>();
    this.blueTokens = new ArrayList<ImageView>();
    this.greenTokens = new ArrayList<ImageView>();
    this.whiteTokens = new ArrayList<ImageView>();
    this.nobleTilesImgV = new ArrayList<ImageView>();

    this.devCards1 = new ArrayList<DevelopmentCard>();
    this.devCards2 = new ArrayList<DevelopmentCard>();
    this.devCards3 = new ArrayList<DevelopmentCard>();
    this.nobleTiles = new ArrayList<NobleTile>();

    this.devCardsLevelO.addAll(Arrays.asList(bottom1, bottom2, bottom3, bottom4));
    this.devCardsLevelOO.addAll(Arrays.asList(center1, center2, center3, center4));
    this.devCardsLevelOOO.addAll(Arrays.asList(top1, top2, top3, top4));
    this.nobleTilesImgV.addAll(Arrays.asList(noble1, noble2, noble3, noble4, noble5));


    for (int i = 0; i < devCardsLevelO.size(); i++) 
      int k = i;
      setImageEffect(devCardsLevelO.get(k), 0.2);

      devCardsLevelO.get(i).setSmooth(true);
      devCardsLevelO.get(i).setOnMouseClicked(e -> 
        forReserve = devCardsLevelO.get(k).getImage();
        optionPreviewCard.setImage(forReserve);
        buyBox.setVisible(true);
        devCards1.get(k).setSelectable(false);
        devCardsLevelO.get(k).setImage(null);
      );

      setImageEffect(devCardsLevelOO.get(k), 0.2);
      devCardsLevelOO.get(k).setOnMouseClicked(e -> 
        buyBox.setVisible(true);
        forReserve = devCardsLevelOO.get(k).getImage();
        optionPreviewCard.setImage(forReserve);
        devCards2.get(k).setSelectable(false);
        devCardsLevelOO.get(k).setImage(null);
      );

      setImageEffect(devCardsLevelOOO.get(k), 0.2);
      devCardsLevelOOO.get(k).setOnMouseClicked(e -> 
        buyBox.setVisible(true);
        forReserve = devCardsLevelOOO.get(k).getImage();
        optionPreviewCard.setImage(forReserve);
        devCards3.get(k).setSelectable(false);
        devCardsLevelOOO.get(k).setImage(null);
      );
    

  

  @Override
  public void update() 
    Platform.runLater(new Runnable() 
      @Override
      public void run() 
        devCards1 = StartUI.getClient().getGamestate().getDevelopmentCardsLevelO();
        devCards2 = StartUI.getClient().getGamestate().getDevelopmentCardsLevelOO();
        devCards3 = StartUI.getClient().getGamestate().getDevelopmentCardsLevelOOO();
        nobleTiles = StartUI.getClient().getGamestate().getNobleTiles();
        for (int i = 0; i < nobleTilesImgV.size(); i++) 
          if (nobleTiles.get(i).isSelectable()) 
            nobleTilesImgV.get(i).setImage(
                new Image(this.getClass().getResourceAsStream(nobleTiles.get(i).getPath())));
          
        
        for (int i = 0; i < devCardsLevelO.size(); i++) 
          if (devCards1.get(i).isSelectable()) 
            devCardsLevelO.get(i).setImage(
                new Image(this.getClass().getResourceAsStream(devCards1.get(i).getPath())));
          
        
        for (int i = 0; i < devCardsLevelOO.size(); i++) 
          if (devCards2.get(i).isSelectable()) 
            devCardsLevelOO.get(i).setImage(
                new Image(this.getClass().getResourceAsStream(devCards2.get(i).getPath())));
          
        
        for (int i = 0; i < devCardsLevelOOO.size(); i++) 
          if (devCards3.get(i).isSelectable()) 
            devCardsLevelOOO.get(i).setImage(
                new Image(this.getClass().getResourceAsStream(devCards3.get(i).getPath())));
          
        
      
    );
  

我在这个漏洞上工作了一天,但仍然无法弄清楚是什么导致了这个错误。它开始变得非常令人沮丧,如果我们能解决这个问题,那就太棒了:)

【问题讨论】:

第一个错误告诉您在尝试加载 Main.fxml 时出现问题。由于加载失败,您有一个空根,并且您发布的异常表明场景无法加载空根。能否将e1.printStackTrace() 添加到catch 子句catch (Exception e1) ,再次运行并发布异常? 感谢您的快速回答!哇!我实际上可以用 e1.printStackTrace() 解决这个问题,因为它给了我一个额外的错误和问题的确切行。我没有在 System.out.print(e1.getStackTrace()) 中看到这一点。非常感谢! :) 【参考方案1】:

通过阅读您的 StackTrace,我看到以下行:Caused by: java.lang.NullPointerException: Root cannot be null。 这意味着您不能将 Root 设置为空。 在您的一个 sn-ps 中,您有以下几行:

@FXML private void handleButtonAction(ActionEvent e) Stage stage = null; Parent root = null;

您正在为您分配 Parent 以具有空值,这会导致您得到 NullPointException。我建议您删除分配给Parentnull 值。

【讨论】:

感谢您的快速回答!就是 root 保持为空。但是需要这些行来初始化阶段和根。问题是,应该为根分配 FXMLLoader.load(...)。这适用于我想切换到的所有其他场景,除了 Main.fxml。 FXMLLoader.load(getClass().getResource("Main.fxml"));返回 null 但我不明白为什么。

以上是关于使用 JavaFX 切换场景时出现 InvocationTargetException的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX 11:创建标签时出现 IllegalAccessError

JavaFX 11:创建标签时出现 IllegalAccessError

运行 JavaFx 媒体应用程序时出现模块错误

渲染大图像时出现javafx NullPointerException

更改 JavaFX 选项卡顺序时出现 NullPointerException

在 JavaFX 中更新 ListView 时出现 IndexOutOfBoundsException