【问题标题】:How to get a DefaultTableModel object's data into a subclass of DefaultTableModel如何将 DefaultTableModel 对象的数据获取到 DefaultTableModel 的子类中
【发布时间】:2019-09-01 19:32:11
【问题描述】:

我有一个 jTable 显示一个简单的两列 sql 表的数据并允许用户维护列表。这是我的第一个 java 程序。让它工作,以便用户可以编辑数据列表并按保存进行更新。 我从这行代码获取到 jTable 的 DefaultTableModel 的 sql 数据:

paCutAboveTable.SetTableModel((DefaultTableModel) DbUtils.resultSetToTableModel(rs));

我猜这里的人对 DBUtils 和 resultSets 很熟悉。 我想为每一行添加一个 CheckBox。在这里和其他地方看,我一直看到子类 DefaultTableModel 以便重写一个方法:

/*

  * JTable uses this method to determine the default renderer/
  * editor for each cell.  If we didn't implement this method,
  * then the last column would contain text ("true"/"false"),
  * rather than a check box.
  */

 public Class getColumnClass(int c) {

     return getValueAt(0, c).getClass();
   }

但是,我不知道如何将 DefaultTableModel 的输出从 resultSetToTableModel 方法获取到我的子类 - 如果将 SetTableModel 方法更改为接受子类作为其参数,则显示的语句不会编译。 有没有我想念的简单方法?

【问题讨论】:

  • 感谢您的快速输入 Sergiy。读到我看到“请记住,如果让表创建自己的模型,它使用 Object 作为每一列的类型。要指定更精确的列类型,表模型必须适当地定义 getColumnClass 方法,如 TableDemo.java 所示。”这不会让我回到我的问题吗?
  • 我想我要改变思路,根据link编写我自己的代码从结果集(到我的子类)中提取数据。
  • 当你想得到一个复选框时,你只需要在getColumnClass方法中为列retern Boolean.class。但它也可以由自定义渲染器/编辑器制作。我将尝试提供一个示例。
  • Here 就是一个例子。

标签: java swing jtable


【解决方案1】:

这是一个示例,展示了如何从 ResultSet 中读取数据并在您自己的自定义 DefaultTableModel 中实现getColumnClass(...) 方法:

import java.awt.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableFromDatabase extends JFrame
{
    public TableFromDatabase()
    {
        Vector<Object> columnNames = new Vector<Object>();
        Vector<Object> data = new Vector<Object>();

        try
        {
            //  Connect to an Access Database

            String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
//            String url = "jdbc:odbc:???";  // if using ODBC Data Source name
            String url =
                "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=c:/directory/???.mdb";
            String userid = "";
            String password = "";

            Class.forName( driver );
            Connection connection = DriverManager.getConnection( url, userid, password );

            //  Read data from a table

            String sql = "Select * from ???";
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery( sql );
            ResultSetMetaData md = rs.getMetaData();
            int columns = md.getColumnCount();

            //  Get column names

            for (int i = 1; i <= columns; i++)
            {
                columnNames.addElement( md.getColumnLabel(i) );
            }

            //  Get row data

            while (rs.next())
            {
                Vector<Object> row = new Vector<Object>(columns);

                for (int i = 1; i <= columns; i++)
                {
                    row.addElement( rs.getObject(i) );
                }

                data.addElement( row );
            }

            rs.close();
            stmt.close();
            connection.close();
        }
        catch(Exception e)
        {
            System.out.println( e );
        }

        //  Create table with database data

        DefaultTableModel model = new DefaultTableModel(data, columnNames)
        {
            @Override
            public Class getColumnClass(int column)
            {
                for (int row = 0; row < getRowCount(); row++)
                {
                    Object o = getValueAt(row, column);

                    if (o != null)
                    {
                        return o.getClass();
                    }
                }

                return Object.class;
            }
        };

        JTable table = new JTable( model );
        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );

        JPanel buttonPanel = new JPanel();
        add( buttonPanel, BorderLayout.SOUTH );
    }

    public static void main(String[] args)
    {
        TableFromDatabase frame = new TableFromDatabase();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible(true);
    }
}

通过覆盖getColumnClass(...) 方法,您现在将看到格式化为右对齐的数字,如果您需要对数据进行排序,它将正常工作,因为该列将根据数值而不是字符串值进行排序。

我想为每一行添加一个 CheckBox。

所以现在你有两个选择:

  1. 修改上述代码,使“columnNames”向量包含复选框列的另一个标题名称,并在遍历 ResultSet 时将Boolean.FALSE 添加到每个“行”向量。

    李>
  2. 按原样使用上面的 TableModel(或使用 DbUtils TableModel),然后创建一个包装器 TableModel,它将一个复选框列添加到任何现有的 TableModel。查看:How to add checkbox in Jtable populated using rs2xml 获取此方法的示例。

【讨论】:

  • 感谢 camickr。你指出了我的严重缺乏理解。我想覆盖我必须通过子类执行的方法 - 即:为我自己的类扩展 DefaultTableModel。我会全力以赴让我的复选框正常工作。
  • @Matthew,我的示例使用“匿名内部类”。
  • 感谢 camickr。阅读后,我发现我需要子类化才能覆盖,除非使用您的代码,这种代码仅用于“本地”使用。感谢人们的帮助。
  • 嗨 camickr 我点击了对勾,希望那是复选标记
猜你喜欢
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 2013-12-18
  • 2011-05-18
  • 2013-10-06
  • 1970-01-01
  • 2013-02-17
相关资源
最近更新 更多