打开csv文件时在javafx中同时使用两个控制器类时出现NullPointerException

打开csv文件时在javafx中同时使用两个控制器类时出现NullPointerException,javafx,nullpointerexception,javafx-8,Javafx,Nullpointerexception,Javafx 8,我有两个类PersonOverviewController和RootLayoutController 我正试图从RootLayoutController导入一个csv文件,并通过RootLayoutController的onLoad()方法在PersonOverViewController中创建的TableView中显示它。。但是他给了我一个例外 package example.address.view; import example.address.MainApp; import examp

我有两个类
PersonOverviewController
RootLayoutController
我正试图从
RootLayoutController
导入一个csv文件,并通过
RootLayoutController
onLoad()
方法在
PersonOverViewController
中创建的
TableView
中显示它。。但是他给了我一个例外

package example.address.view;

import example.address.MainApp;
import example.address.model.Person;
import example.address.util.DateUtil;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;

public class PersonOverviewController {
    @FXML
    public TableView<Person> personTable;
    @FXML
    public TableColumn<Person, String> firstNameColumn;
    @FXML
    public TableColumn<Person, String> lastNameColumn;

    @FXML
    public Label firstNameLabel;
    @FXML
    public Label lastNameLabel;
    @FXML
    private Label streetLabel;
    @FXML
    private Label postalCodeLabel;
    @FXML
    private Label cityLabel;
    @FXML
    private Label birthdayLabel;
    @FXML 
    private Button btnLoad = new Button("Load");
    // Reference to the main application.
    private MainApp mainApp;


    /**
     * The constructor.
     * The constructor is called before the initialize() method.
     */
    public PersonOverviewController() {
    }


    /**
     * Fills all text fields to show details about the person.
     * If the specified person is null, all text fields are cleared.
     * 
     * @param person the person or null
     */
    private void showPersonDetails(Person person) {
        if (person != null) {
            // Fill the labels with info from the person object.
            firstNameLabel.setText(person.getFirstName());
            lastNameLabel.setText(person.getLastName());
            streetLabel.setText(person.getStreet());
            postalCodeLabel.setText(Integer.toString(person.getPostalCode()));
            cityLabel.setText(person.getCity());

            // TODO: We need a way to convert the birthday into a String! 
            birthdayLabel.setText(DateUtil.format(person.getBirthday()));
            // birthdayLabel.setText(...);
        } else {
            // Person is null, remove all the text.
            firstNameLabel.setText("");
            lastNameLabel.setText("");
            streetLabel.setText("");
            postalCodeLabel.setText("");
            cityLabel.setText("");
            birthdayLabel.setText("");
        }
    }

    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {
        // Initialize the person table with the two columns.
        firstNameColumn.setCellValueFactory(
                cellData -> cellData.getValue().firstNameProperty());
        lastNameColumn.setCellValueFactory(
                cellData -> cellData.getValue().lastNameProperty());

        // Clear person details.
        showPersonDetails(null);

        // Listen for selection changes and show the person details when changed.
        personTable.getSelectionModel().selectedItemProperty().addListener(
                (observable, oldValue, newValue) -> showPersonDetails(newValue));
    }

    /**
     * Is called by the main application to give a reference back to itself.
     * 
     * @param mainApp
     */
    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;

        // Add observable list data to the table
        personTable.setItems(mainApp.getPersonData());
    }

    /**
     * Called when the user clicks on the delete button.
     */
    @FXML
    private void handleDeletePerson() {
        int selectedIndex = personTable.getSelectionModel().getSelectedIndex();
        if (selectedIndex >= 0) {
            personTable.getItems().remove(selectedIndex);
        } else {
            // Nothing selected.
            Alert alert = new Alert(AlertType.WARNING);
            alert.initOwner(mainApp.getPrimaryStage());
            alert.setTitle("No Selection");
            alert.setHeaderText("No Person Selected");
            alert.setContentText("Please select a person in the table.");

            alert.showAndWait();
        }
    }

    /**
     * Called when the user clicks the new button. Opens a dialog to edit
     * details for a new person.
     */
    @FXML
    private void handleNewPerson() {
        Person tempPerson = new Person();
        boolean okClicked = mainApp.showPersonEditDialog(tempPerson);
        if (okClicked) {
            mainApp.getPersonData().add(tempPerson);
        }
    }

    /**
     * Called when the user clicks the edit button. Opens a dialog to edit
     * details for the selected person.
     */
    @FXML
    private void handleEditPerson() {


        Person selectedPerson = personTable.getSelectionModel().getSelectedItem();
        if (selectedPerson != null) {
            boolean okClicked = mainApp.showPersonEditDialog(selectedPerson);
            if (okClicked) {
                showPersonDetails(selectedPerson);

            }

        } else {
            // Nothing selected.
            Alert alert = new Alert(AlertType.WARNING);
            alert.initOwner(mainApp.getPrimaryStage());
            alert.setTitle("No Selection");
            alert.setHeaderText("No Person Selected");
            alert.setContentText("Please select a person in the table.");

            alert.showAndWait();
        }

    }

}

我该怎么办?

这可能是我的一个奇怪的重复:
String fname=scan.next();String lname=scan.nextLine()。在csv文件中,两个数据应位于同一行上,由coma分隔,下一行是另一个人的fname和lname的新集合。无论如何,要解决NullPointerException问题,您最好使用IDE调试器。
@FXML
-当加载FXML并创建控制器时,
fxmloader
会初始化带注释的字段。但是,在这里您可以手动创建控制器(
PersonOverviewController overView=new PersonOverviewController();
),因此这些字段不会被初始化。大概在某个地方,您实际加载了一个与
PersonOverviewController
关联的FXML文件:加载控制器时,您需要从
FXMLLoader
获取控制器。
package example.address.view;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Scanner;

