如何强制TableRow重绘

时间:2017-06-01 12:16:22

标签: javafx

如何强制TableRow重绘?。

想象一下以下场景:tableView每180毫秒更新一次,但接收TableRow样式信息的单元格不可见,每次升级时都需要重新绘制TableRow。当我使用 refresh()方法时,它看起来不太好,特别是在TableView上使用鼠标定位时,它会闪烁,在这种情况下会占用cpu。

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;"); 

                        }   
                    }    
                }
            };

        }
    });    

1 个答案:

答案 0 :(得分:2)

由于样式取决于可观察的statusProperty()的{​​{1}},因此您可以使用绑定:

Line

创建绑定的另一种方法是

,如果逻辑更复杂可能更方便
@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("");
    } 
}

这样,表行将观察当前项的status属性,并在该属性发生更改时自动更新样式。

如果你真的想让代码更干净,你当然应该将样式移到外部CSS文件中。您可以创建一个CSS @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(""); } } (或多个),您可以在该行上设置和取消设置:

PseudoClass

然后在外部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添加更多伪造类,更多规则以及其他测试和伪类更新。