Помимо всех хороших и ценных предложений в комментариях, чтобы ответить на актуальный вопрос «почему» :: метод isCelected () TableCell действительно работает нормально , и в вашем коде есть проблемакоторый неправильно вычисляет требуемую логику.
Чтобы оправдать это, я бы хотел, чтобы вы обновили оператор print в методе updateStyle () до значения ниже
System.out.println(getItem() + " :: in updateStyle(), isLockedProperty = " + isLockedProperty.get() + ", isSelected() = " + isSelected());
Давайте рассмотрим первую строку:
Если я выбираю ячейки слева направо, вывод будет таким, как показано ниже: *
// When field1 is selected
row LOCKED :: in updateStyle(), isLockedProperty = true, isSelected() = true
row LOCKED :: in updateStyle(), isLockedProperty = true, isSelected() = true
// When field2 is selected
row LOCKED :: in updateStyle(), isLockedProperty = true, isSelected() = false
row LOCKED :: in updateStyle(), isLockedProperty = true, isSelected() = false
0 :: in updateStyle(), isLockedProperty = true, isSelected() = true
0 :: in updateStyle(), isLockedProperty = true, isSelected() = true
// When field3 is selected
0 :: in updateStyle(), isLockedProperty = true, isSelected() = false
0 :: in updateStyle(), isLockedProperty = true, isSelected() = false
a0 :: in updateStyle(), isLockedProperty = true, isSelected() = true
a0 :: in updateStyle(), isLockedProperty = true, isSelected() = true
В настоящее время, не беспокойтесь о двойной печати каждого выбора (потому что вы устанавливаете и сильный, и слабый слушатели).Но из вывода мы понимаем, что каждый раз, когда мы выбираем ячейку, для выбранной ранее ячейки устанавливается значение false, что является правильным.Это хорошо работает для обновления вашего стиля, так как «true» всегда идет после «false».
Теперь попробуйте выбрать ячейки справа налево, вывод будет таким, как показано ниже: *
// When field3 is selected
a0 :: in updateStyle(), isLockedProperty = false, isSelected() = true
a0 :: in updateStyle(), isLockedProperty = false, isSelected() = true
// When field2 is selected
0 :: in updateStyle(), isLockedProperty = false, isSelected() = true
0 :: in updateStyle(), isLockedProperty = false, isSelected() = true
a0 :: in updateStyle(), isLockedProperty = false, isSelected() = false
a0 :: in updateStyle(), isLockedProperty = false, isSelected() = false
// When field1 is selected
row NOT locked :: in updateStyle(), isLockedProperty = false, isSelected() = true
row NOT locked :: in updateStyle(), isLockedProperty = false, isSelected() = true
0 :: in updateStyle(), isLockedProperty = false, isSelected() = false
0 :: in updateStyle(), isLockedProperty = false, isSelected() = false
Из вывода очень ясно, что «истина» предшествует «ложь».Другими словами Возможно, JavaFX внутренне всегда обновляет выбор ячеек последовательно слева направо .
Здесь ваш код не работает.Когда вы изменяете выбор справа налево, сначала вызывается обновление левой ячейки, а затем вызывается обновление правой ячейки.А так как ваша правая ячейка не выбрана, вы никогда не увидите желаемый выбранный стиль строки.
Возможное решение ::
Я сноваупомянув об этом, просим учесть все предложения в комментариях .Поскольку вы планируете отказаться от этой идеи, я просто хочу сообщить вам, что это все еще осуществимая реализация.Могут быть и другие лучшие способы, но это одно из возможных решений.
Из приведенного выше анализа очень ясно, что получить желаемое поведение, полагаясь на выбор ячейки, не является подходящим решением.Я бы порекомендовал выполнить все стили строк в самой фабрике строк.
Конечно, для этого вам понадобится новый BooleanProperty в элементе таблицы, чтобы вы знали, выбрана строка или нет.
Пожалуйста, внесите следующие изменения в текущий код:
1) Закомментируйте метод updateStyle () в TestTextCell.java и избавьтесь от всех слушателей.
2) Добавьте новое свойствов TestModel и соответствующих методах получения и установки.
private final BooleanProperty selected = new SimpleBooleanProperty();
3) Добавьте прослушиватель selectedItem tableView для обновления выбора элементов в модели.
table.getSelectionModel().selectedItemProperty().addListener((obs, oldItem, newItem) -> {
if (oldItem != null) {
oldItem.setSelected(false);
}
if (newItem != null) {
newItem.setSelected(true);
}
});
4) Обновите реализацию фабрики строкниже:
//Set a row factory to set the background colour of any LOCKED row to be yellow
table.setRowFactory(tv -> {
TableRow<TestModel> row = new TableRow<TestModel>() {
private final ChangeListener<Boolean> listener = (o, v, newValue) -> updateStyle();
{
itemProperty().addListener((obs, oldItem, newItem) -> {
if(oldItem!=null) {
oldItem.selectedProperty().removeListener(listener);
}
if(newItem!=null) {
newItem.selectedProperty().addListener(listener);
}
});
}
@Override
public void updateItem(TestModel item, boolean empty) {
super.updateItem(item, empty);
if (getItem() != null) {
setEditable(!getItem().getLocked());
} else {
setEditable(false);
}
updateStyle();
}
private void updateStyle(){
if(getItem()!=null) {
boolean isLocked = getItem().getLocked();
boolean isSelected = getItem().isSelected();
if (isLocked) {
if (isSelected) {
setStyle("-fx-background-color: pink;");
} else {
setStyle("-fx-background-color: yellow;");
}
} else {
if (isSelected) {
setStyle("-fx-background-color: #b6e1fc;");
} else {
setStyle("-fx-background-color: transparent;");
}
}
}else{
setStyle("-fx-background-color: transparent;");
}
}
};
return row;
});
Буду очень признателен за любые исправления в моем понимании.