0

我使用这 3 个类将数据库中的数据显示到JTable.

public class TableContent {

private final Vector<String> headers;
private final Vector<Vector<String>> content;

public TableContent(final Vector<String> headers, final Vector<Vector<String>> content) {
this.headers = headers;
this.content = content;
  }

public Vector<String> headers() {
return headers;
}

public Vector<Vector<String>> content() {
return content;
}

和:

public class TableData {

public TableContent getData() {
Vector<String> headers = new Vector<String>();
Vector<Vector<String>> content = new Vector<Vector<String>>();

try {
    Connection conn = DriverManager.getConnection("");
    Statement statement = conn.createStatement();
    ResultSet rs = statement.executeQuery("Select * from table");

    headers = buildHeaders(rs);
    content = buildContent(rs);

} catch (SQLException e) {
    e.printStackTrace();
}

return new TableContent(headers, content);
 }

private Vector<String> buildHeaders(final ResultSet rs) throws SQLException {
Vector<String> headers = new Vector<String>();

int col = rs.getMetaData().getColumnCount();
for (int i = 1; i <= col; i++) {
    headers.add(rs.getMetaData().getColumnName(i));
    }
return headers;
}

private Vector<Vector<String>> buildContent(final ResultSet rs) throws SQLException {
Vector<Vector<String>> content = new Vector<Vector<String>>();

while (rs.next()) {
    int col = rs.getMetaData().getColumnCount();
    Vector<String> newRow = new Vector<String>(col);

    for (int i = 1; i <= col; i++) {
        newRow.add(rs.getString(i));
    }
    content.add(newRow);
 }
return content;
  }
 }
}

和:

public class TableGUI extends JFrame {
// Create GUI and Show table
 }

以前我将我的方法添加到我的扩展 DefaultTableModel 类中,现在我该如何定义这些方法以及应该在哪里做呢?

更新:

例如,我测试了这个方法:

public class TableContent {
String dbUrl = "...";

private final Vector<String> headers;
private final Vector<Vector<String>> content;

public TableContent(final Vector<String> hdr, final Vector<Vector<String>> cnt) {
    headers = hdr;
    content = cnt;
}

public Vector<String> headers() {
    return headers;
}

public Vector<Vector<String>> content() {
    return content;
}
public void removeRow(int modelRow, Object rowID) {
    String removeQuery = "delete from table where id=?";
    Connection conn;
    PreparedStatement ps = null;
    try {
        conn = DriverManager.getConnection(...);
        ps = conn.prepareStatement(removeQuery);
        Object idValue = rowID;
        ps.setObject(1, idValue);
        if (ps.executeUpdate() == 1) {
            content.remove(modelRow);
         fireTableRowsDeleted(modelRow, modelRow);   // Error
        }
    } catch (SQLException sqle) {
        sqle.printStackTrace();
    }
}
}

现在在这里,问题是fireTableRowsDeleted(...);

