应该在哪里定义我的可选 DefaultTableModel 方法?

Posted

技术标签:

【中文标题】应该在哪里定义我的可选 DefaultTableModel 方法?【英文标题】:Where should definition my optional DefaultTableModel methods? 【发布时间】: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 ,但我不知道应该在哪里写这些方法?在哪个班级? 【参考方案1】:

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

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

    创建一个帮助类,其中包含更新数据库和 TableModel 的方法 扩展 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 教程或再次阅读并学习链接到那里的演示程序。

以上是关于应该在哪里定义我的可选 DefaultTableModel 方法?的主要内容,如果未能解决你的问题,请参考以下文章

pip 需求文件中的可选依赖项

AngularJS 表单。 JSON中的可选属性[重复]

Express:***路径的可选斜杠

匹配正则表达式中的可选斜杠

与 try 的可选绑定?并作为?仍然产生一个可选类型

如何在带有 defaultValue 的可选字段上使用 jQuery Validator 自定义方法?