2016-05-04 99 views
1

我是JavaFX的新手。我正在嘗試構建一個示例性大學管理應用程序,其中我有一個帶有表格視圖的儀表板(dashboard.fxml)以填充學生數據。如何在插入新數據後重新加載JavaFX tableview?

有一個按鈕可以加載(newStduent.fxml)學生數據輸入窗口並存儲到數據庫。數據插入表後,我需要自動重新加載表。

下面的代碼處理加載另一個FXML文件newStudent.fxml,這是由AdmissionController.java

public void buildData(String SQL) 
    { 
     data = FXCollections.observableArrayList(); 
     try { 
      ResultSet rs = connection.createStatement().executeQuery(SQL); 
      while(rs.next()) 
      { 
       StudentMaster studentData = new StudentMaster(); 
       studentData.studentId.set(rs.getInt("student_id")); 
       studentData.stdClass.set(rs.getString("student_std")); 
       studentData.name.set(rs.getString("student_name")); 
       studentData.admNo.set(rs.getString("student_admn_no")); 
       studentData.regno.set(rs.getString("student_regno")); 
       studentData.stdDiv.set(rs.getString("student_div")); 
       data.add(studentData); 
       studentTable.setItems(data); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    @FXML 
    void initialize() { 
     assert studentTable != null : "fx:id=\"studentTable\" was not injected: check your FXML file 'dashboard.fxml'."; 
     assert studID != null : "fx:id=\"studID\" was not injected: check your FXML file 'dashboard.fxml'."; 
     assert studReg != null : "fx:id=\"studReg\" was not injected: check your FXML file 'dashboard.fxml'."; 
     assert stdAdm != null : "fx:id=\"stdAdm\" was not injected: check your FXML file 'dashboard.fxml'."; 
     assert stdName != null : "fx:id=\"stdName\" was not injected: check your FXML file 'dashboard.fxml'."; 
     assert stdClass != null : "fx:id=\"stdClass\" was not injected: check your FXML file 'dashboard.fxml'."; 
     assert stdDiv != null : "fx:id=\"stdDiv\" was not injected: check your FXML file 'dashboard.fxml'."; 

     loadDataToTable(); 

     DatabaseAccess newConnection = new DatabaseAccess(); 
     connection = newConnection.startConnection(); 
     String SQL = "Select * from student"; 
     buildData(SQL); 
     newConnection.shutdown(); 

    } 

    private void loadDataToTable() 
    { 
     studID.setCellValueFactory(new PropertyValueFactory<StudentMaster, Integer>("studentId")); 
     studReg.setCellValueFactory(new PropertyValueFactory<StudentMaster, String>("regno")); 
     stdName.setCellValueFactory(new PropertyValueFactory<StudentMaster, String>("name")); 
     stdAdm.setCellValueFactory(new PropertyValueFactory<StudentMaster, String>("admNo")); 
     stdClass.setCellValueFactory(new PropertyValueFactory<StudentMaster, String>("stdClass")); 
     stdDiv.setCellValueFactory(new PropertyValueFactory<StudentMaster, String>("stdDiv")); 
    } 

    @FXML 
    void createStudent(ActionEvent event) 
    { 
     FXMLLoader fxmlLoader; 
     fxmlLoader = new FXMLLoader(getClass().getResource("/resources/fxml/newStudent.fxml")); 
     try { 
      Parent root1 = (Parent)fxmlLoader.load(); 
      Stage stage = new Stage(); 
      stage.initModality(Modality.APPLICATION_MODAL); 
//   stage.initStyle(StageStyle.UNDECORATED); 
      stage.setTitle("New Admission"); 
      stage.setScene(new Scene(root1)); 
      stage.show(); 
     } catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    @FXML 
    void searchBtnClicked(ActionEvent event) 
    { 
     String name = nameBox.getText(); 
     String regno = regBox.getText(); 
     String admno = admBox.getText(); 
     String stdClass = classBox.getText(); 

     String SQL = "Select * from student where student_name like '"+name+"%'"; 
     System.out.println(SQL); 
     DatabaseAccess newConnection = new DatabaseAccess(); 
     connection = newConnection.startConnection(); 
     buildData(SQL); 
     newConnection.shutdown(); 
     loadDataToTable(); 
    } 

    public void reloadStudentTable() 
    { 
     loadDataToTable(); 
    } 

} 

AdmissionController.java處理內部事件Controller.java

以下事件處理數據插入並關閉窗口,但它在插入後不更新表視圖。

@FXML 
    void doneBtnClicked(ActionEvent event) 
    { 
     String name = nameBox.getText(); 
     String SQLquery = "INSERT INTO student (student_name) VALUES ('"+name+"')"; 
     ExecuteSQL newQuery = new ExecuteSQL(); 
     Boolean executeStatus = newQuery.ExecuteSQL(SQLquery); 
     System.out.println(executeStatus ? "Data Inserted" : "Error in execution");  


     //  Close the Window after successfully inserted 

     Node node = (Node)event.getSource(); 
     Stage stage = (Stage)node.getScene().getWindow(); 
     stage.close(); 
    } 

我試着撥打Controller.javareloadStudentTable()方法這樣

Controller reloadData = new Controller(); 
reloadData.reloadStudentTable(); 

但它產生一些像這樣的錯誤。

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:8411) 
    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: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) 
Data Inserted 
    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:497) 
    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:497) 
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) 
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769) 
    ... 48 more 
