Java 我所有的@FXML引用都为空

Java 我所有的@FXML引用都为空,java,javafx-8,fxml,playing-cards,Java,Javafx 8,Fxml,Playing Cards,我试图在流程窗格中显示扑克牌。我有一个主布局和一个嵌套布局。出于某种原因,当我调试IntelliJ报告时,两个控制器上用@FXML注释的所有字段都为空 这是我到目前为止得到的一个简短版本: MainWindow.fxml TableScene.fxml 我这辈子都搞不懂这个。我哪里出错了?我再次检查了我是否已在*.fxml文件的fx:controller属性中设置了控制器的名称。我还仔细检查了组件中的fx:id属性是否正确,以及它们是否与控制器中的@FXML注释正确匹配 我对JavaFX过程的理

我试图在流程窗格中显示扑克牌。我有一个主布局和一个嵌套布局。出于某种原因,当我调试IntelliJ报告时,两个控制器上用@FXML注释的所有字段都为空

这是我到目前为止得到的一个简短版本:

MainWindow.fxml TableScene.fxml 我这辈子都搞不懂这个。我哪里出错了?我再次检查了我是否已在*.fxml文件的
fx:controller
属性中设置了控制器的名称。我还仔细检查了组件中的
fx:id
属性是否正确,以及它们是否与控制器中的
@FXML
注释正确匹配

