-1

I've created a class called "ChatMessage" with 3 attributes:

a) timeOfMessage
b) sentOrReceived
c) message

and chat messages are stored inside an array of ChatMessages. I've defined a tableView, and 3 tableColumns (for a, b and c), like so:

// ------------------------
// Step 1: Define tableView
// ------------------------
@FXML private TableView<ChatMessage> tableViewAllMessages;

// ---------------------------
// Step 2: Define table's data
// ---------------------------
private ObservableList<ChatMessage> allMessagesList;

// --------------------------------
// Step 3: Define table's 3 columns
// --------------------------------
@FXML private TableColumn<ChatMessage, LocalDateTime> timeColumn;
@FXML private TableColumn<ChatMessage, Boolean> sentOrReceivedColumn;
@FXML private TableColumn<ChatMessage, String> messageColumn;

// ---------------------------------
// Step 4: Using setCellValueFactory
// ---------------------------------
timeColumn.setCellValueFactory(new PropertyValueFactory<ChatMessage,LocalDateTime>("dateTime"));
sentOrReceivedColumn.setCellValueFactory(new PropertyValueFactory<ChatMessage, Boolean>("sentOrReceived"));
messageColumn.setCellValueFactory(new PropertyValueFactory<ChatMessage,String>("message"));
tableViewAllMessages.setItems(allMessagesList);

Everything works fine! However, I would like to turn sentOrReceivedColumn (in Step 2), which currently of a boolean value, into a string value, based on the true/false it returns. Is there a way to make a cell write 'someStringA' when false and 'someStringB' when true? To be more specific, what do I need to change in here:

sentOrReceivedColumn.setCellValueFactory(new PropertyValueFactory<ChatMessage, Boolean>("sentOrReceived"));

or maybe add a line like this:

sentOrReceivedColumn.setCellFactory(/* But what Do I write here? */);

?


// Here is my ChatMessage Class:
public class ChatMessage {
    private Customer customer;
    private int messageNumber;
    private LocalDateTime dateTime;
    private String message;
    private boolean sentOrReceived;

    public ChatMessage(Customer customer, int messageNumber, LocalDateTime dateTime, String message, boolean sentOrReceived) {
        this.customer = customer;
        this.messageNumber = messageNumber;
        this.dateTime = dateTime;
        this.message = message;
        this.sentOrReceived = sentOrReceived;
    }
}
Tal Kohavy
  • 438
  • 2
  • 8
  • 22
  • 2
    The cell value factory is just a `Callback, ObservableValue>`, which means you can implement your own factory that maps the value with just a lambda expression. Note you'll have to change the type arguments of the column to `TableColumn`. That said, it may be easier (and possibly more appropriate) to use a [cell factory](https://openjfx.io/javadoc/13/javafx.controls/javafx/scene/control/TableColumn.html#cellFactoryProperty) for this instead. – Slaw Feb 17 '20 at 06:57

1 Answers1

0

Thank you Slaw for your comment! It steered me in the right direction. I implemented my own factory that maps the value with just a lambda expression as you suggested. This was the answer I was looking for:

col2_Nickname.setCellFactory(lambda -> new TableCell<ChatMessage, Boolean>() {
            @Override
            public void updateItem(Boolean sentOrReceived, boolean empty) {
                super.updateItem(sentOrReceived, empty);
                if (empty) {
                    setText(null);
                }else{
                    setText(sentOrReceived ? "MyNickname" : "His/Her nickname");
                }
            }
        });
Tal Kohavy
  • 438
  • 2
  • 8
  • 22
  • 1
    I'm glad you were able to find a solution using a cell factory. Though kleopatra is probably correct in that changing the model would be the better solution. You mention you don't want to change `ChatMessage` for database reasons, which is understandable, but you could add a sort of "translation" model class (e.g. a _view model_ of sorts). Depending on your application design this may require adding another layer of abstraction or at least "glue code", which may or may not be acceptable to you. – Slaw Feb 17 '20 at 15:55
  • be careful with gender assumptions - they could be construed as being offensive if wrong (as yours is ) And no, not possible to edit comments (except in the first couple of minutes), looks like some have been deleted. – kleopatra Feb 17 '20 at 16:45