I have a JavaFX TableView that I'm populating with an ObservableList of Tasks. I've been trying to create a column that displays the index of each row, which serves as the ID for the tasks in the table, but I've tried the method here and similar methods from other sources with little success.
My code for reference, which has no superficial errors (as far as Eclipse can tell):
@FXML private TableColumn<Task, String> taskIndexCol;
Callback<TableColumn<Task, String>, TableCell<Task, String>> cb =
new Callback<TableColumn<Task, String>, TableCell<Task, String>>(){
@Override
public TableCell<Task, String> call(TableColumn<Task, String> col) {
TableCell<Task, String> cell = new TableCell<Task, String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setText("");
} else {
setText(getIndex()+"");
}
}
};
return cell;
}
};
taskIndexCol.setCellFactory(cb);
Currently, my code gives me a NullPointerException when I try to set the CellFactory of the column. I've tried it with a populated task list, but that didn't help. I've been stumped for a very long time -- and theoretically this should be pretty easy, since it's just numbering the rows? It feels like I'm jumping through a million hoops to do something frustratingly simple.
Edit: The last line gives me the NPE.
It's impossible to tell the cause of the Null pointer exception, because you haven't shown the stack trace, identified the line which throws the exception, or posted enough of your code (none of the code in your callback can throw a null pointer exception, so something is wrong somewhere else).
For your actual cell implementation, you didn't show if you had a
cellValueFactory
set on the column. If you don't, then theitem
will always benull
, and so you will never see any text in the cells in that column. You can check theempty
property (or method parameter) as a means to check if the cell is in an empty row or one with actual data. (Note this means the column really doesn't need to provide any data at all: it can be aTableColumn<Task, Void>
.)Additionally, it's probably safer to rely on using
updateIndex(...)
instead ofupdateItem(...)
.updateIndex
is guaranteed to be called when the index changes; if you implementupdateItem
you are assuming the index is set before the item, which means you are relying on an implementation detail.Your code is a lot shorter and easier to read if you use Java 8 lambda expressions:
or alternatively
Here is a SSCCE: