JavaFX TableView dynamic column and data values
Asked Answered
G

2

9

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!
}
Gimp answered 11/11, 2012 at 14:49 Comment(0)
D
9

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
Derivation answered 11/11, 2012 at 20:33 Comment(5)
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 ..Gimp
@Gimp edited DataFx code which will work fine now:) , and also added Standard JavaFX way code:)Derivation
Hi @invariant, could you check out my post? I follow your standard javaFX way but still have some problems #22130059Lelialelith
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.Intrinsic
For detailed standard JavaFX way, refer - community.oracle.com/thread/2474328Finley
B
1

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

Batfowl answered 25/11, 2021 at 19:0 Comment(2)
Thanks for reminding me how old I got :)Gimp
I would prefer the term experienced :)Batfowl

© 2022 - 2024 — McMap. All rights reserved.