为什么实例变量在JavaFX中变空

时间:2016-08-27 07:49:33

标签: javafx

我在界面开发中使用场景构建器,当我在我的controller.java文件中加载FXML文件时,我得到了我的layout.fxml文件中定义的HBox,它工作正常。但是当我在这些HBoxes中定义的内容上添加onMouseClicked属性并实现controller.java文件中的方法时,它会抛出空指针异常。它将所有HBoxes变量设置为null。这是controller.java文件的代码

package application;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;


public class Main extends Application {

    private  HBox subTabPaneAppendData;
    private  HBox subTabPaneRecord;
    private  HBox subTabPaneSetting;

    @Override
    public void start(Stage primaryStage) {

        startActivity(primaryStage);
    }

    public void startActivity(Stage primaryStage){

        try {
            Parent root = FXMLLoader.load(getClass().getResource("/application/Layout.fxml"));
            Scene scene = new Scene(root,1400,800);

            //getting all the HBoxes from layout.fxml file

            subTabPaneAppendData = (HBox) root.lookup("#subTabPaneAppendData");
            subTabPaneRecord = (HBox) root.lookup("#subTabPaneRecord");
            subTabPaneSetting = (HBox) root.lookup("#subTabPaneSetting");

            subTabPaneAppendData.setVisible(true);
            subTabPaneRecord.setVisible(false);
            subTabPaneSetting.setVisible(false);

            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }


    public void appendDataOnClicked() throws IOException{

        //here all the variables are null

        subTabPaneAppendData.setVisible(true);
        subTabPaneRecord.setVisible(false);
        subTabPaneSetting.setVisible(false);
    }

    public void recordOnClicked() throws IOException{

        //here all the variables are null

        subTabPaneAppendData.setVisible(true);
        subTabPaneRecord.setVisible(false);
        subTabPaneSetting.setVisible(false);
    }

    public void searchOnClicked(){      

        //here all the variables are null

        subTabPaneAppendData.setVisible(false);
        subTabPaneRecord.setVisible(false);
        subTabPaneSetting.setVisible(false);
    }

    public void settingOnClicked(){

        //here all the variables are null

        subTabPaneAppendData.setVisible(false);
        subTabPaneRecord.setVisible(false);
        subTabPaneSetting.setVisible(true);
    }

    public void helpOnClicked(){

        //here all the variables are null

        subTabPaneAppendData.setVisible(false);
        subTabPaneRecord.setVisible(false);
        subTabPaneSetting.setVisible(false);
    }


    public static void main(String[] args) {
        launch(args);
    }
}

1 个答案:

答案 0 :(得分:1)

您没有使用Main实例start被称为控制器。

使用fx:controller="application.Main",您告诉FXMLLoader创建Main的新实例作为控制器。恕我直言,这是不好的,原因如下:
Application类包含一些东西,你的控制器不需要让这个类比没有充分理由需要更大。

此外,您查找的Node将写入由javafx平台运行的Main实例的字段,而不是写入用作控制器的字段的字段。由于新实例的方法用作事件处理程序,因此您为字段为null的实例调用方法,这会导致NPE。

使用与Main不同的类作为控制器会好得多。此外,您可以FXMLLoader使用目标字段名称作为值的fx:id属性自动设置字段,并确保FXMLLoader可以访问该字段(public @FXML }或注释package application; ... public class LayoutController { @FXML private HBox subTabPaneAppendData; @FXML private HBox subTabPaneRecord; @FXML private HBox subTabPaneSetting; @FXML private void initialize() { subTabPaneAppendData.setVisible(true); subTabPaneRecord.setVisible(false); subTabPaneSetting.setVisible(false); } public void appendDataOnClicked() throws IOException { subTabPaneAppendData.setVisible(true); subTabPaneRecord.setVisible(false); subTabPaneSetting.setVisible(false); } public void recordOnClicked() throws IOException { subTabPaneAppendData.setVisible(true); subTabPaneRecord.setVisible(false); subTabPaneSetting.setVisible(false); } public void searchOnClicked() { subTabPaneAppendData.setVisible(false); subTabPaneRecord.setVisible(false); subTabPaneSetting.setVisible(false); } public void settingOnClicked() { subTabPaneAppendData.setVisible(false); subTabPaneRecord.setVisible(false); subTabPaneSetting.setVisible(true); } public void helpOnClicked() { subTabPaneAppendData.setVisible(false); subTabPaneRecord.setVisible(false); subTabPaneSetting.setVisible(false); } } ):

控制器类

 ...
 <... xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.LayoutController">
 ...
     <HBox fx:id="subTabPaneAppendData" ...
     ...
     <HBox fx:id="subTabPaneRecord" ...
     ...
     <HBox fx:id="subTabPaneSetting" ...
  ...

fxml文件

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function ($scope) {
  $scope.oneAtATime = true;

  $scope.groups = [
    {
      title: 'Dynamic Group Header - 1',
      content: 'Dynamic Group Body - 1'
    },
    {
      title: 'Dynamic Group Header - 2',
      content: 'Dynamic Group Body - 1'
    },
    {
      title: 'Dynamic Group Header - 3',
      content: 'Dynamic Group Body - 1'
    },
    {
      title: 'Dynamic Group Header - 4',
      content: 'Dynamic Group Body - 1'
    },
    {
      title: 'Dynamic Group Header - 5',
      content: 'Dynamic Group Body - 2'
    }
  ];
  


  $scope.item = {
      title: 'Dynamic Group Header - The new!!!',
      content: 'Dynamic Group Body - 20'
    } 
    

  $scope.addItem = function() {
    $scope.groups.push($scope.item);
    
    $scope.isOpen = true;
  };

  $scope.status = {
    isFirstOpen: true,
    isFirstDisabled: false
  };
});