Mr.Fireman
Mr.Fireman

Reputation: 554

JavaFX Derby TableView

I found several solutions for writing data to tableView.

My question is: Is there any solution for writing data to a TableView in JavaFX from local Derby where we don't know how many columns and records will be and what will be the name of the attributes?

I need somekind of dynamic solution which numbers the columns and the records of a table and after generate the Table's content.

Upvotes: 1

Views: 186

Answers (1)

James_D
James_D

Reputation: 209225

You can do something like this:

public TableData readData(Connection conn, String dbTableName) throws SQLException {
    try (
        Statement stmnt = conn.createStatement() ;
        ResultSet resultSet = stmnt.executeQuery("select * from "+dbTableName) ) {

        ResultSetMetaData meta = resultSet.getMetaData() ;
        List<String> colNames = new ArrayList<>();
        for (int i = 1; i <= meta.getColumnCount(); i++) {
            String columnName = meta.getColumnName(i);
            colNames.add(columnName);                
        }

        List<Map<String, String>> data = new ArrayList<>();

        while (resultSet.next()) {
            Map<String, String> row = new HashMap<>();
            for (String col : colNames) {
                row.put(col, resultSet.getString(col));
            }
            data.add(row);
        }

        return new TableData(colNames, data);
    }
}

public static class TableData {
    private final List<String> columnNames ;
    private final List<Map<String, String>> data ;

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

    public List<String> getColumnNames() {
        return columnNames;
    }

    public List<Map<String, String>> getData() {
        return data;
    }


}

Which you could use as follows:

TableView<Map<String, String>> table = new TableView<>();
Connection conn = ... ;
String dbTableName = ... ;

Task<TableData> loadDataTask = new Task<TableData>() {
    @Override
    public TableData call() throws Exception {
        return readData(conn, dbTableName);
    }
};
loadDataTask.setOnSucceeded(event -> {
    table.getColumns().clear();

    TableData tableData = loadDataTask.getValue();
    for (String columnName : tableData.getColumnNames()) {
        TableColumn<Map<String, String>, String> col = new TableColumn<>(columnName);
        col.setCellValueFactory(cellData -> 
            new ReadOnlyStringWrapper(cellData.getValue().get(columnName)));
        table.getColumns().add(col);
    }
    table.getItems().setAll(tableData.getData());
});

loadDataTask.setOnFailed(event -> loadDataTask.getException().printStackTrace());

Thread loadThread = new Thread(loadDataTask);
loadThread.setDaemon(true);
loadThread.start();

Upvotes: 2

Related Questions