插入新数据后如何重新加载JavaFX tableview? [英] How to reload a JavaFX tableview after inserting new data?

查看:55
本文介绍了插入新数据后如何重新加载JavaFX tableview?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是JavaFX的新手.我正在尝试构建一个示例大学管理应用程序,其中有一个带有表视图的仪表板(dashboard.fxml)来填充学生数据.

I am new to JavaFX. I was trying to build a sample college management application, where I have a dashboard(dashboard.fxml) with a table view to fill the student data.

有一个按钮可以加载(newStduent.fxml)学生数据输入窗口并将其存储到数据库.数据插入到表后,我需要自动重新加载表.

There is a button that loads(newStduent.fxml) the student data input window and stores to the database. I need to automatically reloads the table after the data gets inserted to the table.

以下代码处理 Controller.java 中的事件,该事件将加载另一个fxml文件 newStudent.fxml ,该文件由 AdmissionController.java 处理

Following code handles the Event inside Controller.java that loads another fxml file newStudent.fxml, which is handled by 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

以下事件处理数据插入并关闭窗口,但插入后不会更新表视图.

The following event handles the data insertion and closes the window, but it does not updates the table view after insertion.

@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.java内部调用reloadStudentTable()方法

I tried to call the reloadStudentTable() method inside the Controller.java like this

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

但是它会产生这样的错误.

But it generate some error like this.

    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

推荐答案

FXMLLoader在加载FMXL时初始化控制器中带@FXML注释的字段.如果您手动创建一个新的控制器实例(即Controller reloadData = new Controller();),那么显然这些字段将不会在该控制器实例中初始化.

The @FXML-annotated fields in a controller are initialized by the FXMLLoader when it loads the FMXL. If you create a new controller instance by hand (i.e. Controller reloadData = new Controller();), then obviously those fields will not be initialized in that controller instance.

无论如何都不需要调用reloadStudentTable方法.它所做的只是配置列,以便他们知道要显示哪些数据.您不需要多次执行该操作.您需要做的就是将新学生添加到表格的数据列表中:

There is no need to call the reloadStudentTable method anyway. All it does is configure the columns so they know which data to display; you do not need to do that more than once. All you need to do is add the new student to the table's data list:

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

为此,您只需要AdmissionController即可引用数据:

In order to do this, you simply need the AdmissionController to have a reference to the data:

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();
    }  

    // ...
}

然后在您的主控制器中执行:

And then in your main controller do:

@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();
    }
}

这篇关于插入新数据后如何重新加载JavaFX tableview?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