Inserting integer (not String) data into a JavaFX2 TableView


Question

so I've got a table working properly and grabbing data from an ObservableList with the code here:

public void setMainTableData(ObservableList<FileMP3> list)
    {
        artistCol.setCellValueFactory(new PropertyValueFactory<FileMP3, String>("artist"));
        albumCol.setCellValueFactory(new PropertyValueFactory<FileMP3, String>("album"));
        titleCol.setCellValueFactory(new PropertyValueFactory<FileMP3, String>("title"));
        trackCol.setCellValueFactory(new PropertyValueFactory<FileMP3, String>("track"));
        yearCol.setCellValueFactory(new PropertyValueFactory<FileMP3, String>("year"));
        mainTable.setItems(list);
    }   

These columns, however do not ALL contain string data - I need to able to insert an int, and potentially other types like Duration. The track and year entries are stored as integers, and there is a (not shown) entry called length. This is stored in my FileMP3 object as a Duration, and I don't see any obvious way to manipulate the data stored there before inserting it into the table. I'd like to be able to use Duration.getMillis() and then perform some math on that to get it into a displayable int format, but I want to keep it stored in the FileMP3 as Duration.

All the tutorials I've read on the topic all use the constructor as such:

new PropertyValueFactory<FileMP3, String>("genre")

All in all, I'd like to be able to insert something other than a String into the table.

1
1
12/13/2013 12:08:24 AM

Accepted Answer

You can just replace String with any (reference, not primitive) type. For example:

TableColumn<FileMP3, Integer> yearCol = new TableColumn<>("Year");
yearCol.setCellValueFatory(new PropertyValueFactory<FileMP3, Integer>("year"));

Similarly with Duration (instead of Integer).

By default, the value in the cell will be displayed by calling toString() on the value in the cell. If you want the value to be displayed differently, you can create a custom cell factory (different to a cell value factory):

TableColumn<FileMP3, Integer> durationCol = new TableColumn<>("Duration");
durationCol.setCellValueFactory(new PropertyValueFactory<FileMP3, Duration>("duration"));
durationCol.setCellFactory(new Callback<TableColumn<FileMP3, Duration>, TableCell<FileMP3, Duration>>() {
    @Override
    public TableCell<FileMP3, Duration> call(TableColumn<FileMP3, Duration> col) {
        return new TableCell<FileMP3, Duration>() {
            @Override
            protected void updateItem(Duration duration, boolean empty) {
                super.updateItem(duration, empty);
                if (empty) {
                    setText(null);
                } else {
                    setText(Double.toString(duration.toMillis());
                }
            }
        };
    }
});
4
12/13/2013 1:49:12 AM

You can provide a custom cell value factory:

duration.setCellValueFactory(new Callback<CellDataFeatures<FileMP3, Integer>, ObservableValue<Integer>>() {
    @Override public ObservableValue<Integer> call(CellDataFeatures<FileMP3, Integer> c) {
        return new SimpleIntegerProperty(c.getValue().getDurationAsInt()));
    }
});

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon