JavaFX:创建具有泛型类型的动态 tableview

Chr*_*org 3 java generics javafx tableview

因此,首先,我的代码基于此线程中已接受的答案

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

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

示例:值 921、200、110、1、2011、1299 将被排序为(使用整数数据类型)1、110、200、921、1299、2011,而它将被排序为 1、110、1299、20101 921 使用字符串数据类型。

总的来说,我对泛型和 java 很陌生,希望这里的人能够帮助我。

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

Jam*_*s_D 5

如果您ResultSet.getObject(index)用来填充表格,这应该可以工作。JDBC 驱动程序将根据 JDBC 规范中定义的标准映射返回适当的对象类型(例如,一个 int 列将映射到 ajava.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 ;
    }
}
Run Code Online (Sandbox Code Playgroud)

数据库访问器类:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

图形界面代码:

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());
Run Code Online (Sandbox Code Playgroud)

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