【问题标题】:How to define a cell's content based on the contents of an object's attribute using setCellFactory? [closed]如何使用 setCellFactory 根据对象属性的内容定义单元格的内容? [关闭]
【发布时间】:2020-05-31 22:28:53
【问题描述】:

我有一个名为“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);

一切正常! 但是,我想根据它返回的真/假,将当前为布尔值的 col2_sentOrReceived(在步骤 2 中)转换为字符串值。 有没有办法让单元格在布尔值为假时写 X 和在布尔值为真时写 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.
    }
}

【问题讨论】:

  • 单元格值工厂只是一个Callback&lt;TableColumn.CellDataFeatures&lt;S, T&gt;, ObservableValue&lt;T&gt;&gt;,这意味着您可以实现自己的工厂,只用一个lambda表达式来映射值。请注意,您必须将列的类型参数更改为TableColumn&lt;ChatMessage, OtherType&gt;。也就是说,改用cell factory 可能更容易(也可能更合适)。
  • 错误方法:更改数据,视图(又名:单元格)将自动跟随 :)
  • 在建议您应该去哪条路线来解决您的问题时没有任何居高临下的意思 - 您正在寻找错误的方向!坚持下去,你无法解决它,就这么简单......你必须了解 TableView 的机制,没有没有的方法。并且提供minimal reproducible example 是获得帮助的必要条件。
  • java 命名约定,拜托
  • 有趣。斯劳的理解没有问题。另外,很高兴看到你在跟踪我,即使一年过去了,你仍然无法弄清楚一个已经解决的问题的答案。向你致敬。请打开帖子并停止这个幼稚的游戏。或者继续……我只是喜欢打印你的仇恨行为。

标签: java javafx tableview tablecolumn


【解决方案1】:

感谢色拉的评论!它引导我朝着正确的方向前进。 我实现了我自己的工厂,它按照您的建议仅使用 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");
                }
            }
        });

【讨论】:

  • 很高兴您能够使用细胞工厂找到解决方案。尽管 kleopatra 可能是正确的,因为改变模型将是更好的解决方案。您提到出于数据库原因不想更改 ChatMessage,这是可以理解的,但您可以添加一种“翻译”模型类(例如,view model 之类的)。根据您的应用程序设计,这可能需要添加另一层抽象或至少是“胶水代码”,您可能接受也可能不接受。
  • 他编辑了他的回复,在此之前完全是另外一回事。无论如何,关于你的其他建议,我一定会考虑的。至于现在,这个更简单的方法对我有用:)
  • 小心性别假设 - 如果错误,它们可能会被视为冒犯(就像你的 一样)而且不,不可能编辑 cmets(除了前几分钟),看起来好像有些已经被删除了。
  • 它被删除,因为它所引用的消息被“优化”和编辑,所以它不再适用。再一次,另一个零贡献的评论,只是诽谤。 “坚持就解决不了”——半小时后解决了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
  • 2017-01-14
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-30
相关资源
最近更新 更多