Класс стиля TableRow, не придерживающийся строки при заказе TableView - PullRequest
0 голосов
/ 20 мая 2018

Я хочу добавить / удалить класс стиля в строку таблицы на основе логического значения в элементе строки.

Добавление и удаление класса работает, как и ожидалось, с помощью следующего кода.Но когда я нажимаю на заголовок столбца, чтобы изменить порядок таблицы, стиль привязывается к идентификатору строки, а не к элементу строки.Это означает, что если до упорядочивания первый ряд был стилизован, то после упорядочивания стиль все еще находится в первом ряду, а не в строке на новой позиции.

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 ]

0 голосов
/ 20 мая 2018

Вы никогда не отменяете регистрацию слушателя из старых предметов.Также слушатель не вызывается для начального значения свойства.Даже если это так, ваш код может привести к тому, что один и тот же класс стиля будет добавлен к узлу несколько раз.Кроме того, клетки могут стать пустыми.В этом случае вам также необходимо удалить класс стилей.

Чтобы избежать многократного добавления одного и того же класса стилей, используйте псевдокласс:

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

0 голосов
/ 20 мая 2018

A 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[].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...