import example.address.MainApp;
import example.address.model.Person;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.stage.FileChooser;

/**
 * The controller for the root layout. The root layout provides the basic
 * application layout containing a menu bar and space where other JavaFX
 * elements can be placed.
 * 
 * @author Marco Jakob
 */
public class RootLayoutController {

    // Reference to the main application
    private MainApp mainApp;
    public ArrayList<Contacts> list;
    private ListIterator<Contacts> LIT;
    FileChooser fc = new FileChooser();
    public ObservableList<Person> data;

    PersonOverviewController overView = new PersonOverviewController();
    /**
     * Is called by the main application to give a reference back to itself.
     * 
     * @param mainApp
     */
    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;
    }

    /**
     * Creates an empty address book.
     */
    @FXML
    private void handleNew() {
        mainApp.getPersonData().clear();
        mainApp.setPersonFilePath(null);
    }

    /**
     * Opens a FileChooser to let the user select an address book to load.
     */
    @FXML
    private void handleOpen() {
        FileChooser fileChooser = new FileChooser();

        // Set extension filter
        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
                "XML files (*.xml)", "*.xml");
        fileChooser.getExtensionFilters().add(extFilter);

        // Show save file dialog
        File file = fileChooser.showOpenDialog(mainApp.getPrimaryStage());

        if (file != null) {
            mainApp.loadPersonDataFromFile(file);
        }
    }

    /**
     * Saves the file to the person file that is currently open. If there is no
     * open file, the "save as" dialog is shown.
     */
    @FXML
    private void handleSave() {
        File personFile = mainApp.getPersonFilePath();
        if (personFile != null) {
            mainApp.savePersonDataToFile(personFile);
        } else {
            handleSaveAs();
        }
    }

    /**
     * Opens a FileChooser to let the user select a file to save to.
     */
    @FXML
    private void handleSaveAs() {
        FileChooser fileChooser = new FileChooser();

        // Set extension filter
        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
                "XML files (*.xml)", "*.xml");
        fileChooser.getExtensionFilters().add(extFilter);

        // Show save file dialog
        File file = fileChooser.showSaveDialog(mainApp.getPrimaryStage());

        if (file != null) {
            // Make sure it has the correct extension
            if (!file.getPath().endsWith(".xml")) {
                file = new File(file.getPath() + ".xml");
            }
            mainApp.savePersonDataToFile(file);
        }
    }

    /**
     * Opens an about dialog.
     */
    @FXML
    private void handleAbout() {
        Alert alert = new Alert(AlertType.INFORMATION);
        alert.setTitle("AddressApp");
        alert.setHeaderText("About");
        alert.setContentText("STY");

        alert.showAndWait();
    }

    /**
     * Opens the birthday statistics.
     */
    @FXML
    private void handleShowBirthdayStatistics() {
      mainApp.showBirthdayStatistics();
    }

    /**
     * Closes the application.
     */
    @FXML
    private void handleExit() {
        System.exit(0);
    }

    @FXML//Load CSV Data
    public void onLoad()throws IOException {

        data = FXCollections.observableArrayList();//Hold data for the table

        File fileInfo = new File("C:/A_CSV/People.csv");
        if(fileInfo.length()==0) {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Information");
            alert.setHeaderText("");
            alert.setContentText("No Data in File at "+ fileInfo+"\n"+
            "Enter Data and Save");
            alert.showAndWait();
            return;  
        }

        fc.setTitle("Load Contacts Info");
        fc.setInitialDirectory(new File("C:/"));
        fc.setInitialDirectory(new File("C:/A_CSV"));
        fc.setInitialFileName("People.csv");
        File file = fc.showOpenDialog(null);
        if (file == null) {
        return;
        }

        String correctFile = file.getName();
        if(!(correctFile.matches("People.csv"))){
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Information");
            alert.setHeaderText("");
            alert.setContentText("The File at " + file + "\n\n"+
            "is NOT accociated with this application\n\n"+
            "Select the File at "+fileInfo);
            alert.showAndWait();
            return;
        }

        Path dirP = Paths.get(String.valueOf(file));
        InputStream in = Files.newInputStream(dirP);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));

        list = new ArrayList<Contacts>();
        Scanner scan = new Scanner(reader);
        scan.useDelimiter(",");
//        scan.useDelimiter("\\s*,\\s*");

        while (scan.hasNext()){
           String fname = scan.next();
           String lname = scan.nextLine();
           lname = lname.replaceAll(",", "");
           overView.firstNameLabel.setText(String.valueOf(fname));
           overView.lastNameLabel.setText(String.valueOf(lname));

           list.add(new Contacts(fname,lname));
           data.add(new Person(fname,lname));
           overView.personTable.setItems(data);

           overView.firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
           overView.lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());

        }
        scan.close();

        LIT = list.listIterator();                  
        if (LIT.hasNext()){          
            Contacts p = LIT.next();
            getContacts(p); 
        } 
    }

    public void getContacts(Contacts p){
        overView.firstNameLabel.setText("" + p.getFName());
        overView.lastNameLabel.setText("" + p.getLName());
    }
}
    Feb 15, 2016 1:28:39 PM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 8.0.65 by JavaFX runtime of version 8.0.45
Feb 15, 2016 1:28:43 PM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 8.0.65 by JavaFX runtime of version 8.0.45
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.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.control.MenuItem.fire(Unknown Source)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(Unknown Source)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$341(Unknown Source)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer$$Lambda$343/4980353.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.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$350(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$326/15265021.get(Unknown Source)
at com.sun.javafx.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$145(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/3326003.run(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)
... 47 more
Caused by: java.lang.NullPointerException
at example.address.view.RootLayoutController.onLoad(RootLayoutController.java:198)
... 56 more