【问题标题】:JTable is not appending data from databaseJTable 没有从数据库中追加数据
【发布时间】:2014-11-21 00:32:14
【问题描述】:

我有一个使用嵌入式 derby jdbc 和 jtable 设置的项目,但是当我尝试通过结果集将数据库中的数据附加到我的 jtable 并将结果集中的结果添加到 string[] 并将其添加到我的 tablemodel 结果显示为空白。

这是我的数据库结果集:

ResultSet res = statement.executeQuery("SELECT * FROM VAULT");
    while (res.next()) {
        String [] row = {res.getString("Expenses"), res.getString("ExpensesType"), res.getString("PaymentType"), res.getString("Amount"), res.getString("Date")};
        System.out.print(res.getString("Expenses"));
        System.out.print(res.getString("ExpensesType"));
        System.out.print(res.getString("PaymentType"));
        System.out.print(res.getString("Amount"));
        System.out.print(res.getString("Date"));

        GUI.tableModel.addRow(row);
        GUI.tableModel.fireTableDataChanged();
    }

    res.close();

这是我的表格代码:

table = new JTable(tableModel);
    table.setBackground(Color.GRAY);
    table.setFillsViewportHeight(true);
    JTableHeader header = table.getTableHeader();
    header.setBackground(Color.DARK_GRAY);
    header.setForeground(Color.LIGHT_GRAY);
    scrollPane.setViewportView(table);

    tableModel.addColumn("Expenses");
    tableModel.addColumn("Expense Type");
    tableModel.addColumn("Payment Type");
    tableModel.addColumn("Amount");
    tableModel.addColumn("Date");

【问题讨论】:

  • 你有什么错误吗?
  • 应该不需要调用fireTableDataChanged,这应该由表模型本身自动完成,永远不应该被外部调用。考虑提供一个runnable example 来证明您的问题。这将导致更少的混乱和更好的响应
  • @getlost 我没有收到任何错误
  • @MikeNguyen 你得到 System.out.print 正确吗?
  • @getlost 是的,我的系统输出是 CookieFoodChase Debit Card2.50Sep/25/2014,这是我作为测试导入的数据。

标签: java database swing jdbc jtable


【解决方案1】:

由于代码基本上可以正常工作,我不得不假设问题出在我无法复制的应用程序的其他部分,例如数据库管理......

不过……

您的资源管理不存在...数据库Statement 具有上下文并且与生成它的查询有直接关系,例如,一旦您完成使用它,您应该确保关闭它。 ..

public static Connection createDatabaseConnection() throws SQLException, ClassNotFoundException {
    //...
    System.out.println("Database Connected...");
    try (Statement statement = c.createStatement()) {
        count = statement.executeUpdate("CREATE TABLE VAULT (Expenses VARCHAR(5000), ExpensesType VARCHAR(5000), PaymentType VARCHAR(5000), Amount VARCHAR(10), Date VARCHAR(5000))");
        System.out.println("Table Created...");
    }

    try (Statement statement = c.createStatement()) {
        ResultSet res = statement.executeQuery("SELECT * FROM VAULT");
        while (res.next()) {
            String[] row = {res.getString("Expenses"), res.getString("ExpensesType"), res.getString("PaymentType"), res.getString("Amount"), res.getString("Date")};
            System.out.print(res.getString("Expenses"));
            System.out.print(res.getString("ExpensesType"));
            System.out.print(res.getString("PaymentType"));
            System.out.print(res.getString("Amount"));
            System.out.print(res.getString("Date"));

            GUI.tableModel.addRow(row);
        }
    }

还有……

String updateStatement = "INSERT INTO VAULT"
                + " (Expenses, ExpensesType, PaymentType, Amount, Date)"
                + " VALUES (\'" + expenses + "\',\'" + expensesType + "\',\'" + paymentType + "\',\'" + amount + "\',\'" + date + "\')";
try (Statement statement = c.createStatement()) {
    System.out.print(updateStatement);
    int c = statement.executeUpdate(updateStatement);
    count = count + c;

    System.out.println("Data Inserted in to Database...");
} catch (Exception ex) {
    ex.printStackTrace();
}

这将确保一旦您离开try 部分,资源将自动关闭。

您还应该考虑使用PreparedStatements,有关详细信息,请参阅Using Prepared Statements

在您的 actionPerformed 方法中,这个...

table.setModel(tableModel);

令人担忧。模型在您设置 UI 时已经设置好了,除非您创建了一个新模型或表格,否则您不需要再次设置它,而您都没有这样做...

还有……

tableModel.fireTableDataChanged();
table.updateUI();

永远不应该这样做。你永远不应该在外部调用模型的任何通知方法,这些都应该由它自己的模型来处理(在 DefaultTableModel 的情况下)。

updateUI 与“更新 UI 的状态”无关,它可能是您可以使用的最有效的方法。您fireTableDataChanged 的简单事实应该已经触发了更新(尽管fireTableDataChanged 也是您可以使用的最有效的方法之一)。

只需致电tableModel.addRow,然后让模型和表格完成剩下的工作。

你的工作流程有点不对劲。在确定已将其添加到数据库之后,您不应该将行添加到表中,如果由于某种原因插入失败会发生什么?

你真的,真的,真的应该学会使用对话框,请参阅How to Make Dialogs 了解更多详细信息,而不是向用户抛出另一个框架......

static 不是你的朋友,当然它可能“似乎”让生活更轻松,“它只是一个快速的 {whatever}”,但任何时候都是坏事......

你不应该让 UI 组件 static 容易丢失上下文并且不知道你是否正在更新屏幕上实际显示的内容。

“但是类 X 是如何引用组件 Y 的呢?” - 在大多数情况下,它不应该。我应该返回容器类可以处理的一个/多个值,或者应该通过使用某种模型或观察者模式进行通信......

如果你要剥离窗口框架,你最好实现允许我拖动它的功能,因为这是我个人的控制,所以调整它的大小,否则你的用户不会喜欢你

避免使用null 布局,像素完美的布局是现代用户界面设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

请参阅Why is it frowned upon to use a null layout in Swing?Laying Out Components Within a Container 了解更多详情...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多