0
votes

I'm trying to build a program in JavaFX that allows me to check a list of payments in a TableView. To do this I created a class Bill that contains all the data I need, and in particular the attribute amount. The amount could be an exit or an entry, and this is estabilished by the enum Type in Bill (that can be ENTRY or EXIT). Now, I'm trying to override the method updateItem of TableCell to set the background color of the amount column green if the amount is an entry or red if it's an exit.

This is my code for the class AmountCell that extends TableCell and overrides updateItem:

public class AmountCell extends TableCell<Bill, Float> {

@Override
protected void updateItem(Float item, boolean empty) {
    super.updateItem(item, empty);

    setText(item==null ? "" : String.format("%.2f", item.floatValue()));

    if(item != null) {
        setStyle("-fx-background-color: " + (getTableRow().getItem().getType() == Type.ENTRY ? "#93C572" : "#CC0000" ));
    }
}
}

The problem is that when the records are displayed in the TableView, also the last empty rows of the table are colored, and I can't understand why! Also, try to debug the program, I noticed that the method updateItem has a strange behavior: it's often called twice with nosense. Anyone can explain me why and when the method is effectively called?

1

1 Answers

0
votes

updateItem is called when TableView determines the cell value has changed. Since cells are reused,

  • Different items may be assigned to the same cell during it's lifecycle
  • cells that contained an item could become empty again (for this reason you should make sure to deal with the case of the cell becoming empty by reseting to the "empty" state.)

In this case you need to clear the style when the item becomes null.

@Override
protected void updateItem(Float item, boolean empty) {
    super.updateItem(item, empty);

    setText(item == null ? "" : String.format("%.2f", item.floatValue()));

    if(item == null) {
        setStyle(null);
    } else {
        setStyle("-fx-background-color: " + (getTableRow().getItem().getType() == Type.ENTRY ? "#93C572" : "#CC0000" ));
    }
}

Note: For currency it's better to use BigDecimal to avoid rounding issues.