我想根据行项中的布尔值将样式类添加/删除到表行。
使用以下代码添加和删除类可以按预期工作。但是,当我单击列标题以重新排序表时,样式会粘贴到行ID而不是行项。意思是如果在订购之前第一行被设置样式,在订购之后样式仍然在第一行而不是新位置的行。
setRowFactory(table -> {
TableRow<PowerPlantPM> row = new TableRow<>() {
@Override
protected void updateItem(PowerPlantPM pp, boolean empty) {
super.updateItem(pp, empty);
if (!empty && pp != null) {
pp.savedProperty().addListener((observable, oldValue, newValue) -> {
if (newValue) {
getStyleClass().remove("unsaved");
} else {
getStyleClass().add("unsaved");
}
});
// the following binding works (including ordering), but is not what I want because of the ":selected" pseudo class
// styleProperty().bind(Bindings.when(pp.savedProperty()).then("").otherwise("-fx-background-color: #f2dede"));
}
}
};
return row;
});
我希望很清楚我想要实现的目标。重新排序时,如何让样式粘在行项上?
答案 0 :(得分:1)
尽可能重用TableRow
,在updateItem
中,您需要查询相应的属性,而不是向其添加侦听器。只有在属性发生变化时才会触发监听器,但TableRow
可能会要求重新绘制其他位置或不同的项目。
protected void updateItem(PowerPlantPM pp, boolean empty) {
super.updateItem(pp, empty);
if (!empty && pp != null) {
if (!pp.isSaved()) {
getStyleClass().add("unsaved");
} else {
getStyleClass().remove("unsaved");
}
.....
}
}
使用
创建的属性创建ObservableList
ObservableListFX<PowerPlantPM> powerplants =
Collections.observableArrayList(pp -> new Observable[] { pp.savedProperty() });
此列表将报告您在Observable[]
。
答案 1 :(得分:1)
您永远不会从旧项目中取消注册侦听器。此外,不会为侦听器调用属性的初始值。即使它是,您的代码也可能导致相同的样式类被多次添加到节点。此外,细胞可能变空。在这种情况下你也需要删除样式类。
为避免多次添加相同的样式类,请使用伪类:
final PseudoClass unsaved = PseudoClass.getPseudoClass("unsaved");
setRowFactory(table -> {
TableRow<PowerPlantPM> row = new TableRow<>() {
private final ChangeListener<Boolean> listener = (observable, oldValue, newValue) -> {
pseudoClassStateChanged(unsaved, !newValue);
};
@Override
protected void updateItem(PowerPlantPM pp, boolean empty) {
PowerPlantPM oldItem = getItem();
if (oldItem != null) {
// remove old listener
oldItem.savedProperty().removeListener(listener);
}
super.updateItem(pp, empty);
if (empty || pp == null) {
// remove pseudoclass from empty cell
pseudoClassStateChanged(unsaved, false);
} else {
// add new listener & handle initial value
pp.savedProperty().addListener(listener);
pseudoClassStateChanged(unsaved, pp.isSaved());
}
}
};
return row;
});
(当然,您需要调整CSS选择器以使用:unsaved
而不是.unsaved
。)