TableView setRowFactory CSS 选择器

TableView setRowFactory CSS selector

我想根据该行中的项目在 TableView 中呈现完整的行。我使用 TableView.setRowFactory,但似乎这不起作用。

如您在代码中所见,如果该行中人员的姓氏为 "Smith"。

,则应使用不同的文本颜色呈现该行

如果我使用 TableColumn.setCellFactory,同样的代码可以工作。但我不想在所有不同的细胞工厂中复制必要的代码。

我哪里错了?

public class TableViewTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        final Scene scene = new Scene(createContents());
        scene.getStylesheets().add(getClass().getResource("test.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Pane createContents() {
        final ObservableList<Person> items = FXCollections.observableArrayList(
                new Person("John", "Smith"), new Person("Mary", "Smith"),
                new Person("William", "Young"));
        final TableView<Person> table = new TableView<>(items);
        final TableColumn<Person, String> c1 = new TableColumn<>("First name");
        c1.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().getFName()));
        final TableColumn<Person, String> c2 = new TableColumn<>("Last name");
        c2.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().getLName()));
        table.getColumns().setAll(c1, c2);
        table.setRowFactory(param -> new TableRow<Person>() {
            protected void updateItem(Person item, boolean empty) {
                super.updateItem(item, empty);
                getStyleClass().remove("own-cell");
                if (item != null && item.getLName().equals("Smith")) {
                    getStyleClass().add("own-cell");
                }
            };
        });
        return new HBox(table);
    }
}

这是简单的样式 sheet test.css 只有一种样式:

.table-row-cell:filled .own-cell {
    -fx-text-fill: cyan;
}

您的 CSS 不正确: select 或

.table-row-cell:filled .own-cell

selects 样式为 class own-cell 的元素是样式为 class 的元素的 后代 table-row-cell(并且有伪class filled)。

您需要 select 任何 table-cell 是具有两种样式的元素的后代 class own-cell table-row-cell.

以下将执行此操作:

.own-cell.table-row-cell:filled .table-cell {
    -fx-text-fill: cyan;
}

请注意 .own-cell.table-row-cell 之间没有 space。

顺便说一句,如果你有一个可以用布尔表达式打开或关闭的 CSS class,通常使用自定义 PseudoClass 比添加更容易并从列表中删除样式 classes。您可以考虑进行以下修改:

    PseudoClass ownCell = PseudoClass.getPseudoClass("own-cell");
    table.setRowFactory(param -> new TableRow<Person>() {
        protected void updateItem(Person item, boolean empty) {
            super.updateItem(item, empty);
            pseudoClassStateChanged(ownCell, item != null && item.getLName().equals("Smith"));
        };
    });

您使用 CSS

.table-row-cell:filled:own-cell .table-cell {
    -fx-text-fill: cyan;
}