JavaFX初始化方法中的NullPointerException

我有控制器,我尝试从电子邮件服务器获取INBOX文件夹。 随着下载一切都很好。 我可以把这些数据(电子邮件主题,从,日期)放到TableView中但是……只有当我在等待负责在TableView中设置这个数据的线程时。 码:

// The table and columns @FXML TableView itemTbl; @FXML TableColumn itemNameCol; @FXML TableColumn itemQtyCol; @FXML TableColumn itemTitleCol; // The table's data static ObservableList data; public void dataSet(){ // Set up the table data itemNameCol.setCellValueFactory( new PropertyValueFactory("name") ); itemQtyCol.setCellValueFactory( new PropertyValueFactory("qty") ); itemTitleCol.setCellValueFactory( new PropertyValueFactory("title") ); data = FXCollections.observableArrayList(); itemTbl.setItems(data); } public void setEnemyEvent() { itemTbl.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler() { @Override public void handle(MouseEvent event) { if (event.getClickCount() == 2) { if(itemTbl.getSelectionModel().getSelectedItem()!=null){ System.out.println(itemTbl.getSelectionModel().getSelectedItem().name); } } } }); } @Override public void initialize(URL url, ResourceBundle rb) { setEnemyEvent(); dataSet(); Thread t = new Thread(new MessageLoop()); //HERE: t.start(); //of course normally here is try and catch t.join(); } //staric nested class "for loop" private static class MessageLoop implements Runnable { public void run() { try { EmailConnetion con = new EmailConnetion(); MainModel MainModel = new MainModel(); for(int i=0;i<con.message.length;i++){ try{ MainModel.Item item = MainModel.new Item(); item.name.setValue(i+""+con.message[i].getFrom()[0].toString()); item.qty.setValue(con.message[i].getSentDate().toString()); item.title.setValue(con.message[i].getSubject().toString()); //Here is a problem. data.add(item);//This indicate my IDE //***************** } catch(AddressException e) { System.out.println("Error : " + "AddressException:"+i); } } } catch (NoSuchProviderException ex) { Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex); } catch (MessagingException ex) { Logger.getLogger(SimpleController.class.getName()).log(Level.SEVERE, null, ex); } } } 

当我删除t.join()时,它将抛出此NullPointerException。

 Exception in thread "Thread-3" java.lang.NullPointerException at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:291) at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:48) at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:74) at javafx.scene.control.TableView$TableViewArrayListSelectionModel$3.onChanged(TableView.java:1725) at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:134) at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:48) at com.sun.javafx.collections.ObservableListWrapper.callObservers(ObservableListWrapper.java:97) at com.sun.javafx.collections.ObservableListWrapper.clear(ObservableListWrapper.java:184) at javafx.scene.control.TableView$TableViewArrayListSelectionModel.quietClearSelection(TableView.java:2154) at javafx.scene.control.TableView$TableViewArrayListSelectionModel.updateSelection(TableView.java:1902) at javafx.scene.control.TableView$TableViewArrayListSelectionModel.access$2600(TableView.java:1681) at javafx.scene.control.TableView$TableViewArrayListSelectionModel$8.onChanged(TableView.java:1802) at com.sun.javafx.scene.control.WeakListChangeListener.onChanged(WeakListChangeListener.java:71) at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:291) at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:48) at com.sun.javafx.collections.ObservableListWrapper.callObservers(ObservableListWrapper.java:97) at com.sun.javafx.collections.ObservableListWrapper.add(ObservableListWrapper.java:154) at com.sun.javafx.collections.ObservableListWrapper.add(ObservableListWrapper.java:144) at javasplitpane.SimpleController$MessageLoop.run(SimpleController.java:95) at java.lang.Thread.run(Thread.java:722) 

这出现在不同的位置,在十四封电子邮件中,三十封电子邮件。 你有一些想法吗?

ps我不能等待下载,因为它需要20秒。 有50封电子邮件 – 我必须在初始化期间这样做。

你的错误

不要从JavaFX Application Thread以外的任何其他线程修改连接到活动场景图的任何内容。

背景资料

有关此规则的说明,请参阅JavaFX并发教程以及JavaFX Platform.runLater的用法以及从其他线程访问UI 。

由于您的数据列表是支持活动场景图中显示的TableView的ObservableList,因此当您修改ObservableList时,它会向TableView触发更改事件,从您的用户线程而不是JavaFX应用程序线程修改它 – 这会导致竞争条件和不一致的程序故障。

如何解决它

要解决您的问题,请将调用包装为更新Platform.runLater中的数据项:

 Platform.runLater(new Runnable() { @Override public void run() { data.add(item); } }); 

提交给Platform.runLaterrun方法的内容在JavaFX Application Thread上执行。