JavaFX: изменить цвет ячейки после добавления новой строки в таблицу - PullRequest
0 голосов
/ 11 октября 2019

У меня есть программа, которая читает определенные файлы, а затем отображает значения в таблице. Пользователь может добавлять новые строки с помощью кнопки.

Теперь я хочу изменить цвет фона добавленной строки, чтобы пользователь мог видеть, что нового и что старое.

Теперь у меня вопрос: как я могу выбрать новую строку напрямую и затем изменить цвет фона?

Я знаю, как получить позицию в одной ячейке с классом TablePosition .

Пример

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

Но как это работает, если я хочу всю строку?

Ожидаемый результат

В конце я ожидаю, что я могу добавить добавленную строку, чтобы я мог изменить цвет фона.

1 Ответ

2 голосов
/ 11 октября 2019

Создайте наблюдаемую коллекцию, в которой вы можете хранить новые предметы. ObservableSet хорошо справляется с работой.

Более того, создайте пользовательский rowFactory для TableView. Строки, созданные фабрикой, обновляют стиль каждый раз, когда изменяется элемент или коллекция. Это позволяет довольно легко изменять выбранные элементы.

Пример:

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