JavaFX:使用泛型类型创建动态表视图

时间:2017-03-23 08:22:52

标签: java generics javafx tableview

首先,我的代码基于this thread.

中接受的答案

我尝试从数据库创建一个tableview,并且应该根据用户要求的数据动态填充此tableview。到目前为止,我的问题是从数据库收集的所有值都被解释为java中的字符串,但我需要它们的实际值。

原因是javafx tableview的内置排序机制将所有数字排序为字符串,因为在填充表时它们的类型转换为字符串。

实施例: 值 921,200,110,1,2011,1299 将被排序为(使用整数数据类型)1,110,200,921,1299,2011 虽然它将使用字符串数据类型排序为1,110,1299,200,2011,921。

我对泛型和java一般都很陌生,希望有人能帮到我。

基本上:每当我从数据库中读取一个值时,我需要在tableview中插入其实际数据类型的值,而不是将其转换为字符串。

1 个答案:

答案 0 :(得分:2)

如果您使用ResultSet.getObject(index)填充表格,这应该有效。 JDBC驱动程序将根据JDBC规范中定义的标准映射返回适当的对象类型(例如,int列将映射到java.lang.Integer等)。

我并不特别喜欢您链接的代码:它会产生很多关于类型安全的警告,您应该注意这些警告。我会使用这样的东西(警告:未经测试):

数据包装类:

public class DataResult {

    private final List<String> columnNames ;
    private final List<List<Object>> data ;

    public DataResult(List<String> columnNames, List<List<Object>> data) {
        this.columnNames = columnNames ;
        this.data = data ;
    }

    public int getNumColumns() {
        return columnNames.size();
    }

    public String getColumnName(int index) {
        return columnNames.get(index);
    }

    public int getNumRows() {
        return data.size();
    }

    public Object getData(int column, int row) {
        return data.get(row).get(column);
    }

    public List<List<Object>> getData() {
        return data ;
    }
}

数据库访问者类:

public class DAO {

    private Connection conn ;


    public DAO() {
        // initialize connection...
    }

    public DataResult getAllData() throws SQLException {

        List<List<Object>> data = new ArrayList<>();
        List<String> columnNames = new ArrayList<>();

        try (
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery("select * from some_table")) {


            int columnCount = rs.getMetaData().getColumnCount();

            for (int i = 1 ; i <= columnCount ; i++) {
                columnNames.add(rs.getMetaData().getColumnName(i));
            }

            while (rs.next()) {
                List<Object> row = new ArrayList<>();
                for (int i = 1 ; i <= columnCount ; i++) {
                    row.add(rs.getObject(i));
                }
                data.add(row);
            }
        }

        return new DataResult(columnNames, data);
    }
}

GUI代码:

TableView<List<Object>> table = new TableView<>();
DAO dao = new DAO();
DataResult data = dao.getAllData();

for (int i = 0 ; i < data.getNumColumns() ; i++) {
    TableColumn<List<Object>, Object> column = new TableColumn<>(data.getColumnName(i));
    int columnIndex = i ;
    column.setCellValueFactory(cellData -> 
        new SimpleObjectProperty<>(cellData.getValue().get(columnIndex)));
    table.getColumns().add(column);
}

table.getItems().setAll(data.getData());

使用此版本,提供给表的数据包含列的相应类型的对象 - 不一定是字符串。因此,例如,如果使用(SQL)类型int定义数据库列,则表视图列将包含java.lang.Integer个实例,并且排序将根据Integer.compareTo(...)的实现(即,正确的数字顺序)。