gpt4 book ai didi

css - JavaFX - 使用 setRowFactory 突出显示新行

转载 作者:太空宇宙 更新时间:2023-11-04 07:35:39 25 4
gpt4 key购买 nike

我正在编写一个 JavaFX 应用程序,其中一系列消息显示在 TableView 中。当一条新消息出现时,它在表格中的行应该突出显示,这意味着它的背景颜色应该是橙色或其他颜色。一旦用户点击它,背景颜色应该清除,确认消息已被阅读。应该很简单。

我已经做了足够的研究,意识到我需要使用 rowFactory 来设置或清除行的背景。但我正在为 setRowFactory() 的机制而苦苦挣扎。关于 Oracle 的文档让我头疼,我在网上找到的每个示例似乎都与上一个完全不同。

这是我所拥有的:

public class Message {
private boolean readOnce;
private int date;
private String msg;

public Message(int date, String msg, String msg2){
this.readOnce = false;
this.date = date;
this.msg = msg;
}

public boolean isReadOnce() {
return readOnce;
}
public void setReadOnce(){
readOnce = true;
}
// ...and more standard getters & setters here...
}

在主 Controller 中设置TableView:

    @FXML   TableView<Message> messageTable;
@FXML TableColumn<Message, Integer> Col1;
@FXML TableColumn<Message, String> Col2;
ObservableList<Message> tableItems;

// ...

// Setting up the Table:
PropertyValueFactory<Message, Integer> dateProperty = new PropertyValueFactory<Message, Integer>("date");
PropertyValueFactory<Message, String> msgProperty = new PropertyValueFactory<Message, String>("msg");
Col1.setCellValueFactory( dateProperty );
Col2.setCellValueFactory( msgProperty );
messageTable.setItems( tableItems );

// If we click an item in the table: messageTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null) {
System.out.println("Troubleshoot: You clicked: "+newSelection.getMsg());
newSelection.setReadOnce(true);
}
});

如果我想向表中添加一条新消息,我只需将其添加到可观察列表中即可:

public void addMsg(int num, String msg){
tableItems.add(new Message(num, msg));
}

到目前为止,非常简单。但是当涉及到 rowFactory 时,我完全不赞成:

    messageTable.setRowFactory(messageTable -> {
TableRow<Message> row = new TableRow<>();
ObjectProperty<Message> opMsg = row.itemProperty();
Message tmpMsg = opMsg.get();
if(!tmpMsg.isReadOnce()){
row.getStyleClass().add("highlight-message"); // defined in CSS
} else {
row.getStyleClass().add("clear-message"); // defined in CSS
}
return row;
});

老实说,我不知道我在这里做什么。我知道 rowFactory 接收整个表并逐行重新生成每一行。我不明白的是 RowFactory 代码如何检查表中的每个 Message 以及我如何访问它们?最初我认为这些行可能会让我看到行内的消息:

        TableRow<Message> row = new TableRow<>();
ObjectProperty<Message> opMsg = row.itemProperty();
Message tmpMsg = opMsg.get();

但是当我调试代码时,tmpMsg == NULL。所以这是一个巨大的死胡同。

有人看到我做错了什么吗?我已经对此进行了大约一个星期的研究,但绝对无处可去。非常感谢任何人可以提供的任何帮助。

非常感谢,-饶

最佳答案

TableRowTableView 创建以填充其视口(viewport)并包含 TableCell。在创建它们时,item 属性仍包含默认值 null。您可以为该属性注册一个监听器,但通常我更喜欢重写单元格的 updateItem 方法。

此外,使用 PseudoClass 比使用样式类更简单。新元素可以分配到一行;这可能会导致多次添加相同的样式类,甚至可能将两个样式类都添加到同一个单元格中。但是,PseudoClasses 可以打开/关闭,而无需注意删除其他类。

final PseudoClass highlightMessage = PseudoClass.getPseudoClass("highlight-message");

messageTable.setRowFactory(messageTable -> new TableRow<Message>() {

{
selectedProperty().addListener((o, oldVal, newVal) -> {
if (newVal) {
Message item = getItem();
if (item != null) {
item.setReadOnce();
pseudoClassStateChanged(highlightMessage, false);
}
}
});
}

@Override
protected void updateItem(Message item, boolean empty) {
super.updateItem(item, empty);

pseudoClassStateChanged(highlightMessage, item != null && !item.isReadOnce());
}

});

在 CSS 样式表中,您可以使用如下规则:

.table-row-cell:filled {
/* style for non-highlighted rows */
}

.table-row-cell:filled:highlight-message {
/* style for highlighted rows */
}

请注意,这不允许您以编程方式更改读取状态。它更新选择单元格的状态。您可以将 BooleanProperty 添加到 Message 或使用 ObservableSet 来存储突出显示的消息并在需要时从监听器更新单元格状态以编程方式更新 readOnce 属性。在后一种情况下,您不需要在 Message 本身中存储 readOnce 属性...

关于css - JavaFX - 使用 setRowFactory 突出显示新行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48979109/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com