JavaFX:将新行添加到 table 后更改单元格颜色

JavaFX: Change cell color after adding new row to the table

我有一个程序可以读取某些文件,然后在 table 中显示值。用户可以通过按钮添加新行。

现在我想更改添加行的背景颜色,以便用户可以看到新旧内容。

我现在的问题是,如何直接select新行然后改变背景颜色?

我知道如何使用 class TablePosition 获取单个单元格的位置。

例子

TablePosition pos = tableView.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
int col = pos.getColumn();
TableColumn column = pos.getTableColumn();

但是如果我想要整行,它是如何工作的呢?

预期结果

最后我希望我可以对添加的行进行 select 编辑,以便我可以更改背景颜色。

创建一个可以存储新项目的可观察集合。ObservableSet 做得很好。

进一步为 TableView 创建自定义 rowFactory。每次项目或集合更改时,工厂创建的行都会更新样式。这使您可以非常轻松地修改所选项目。

示例:

@Override
public void start(Stage primaryStage) throws Exception {
    // bad design here, but this type is not important
    class Item {
        final StringProperty value;

        Item(String value) {
            this.value = new SimpleStringProperty(value);
        }
    }

    TableView<Item> table = new TableView();

    TableColumn<Item, String> column = new TableColumn<>("value");
    column.setCellValueFactory(i -> i.getValue().value);
    table.getColumns().add(column);

    for (int i = 0; i < 20; i++) {
        table.getItems().add(new Item(Integer.toString(i)));
    }

    // set storing items to be marked as new
    final ObservableSet<Item> newItems = FXCollections.observableSet(new HashSet<>());

    final PseudoClass newPc = PseudoClass.getPseudoClass("new");
    table.setRowFactory(t -> new TableRow<Item>() {

        private final InvalidationListener l = o -> update();

        // prevent memory leak for cells that are "thrown away"
        private final WeakInvalidationListener listener = new WeakInvalidationListener(l);

        {
            newItems.addListener(listener);
        }

        private void update() {
            pseudoClassStateChanged(newPc, isEmpty() || newItems.contains(getItem()));
        }

        @Override
        protected void updateItem(Item item, boolean empty) {
            super.updateItem(item, empty);
            update();
        }

    });

    // create buttons modifying the new items

    Button addButton = new Button("add");
    addButton.setOnAction(new EventHandler<ActionEvent>() {

        int counter = 20;

        @Override
        public void handle(ActionEvent event) {
            for (int i = 0; i < 3; i++, counter++) {
                Item item = new Item(Integer.toString(counter));
                newItems.add(item);
                table.getItems().add(item);
            }
        }

    });

    Button clearNew = new Button("clear new");
    clearNew.setOnAction(evt -> newItems.clear());

    Scene scene = new Scene(new HBox(table, new VBox(addButton, clearNew)));
    scene.getStylesheets().add(getClass().getResource("/path/to/my/style.css").toString());

    primaryStage.setScene(scene);
    primaryStage.show();
}

style.css

.table-row-cell:new {
    -fx-background: #DDDD00;
}

.table-row-cell:new:selected {
    -fx-background: #BBBB00;
}