【问题标题】:Where should definition my optional DefaultTableModel methods?应该在哪里定义我的可选 DefaultTableModel 方法?
【发布时间】:2013-09-02 20:41:59
【问题描述】:

我使用这 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 类中,现在我该如何定义这些方法以及应该在哪里做呢?

更新:

对于 e.x 我测试这个方法:

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)`

【问题讨论】:

  • 您能否详细说明您想要实现的目标?你的确切问题是什么?
  • @micha 我想为我的表模型添加更多方法。例如,我希望能够在表格中选择一行并删除或编辑它。
  • @micha 我知道如何使用 JDBC ,但我不知道应该在哪里写这些方法?在哪个班级?

标签: java swing jdbc defaulttablemodel


【解决方案1】:

关于这个主题的第 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() 方法。

【讨论】:

  • 很好,是的,我想做你的第二种方式,扩展 DefaultTableModel。我不想通过方法创建表模型,这对我来说很复杂
  • 我知道我需要 3 节课才能做到。从数据库中检索数据的第 1 类,第 2 类应该通过扩展 DefaultTableModel 和第 3 类创建表模型,它是显示 JTable 的 GUI。对吗?
  • 所以我知道我不应该在表模型类中使用 JDBC 代码。应该如何将数据从我的 2th class 传输到我的 1th class?通过方法?
  • 如何将数据库中的数据加载到表模型中?
  • 你没看我的回答吗?我建议您需要一个用于所有数据库/模型相关代码的辅助类。或者您需要扩展 DefaultTableModel 以便所有代码都在一个类中。我在之前的帖子中向您展示了如何将数据加载到模型中。为什么你不看答案还要费心发问题???????
【解决方案2】:

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

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

并删除或编辑它。

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

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


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

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

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

而且您还没有发布任何表格模型代码。即,没有扩展任何 TableModel 的类的代码,既不是 AbstractTableModel 也不是 DefaultTableModel。您的模型代码不能凭空运行,父类需要这两者之一。


编辑 2
在阅读了您的 cmets 之后,我的印象是您相信您的 TableContent 是您的 TableModel,并且期望它能够使用诸如 fireTableRowsDeleted(...) 之类的方法调用进行编译,即使您的类没有扩展任何内容。一些建议:

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

【讨论】:

  • @APoliteBoy:您没有发布任何代码显示您尝试使用 TableModel。如果您需要特定的答案,那以及有关它如何不起作用的信息会很有用。否则,我们所能做的就是为您提供类似于我上面发布的一般性建议。
  • 好的,问题意味着IDE说cannot resolve method fireTableRowsDeleted(int,int);
  • @APoliteBoy:这很有意义。您正在调用一个您在类中没有声明的方法,并且它在父类中不存在(这里的父类是 Object)。我猜你正在考虑扩展 TableModel 类之一,但你还没有扩展任何东西。再一次,这不会靠魔法起作用——你必须编写类来扩展父类。
  • 你推荐我去Extend DefaultTableModel我的TableContent Class吗?
  • @APoliteBoy:请参阅上面的编辑评论。但正如目前所写的那样,不,您不应该为该类扩展 DefaultTableModel,因为您似乎将数据保存在类中,而不是保存在 DefaultTableModel 超类中。您将需要扩展 AbstractTableModel。您将需要阅读 Swing Table 教程或再次阅读并学习链接到那里的演示程序。
猜你喜欢
  • 1970-01-01
  • 2020-09-13
  • 2016-03-08
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多