JavaFX : Coloring TableView row and formatting the

2019-09-20 07:27发布

问题:

I've a TableView (located inside a ScrollPane), one of the rows is as follows:

tc_proj_amount.setCellValueFactory(cellData -> 
     new SimpleStringProperty(cellData.getValue().getBalance().toPlainString()));

I want to color the whole row where tc_proj_amount is negative. For this purpose I use this:

tc_proj_amount.setCellFactory(column -> new TableCell<Transaction, String>() {
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setText(null);

                } else {

                    setText(item);

                    // Style row where balance < 0 with a different color.
                    BigDecimal balance = new BigDecimal(item);
                    if (balance.compareTo(BigDecimal.valueOf(0)) < 0) {
                        TableRow currentRow = getTableRow();
                        currentRow.setStyle("-fx-background-color: tomato;");

                    }
                }
            }
        });

When I run my app, rows are colured as needed, but when I scroll up-down a list more and more rows become coloured, even when tc_proj_amount is not negative. When I try to sort columns, all rows become coloured. How can I fix this problem?

2nd question. I want to somehow format the value of tc_proj_amount. For this purpose I did this:

DecimalFormat df = new DecimalFormat("#,###.00");
tc_proj_amount.setCellValueFactory(cellData -> 
 new SimpleStringProperty(df.format(cellData.getValue().getBalance()).toString()));

Part that changes row colour is the same as above. In this case I receive an exception. How can I fix it?

Exception in thread "JavaFX Application Thread" java.lang.NumberFormatException

Exception is pointing into part where rows are colored.

回答1:

1) The rule of thumb when overriding the updateItem() method is to handle all cases of logical branching. Just like as setText() for both item empty and non-empty cases, you need to set the color when the balance>=0 (i.e. the "else" case). In future, you are likely go with using css selectors instead of inline styling, so the common approach will be:

if(condition)
    item.getStyleClass().add("css");
else
    item.getStyleClass().remove("css");

2) You already have a cellFactory, format the text in there, no need for cellValueFactory.

setText(df.format(item));


回答2:

I believe your first question has been answered here: https://stackoverflow.com/a/12425646

In summary the cells are being destroyed and recreated when scrolling, and indirectly destroying your colour changes.