Java 更新ListView会导致NullPointerException

Java 更新ListView会导致NullPointerException,java,listview,javafx,nullpointerexception,updating,Java,Listview,Javafx,Nullpointerexception,Updating,我正在尝试更新一个ListView,这会在执行list.setItems(newObList)时导致java.lang.NullPointerException,尝试将ObservableList引用更改为一个新的更新列表,但没有任何效果。首先清除列表,然后重置项目也会导致NullPointerException。还尝试将项目设置为null,然后将其重置,还尝试了NullPointerException。我只是感到困惑,我不知道如何解决这个问题。请引导我 异常发生在list.setItems(o

我正在尝试更新一个ListView,这会在执行list.setItems(newObList)时导致java.lang.NullPointerException,尝试将ObservableList引用更改为一个新的更新列表,但没有任何效果。首先清除列表,然后重置项目也会导致NullPointerException。还尝试将项目设置为null,然后将其重置,还尝试了NullPointerException。我只是感到困惑,我不知道如何解决这个问题。请引导我

异常发生在
list.setItems(obList)中的
refreshData()
方法中语句。当按下第二阶段中的关闭按钮(“插入新单词”阶段)时,该按钮调用
closeInsertWord()
方法,该方法调用
refreshData()
方法。我只使用一个名为
MainController.java
的控制器类

public class MainController implements Initializable{

@FXML
private ListView<String> list;


@FXML
TextField iWord, iMeanings, iSyn, iAnt;


public AVLTree dictTree;
public ArrayList<String> aList;
ObservableList<String> obList;

@Override
public void initialize(URL location, ResourceBundle resources)
{
    dictTree = readData();
}

public void fillList()
{

    aList = new ArrayList<>();

    aList.add("Word: meaning1, meaning2, ... , meaningN / a synonym * an antonym");
    dictTree.inOrder(aList);

    obList = FXCollections.observableArrayList(aList);
    list.setItems(obList);
}
堆栈跟踪:

    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.EventDispatchChainImp`enter code here`l.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:381)
    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$354(GlassViewEventHandler.java:417)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
    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$148(WinApplication.java:191)
    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 MainController.refreshData(MainController.java:155)
    at MainController.closeInsertWord(MainController.java:161)
    ... 58 more
主阶段FXML文件的内容(MainUI.FXML):


closeInsertWord()
在控制器上为第二个FXML文件调用,作为该文件中定义的按钮的处理程序。该FXML文件中没有带有
fx:id=“list”
的元素,因此该控制器中的list为null。因此,当调用
list.setItems()
时,会出现null指针异常

对于与两个不同FXML文件关联的控制器,使用同一个类通常是一个坏主意,因为很难跟踪每个不同控制器实例中哪些字段已初始化,哪些字段为空

为每个FXML文件创建不同的控制器类。加载该文件时,将数据传递给它所需的第二个控制器

比如:

public class MainController implements Initializable{

    @FXML
    private ListView<String> list;

    private AVLTree dictTree;

    @Override
    public void initialize(URL location, ResourceBundle resources)
    {
        dictTree = readData();
    }

    public void fillList()
    {

        List<String> aList = new ArrayList<>();
        String data = "Word: meaning1, meaning2, ... , meaningN / a synonym * an antonym";
        aList.add(data);
        dictTree.inOrder(aList);

        list.getItems.add(data);
    }

    public void openInsertWord() throws Exception
    {
        Stage primaryStage2 = new Stage();

        FXMLLoader loader = new FXMLLoader(getClass().getResource("InsertUI.fxml"));
        Parent root = FXMLLoader.load();

        InsertWordController controller = loader.getController();
        // seems like these two things really contain the same information...
        // I don't think you need both of them?
        controller.setDictTree(dictTree);
        controller.setItemsList(list.getItems());

        primaryStage2.setTitle("Insert a word");
        primaryStage2.getIcons().add(new Image("file:icon.png"));
        primaryStage2.setScene(new Scene(root));
        primaryStage2.setResizable(false);
        primaryStage2.initStyle(StageStyle.UNDECORATED);
        primaryStage2.show();
    }
}
public类MainController实现可初始化{
@FXML
私有列表视图列表;
私有AVLTree树;
@凌驾
公共void初始化(URL位置、ResourceBundle资源)
{
dictTree=readData();
}
公共无效填充列表()
{
列表列表=新的ArrayList();
String data=“单词:meaning1,meaning2,…,meaningN/a同义词*反义词”;
添加(数据);
目录树。有序(列表);
list.getItems.add(数据);
}
public void openInsertWord()引发异常
{
阶段primaryStage2=新阶段();
FXMLLoader=newFXMLLoader(getClass().getResource(“InsertUI.fxml”);
父根=fxmloader.load();
InsertWordController=loader.getController();
//看起来这两个东西包含了相同的信息。。。
//我不认为你们两个都需要?
控制器。设置目录树(目录树);
controller.setItemsList(list.getItems());
primaryStage2.setTitle(“插入单词”);
添加(新图像(“文件:icon.png”);
primaryStage2.setScene(新场景(根));
primaryStage2.可设置大小(false);
primaryStage2.initStyle(StageStyle.UNDECORATED);
primaryStage2.show();
}
}
然后是第二个FXML文件的控制器:

public class InsertWordController {

    @FXML
    private TextField iWord;
    @FXML
    private TextField iMeanings ;
    @FXML
    private TextField iSyn ;
    @FXML
    private TextField iAnt ;

    private AVLTree dictTree ;
    private List<String> itemsList ;

    public void setDictTree(AVLTree dictTree) {
        this.dictTree = dictTree ;
    }

    public void setItemsList(List<String> itemsList) {
        this.itemsList = itemsList ;
    }

    public void closeInsertWord()
    {
        iWord.getScene().getWindow().hide();
        String data = "Word: meaning1, meaning2, ... , meaningN / a synonym * an antonym" ;
        List<String> aList = new ArrayList<>();
        aList.add(data);
        dictTree.inOrder(aList);
        itemsList.add(data);
    }
}
公共类InsertWordController{
@FXML
私有文本域iWord;
@FXML
私有文本字段;
@FXML
私有文本字段iSyn;
@FXML
私有文本字段;
私有AVLTree树;
私人物品清单;
公共void setDictTree(AVLTree dictTree){
this.dictTree=dictTree;
}
公共无效集合项目列表(列表项目列表){
this.itemsList=itemsList;
}
public void closeInsertWord()
{
iWord.getScene().getWindow().hide();
String data=“单词:meaning1,meaning2,…,meaningN/a同义词*反义词”;
列表列表=新的ArrayList();
添加(数据);
目录树。有序(列表);
itemsList.add(数据);
}
}

当然,还要更改第二个FXML文件中的
fx:controller
属性。

发布完整的堆栈跟踪和FXML。异常发生在哪里?在调用
fillList()
期间?或在
refreshData()期间
?如果是,从何处调用该方法?@James\u D All已更新。已添加所有内容。在控制器上为第二个FXML文件调用了
closeInsertWord()
。该FXML文件中没有包含
fx:id=“list”的元素“
,因此该控制器中的
列表
为空。因此,当调用
list.setItems()
时,会出现空指针异常。首先为不同的控制器创建不同的类:当您为不同的FXML文件的控制器使用相同的类时,这太令人困惑了(正如您所发现的)。您可以使用我尝试了多个控制器/嵌套控制器,将
列表视图的支持列表传递给第二个控制器(这样它就可以向其中添加内容),但由于混淆和失败,因此我恢复为1个控制器。那我就得学了。你向我推荐一种特定的资源吗?我将尝试传递支持列表(我不知道存在这样的事情),并让您知道结果。谢谢“还原回1控制器”。当然,你是说“一个控制器类”。您仍然有两个控制器。我所说的“支持列表”是指从
list.getItems()
中获得的列表,即
ListView
显示的数据列表。经过一些修改,以适应我所拥有的,它工作得完美无瑕!非常感谢你给我这么多时间:)
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.effect.InnerShadow?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="698.0" prefWidth="582.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
   <children>
      <Label layoutX="257.0" layoutY="42.0" text="Dictionary" textFill="#720000">
         <font>
            <Font name="System Bold" size="14.0" />
         </font>
      </Label>
      <ListView fx:id="list" layoutX="22.0" layoutY="72.0" prefHeight="148.0" prefWidth="541.0">
         <effect>
            <InnerShadow blurType="TWO_PASS_BOX" />
         </effect></ListView>
      <MenuBar prefHeight="20.0" prefWidth="582.0">
        <menus>
          <Menu mnemonicParsing="false" text="File">
            <items>
              <MenuItem fx:id="load" mnemonicParsing="false" onAction="#fillList" text="Load Data" />
                  <MenuItem fx:id="export" mnemonicParsing="false" onAction="#export" text="Export to a file" />
                  <MenuItem fx:id="close" mnemonicParsing="false" onAction="#close" text="Close" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Available Operations">
            <items>
              <MenuItem fx:id="InsertNew" mnemonicParsing="false" onAction="#openInsertWord" text="Insert new word" />
                  <MenuItem fx:id="showPost" mnemonicParsing="false" text="Show Postfix Expressions" />
                  <MenuItem fx:id="evPost" mnemonicParsing="false" text="Evaluate Postfix Expressions" />
            </items>
          </Menu>
        </menus>
      </MenuBar>
   </children>
</AnchorPane>
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>


<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="297.0" prefWidth="503.0" style="-fx-border-color: #720000; -fx-border-width: 3;" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
   <children>
      <Label layoutX="176.0" layoutY="23.0" text="Insert a new word" textFill="#720000">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Label>
      <Label layoutX="32.0" layoutY="74.0" text="Word">
         <font>
            <Font name="System Bold" size="13.0" />
         </font>
      </Label>
      <Label layoutX="32.0" layoutY="116.0" text="Meaning(s)">
         <font>
            <Font name="System Bold" size="13.0" />
         </font>
      </Label>
      <Label layoutX="32.0" layoutY="159.0" text="Synonym">
         <font>
            <Font name="System Bold" size="13.0" />
         </font>
      </Label>
      <Label layoutX="32.0" layoutY="204.0" text="Antonym">
         <font>
            <Font name="System Bold" size="13.0" />
         </font>
      </Label>
      <TextField fx:id="iWord" layoutX="134.0" layoutY="71.0" />
      <TextField fx:id="iMeanings" layoutX="134.0" layoutY="113.0" prefHeight="25.0" prefWidth="355.0" />
      <TextField fx:id="iSyn" layoutX="134.0" layoutY="156.0" />
      <TextField fx:id="iAnt" layoutX="134.0" layoutY="201.0" />
      <Button layoutX="355.0" layoutY="245.0" mnemonicParsing="false" onAction="#insertWord" text="Insert" textFill="#720000">
         <font>
            <Font name="System Bold" size="16.0" />
         </font>
      </Button>
      <Button layoutX="444.0" layoutY="263.0" mnemonicParsing="false" onAction="#closeInsertWord" text="close" />
   </children>
</AnchorPane>
public class MainController implements Initializable{

    @FXML
    private ListView<String> list;

    private AVLTree dictTree;

    @Override
    public void initialize(URL location, ResourceBundle resources)
    {
        dictTree = readData();
    }

    public void fillList()
    {

        List<String> aList = new ArrayList<>();
        String data = "Word: meaning1, meaning2, ... , meaningN / a synonym * an antonym";
        aList.add(data);
        dictTree.inOrder(aList);

        list.getItems.add(data);
    }

    public void openInsertWord() throws Exception
    {
        Stage primaryStage2 = new Stage();

        FXMLLoader loader = new FXMLLoader(getClass().getResource("InsertUI.fxml"));
        Parent root = FXMLLoader.load();

        InsertWordController controller = loader.getController();
        // seems like these two things really contain the same information...
        // I don't think you need both of them?
        controller.setDictTree(dictTree);
        controller.setItemsList(list.getItems());

        primaryStage2.setTitle("Insert a word");
        primaryStage2.getIcons().add(new Image("file:icon.png"));
        primaryStage2.setScene(new Scene(root));
        primaryStage2.setResizable(false);
        primaryStage2.initStyle(StageStyle.UNDECORATED);
        primaryStage2.show();
    }
}
public class InsertWordController {

    @FXML
    private TextField iWord;
    @FXML
    private TextField iMeanings ;
    @FXML
    private TextField iSyn ;
    @FXML
    private TextField iAnt ;

    private AVLTree dictTree ;
    private List<String> itemsList ;

    public void setDictTree(AVLTree dictTree) {
        this.dictTree = dictTree ;
    }

    public void setItemsList(List<String> itemsList) {
        this.itemsList = itemsList ;
    }

    public void closeInsertWord()
    {
        iWord.getScene().getWindow().hide();
        String data = "Word: meaning1, meaning2, ... , meaningN / a synonym * an antonym" ;
        List<String> aList = new ArrayList<>();
        aList.add(data);
        dictTree.inOrder(aList);
        itemsList.add(data);
    }
}