简体   繁体   English

如何将数据库中的行数据插入到JTable的特定列中?

[英]How to Insert row data from database into specific columns of a JTable?

I have written a GUI Java program that manages a MySQL database. 我已经编写了一个用于管理MySQL数据库的GUI Java程序。 The user selects which columns (which tables and columns will be selected from the database) he/she wants to populate the JTable with. 用户选择他/她要用来填充JTable的列(将从数据库中选择哪些表和列)。

I hard-coded the column names for the JTable so even if the user chooses to only display the data from a subset of columns, all of the column-names will be visible. 我对JTable的列名进行了硬编码,因此,即使用户选择仅显示列子集中的数据,所有列名也将可见。

The problem is that when the user chooses columns in a different order than my JTable is anticipating, the data gets displayed in the wrong column.. It's a bit hard to explain so here's a screenshot of the genre data being loaded into the length column: 问题在于,当用户选择的顺序与我的JTable预期的顺序不同时,数据将显示在错误的列中。很难解释,因此下面是将类型数据加载到length列中的屏幕截图:

如您所见,它在长度列中显示类型数据

tableGenerator class: tableGenerator类:

package gui;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Vector;

public class TableGenerator
{

    private ArrayList columnNames = new ArrayList();
    private ArrayList data = new ArrayList();
    private Vector columnNamesVector = new Vector();
    private Vector dataVector = new Vector();
    private int columns = 0;
    private int rows = 0;

    @SuppressWarnings("unchecked")
    public TableGenerator(ResultSet rs)
    {
        try{
            ResultSetMetaData md = rs.getMetaData();
            columns = md.getColumnCount();
            //  Get column names

                columnNames.add("Title");
                columnNames.add("Year");
                columnNames.add("Length");
                columnNames.add("Genre");
                columnNames.add("Actor");
                columnNames.add("Producer");
                columnNames.add("Director");
                columnNames.add("Writer");

            //  Get row data
            while (rs.next())
            {
                ArrayList row = new ArrayList(columnNames.size());

                for (int i = 1; i <= columns; i++)
                {
                        row.add(rs.getObject(i));
                }
                data.add( row );
                rows++;
            }
        }
        catch (SQLException e)
        {
            System.out.println( e.getMessage() );
        }

        // Create Vectors and copy over elements from ArrayLists to them
        // Vector is deprecated but I am using them in this example to keep 
        // things simple - the best practice would be to create a custom defined
        // class which inherits from the AbstractTableModel class


        for (int i = 0; i < data.size(); i++)
        {
            ArrayList subArray = (ArrayList)data.get(i);
            Vector subVector = new Vector();
            for (int j = 0; j < subArray.size(); j++)
            {
                subVector.add(subArray.get(j));
            }
            dataVector.add(subVector);
        }

        for (int i = 0; i < columnNames.size(); i++ )
            columnNamesVector.add(columnNames.get(i));
        }

    public Vector getColumns(){
        return columnNamesVector;
    }
    public Vector getData(){
        return dataVector;
    }
    public ArrayList getColumnNames(){
        return columnNames;
    }
    public int getNumberOfRows(){
        return rows;
    }

}

I'm using the DefaultTableModel with some modifications.. : 我使用带有一些修改的DefaultTableModel ..:

model = new DefaultTableModel(rows, columns){

    private static final long serialVersionUID = 1L;

    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }

    @Override
    public Class<?> getColumnClass(int column) {
        if (column < classes.length) 
            return classes[column];
        return super.getColumnClass(column);

    };};

Your query should always return the data for all columns. 您的查询应始终返回所有列的数据。 This means the data will be stored in the same manner in the TableModel. 这意味着数据将以相同的方式存储在TableModel中。

You can then change the view for the columns to be displayed. 然后,您可以更改要显示的列的视图。 That is you can remove TableColumns from the TableColumnModel of the JTable and only the data the user want to view will be displayed, even though it is still available in the model. 也就是说,您可以从JTableTableColumnModel中删除TableColumns ,并且即使该数据在模型中仍然可用,也仅显示用户要查看的数据。 Then means the user can click on any check box at any time and you don't need to redo the database query, only add the TableColumn back to the table. 这意味着用户可以随时单击任何复选框,而无需重做数据库查询,只需将TableColumn添加回表中即可。

Check out Table Column Manager for an example of this approach. 请查看表列管理器以获取此方法的示例。 This class uses a popup menu to manage the columns, but you can still use your check boxes. 此类使用弹出菜单来管理列,但是您仍然可以使用复选框。 You just need to invoke the appropriate method of the TableColumnManager to hide/show a column. 您只需要调用TableColumnManager的适当方法即可隐藏/显示列。 That is, assuming the labels of the check boxes match the headings in the table you can just use the check box text to hide/show a column. 也就是说,假设复选框的标签与表中的标题匹配,则可以仅使用复选框文本来隐藏/显示列。

The other approach is to NOT hard code the column names (if you build your query to only get specific columns) but instead get the column names from the meta data of the ResultSet. 另一种方法是不对列名进行硬编码(如果将查询构建为仅获取特定列),而是从ResultSet的元数据中获取列名。 The TableFromDatabaseExample.java from Table From Database shows how this can be done. Table From Database中的TableFromDatabaseExample.java显示了如何完成此操作。 The code is generic so that appropriate renderers are used for Dates, Integers etc. 该代码是通用代码,因此适当的渲染器用于Date,Integers等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM