Cell factory in javafx

user1332356 picture user1332356 · May 9, 2012 · Viewed 51.6k times · Source

I am using JavaFx 2.0 and Java 7. The question is regarding Table View in JavaFX.

The below sample code creates a firstName column and assigns cell factory and cell value factory to it.

Callback<TableColumn, TableCell> cellFactory = 
new Callback<TableColumn, TableCell>() {
    public TableCell call(TableColumn p) {
        return new EditingCell();
} };


TableColumn firstNameCol = new TableColumn("First Name");
    firstNameCol.setCellValueFactory(
        new PropertyValueFactory<Person,String>("firstName")
    );
firstNameCol.setCellFactory(cellFactory);

My requirement is I have a column which doesn't directly map to a single attribute in Person object, but instead is a custom value created by concatenating one or more attributes of Person object.

Consider a scenario where I have a table column named Full Name which will have values of Prefix + Last Name + "," + First Name .

1) In this scenario, how will you write the cell value factory?

firstNameCol.setCellValueFactory(
            new PropertyValueFactory<Person,String>(???????)
        );

2) how will you write cell factory?

In this scenario do we need to implement both cell value factory and cell factory or any one is sufficient? If one is sufficient then which one?

Thanks

Answer

Uluk Biy picture Uluk Biy · May 10, 2012

Straightforwardly,

Cell Value Factory : it is like a "toString()" of only part of the row item for that related cell.
Cell Factory : it is a renderer of the cell from the cell item. Default behavior is setText(cell.item.toString()) if the cell item is not a Node, setGraphic((Node)cell.item) otherwise. Set this property if the cell is supposed to support editing OR if you want more graphics (controls) other than default Label.

So for your scenario, leaving cell factory with default value will be sufficient (2). And here is sample code for (1):

firstAndLastNameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {

    @Override
    public ObservableValue<String> call(TableColumn.CellDataFeatures<Person, String> p) {
        if (p.getValue() != null) {
            return new SimpleStringProperty(p.getValue().getPrefix() + " " + p.getValue().getFirstName() + "," + p.getValue().getLastName());
        } else {
            return new SimpleStringProperty("<no name>");
        }
    }
});