JavaFX TableView dynamic column and data values

25,215

Solution 1

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

Solution 2

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>>).

Share:
25,215
AlenBer
Author by

AlenBer

Updated on July 23, 2022

Comments

  • AlenBer
    AlenBer almost 2 years

    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!
    }
    
  • AlenBer
    AlenBer over 11 years
    Thanks for your answer, but.. the example above says: Cannot cast java.io.FileReader to org.javafxdata.datasources.io.DataSourceReader. The downloaded DataFX library (v0.0.6 - latest) does not contain it's own implementation of FileReader, but NetBeans suggested org.javafxdata.datasources.io.FileSource and it works (all values are parsed and stored into CSVDataSource) but the CSVDataSource does not contain the columns (ds1.getColumns() returns an 0 length array). It would be a quick solution, but still trying to find a standard JavaFx way ..
  • invariant
    invariant over 11 years
    @AlenBer edited DataFx code which will work fine now:) , and also added Standard JavaFX way code:)
  • Arvin
    Arvin about 10 years
    Hi @invariant, could you check out my post? I follow your standard javaFX way but still have some problems stackoverflow.com/questions/22129559/…
  • Jason Weh
    Jason Weh almost 9 years
    I don think this class is in the latest release of datafx. Be happy to be corrected on this as i was hoping to use it.
  • BEWARB
    BEWARB about 4 years
    For detailed standard JavaFX way, refer - community.oracle.com/thread/2474328
  • AlenBer
    AlenBer over 2 years
    Thanks for reminding me how old I got :)
  • Renis1235
    Renis1235 over 2 years
    I would prefer the term experienced :)