Я согласен с комментарием @kleopatra.Вы не можете выполнять сложную обработку данных внутри ячейки.В основном ваш Row / Cell / updateItem () должен больше фокусироваться на том, «как / что визуализировать». Я могу предложить вам несколько ключевых направлений, на которые вы можете взглянуть.
Если вы хотите обновить свой стиль строк на основепри некотором обновлении элемента (не из-за добавления / удаления элемента, а из-за обновления в свойстве элемента) вы должны сначала прослушать изменения.
Установка ListChangeListener только для ObservableList приведет кне уведомлять вас о любых изменениях, произошедших «в пределах» свойств. Вы должны зарегистрировать свой ObservableList со свойствами, которые вас интересуют, и должны быть уведомлены при обновлении. Поэтому ObservableList, который вы собираетесь установить в TableView, должен быть зарегистрирован / объявленчто-то вроде ниже: *
ObservableList<Person> persons = FXCollections.observableArrayList(e ->
new Observable[]{e.pointsProperty()});
Приведенный выше код заставляет запускать ListChangeListener ObservableList при обновлении pointsProperty. Оттуда вы можете выполнить то, что вам нужно.
Ниже приведена быстро работающая демонстрациявыделять строку на 3 секунды при каждом обновлении столбца ОчкиМНБ.Я надеюсь, что эта демонстрация поможет вам решить вашу проблему.Это один из подходов.Могут быть более лучшие способы для достижения нижеуказанной функции.Вы все еще можете воспользоваться решением @fabian.
Примечание: Использовать тот же файл CSS, который вы указали.
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.Duration;
import java.security.SecureRandom;
public class TableRowUpdateHighlightDemo extends Application {
private final SecureRandom rnd = new SecureRandom();
@Override
public void start(Stage primaryStage) throws Exception {
ObservableList<Person> persons = FXCollections.observableArrayList(e -> new Observable[]{e.pointsProperty()});
persons.add(new Person("Harry", "John"));
persons.add(new Person("Mary", "King"));
persons.add(new Person("Don", "Bon"));
persons.add(new Person("Pink", "Wink"));
TableView<Person> tableView = new TableView<>();
TableColumn<Person, String> fnCol = new TableColumn<>("First Name");
fnCol.setCellValueFactory(param -> param.getValue().firstNameProperty());
TableColumn<Person, String> lnCol = new TableColumn<>("Last Name");
lnCol.setCellValueFactory(param -> param.getValue().lastNameProperty());
TableColumn<Person, Integer> pointsCol = new TableColumn<>("Points");
pointsCol.setCellValueFactory(param -> param.getValue().pointsProperty().asObject());
tableView.getStylesheets().add(this.getClass().getResource("tableColor.css").toExternalForm());
tableView.getColumns().addAll(fnCol, lnCol, pointsCol);
tableView.setItems(persons);
tableView.getItems().addListener((ListChangeListener<Person>) c -> {
if (c.next()) {
if (c.wasUpdated()) {
tableView.getItems().get(c.getFrom()).setHightlight(true);
tableView.refresh();
}
}
});
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
tableView.setRowFactory(new Callback<TableView<Person>, TableRow<Person>>() {
@Override
public TableRow<Person> call(TableView<Person> param) {
return new TableRow<Person>() {
Timeline highlightTL;
@Override
protected void updateItem(Person item, boolean empty) {
super.updateItem(item, empty);
removeHighlight();
if (item != null && item.isHightlight()) {
getStyleClass().add("highlightedRow");
getHighlightTL().playFromStart();
}
}
private void removeHighlight() {
getHighlightTL().stop();
getStyleClass().removeAll("highlightedRow");
}
private Timeline getHighlightTL() {
if (highlightTL == null) {
// After 3 secs, the hightlight will be removed.
highlightTL = new Timeline(new KeyFrame(Duration.millis(3000), e -> {
getItem().setHightlight(false);
removeHighlight();
}));
highlightTL.setCycleCount(1);
}
return highlightTL;
}
};
}
});
Scene sc = new Scene(tableView);
primaryStage.setScene(sc);
primaryStage.show();
// Updating points every 5 secs to a random person.
Timeline tl = new Timeline(new KeyFrame(Duration.millis(5000), e -> {
Person p = persons.get(rnd.nextInt(4));
p.setPoints(p.getPoints() + 1);
}));
tl.setCycleCount(Animation.INDEFINITE);
tl.play();
}
class Person {
private StringProperty firstName = new SimpleStringProperty();
private StringProperty lastName = new SimpleStringProperty();
private IntegerProperty points = new SimpleIntegerProperty();
private BooleanProperty hightlight = new SimpleBooleanProperty();
public Person(String fn, String ln) {
setFirstName(fn);
setLastName(ln);
}
public String getFirstName() {
return firstName.get();
}
public StringProperty firstNameProperty() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
return lastName.get();
}
public StringProperty lastNameProperty() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public int getPoints() {
return points.get();
}
public IntegerProperty pointsProperty() {
return points;
}
public void setPoints(int points) {
this.points.set(points);
}
public boolean isHightlight() {
return hightlight.get();
}
public BooleanProperty hightlightProperty() {
return hightlight;
}
public void setHightlight(boolean hightlight) {
this.hightlight.set(hightlight);
}
}
}
Update :: Если вам удастся обновить значение свойства «hightlight» извне (после 3 сек), тогда в RowFactory нет необходимости использовать временную шкалу.Простой вызов tableView.refresh () в ListChangeListener должен сделать свое дело:)