Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX TableView dynamic column and data values

I'm testing myself with a simple CSV Viewer using JavaFX and I'm stuck at populating the table data. I do create the columns dynamically, but the data values are a no-go. I searched the web and found a few ways but all ways include a ObservableList with a custom class (including get/set), which in a CSV Viewer must be dynamically (The CSV can have any number of columns, and that means any number of data values).

Example:

List<String> columns;
List<List<String>> data;

/* Fills 'columns' and 'data' */
parseCSV("C:/list.csv");

int columnIndex = 0;
TableColumn [] tableColumns = new TableColumn[columns.size()];        
for(String columName : columns) {
    tableColumns[columnIndex++] = new TableColumn(columName);
}
table1.getColumns().addAll(tableColumns);

for(List<String> dataList : data) {
    table1.setItems(dataList); // Requires an ObservableList!
}
like image 821
AlenBer Avatar asked Nov 11 '12 14:11

AlenBer


2 Answers

use DataFX,which will make your job easier :)

Example Code :

DataSourceReader dsr1 = new FileSource("your csv file path");
String[] columnsArray // create array of column names you want to display 
CSVDataSource ds1 = new CSVDataSource(dsr1,columnsArray);
TableView tableView = new TableView();
tableView.setItems(ds1.getData());
tableView.getColumns().addAll(ds1.getColumns());

Reference : Introduction to DataFX

Edit : Standard JavaFX Way

replace your code :

for(List<String> dataList : data) {
    table1.setItems(dataList); // Requires an ObservableList!
}

with

  //  which will make your table view dynamic 
 ObservableList<ObservableList> csvData = FXCollections.observableArrayList(); 

 for(List<String> dataList : data) {
     ObservableList<String> row = FXCollections.observableArrayList();
    for( String rowData : dataList) {
      row.add(rowData); 
  }
   cvsData.add(row); // add each row to cvsData
}

table1.setItems(cvsData); // finally add data to tableview
like image 66
invariant Avatar answered Nov 11 '22 20:11

invariant


I didn't follow the way described by the answer by @invariant.

I had an excel file with several columns and a lot of rows. I used a HashMap to keep track of what value belongs to what column. This way:

int i = 0;
HashMap<String, Integer> columnNameIndexMap = new HashMap<>();

for (String header : excelFileData.getHeaders())
{
    TableColumn<List<String>, String> column = new TableColumn<>(header);
    columnNameIndexMap.put(header, i++); // Adding the connecting index to our map with key, name of column

    column.setCellValueFactory(data ->
            {
                String columnName = data.getTableColumn().getText();
                int currentIndex = columnNameIndexMap.get(columnName);
                String currentValue = data.getValue().get(currentIndex);

                return new SimpleStringProperty(currentValue);
            });
    tableView.getColumns().add(column);
}

for (List<String> row : excelFileData.getRows())
{
    tableView.getItems().add(row);
}

P.S: You can also use excelFileData.getHeaders().indexOf(columnName) to get the index without a HashMap.

Do not pay attention to excelFileData.getHeaders() returns a list with strings and excelFileData.getRows() returns a list with lists of strings (List<List<String>>).

like image 20
Renis1235 Avatar answered Nov 11 '22 21:11

Renis1235