JavaFX:使用泛型类型创建动态表格视图 [英] JavaFX: Create a dynamic tableview with generic types

查看:268

您可以使用 ResultSet.getObject(index) 来填充选项卡乐。根据JDBC规范中定义的标准映射,JDBC驱动程序将返回适当的对象类型(例如,int列将映射到 java.lang.Integer 等)。

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

数据包装类:

  public class DataResult {

private final List< String> columnNames;
private final List< List< Object>>数据;

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(){
返回数据;


$ / code $ / pre

$ hr

数据库访问器类:

  public class DAO {

private连接conn;

$ b $ public DAO(){
//初始化连接...
}

public DataResult getAllData()throws SQLException { b
$ b列表< List< Object>> data = new ArrayList<>();
列表< String> columnNames = new ArrayList<>();
$ b $ try(
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(select * from some_table)){


int columnCount = rs.getMetaData()。getColumnCount(); (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);
}
}

返回新的DataResult(columnNames,data);


$ / code $ / pre

$ hr

GUI代码:

  TableView< List< Object>> table = new TableView<>(); 
DAO dao =新的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(...)(即以正确的数字顺序)的实现。


So, first of all, my code is based on the accepted answer in this thread.

I'm trying to create a tableview from a database, and this tableview should be populated dynamically based on what data the user asks for. While that's working so far, my problem is that all values gathered from the database are interpreted as strings in java, but I need their actual values.

The reason for this is that the built-in sorting mechanism of the javafx tableview sorts all numbers as strings because their type is converted to string when populating the table.

Example: Values 921, 200, 110, 1, 2011, 1299 would be sorted as (using integer datatype) 1, 110, 200, 921, 1299, 2011 while it would be sorted as 1, 110, 1299, 200, 2011, 921 using string datatype.

I'm quite new to generics and java in general, and hope someone here might be able to help me out.

Basically: whenever I read a value from the database, I need to insert the value in the tableview with its actual datatype, rather than it being converted to string.

解决方案

This should work if you use ResultSet.getObject(index) to populate the table. The JDBC driver will return an appropriate object type, according to standard mappings defined in the JDBC specification (e.g. an int column will map to a java.lang.Integer, etc).

I don't particularly like the code you linked: it produces a lot of warnings about type safety, to which you should pay attention. I would use something like this (caveat: not tested):

Data wrapper class:

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 ;
    }
}


Database accessor class:

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 code:

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());

Using this version, the data provided to the table contains objects of the appropriate type for the columns - not necessarily strings. So, for example, if a database column is defined with (SQL) type int, then the table view column will contain java.lang.Integer instances, and the sorting will be according to the implementation of Integer.compareTo(...) (i.e. in proper numeric order).

这篇关于JavaFX:使用泛型类型创建动态表格视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