有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java TableRow样式类在排序TableView时不固定到行

我想根据行项目中的布尔值向表行添加/删除样式类

通过以下代码,添加和删除类的效果与预期一致。但是,当我单击列标题对表进行重新排序时,样式将保留行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;
});

我希望我想要实现的目标是明确的。如何在重新排序时使样式保持在行项目上


共 (2) 个答案

  1. # 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[]中返回的属性项的更改

  2. # 2 楼答案

    您从未从旧项目中注销侦听器。此外,不调用侦听器获取属性的初始值。即使是这样,您的代码也可能会导致同一样式的类被多次添加到节点中。此外,细胞可能会变空。在这种情况下,也需要删除样式类

    要避免多次添加同一样式类,请使用伪类:

    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。)