Caused by: java.lang.NullPointerException 
    at dashboard.Controller.loadDataToTable(Controller.java:132) 
    at dashboard.Controller.reloadStudentTable(Controller.java:178) 
    at dashboard.AdmissionController.doneBtnClicked(AdmissionController.java:72) 
    ... 58 more 
+0

發佈整個堆棧跟蹤。你的'loadDataToTable'方法只需要執行一次(來自'initialize()'方法:再次調用它什麼都不新)。一旦您操作了數據(例如添加更多項目到列表中),就不需要刷新表格,它會自動更新。但是如果沒有看到完整的堆棧跟蹤,並且您告訴我們哪條線路導致錯誤,那麼沒有人能真正幫助。 –

+0

@James_D對不起,我已經更新了完整的堆棧跟蹤。希望我會得到一些幫助。 – nitroman

回答

5

控制器中的@FXML -annotated字段由FXMLLoader當它加載FMXL初始化。如果您手動創建新的控制器實例(即Controller reloadData = new Controller();),那麼顯然這些字段將不會在該控制器實例中初始化。

無論如何,沒有必要調用reloadStudentTable方法。它所做的只是配置列,以便他們知道要顯示哪些數據;你不需要這樣做一次以上。所有你需要做的是新來的同學加入到表的數據列表:

data.add(new StudentMaster(...)); 

爲了做到這一點,你只需要簡單的AdmissionController具有對數據的引用:

public class AdmissionController { 

    private ObservableList<StudentMaster> data ; 

    public void setStudentData(ObservableList<StudentMaster> data) { 
     this.data = data ; 
    } 

    // existing code... 

    @FXML 
    void doneBtnClicked(ActionEvent event) 
    { 
     String name = nameBox.getText(); 
     String SQLquery = "INSERT INTO student (student_name) VALUES ('"+name+"')"; 
     ExecuteSQL newQuery = new ExecuteSQL(); 
     boolean executeStatus = newQuery.ExecuteSQL(SQLquery); 
     System.out.println(executeStatus ? "Data Inserted" : "Error in execution");  

     if (executeStatus) { 
      StudentMaster student = new StudentMaster(...); 
      data.add(student); 
     } 

     //  Close the Window after successfully inserted 

     Node node = (Node)event.getSource(); 
     Stage stage = (Stage)node.getScene().getWindow(); 
     stage.close(); 
    } 

    // ... 
} 

而且然後在你的主控制器上執行:

@FXML 
void createStudent(ActionEvent event) 
{ 
    FXMLLoader fxmlLoader; 
    fxmlLoader = new FXMLLoader(getClass().getResource("/resources/fxml/newStudent.fxml")); 
    try { 
     Parent root1 = (Parent)fxmlLoader.load(); 

     AdmissionController admissionController = fxmlLoader.getController(); 
     admissionController.setStudentData(studentTable.getItems()); 

     Stage stage = new Stage(); 
     stage.initModality(Modality.APPLICATION_MODAL); 
     stage.setTitle("New Admission"); 
     stage.setScene(new Scene(root1)); 
     stage.show(); 
    } catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 
+0

謝謝你的男人!我一直在尋找這個好幾天!像魅力一樣工作! – xadun

相關問題