繁体   English   中英

JavaFX TableView ChangeListener经常更改

[英]Javafx tableview changelistener changes to often

我想根据状态为表中的行上色。 搜索之后,我在使用CSS伪类的JavaFX TableView中找到了这种格式化行

我尝试实现此目的。 它也可以使用,但是如果我滚动,颜色将变回默认的颜色。
我究竟做错了什么?

@FXML
private void initialize(){

    PseudoClass online = PseudoClass.getPseudoClass("online");
    PseudoClass offline = PseudoClass.getPseudoClass("offline");
    PseudoClass unknown = PseudoClass.getPseudoClass("unknown");

    //Set a rowFactory for the table view.
    overviewTable.setRowFactory(tableView -> {
            TableRow<State> row = new TableRow<>();
            ChangeListener<String> changeListener = (obs, oldValue, newValue) -> {
                System.out.println("1: " + obs + " : " + oldValue + " : " + newValue);
                row.pseudoClassStateChanged(online, newValue.equals("online"));
                row.pseudoClassStateChanged(offline, newValue.equals("offline"));
                row.pseudoClassStateChanged(unknown, newValue.equals("unknown"));
            };

            row.itemProperty().addListener((obs, oldValue, newValue) -> {
                System.out.println("2: " + obs + " : " + oldValue + " : " + newValue);
                if (oldValue != null) {
                    oldValue.stateProperty().removeListener(changeListener);
                }
                if (newValue != null) {
                    newValue.stateProperty().addListener(changeListener);
                    row.pseudoClassStateChanged(online, newValue.equals("online"));
                    row.pseudoClassStateChanged(offline, newValue.equals("offline"));
                    row.pseudoClassStateChanged(unknown, newValue.equals("unknown"));
                } else {
                    row.pseudoClassStateChanged(online, false);
                    row.pseudoClassStateChanged(offline, false);
                    row.pseudoClassStateChanged(unknown, false);
                }
            });
            return row;
        });
}

CSS:

.table-row-cell:unknown{
-fx-background-color: blue;
}

.table-row-cell:online{
-fx-background-color: #2EAB15;
}

.table-row-cell:offline{
-fx-background-color: #BB0000;
}

.table-row-cell .text{
-fx-fill: white;
}

问题就在item属性的侦听器中:

if (newValue != null) {
    newValue.stateProperty().addListener(changeListener);
    row.pseudoClassStateChanged(online, newValue.equals("online"));
    row.pseudoClassStateChanged(offline, newValue.equals("offline"));
    row.pseudoClassStateChanged(unknown, newValue.equals("unknown"));

这里newValueState类型的对象。 如果传递了String ,则不太可能以返回true的方式覆盖equals (并且我建议不要以这种方式实现equals )。

相反,您应该将新值传递给侦听器以触发更新,就像state属性的值已更改一样:

if (newValue != null) {
    newValue.stateProperty().addListener(changeListener);
    changeListener.changed(null, null, newValue.getState());

或者将其与state属性进行比较(尽管这违反了DRY原理):

if (newValue != null) {
    newValue.stateProperty().addListener(changeListener);
    row.pseudoClassStateChanged(online, newValue.getState().equals("online"));
    row.pseudoClassStateChanged(offline, newValue.getState().equals("offline"));
    row.pseudoClassStateChanged(unknown, newValue.getState().equals("unknown"));

我在这里假设State类包含一个getState()方法,该方法返回state属性的内容。 如果不是这种情况,则对该方法的所有调用都需要替换为stateProperty().getValue()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM