JavaFX使用fxml打开新窗口问题

JavaFX使用fxml打开新窗口问题,java,javafx,Java,Javafx,我正在开发一个密码管理程序。在此程序中打开新窗口时,它会在addEntry()鼠标单击事件上引发异常。我有一个打开主窗口的Main类(使用sample.fxml)和一个管理打开新窗口的Controller类(使用addNewEntryDialog.fxml)。这是我的密码: Main.java package sample; import javafx.application.Application; import javafx.fxml.FXML; import javafx.fxml.FX

我正在开发一个密码管理程序。在此程序中打开新窗口时,它会在
addEntry()
鼠标单击事件上引发异常。我有一个打开主窗口的
Main
类(使用
sample.fxml
)和一个管理打开新窗口的
Controller
类(使用
addNewEntryDialog.fxml
)。这是我的密码:

Main.java

package sample;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;

import java.io.IOException;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml"));
        primaryStage.setTitle("Password Manager");
        primaryStage.setScene(new Scene(root, 800, 600));
        primaryStage.show();
    }

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

package sample;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.ResourceBundle;

public class Controller implements Initializable {
    public ObservableList<Data> data;
    public TableView dbTable;
    public TableColumn siteColumn, usernameColumn, passwordColumn;

    public ToggleButton showPasswordToggle;


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        fillTable();
    }

    public void fillTable(){
        data = FXCollections.observableArrayList();
        String query = "SELECT * FROM accounts";

        try {
            Connection connection = connectToDatabase();
            ResultSet resultSet = connection.createStatement().executeQuery(query);

            while (resultSet.next()) {
                data.add(new Data(resultSet.getString(1), resultSet.getString(2), resultSet.getString(3)));
            }

            siteColumn.setCellValueFactory(new PropertyValueFactory("site"));
            usernameColumn.setCellValueFactory(new PropertyValueFactory("username"));
            passwordColumn.setCellValueFactory(new PropertyValueFactory("password"));

            dbTable.setItems(data);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @FXML
    public void addEntry() throws IOException {
        Stage stage = new Stage();
        Parent root = FXMLLoader.load(getClass().getResource("/addEntryDialog.fxml"));
        stage.setTitle("Add new entry");
        stage.setScene(new Scene(root, 800, 600));
        stage.show();
    }

查看您的
addEntryDialog.fxml
文件。此视图的控制器有以下定义:

<Pane ... fx:controller="sample.Controller>

那么问题出在哪里呢?调用addEntry()方法(鼠标单击事件)时会出现许多异常错误,因此请将堆栈跟踪添加到问题中。您没有包含sample.fxml/addEntryDialog.fxml文件或实际的错误消息/堆栈跟踪,因此无法确定问题出在哪里。您应该创建一个实际可运行的应用程序片段,因此重构数据库代码并包括Data domain对象。不过,仅使用堆栈跟踪将非常有帮助。好的,我将添加堆栈跟踪和fxml文件。我只需要addEntryView.fxml。单击“添加”按钮添加新表项时,siteColumn是表的一部分。所以我只需要从一个方法打开一个新窗口,我不关心表列。@UmbertoPalazzini没错,但您已经将
sample.Controller
定义为
addEntryView
对话框的控制器。这就是它抛出空指针异常的原因。创建新窗口涉及为其创建控制器,控制器被创建并在初始化过程中抛出NPE,因为
addEntryView
上没有列。
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>

<Pane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <TableView fx:id="dbTable" layoutX="4.0" layoutY="85.0" prefHeight="505.0" prefWidth="790.0">
        <columns>
          <TableColumn fx:id="siteColumn" prefWidth="263.0" text="Site" />
          <TableColumn fx:id="usernameColumn" prefWidth="263.0" text="Username" />
          <TableColumn fx:id="passwordColumn" prefWidth="263.0" text="Password" />
        </columns>
      </TableView>
      <GridPane layoutX="14.0" layoutY="27.0" prefHeight="25.0" prefWidth="263.0">
         <columnConstraints>
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
         </columnConstraints>
         <rowConstraints>
            <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
         </rowConstraints>
         <children>
            <Button fx:id="addNewEntry" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onMouseClicked="#addEntry" text="Add.." GridPane.columnIndex="0" />
            <Button fx:id="removeEntry" layoutX="83.0" layoutY="14.0" mnemonicParsing="false" text="Remove.." GridPane.columnIndex="1" />
            <Button fx:id="editEntry" layoutX="178.0" layoutY="14.0" mnemonicParsing="false" text="Edit.." GridPane.columnIndex="2" />
         </children>
      </GridPane>
      <ToggleButton fx:id="showPasswordToggle" layoutX="671.0" layoutY="27.0" mnemonicParsing="false" text="Show Password" />
   </children>
</Pane>
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:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
    at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
    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:352)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:388)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
    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.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:745)
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)
    ... 31 more
Caused by: javafx.fxml.LoadException: 
/home/umberto/passwordManager/out/production/passwordManager/addEntryDialog.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at sample.Controller.addEntry(Controller.java:58)
    ... 41 more
Caused by: java.lang.NullPointerException
    at sample.Controller.loadTableData(Controller.java:45)
    at sample.Controller.initialize(Controller.java:30)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    ... 49 more
<Pane ... fx:controller="sample.Controller>