2013-03-08 238 views
5

我有控制器,在那裏我試圖從電子郵件服務器獲取INBOX文件夾。隨着下載一切正常。我可以將這些數據(電子郵件主題,來自日期)放到TableView中,但是......只有當我等待負責在TableView中設置此數據的線程時。 代碼:JavaFX初始化方法中的NullPointerException

// The table and columns 
@FXML 
TableView<MainModel.Item> itemTbl; 
@FXML 
TableColumn itemNameCol; 
@FXML 
TableColumn itemQtyCol; 
@FXML 
TableColumn itemTitleCol; 
// The table's data 
static ObservableList<MainModel.Item> data; 

public void dataSet(){ 
    // Set up the table data 
    itemNameCol.setCellValueFactory(
     new PropertyValueFactory<MainModel.Item,String>("name") 
    ); 
    itemQtyCol.setCellValueFactory(
     new PropertyValueFactory<MainModel.Item,String>("qty") 
    ); 
    itemTitleCol.setCellValueFactory(
     new PropertyValueFactory<MainModel.Item,String>("title") 
    ); 

    data = FXCollections.observableArrayList(); 
    itemTbl.setItems(data); 
} 

public void setEnemyEvent() { 
    itemTbl.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { 
     @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) 

這出現在不同的位置,在14個電子郵件,30個電子郵件。你有一些想法?

p.s我不能等待這個下載,因爲它需要20秒。有50封電子郵件 - 我必須在初始化過程中完成。

+0

不要用與它們的Class相同的大小寫命名變量。 – 2013-03-08 22:13:32

+1

「數據」未初始化,將其初始化。 – 2013-03-08 22:17:11

+0

我已初始化它(數據在其他文件中):) – user2150038 2013-03-08 22:27:38

回答

10

你的錯誤

不要修改任何連接到活動場景圖中的任何其他線程比JavaFX應用程序線程。

背景信息

此規則的說明,請參閱JavaFX Concurrency TutorialUsage of JavaFX Platform.runLater and access to UI from a different thread

隨着數據列表是一個ObservableList支持顯示在活動場景圖一個TableView,爲您修改ObservableList,他們就觸發改變事件的TableView中從用戶線程,而不是JavaFX應用程序線程修改它 - 這將導致競爭條件和不一致的程序故障。

如何解決它

要解決你的問題,敷調用來更新內部Platform.runLater數據項:

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

提交Platform.runLaterrun方法的內容在執行JavaFX應用程序線程。