How can I add rows and columns to a JavaFX 8 Table

2019-01-07 00:07发布

I see examples on the internet for adding a row to a TableView, for example using the Person class in the Oracle documentation.

But I have a variable number of columns, so I can't bind to a Person (or any other) bean business object.

The Oracle example goes on to show how to bind columns to property names, but for that, it only shows how to add columns, but not rows.

My question is, can someone point me to a Hello, World example of dynamically adding arbitrary columns and/or rows to a JavaFX 8 TableView?

2条回答
淡お忘
2楼-- · 2019-01-07 00:41

Use a List<String> (for example) for the data type, and just set the cell value factory as a callback that indexes into the list.

For example, this will create a TableView<List<String>> that is constructed out of an arbitrary tab-delimited text file. Not all rows in the file need have the same number of elements (it will pad with blanks). (It doesn't support escaped tabs, etc):

public TableView<List<String>> readTabDelimitedFileIntoTable(Path file) throws IOException {
    TableView<List<String>> table = new TableView<>();
    Files.lines(file).map(line -> line.split("\t")).forEach(values -> {
        // Add extra columns if necessary:
        for (int i = table.getColumns().size(); i < values.length; i++) {
            TableColumn<List<String>, String> col = new TableColumn<>("Column "+(i+1));
            col.setMinWidth(80);
            final int colIndex = i ;
            col.setCellValueFactory(data -> {
                List<String> rowValues = data.getValue();
                String cellValue ;
                if (colIndex < rowValues.size()) {
                    cellValue = rowValues.get(colIndex);
                } else {
                     cellValue = "" ;
                }
                return new ReadOnlyStringWrapper(cellValue);
            });
            table.getColumns().add(col);
        }

        // add row:
        table.getItems().add(Arrays.asList(values));
    });
    return table ;
}
查看更多
时光不老,我们不散
3楼-- · 2019-01-07 00:51

Kind of clunky, but this sample code seems to work:

    TableView table = new TableView<>();
    private char nextChar = 'A';

    private void addColumn(TableView table) {
      String mapChar = String.valueOf(nextChar++);
      TableColumn<Map, String> column = new TableColumn<>("Class " + mapChar);
      column.setCellValueFactory(new MapValueFactory(mapChar));
      column.setMinWidth(130);
      column.setCellFactory(cellFactoryForMap);
      table.getColumns().add(column);
    }

    private void addRow(TableView table) {
      ObservableList<Map> allData = table.getItems();
      int offset = allData.size();
      Map<String, String> dataRow = new HashMap<>();
      for (int j = 0; j < table.getColumns().size(); j++) {
        String mapKey = Character.toString((char) ('A' + j));
        String value1 = mapKey + (offset + 1);
        dataRow.put(mapKey, value1);
      }
      allData.add(dataRow);
    }
  }
查看更多
登录 后发表回答