Javafx 如何强制TableRow重新绘制
如何强制TableRow重新绘制 设想以下场景:tableView每180毫秒更新一次,但是接收TableRow样式信息的单元格不可见,并且每次升级TableRow时都需要重新绘制。当我使用refresh()方法时,它看起来不太好,特别是当鼠标定位在TableView上时,它会闪烁,在这种情况下会消耗cpuJavafx 如何强制TableRow重新绘制,javafx,Javafx,如何强制TableRow重新绘制 设想以下场景:tableView每180毫秒更新一次,但是接收TableRow样式信息的单元格不可见,并且每次升级TableRow时都需要重新绘制。当我使用refresh()方法时,它看起来不太好,特别是当鼠标定位在TableView上时,它会闪烁,在这种情况下会消耗cpu myTableView.setRowFactory( new Callback<TableView, TableRow<Line>>() { @Ov
myTableView.setRowFactory( new Callback<TableView, TableRow<Line>>() {
@Override
public TableRow call(final TableView p) {
return new TableRow<Line>() {
@Override
public void updateItem(Line item, boolean empty) {
super.updateItem(item, empty);
if(item != null) {
if(item.statusProperty().getValue().equals("BORDER")) {
setStyle("-fx-border-color:green;-fx-border-width:2;-fx-opacity:1;");
}
}
}
};
}
});
myTableView.setRowFactory(新回调(){
@凌驾
公共TableRow调用(最终TableView p){
返回新的TableRow(){
@凌驾
public void updateItem(行项目,布尔值为空){
super.updateItem(项,空);
如果(项!=null){
if(item.statusProperty().getValue().equals(“边框”)){
设置样式(“-fx边框颜色:绿色;-fx边框宽度:2;-fx不透明度:1;”);
}
}
}
};
}
});
由于样式取决于可观察的行的statusProperty()
,因此可以使用绑定:
@Override
public void updateItem(Line item, boolean empty) {
super.updateItem(item, empty);
if(item != null) {
styleProperty().bind(Bindings
.when(item.statusProperty().isEqualTo("BORDER"))
.then("-fx-border-color:green;-fx-border-width:2;-fx-opacity:1;")
.otherwise(""));
} else {
styleProperty().unbind();
setStyle("");
}
}
另一种创建绑定的方法是
@Override
public void updateItem(Line item, boolean empty) {
super.updateItem(item, empty);
if(item != null) {
styleProperty().bind(Bindings.createStringBinding(() -> {
if ("BORDER".equals(item.getStyle())) {
return "-fx-border-color:green;-fx-border-width:2;-fx-opacity:1;" ;
} else {
return "" ;
}
}, item.statusProperty());
} else {
styleProperty().unbind();
setStyle("");
}
}
这样,表行将观察当前项的status属性,并在该属性更改时自动更新样式
当然,如果您真的想让代码更干净,您应该将样式移动到外部CSS文件中。您可以创建一个CSS伪类(或多个),您可以在行上设置和取消设置该类:
final PseudoClass borderPC = PseudoClass.getPseudoClass("border");
myTableView.setRowFactory(p -> {
TableRow<Line> row = new TableRow<>();
ChangeListener<String> statusListener = (obs, oldStatus, newStatus) ->
row.pseudoClassStateChanged(borderPC, "BORDER".equals(newStatus)) ;
row.itemProperty().addListener((obs, oldLine, newLine) -> {
if (oldLine != null) {
oldLine.statusProperty().removeListener(statusListener);
}
if (newLine == null) {
row.pseudoClassStateChanged(borderPC, false);
} else {
newLine.statusProperty().addListener(statusListener);
row.pseudoClassStateChanged(borderPC, "BORDER".equals(newLine.getStatus()));
}
};
return row ;
});
同样,使用这种方法,您可以轻松地向CSS添加更多的psuedo类、更多的规则以及其他测试和伪类更新。这个解决方案非常有趣。但是…,如果我有很多示例选择,如果“Border”然后“-fx Border color:绿色;-fx Border width:2;-fx opacity:1;“如果“OpacityOff”然后“-fx opacity:0.3”;其他…@Tretonis您可以在调用中包装更多绑定。when().then().other()
,但这很快就会变得难看。我用另一种更容易扩展到更复杂逻辑的方法编辑了答案。非常感谢您分享您的时间和知识。伪类解决方案中似乎缺少括号。我无法添加它,因为编辑至少需要6个字符。。。