我对JavaFX过程的理解是:

  • load()
    应该加载*.fxml文件
  • 实例化控制器(由.fxml文件中的
    fx:controller
    属性指定)
  • 调用控制器上的无参数构造函数
  • 设置@FXML值(通过注入)
  • 注册任何事件处理程序
  • 在每个控制器上调用
    初始化
  • 嵌套的
    fxml
    文件有问题吗?如果是这种情况,我会认为
    MainWindowController.java
    中的@FXML字段也不会是
    null
    。我正在努力想办法解决这个问题。我需要另一双眼睛和一个比我更聪明的人


    提前感谢。

    花了一段时间才弄清楚,但是当您为场景创建控制器时,在
    initializeGame()中您会:

        var tableSceneController = new TableSceneController();
        var mainWindowController = new MainWindowController();
    
    这意味着您正在创建控制器的新实例,而不是在
    initializeMainWindow
    中加载FXML文件时创建的实例

    为了解决这个问题,我建议创建一个类变量来保存每个控制器,然后在加载FXML文件时分配它们

    因此,在
    BlackJackMain.java
    中,声明类变量

    private TableSceneController tableSceneController;
    private MainWindowController mainWindowController;
    
    然后,当您加载它们时,我可以看到您在
    initializeMainWindow
    中加载主窗口,因此添加

    mainWindowController = loader.getController();
    
    到try块,就在
    loader.load
    行之后


    这将解析此场景的空指针,但我无法确定在何处或是否加载表scene FXML,因此您没有要传递到方法中的控制器实例。如果确实加载了该文件,请对其应用相同的逻辑以获取该控制器的实例。

    如果存在一个注入该字段的控制器实例,并不意味着该字段将注入到每个控制器实例。您不会仅仅因为向某些
    ArrayList
    添加了元素,就期望由
    new ArrayList()
    创建的列表包含元素……谢谢您的尝试。我实现了您建议的更改,但是,当我稍后尝试在代码中使用class变量时,仍然收到
    NullPointeException
    。原因:com.frijolie.blackjack.controller.BlackjackMain.initializeGame(BlackjackMain.java:71)上的java.lang.NullPointerException(BlackjackMain.java:49)@frijolie我可能是瞎子,但在
    initializeGame()
    中,它调用
    tablescenecontroller.getPlayerName()
    ,,我在
    表控制器中看不到它,我想我已经解决了。我做了一些重构,并从我的域对象中删除了一些依赖项注入,以使过程更加简单。它似乎在工作。现在开始在将卡片添加到列表时显示卡片。谢谢
    
    public class TableSceneController implements Initializable {
    
        @FXML
        private FlowPane dealerHandFlowPane;
    
        @FXML
        private FlowPane playerHandFlowPane;
    
        public void displayInitialHand(Player player) {
            var cards = new ArrayList<>(player.getHand().getCards());
            for (BlackjackCard card : cards) {
                if(player.getName().equals("Dealer")) {
                    dealerHandFlowPane.getChildren().add(new ImageView(getCardFace(card)));
                } else {
                    playerHandFlowPane.getChildren().add(new ImageView(getCardFace(card)));
                }
            }
        }
    
        public void displayHand(Player player) {
          var cards = new ArrayList<>(player.getHand().getCards());
        }
    
        public Image getCardFace(BlackjackCard card) {
            return new Image("/images/cards/" + card.getRank().getLetter()
                + card.getSuit().getLetter() + ".png");
        }
    
        public Image getCardBack() {
            String color[] = {"blue","red"};
            String design = "123";
            return new Image("/images/backs/" + color[0] + design.charAt(2));
        }
    
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            // nothing here in my code either
        }
    
    }
    
    public class BlackjackMain extends Application {
    
        private final String MAIN_WINDOW_PATH = "/fxml/MainWindow.fxml";
        private final String ICON_PATH = "/images/blackjack_icon.png";
        private final String MAIN_STYLE_PATH = "/css/MainWindow.css";
        private final String TABLE_STYLE_PATH = "/css/TableScene.css";
        private final Image MAIN_ICON = new Image(getClass().getResourceAsStream(ICON_PATH));
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            primaryStage.setTitle("Blackjack");
            // close the app gracefully when the 'X' is clicked
            primaryStage.setOnCloseRequest(e -> Platform.exit());
            primaryStage.centerOnScreen();
            primaryStage.setResizable(false);
            initializeMainWindow(primaryStage);
            primaryStage.getIcons().add(MAIN_ICON);
            primaryStage.show();
            primaryStage.toFront();
            initializeGame();
        }
    
        public void initializeMainWindow(Stage primaryStage) {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource(MAIN_WINDOW_PATH));
            try {
              Parent mainWindow = loader.load();
              Scene scene = new Scene(mainWindow,600,600);
              scene.getStylesheets().add(TABLE_STYLE_PATH);
              primaryStage.setScene(scene);
            } catch (IOException e) {
              System.err.println("There was a problem loading /fxml/MainWindow.fxml");
              e.printStackTrace();
            }
        }
    
        public void initializeGame() {
            var tableSceneController = new TableSceneController();
            var mainWindowController = new MainWindowController();
            Dealer dealer = new Dealer();
            List<Player> allPlayers = new ArrayList<>();
            var playerName = tableSceneController.getPlayerName();
            allPlayers.add(new BlackjackPlayer(playerName));
            BlackjackGame game = new BlackjackGame(dealer, allPlayers,
                mainWindowController, tableSceneController);
            game.playGame();
        }
    }
    
    public class BlackjackGame implements BlackjackGameRules {
    
        private List<Player> playerList;
        private Deck deck;
        private Shoe shoe;
        private final TableSceneController tableSceneController;
        private final MainWindowController mainWindowController;
    
        public BlackjackGame(Dealer dealer, List<Player> players,
            final MainWindowController mainWindowController,
            final TableSceneController tableSceneController) {
            Objects.requireNonNull(dealer,
                "You must provide a dealer to begin the game.");
            Objects.requireNonNull(players,
                "You must provide a list of players to begin the game.");
    
            playerList = new ArrayList<>();
    
            this.tableSceneController = tableSceneController;
            this.mainWindowController = mainWindowController;
    
            // add dealer first for easier future access
            playerList.add(dealer);
            playerList.addAll(players);
    
            deck = new Deck(BlackjackGameRules.NUMBER_OF_DECKS);
    
            // place the shuffled deck in the shoe
            shoe = new Shoe(deck.getDeck());
        }
    
        public void dealInitialCards() {
            for (Player player : playerList) {
                player.getHand().addCard(shoe.dealCard());
                player.getHand().addCard(shoe.dealCard());
            }
        }
    
        public boolean hasValidNumberOfPlayers() {
            // this number includes the dealer
            var numPlayers = playerList.size();
            return numPlayers >= BlackjackGameRules.MIN_PLAYERS &&
                numPlayers <= BlackjackGameRules.MAX_PLAYERS;
        }
    
        public List<Player> getPlayers() {
            return new ArrayList<>(playerList);
        }
    
        public Shoe getShoe() {
            return shoe;
        }
    
        public void playGame() {
            dealInitialCards();
    
            for(Player player: playerList) {
                tableSceneController.displayInitialHand(player);
            }
    
        }
    
    }
    
    Caused by: java.lang.NullPointerException
        at blackjack.controller.TableSceneController.displayInitialHand(TableSceneController.java:35)
        at blackjack.model.BlackjackGame.playGame(BlackjackGame.java:139)
        at blackjack.controller.BlackjackMain.initializeGame(BlackjackMain.java:70)
        at blackjack.controller.BlackjackMain.start(BlackjackMain.java:44)
    
        var tableSceneController = new TableSceneController();
        var mainWindowController = new MainWindowController();
    
    private TableSceneController tableSceneController;
    private MainWindowController mainWindowController;
    
    mainWindowController = loader.getController();