Javafx tableview changelistener经常更改

时间:2016-12-01 20:56:25

标签: java css javafx changelistener

我想根据状态为表中的行着色。搜索后我找到了这个Formatting Rows in a JavaFX TableView Using CSS Pseudo Classes

我试图为我的目的实现它。它也有效,但如果我滚动颜色将改回默认颜色 我究竟做错了什么?

if (ConfigurationManager.AppSettings["Environment"] == "DEV")
{
    ...
}

CSS:

@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;
        });
}

1 个答案:

答案 0 :(得分:1)

这个问题就在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类型的对象。如果传递equals,则true不可能以返回String的方式被覆盖(我建议不要以这种方式实现equals。)< / p>

您应该将新值传递给侦听器以触发更新,就好像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()