JavaFX-将数据从TableView选择填充到对话框

JavaFX-将数据从TableView选择填充到对话框,javafx,dialog,tableview,populate,Javafx,Dialog,Tableview,Populate,我正在学习从TableView的选定行获取数据,并使用该数据预填充对话框。无论我在加载对话框时做什么,我都会在Controller.java->showEditContactDialog()->editController.setItem(item))中获得NullPointerException。不知何故,我无法将所选数据传递给另一个类,并使其在对话框中显示。感谢有人给我指出正确的方向。代码如下: Main.java: package sample; import javafx.applic

我正在学习从TableView的选定行获取数据,并使用该数据预填充对话框。无论我在加载对话框时做什么,我都会在Controller.java->showEditContactDialog()->editController.setItem(item))中获得NullPointerException。不知何故,我无法将所选数据传递给另一个类,并使其在对话框中显示。感谢有人给我指出正确的方向。代码如下:

Main.java:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import sample.datamodel.ContactData;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
        primaryStage.setTitle("Address Book");
        primaryStage.setScene(new Scene(root, 1280, 500));
        primaryStage.show();            
    }

    @Override
    public void stop(){
             ContactData.getInstance().saveContacts();
    }
}
Controller.java:

package sample;

    @FXML
    private TableView<Contact> tableView;   

    @FXML
    private BorderPane mainBorderPane;

    private Contact item;

    public Controller() {
    }

    @FXML
    public TableView<Contact> getTableView() {
        return tableView;
    }

    @FXML
    public void initialize(){
        loadContacts();
        tableView.setOnMouseClicked((MouseEvent event) -> {
                    if (event.getClickCount() > 0) {
                        item = tableView.getSelectionModel().getSelectedItem(); // *** get selection from TableView ***

                    }
                });
    }

    @FXML
    public void handleExit(){
        ContactData.getInstance().saveContacts();
        Platform.exit();
    }

    public void saveContacts() {
        ContactData.getInstance().saveContacts();
    }

    public void loadContacts() {
        ContactData.getInstance().loadContacts(); 
        tableView.setItems(ContactData.getInstance().getContacts()); 
    }

    public void deleteContact(){
        ContactData.getInstance().deleteContact(item);
    }

    public void showAddContactDialog(ActionEvent event) throws IOException {
        Dialog<ButtonType> dialog = new Dialog<>();
        dialog.initOwner(mainBorderPane.getScene().getWindow());
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(getClass().getResource("addContact.fxml"));
        try{
            dialog.getDialogPane().setContent(fxmlLoader.load());
           }catch(IOException e){
            System.out.println("Couldn't load the dialog");
            e.printStackTrace();
            return;
        }
        Optional<ButtonType> result = dialog.showAndWait();
        if(result.isPresent()){
           Dialog controller = fxmlLoader.getController();
        }
    }

    public void showEditContactDialog() throws Exception {
        Dialog<ButtonType> dialog = new Dialog<>();
        dialog.initOwner(mainBorderPane.getScene().getWindow());
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(getClass().getResource("editContact.fxml"));
        EditContactController editController = fxmlLoader.<EditContactController>getController();
        editController.setItem(item); // ****** trying to pass "item" but get NullPointerException *********   
        try{
            dialog.getDialogPane().setContent(fxmlLoader.load()); 
        } catch (IOException e) {
            System.out.println("Couldn't load the dialog");
            e.printStackTrace();
            return;
        }
        Optional<ButtonType> result = dialog.showAndWait(); 
    }
  }
editContact.fxml:

    <?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<GridPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.EditContactController">
    <HBox GridPane.columnSpan="2">
        <Label text="Edit contact">
            <font>
                <Font name="System Bold" size="17.0" />
            </font>
            <padding>
                <Insets bottom="10.0" left="10.0" />
            </padding></Label>
    </HBox>
    <Label text="First Name" GridPane.columnIndex="0" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1">
        <GridPane.margin>
            <Insets left="10.0" />
        </GridPane.margin>
        <padding>
            <Insets bottom="5.0" />
        </padding></Label>
    <Label text="Last Name" GridPane.columnIndex="0" GridPane.rowIndex="2">
        <GridPane.margin>
            <Insets bottom="5.0" left="10.0" />
        </GridPane.margin></Label>
    <Label text="Phone number" GridPane.columnIndex="0" GridPane.rowIndex="3">
        <GridPane.margin>
            <Insets bottom="5.0" left="10.0" />
        </GridPane.margin></Label>
    <Label text="Notes" GridPane.columnIndex="0" GridPane.rowIndex="4">
        <GridPane.margin>
            <Insets bottom="5.0" left="10.0" />
        </GridPane.margin></Label>

    <TextField fx:id="fName" GridPane.columnIndex="1" GridPane.rowIndex="1">
        <GridPane.margin>
            <Insets bottom="5.0" />
        </GridPane.margin></TextField>
    <TextField fx:id="lName" GridPane.columnIndex="1" GridPane.rowIndex="2">
        <GridPane.margin>
            <Insets bottom="5.0" />
        </GridPane.margin></TextField>
    <TextField fx:id="pNumber" GridPane.columnIndex="1" GridPane.rowIndex="3">
        <GridPane.margin>
            <Insets bottom="5.0" />
        </GridPane.margin></TextField>
    <TextArea fx:id="nNotes" GridPane.columnIndex="1" GridPane.rowIndex="4">
    <GridPane.margin>
        <Insets bottom="5.0" />
    </GridPane.margin></TextArea>
    <HBox alignment="TOP_RIGHT" spacing="5.0" GridPane.columnIndex="1" GridPane.rowIndex="5">
        <Button text="Edit">
            <opaqueInsets>
                <Insets />
            </opaqueInsets></Button>
        <Button fx:id="cancelButton" cancelButton="true" onAction="#cancelButtonAction" text="Cancel" />
        <opaqueInsets>
            <Insets />
        </opaqueInsets>
        <GridPane.margin>
            <Insets />
        </GridPane.margin>
        <padding>
            <Insets bottom="5.0" left="5.0" right="5.0" />
        </padding>
    </HBox>


    <columnConstraints>
        <ColumnConstraints maxWidth="288.0" minWidth="22.0" prefWidth="129.0" />
        <ColumnConstraints maxWidth="578.0" minWidth="312.0" prefWidth="471.0" />
    </columnConstraints>
    <rowConstraints>
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
    </rowConstraints>
    <padding>
        <Insets left="5.0" right="5.0" top="5.0" />
    </padding>
    <opaqueInsets>
        <Insets />
    </opaqueInsets>

    </GridPane>

您的控制器类在FXML文件中指定,因此
FXMLLoader
在读取该文件之前无法实例化它。这意味着控制器仅在调用
load()
期间创建,在此之前调用
fxmloader.getController()
将返回null

因此,您需要移动检索控制器并对其执行操作的代码,以便在调用
load()
后执行:


Controller.java缺少导入部分和类定义。您也可以发布堆栈跟踪吗?谢谢,您将是一名优秀的导师,解释得再清楚不过了!另一方面,在对showEditContactDialog()方法应用更改后,InteliJ报告不会引发异常。无论如何,再次感谢你,它现在工作得很好。
    <?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<GridPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.EditContactController">
    <HBox GridPane.columnSpan="2">
        <Label text="Edit contact">
            <font>
                <Font name="System Bold" size="17.0" />
            </font>
            <padding>
                <Insets bottom="10.0" left="10.0" />
            </padding></Label>
    </HBox>
    <Label text="First Name" GridPane.columnIndex="0" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1">
        <GridPane.margin>
            <Insets left="10.0" />
        </GridPane.margin>
        <padding>
            <Insets bottom="5.0" />
        </padding></Label>
    <Label text="Last Name" GridPane.columnIndex="0" GridPane.rowIndex="2">
        <GridPane.margin>
            <Insets bottom="5.0" left="10.0" />
        </GridPane.margin></Label>
    <Label text="Phone number" GridPane.columnIndex="0" GridPane.rowIndex="3">
        <GridPane.margin>
            <Insets bottom="5.0" left="10.0" />
        </GridPane.margin></Label>
    <Label text="Notes" GridPane.columnIndex="0" GridPane.rowIndex="4">
        <GridPane.margin>
            <Insets bottom="5.0" left="10.0" />
        </GridPane.margin></Label>

    <TextField fx:id="fName" GridPane.columnIndex="1" GridPane.rowIndex="1">
        <GridPane.margin>
            <Insets bottom="5.0" />
        </GridPane.margin></TextField>
    <TextField fx:id="lName" GridPane.columnIndex="1" GridPane.rowIndex="2">
        <GridPane.margin>
            <Insets bottom="5.0" />
        </GridPane.margin></TextField>
    <TextField fx:id="pNumber" GridPane.columnIndex="1" GridPane.rowIndex="3">
        <GridPane.margin>
            <Insets bottom="5.0" />
        </GridPane.margin></TextField>
    <TextArea fx:id="nNotes" GridPane.columnIndex="1" GridPane.rowIndex="4">
    <GridPane.margin>
        <Insets bottom="5.0" />
    </GridPane.margin></TextArea>
    <HBox alignment="TOP_RIGHT" spacing="5.0" GridPane.columnIndex="1" GridPane.rowIndex="5">
        <Button text="Edit">
            <opaqueInsets>
                <Insets />
            </opaqueInsets></Button>
        <Button fx:id="cancelButton" cancelButton="true" onAction="#cancelButtonAction" text="Cancel" />
        <opaqueInsets>
            <Insets />
        </opaqueInsets>
        <GridPane.margin>
            <Insets />
        </GridPane.margin>
        <padding>
            <Insets bottom="5.0" left="5.0" right="5.0" />
        </padding>
    </HBox>


    <columnConstraints>
        <ColumnConstraints maxWidth="288.0" minWidth="22.0" prefWidth="129.0" />
        <ColumnConstraints maxWidth="578.0" minWidth="312.0" prefWidth="471.0" />
    </columnConstraints>
    <rowConstraints>
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
        <RowConstraints />
    </rowConstraints>
    <padding>
        <Insets left="5.0" right="5.0" top="5.0" />
    </padding>
    <opaqueInsets>
        <Insets />
    </opaqueInsets>

    </GridPane>
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8413)
    at javafx.scene.control.Button.fire(Button.java:185)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
    ... 48 more
Caused by: java.lang.NullPointerException
    at sample.Controller.showEditContactDialog(Controller.java:105)
    ... 58 more
public void showEditContactDialog() throws Exception {
    Dialog<ButtonType> dialog = new Dialog<>();
    dialog.initOwner(mainBorderPane.getScene().getWindow());
    FXMLLoader fxmlLoader = new FXMLLoader();
    fxmlLoader.setLocation(getClass().getResource("editContact.fxml"));

    try {

        Parent dialogContent = fxmlLoader.load();
        EditContactController editController = fxmlLoader.<EditContactController>getController();
        editController.setItem(item); 


        dialog.getDialogPane().setContent(dialogContent); 

    } catch (IOException e) {
        System.out.println("Couldn't load the dialog");
        e.printStackTrace();
        return;
    }
    Optional<ButtonType> result = dialog.showAndWait(); 
}
public void setItem(Contact item) {
    this.item = item;
    fName.setText(item.getFirstName());
}


@FXML
public void initialize(){

}