【问题标题】:Java: Refreshing my jTable after data updates in child jDialogJava:在子 jDialog 中的数据更新后刷新我的 jTable
【发布时间】:2017-10-29 18:01:17
【问题描述】:

我已经围绕这个问题调查了很多不同的问题和答案,但找不到一个似乎有效的问题和答案。

我是 Java 新手,但有多种不同语言的经验,到目前为止(在我正在试验的上下文中),它感觉有点像 VBA,除了必须建立动作/您认为应该已经存在的功能。我想,这只是我自己缺乏经验所致。

我将 Netbeans IDE 8.2 与 Java Runtime 1.80 一起使用。

我创建了包含 jTable 的 jFrame。 jTable 是用如下数据构建的:

public void showTasks(Boolean removeID) {
    ArrayList<Tasks> list = tasksList("SELECT * FROM tasks");
    JTable table = jTable1;
    DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
    Object[] row = new Object[4];
    for(int i=0;i<list.size();i++) {
        row[0]=list.get(i).getId();
        row[1]=list.get(i).getName();
        row[2]=list.get(i).getDesc();
        row[3]=list.get(i).getDate();
        model.addRow(row);
    }
    // Remove the 'id' column from the table view 
    if(removeID) {    table.removeColumn(table.getColumnModel().getColumn(0)); }
}

这背后的背景不太相关,但本质上,taskList 是一个将查询应用于 SQL 语句的函数,返回一个 ArrayList。我用 4 列构建了我的行,然后删除了第一列,因此“ID”可用但不可见(此最终操作已通过测试/实验隔离)。

我有另一个代码区域,当单击一行时会打开一个 jDialog,其中可以更新 MySQL 数据库。

问题

我试图抛出一个函数调用,以便在 jDialog 关闭时“刷新”表数据。我暂时在 jFrame(jTable 所在的位置)中添加了一个按钮来测试/调试此功能。

不过,我似乎无法让它工作。我最接近的是重新调用 showTasks(false),但这显然只是添加了更新数据的行,而不是替换数据集。我不能 100% 确定是否删除所有行,然后重新构建它们是“最佳实践”。

由于我是 Java 新手,并且可能仍然从一种有缺陷的思维方法来看待它,我发现很难将任何其他示例应用于我自己的示例。我似乎也找不到实现fireTableDataChanged()的方法。

这肯定是我想多了的简单概念?

编辑 - 基于以下答案

如果删除所有行并将它们重新添加是可以的,是否有理由认为这样的事情不正确?

public void refreshTasks() {
    DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
    int row_total = model.getRowCount();
    for(int i= row_total -1;i>=0;i--) {
        model.removeRow(i);
    }
 showTasks(false);
}

编辑:调用数据更新的按钮

现在可以正常工作(如果不是不正确的话):

private DefaultTableModel parentTable;      // To store the parent 'Task' table model

public void setStart(int user,DefaultTableModel table) {

  this.txt_taskID.setText(Integer.toString(user)); // Converts the ID to a string
  addData(user);          // Populates the fields
  parentTable = table;    // Sets parent TableModel to a variable

}

上面的代码在对话框打开时从父 jFrame 调用,并传递表格模型和我要编辑的行的“ID”。表模型存储在parentTable

还有一个“保存”按钮和一个“取消”按钮。我还没有将这些分开,目前“保存”就是这样做的(SQL 更新等)。我的“取消”按钮关闭对话框并刷新 jTable,按照以下功能:

private void btn_CancelActionPerformed(java.awt.event.ActionEvent evt) { 

    this.setVisible(false);            // Hide the dialog
    Menu menu = new Menu();            // for accessing the tasksList function

    parentTable.setRowCount(0);        // Clears the jTable data

    // jTable data is then 'rebuilt' using the new data

    ArrayList<Tasks> list = menu.tasksList("SELECT * FROM tasks");
    Object[] row = new Object[4];
    for(int i=0;i<list.size();i++) {
        row[0]=list.get(i).getId();
        row[1]=list.get(i).getName();
        row[2]=list.get(i).getDesc();
        row[3]=list.get(i).getDate();
        parentTable.addRow(row);
    }
} 

【问题讨论】:

    标签: java mysql swing netbeans-8


    【解决方案1】:

    我不能 100% 确定是否删除所有行,然后重新构建它们是“最佳实践”。

    是的,这可能是最佳做法。

    唯一的其他方法是创建一个全新的 TableModel 并使用 setModel() 方法将其添加到表中。这种方法的问题是它会重置您可能在桌面上设置的任何自定义渲染器/编辑器。

    从 DefaultTableModel 中删除所有行的最简单方法是使用:

    model.setRowCount(0);
    

    【讨论】:

    • 谢谢 - 这无疑是一种更精简的删除当前行的方法。由于某种原因我还没有发现,我无法从jDialog调用函数refreshTasks,通过使用println作为调试方法,我可以看到调用是正确的,但它只是不想修改表模型。 refreshTasks 函数通过使用表单上的按钮按预期工作,但不是远离 jDialog。
    • @ChrisJ,在创建对话框时传递对 TableModel 的引用。然后,当用户单击“保存”按钮时,您只需更新 TableModel 中的数据。表格将自行重新绘制。
    • 谢谢 - 设法让它按要求工作,并根据您的建议更新了我的代码!
    【解决方案2】:

    我不知道你想怎么做,但我会给你一个简单的例子来删除和刷新JTable也许对你有帮助。

    以下btnDelete Jbutton 添加到JFrame 用于从表中删除行:

    btnDelete.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int rowIndex = table.getSelectedRow();
                if(rowIndex > -1) {
                    int x = (Integer) table.getModel().getValueAt(rowIndex, 0);
                    if (conn.removeContact(x) == true) { //here add your own code like removeID
    
                        model.removeRow(rowIndex);
                        lblInfo.setText("Contact deleted successfully.");
                        model.fireTableDataChanged();
                    } else {
                        lblInfo.setText("Cannot remove at this time!");
                    }
                }else {
                    lblInfo.setText("At first you need select a row with single click!");
                    return;
                }
            }
        });
    

    以及以下用于以原始方式刷新表格的代码:

    btnRefresh.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int rowCount = model.getRowCount();
                for (int i = rowCount - 1; i >= 0; i--) {//remove all rows
    
                    model.removeRow(i);
                }
                lblInfo.setText("Table datas updated successfully.");
    
                for (Person p : conn.readAllContacts()) {//add all row from scratch
                    model.addRow(new Object[] { p.getId(), p.getName(), p.getLastName(), p.getPhone(), p.getEmail() });
                }
    
            }
        });
    

    【讨论】:

    • 感谢您的 cmets。如果删除和重建数据是一种有效/可接受的方式来解决这个问题,那么像这样更简洁的人是否有缺陷/不正确? (见编辑过的问题)
    • @ChrisJ 不,这不是错误的,但不是最好的方法。
    • (1-) 不要调用 fireTableDataChanged(...)。调用该方法是 TableModel 的责任,而不是应用程序。在任何情况下,只删除了一行,因此这不是模型调用的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    相关资源
    最近更新 更多