我有一个Java FX8表,我使用一个可观察的列表填充它。该表显示填充的数据。
在用户交互期间创建一个新行,我将这个新数据添加到可观察列表中。表格刷新了。
我知道如何移动焦点以及滚动到这个新添加的行。但是我希望突出显示该行以显示它是新添加的。
如何将整行作为节点引用,以便我可以使用此节点值突出显示该行。
答案 0 :(得分:3)
在创建rowFactory
的{{1}}上使用TableView
。 TableRow
是代表整行的TableRow
。稍微棘手的部分是确定行何时表示“最近添加的行”。
我会按如下方式处理。我将使用usual contact table example
Node
以代表最近添加的人员。大部分时间都是ObjectProperty<Person>
但是当新的null
添加到列表中时,它会设置为新的Person
: Person
在表的项目列表中注册final ObjectProperty<Person> recentlyAddedPerson = new SimpleObjectProperty<>();
。将新项目添加到列表后,请更新ListListener
。由于您不希望新用户无限期地标记为“新”,因此请在一段延迟(一两秒钟)后启动暂停转换,将recentlyAddedPerson
重置为recentlyAddedPerson
。
null
为表创建行工厂。此行工厂返回自定义final Duration timeToGetOld = Duration.seconds(1.0);
table.getItems().addListener((Change<? extends Person> change) -> {
while (change.next()) {
if (change.wasAdded()) {
List<? extends Person> addedPeople = change.getAddedSubList();
Person lastAddedPerson = addedPeople.get(addedPeople.size()-1);
recentlyAddedPerson.set(lastAddedPerson);
// set back to null after a short delay, unless changed since then:
PauseTransition agingTime = new PauseTransition(timeToGetOld);
agingTime.setOnFinished(event -> {
if (recentlyAddedPerson.get() == lastAddedPerson) {
recentlyAddedPerson.set(null);
}
});
agingTime.play();
}
}
});
。此自定义TableRow
会创建一个TableRow
,如果此行代表最近添加的行,则设置为true。 (如果行的项不为空并且等于上面定义的BooleanBinding
,则会出现这种情况。)
为了实际实现突出显示,我只想使用CSS PseudoClass。然后突出显示的实现变得微不足道;只需将伪类状态设置为recentlyAddedPerson
实现中定义的BooleanBinding
中的值。
所以你需要这样的东西:
TableRow
, final PseudoClass newPersonPseudoClass = PseudoClass.getPseudoClass("new");
看起来像
rowFactory
最后,只需将以下css添加到样式表中:
table.setRowFactory(tableView -> new TableRow<Person>() {
// Bindings API uses weak listeners, so this needs to be a field to
// make sure it stays in scope as long as the TableRow is in scope.
private final BooleanBinding itemIsNewPerson
= Bindings.isNotNull(itemProperty())
.and(Bindings.equal(itemProperty(), recentlyAddedPerson));
{
// anonymous constructor:
itemIsNewPerson.addListener((obs, wasNew, isNew)
-> pseudoClassStateChanged(newPersonPseudoClass, isNew));
}
});