问题意味着 IDE 说cannot resolve methodfireTableRowsDeleted(int,int)`

4

2 回答 2

5

我想为我的表模型添加更多方法。例如我希望能够在表格中选择一行

如果您想在选择行/列/单元格时激活某些操作,此代码可以在添加到 JTable 的 ListSelectionListener 中。另一方面,如果您只想在其他事件发生时对当前选定的行和/或列进行操作,例如按下按钮或右键单击鼠标,那么您甚至不必添加ListSelectionListener,而是在表中查询选定的行/列,然后使用适当的convertXxxxIndexToModel(...)方法将行和/或列索引转换为模型。请务必setSelectionMode(...)按照教程正确设置表格的选择模式。

并删除或编辑它。

删除代码将在您希望用于触发删除的任何事件中开始,可能在可以添加到 JButton 或弹出菜单或两者的 AbstractAction 类中。然后这个 Action 会调用deleteRow(...)TableModel 中的一个方法。

如需更具体的帮助,您需要向我们展示您的 TableModel 代码。


编辑
关于您的更新。你说:

现在在这里,问题是 fireTableRowsDeleted(...); !

请理解,我们只能理解您告诉我们的内容,而诸如“问题是……”之类的陈述几乎没有告诉我们。你有什么样的问题?它不编译吗?如果不是,请显示编译器错误消息。它会编译但抛出异常吗?如果是这样,请发布完整的例外?它会让你的显示器冒白烟吗?如果是这样,请关闭计算机,拔下电源并离开它。它会打你耳光并骂你讨厌的名字吗?什么?

而且您还没有发布任何表格模型代码。即,没有扩展任何 TableModel 的类的代码,既不是 AbstractTableModel 也不是 DefaultTableModel。您的模型代码无法通过魔法工作,并且需要这两个中的任何一个作为父类。


编辑 2
阅读您的评论后,我的印象是您相信您的 TableContent 是您的 TableModel 并期望它能够通过方法调用进行编译,例如fireTableRowsDeleted(...) 即使您的类没有扩展任何内容。一些忠告:

  • 要使一个类表现得像 TableModel,它首先必须一个 TableModel。转换为 OOP,这意味着您必须使用继承,因为此类必须满足面向对象编程的“is-a”测试。
  • 所有 TableModel 类至少应该扩展 AbstractTableModel 类,或者它不是那个类,然后是一个最终从它扩展的类,因为这个类包含 JTables 与模型一起工作所必需的布线。
  • 有些类可以通过扩展 DefaultTableModel 类来解决,这可以为您节省一些工作,因为您可以轻松地使用该类的现成方法。
  • 但是要扩展 DefaultTableModel,您必须将所有模型数据放入超类中,通常通过调用适当的超构造函数。您不能从 DefaultTableModel 超类中拥有单独的数据模型核心。所以我不认为这对你的目的很有效。
  • fire***(...)相反,您可能需要扩展 AbstractTableModel,然后编写自己的模型方法,并在更改数据时注意触发适当的通知方法(它们以 开头)。
  • 另一种选择是使用由其他人创建的模型类(如果它们满足您的目的),例如 Rob Camick 的表模型类,它与 SQL 数据库配合良好,可以在他的博客上找到。
  • 无论您做什么,都必须不仅阅读而且学习Swing JTable 教程,因为它包含大量有用的甚至是您需要的必要信息。您可以在Java 教程的真正大索引中找到此教程和其他教程。
于 2013-09-02T21:17:23.427 回答
5

关于这个主题的第 10 个问题是什么?为什么您发布的用于创建 TableModel 的代码与我在您的第 9 篇帖子中建议的代码不同?在该代码示例中,我向您展示了如何从方法中返回 TableModel。相反,您的代码正在创建两个向量并尝试维护对这些向量的引用。那不是这样做的方法。DefaultTableModel 包含数据,您不需要数据的单独副本。您可以使用 getValueAt(..) 方法访问模型中的数据。

正如我一直建议你有两种选择:

  1. 创建一个辅助类,其中包含更新数据库和 TableModel 的方法
  2. 扩展 DefaultTableModel 以添加这些方法。

对于辅助类,您可以定义一个方法,例如:

public void removeRow(DefaultTableModel model, int modelRow)
{
    Object rowID = model.getValueAt(modelRow, theColumn);

    // your code to delete row from database

    if (row delected successfully)
        model.removeRow(modelRow);
}

您不需要 rowID 作为参数,因为您可以使用 getValueAt() 方法从模型中获取数据。这个想法是使用 DefaultTableModel 的方法来管理数据,而不是重新发明轮子。您所做的只是添加代码来更新数据库。

如果你想通过扩展 DefaultTableModel 来创建 CustomTableModel,那么你的 removeRow() 方法不需要 DefaultTableModel 作为参数,你可以调用 DefaultTableModel 的 super.removeRow() 方法。

于 2013-09-04T15:25:11.203 回答