如何使用 setCellFactory 根据对象属性的内容定义单元格的内容?
How to define a cell's content based on the contents of an object's attribute using setCellFactory?
我有一个名为“ChatMessage”的对象,它具有 3 个属性:
a) timeOfMessage
b) sentOrReceived
c) message
有了它我可以创建许多聊天消息,我将它们存储在 ChatMessages 列表中。
我已经定义了一个 tableView,3 个 tableColumns(对于 a、b 和 c),如下所示:
//------------------------
//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> col1_Time;
@FXML private TableColumn<ChatMessage, Boolean> col2_sentOrReceived;
@FXML private TableColumn<ChatMessage, String> col3_Message;
//---------------------------------
//Step 4: Using setCellValueFactory
//---------------------------------
col1_Time.setCellValueFactory(new PropertyValueFactory<ChatMessage,LocalDateTime>("dateTime"));
col2_sentOrReceived.setCellValueFactory(new PropertyValueFactory<ChatMessage, Boolean>("sentOrReceived"));
col3_Message.setCellValueFactory(new PropertyValueFactory<ChatMessage,String>("message"));
tableViewAllMessages.setItems(allMessagesList);
一切正常!
但是,我想根据 true/false 它 returns 将当前为布尔值的 col2_sentOrReceived(在步骤 2 中)转换为字符串值。
有没有办法让单元格在布尔值为 false 时写入 X,在布尔值为 true 时写入 Y?
我需要在这里更改什么:
col2_sentOrReceived.setCellValueFactory(new PropertyValueFactory<ChatMessage, Boolean>("sentOrReceived"));
或者添加这样一行:
col2_sentOrReceived.setCellFactory(/* But what to write here? */);
?
//-----------------------------
//Here is my ChatMessage Class:
//-----------------------------
public class ChatMessage {
//11111111111111111111111111
//11111111111111111111111111
// ----- CLASS FIELDS -----
private Customer customer;
private int messageNumber;
private LocalDateTime dateTime;
private String message;
private boolean sentOrReceived;
//22222222222222222222222222222222222222222
//22222222222222222222222222222222222222222
//22222222222222222222222222222222222222222
//---------- Temp Creation --------------
//---------- Temp Creation --------------
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; //Assumming one side is always me.
}
}
谢谢 Slaw 的评论!它引导我朝着正确的方向前进。
我实现了自己的工厂,按照您的建议仅使用 lambda 表达式映射值。这就是我要找的答案:
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");
}
}
});
我有一个名为“ChatMessage”的对象,它具有 3 个属性:
a) timeOfMessage
b) sentOrReceived
c) message
有了它我可以创建许多聊天消息,我将它们存储在 ChatMessages 列表中。 我已经定义了一个 tableView,3 个 tableColumns(对于 a、b 和 c),如下所示:
//------------------------
//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> col1_Time;
@FXML private TableColumn<ChatMessage, Boolean> col2_sentOrReceived;
@FXML private TableColumn<ChatMessage, String> col3_Message;
//---------------------------------
//Step 4: Using setCellValueFactory
//---------------------------------
col1_Time.setCellValueFactory(new PropertyValueFactory<ChatMessage,LocalDateTime>("dateTime"));
col2_sentOrReceived.setCellValueFactory(new PropertyValueFactory<ChatMessage, Boolean>("sentOrReceived"));
col3_Message.setCellValueFactory(new PropertyValueFactory<ChatMessage,String>("message"));
tableViewAllMessages.setItems(allMessagesList);
一切正常! 但是,我想根据 true/false 它 returns 将当前为布尔值的 col2_sentOrReceived(在步骤 2 中)转换为字符串值。 有没有办法让单元格在布尔值为 false 时写入 X,在布尔值为 true 时写入 Y? 我需要在这里更改什么:
col2_sentOrReceived.setCellValueFactory(new PropertyValueFactory<ChatMessage, Boolean>("sentOrReceived"));
或者添加这样一行:
col2_sentOrReceived.setCellFactory(/* But what to write here? */);
?
//-----------------------------
//Here is my ChatMessage Class:
//-----------------------------
public class ChatMessage {
//11111111111111111111111111
//11111111111111111111111111
// ----- CLASS FIELDS -----
private Customer customer;
private int messageNumber;
private LocalDateTime dateTime;
private String message;
private boolean sentOrReceived;
//22222222222222222222222222222222222222222
//22222222222222222222222222222222222222222
//22222222222222222222222222222222222222222
//---------- Temp Creation --------------
//---------- Temp Creation --------------
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; //Assumming one side is always me.
}
}
谢谢 Slaw 的评论!它引导我朝着正确的方向前进。 我实现了自己的工厂,按照您的建议仅使用 lambda 表达式映射值。这就是我要找的答案:
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");
}
}
});