JavaFX TableView: format one cell based on the value of another in the row

6.1k Views Asked by At

I have a class named TransactionWrapper I'm using to populate my ObservableList for the TableView in my application. This wrapper has an attribute (enum) indicating whether it is a withdrawal or a deposit. I need to get to that to render/format the amount cell (display it in red or green based on the nature of the transaction) and I'm not finding anything out there that is helping me with that battle.

Basically what I want to do is look at the row and say if the type is withdrawal, color the text red and if it's a deposit color it green... I'm hoping someone here can help me out with this. I'll post below my attempt at it with setCellFactory as I found in other places. This approach allows me to format the cell and how it is displayed but the problem is inside of the updateItem function, I can get to my value of my transaction type.

amountCol.setCellFactory(new Callback<TableColumn<TransactionWrapper, String>, TableCell<TransactionWrapper, String>>()
{
    @Override
    public TableCell<TransactionWrapper, String> call(
            TableColumn<TransactionWrapper, String> param)
    {
        return new TableCell<TransactionWrapper, String>()
        {
            @Override
            protected void updateItem(String item, boolean empty)
            {
                if (!empty)
                {
                    // should be something like (transaction.getType().equals(TransactionTypes.DEPOSIT) ? true : false;)
                    boolean isDeposit = true;
                    setText(item);                          
                    if(isDeposit) // should be if type is deposit
                    {
                        setTextFill(Color.GREEN);
                    }
                    else                            
                    {
                        setTextFill(Color.RED);
                    }
                }
            }
        };
    }
});

And here's how I'm setting up my column:

amountCol.setCellValueFactory(cellData -> cellData.getValue().getAmountString());

That is running off of an object called TransactionWrapper with the fol:

private final StringProperty transactionTypeString;
private final StringProperty dateString;
private final StringProperty amountString;
private final StringProperty payeeString;
private final StringProperty categoryString;
private final StringProperty notesString;
private Transaction transaction;

Any ideas on this would be much appreciated. :D

Thanks, Jon

1

There are 1 best solutions below

2
On BEST ANSWER

Figured it out! Thanks for the idea James, but I went a bit of a different way. Here's the code for anyone in the future reading this post:

amountCol.setCellFactory(new Callback<TableColumn<TransactionWrapper, String>, 
            TableCell<TransactionWrapper, String>>()
            {
                @Override
                public TableCell<TransactionWrapper, String> call(
                        TableColumn<TransactionWrapper, String> param)
                {
                    return new TableCell<TransactionWrapper, String>()
                    {
                        @Override
                        protected void updateItem(String item, boolean empty)
                        {
                            if (!empty)
                            {
                                int currentIndex = indexProperty()
                                        .getValue() < 0 ? 0
                                        : indexProperty().getValue();
                                TransactionTypes type = param
                                        .getTableView().getItems()
                                        .get(currentIndex).getTransaction()
                                        .getTransactionType();
                                if (type.equals(TransactionTypes.DEPOSIT))
                                {
                                    setTextFill(Color.GREEN);
                                    setText("+ " + item);
                                } else
                                {
                                    setTextFill(Color.RED);
                                    setText("- " + item);
                                }
                            }
                        }
                    };
                }
            });

The param.getTableView().getItems().get(currentIndex) was key.. had to drill into the parent a bit there, but it got the job done. The biggest challange there was finding the index. Felt a bit silly when I figure out that the indexProperty() function existed.. lol. Didn't think to look at the class level functions that were available. Happy coding!