Обновление внешнего вида строки TableView
У меня есть некоторые трудности, чтобы изменить внешний вид некоторых строк TableView. В строке должен отображаться текст с обводкой и красным цветом. На самом деле, я могу показать это красным цветом, но все еще не могу сделать удар. Это класс css, который я использую для изменения внешнего вида строки:
.itemCancelado {
-fx-strikethrough: true;
-fx-text-fill: red;
}
Этот класс стиля добавляется, когда пользователь помечает элемент как отмененный:
public class ItemCanceladoCellFactory implements Callback<TableColumn, TableCell> {
@Override
public TableCell call(TableColumn tableColumn) {
return new TableCell<ItemBean, Object>() {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? "" : getItem().toString());
setGraphic(null);
int indice=getIndex();
ItemBean bean=null;
if(indice<getTableView().getItems().size())
bean = getTableView().getItems().get(indice);
if (bean != null && bean.isCancelado())
getStyleClass().add("itemCancelado");
}
};
}
}
Здесь есть еще одна проблема: строка, помеченная как отмененная, меняет цвет только тогда, когда пользователь добавляет или удаляет элемент из наблюдаемого списка. Есть ли способ заставить обновление TableView?
РЕДАКЦИОННАЯ ИНФОРМАЦИЯ
Я изменил класс ItemBean для использования BooleanProperty, и он решил частично:
public class ItemBean {
...
private BooleanProperty cancelado = new SimpleBooleanProperty(false);
...
public Boolean getCancelado() {
return cancelado.get();
}
public void setCancelado(Boolean cancelado){
this.cancelado.set(cancelado);
}
public BooleanProperty canceladoProperty(){
return cancelado;
}
}
К сожалению, только столбец "отмена" (который будет скрыт или удален, когда это наконец сработает) изменяет внешний вид:
здесь я настраиваю столбцы и таблицу:
public class ControladorPainelPreVenda extends ControladorPainel {
@FXML
private TableView<ItemBean> tabelaItens;
private ObservableList<ItemBean> itens = FXCollections.observableArrayList();
...
private void configurarTabela() {
colunaCodigo.setCellValueFactory(new MultiPropertyValueFactory<ItemBean, String>("produto.id"));
colunaCodigo.setCellFactory(new ItemCanceladoCellFactory());
colunaDescricao.setCellValueFactory(new MultiPropertyValueFactory<ItemBean, String>("produto.descricao"));
colunaDescricao.setCellFactory(new ItemCanceladoCellFactory());
colunaLinha.setCellValueFactory(new MultiPropertyValueFactory<ItemBean, String>("produto.nomeLinha"));
colunaLinha.setCellFactory(new ItemCanceladoCellFactory());
colunaQuantidade.setCellValueFactory(new PropertyValueFactory<ItemBean, BigDecimal>("quantidade"));
colunaQuantidade.setCellFactory(new ItemCanceladoCellFactory());
colunaValorLiquido.setCellValueFactory(new PropertyValueFactory<ItemBean, BigDecimal>("valorLiquido"));
colunaValorLiquido.setCellFactory(new ItemCanceladoCellFactory());
colunaValorTotal.setCellValueFactory(new PropertyValueFactory<ItemBean, BigDecimal>("valorTotal"));
colunaValorTotal.setCellFactory(new ItemCanceladoCellFactory());
colunaCancelado.setCellValueFactory(new PropertyValueFactory<ItemBean, Boolean>("cancelado"));
colunaCancelado.setCellFactory(new ItemCanceladoCellFactory());
tabelaItens.setItems(itens);
}
...
}
Как я могу обновить все столбцы?
3 ответа
Есть ли способ заставить обновление TableView?
Сделать Cancelado
свойство ItemBean
учебный класс:
private BooleanProperty cancelado = new SimpleBooleanProperty(false);
public BooleanProperty canceladoProperty() {
return cancelado;
}
Теперь реализация ячейки по умолчанию для представления списка будет прослушивать изменения в cancelado
свойство и триггер updateItem
при необходимости вызывает соответствующую ячейку просмотра списка.
Обратите внимание, что имя функции, которая возвращает свойство, важно, оно должно быть canceladoProperty()
поскольку JavaFX расширяет стандартную модель получения и установки элемента Java Beans для свойств.
Соглашение об именах собственности
Соглашение об именовании для доступа к свойствам JavaFX продемонстрировано в этом фрагменте кода из руководства Oracle " Использование свойств JavaFX и привязки".
package propertydemo;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
class Bill {
// Define a variable to store the property
private DoubleProperty amountDue = new SimpleDoubleProperty();
// Define a getter for the property's value
public final double getAmountDue(){return amountDue.get();}
// Define a setter for the property's value
public final void setAmountDue(double value){amountDue.set(value);}
// Define a getter for the property itself
public DoubleProperty amountDueProperty() {return amountDue;}
}
На вики-сайте openfx представлен большой обзор архитектуры свойств JavaFX, в котором подробно описаны соглашения об именах свойств и различные более сложные сценарии использования, такие как свойства только для чтения и свойства lazy.
Настройка внешнего вида строки в табличном представлении
Более подробная информация и пример настройки внешнего вида строки таблицы на основе логического значения строки представлены в этом основном примере кода.
private TableColumn<Friend, Boolean> makeBooleanColumn(String columnName, String propertyName, int prefWidth) {
TableColumn<Friend, Boolean> column = new TableColumn<>(columnName);
column.setCellValueFactory(new PropertyValueFactory<Friend, Boolean>(propertyName));
column.setCellFactory(new Callback<TableColumn<Friend, Boolean>, TableCell<Friend, Boolean>>() {
@Override public TableCell<Friend, Boolean> call(TableColumn<Friend, Boolean> soCalledFriendBooleanTableColumn) {
return new TableCell<Friend, Boolean>() {
@Override public void updateItem(final Boolean item, final boolean empty) {
super.updateItem(item, empty);
// clear any custom styles
this.getStyleClass().remove("willPayCell");
this.getStyleClass().remove("wontPayCell");
this.getTableRow().getStyleClass().remove("willPayRow");
this.getTableRow().getStyleClass().remove("wontPayRow");
// update the item and set a custom style if necessary
if (item != null) {
setText(item.toString());
this.getStyleClass().add(item ? "willPayCell" : "wontPayCell");
this.getTableRow().getStyleClass().add(item ? "willPayRow" : "wontPayRow");
}
}
};
}
});
column.setPrefWidth(prefWidth);
}
связанные с
Вопрос Stackru Фон с 2 цветами в JavaFX?, предоставляет аналогичное решение. Обсуждение в ответе на этот вопрос предоставляет дополнительную информацию о предостережениях и тонкостях выделения строк таблицы в JavaFX (в основном, очень трудно получить стили псевдо-класса - кольца фокуса, выбранные полосы, обратную связь при наведении курсора и т. Д. - прямо с пользовательской строкой стили).
Вы должны установить зачеркнутый класс.text:;-)
.itemCancelado {
-fx-text-fill: red;
}
.itemCancelado .text {
-fx-strikethrough: true;
}
Как я могу обновить все столбцы? Если вы хотите вычеркнуть всю строку, т. Е. Все ячейки в строке, каждая другая CellValueFactory должна иметь проверку этого условия:
...
if (indice < getTableView().getItems().size())
bean = getTableView().getItems().get(indice);
if (bean != null && bean.isCancelado())
getStyleClass().add("itemCancelado");
...
Или вы можете реализовать свои обратные вызовы как декораторы и получить что-то вроде этого:
public class CellDecorator implements Callback<TableColumn, TableCell> {
private Callback<TableColumn, TableCell> decorated;
public CellDecorator(Callback<TableColumn, TableCell> toDecorate) {
this.decorated = toDecorate;
}
// Override this to do your thing.
public abstract void doStyle(TableCell tableCell);
@Override
public void style(TableCell tableCell) {
// Let the decorated styler do its thing.
decorated.style(tableCell);
// Now we do our thing.
doStyle(cell);
}
}
public class ItemCanceladoCellFactory extends CellDecorator {
public ItemCanceladoCellFactory(Callback<TableColumn, TableCell> toDecorate) {
super(toDecorate);
}
@Override
public void doStyle(TableCell tableCell) {
...
if (bean != null && bean.isCancelado())
getStyleClass().add("itemCancelado");
}
}
...
colunaCodigo.setCellValueFactory(new ItemCanceladoCellFactory(new MultiPropertyValueFactory<ItemBean, String>("produto.id")));
colunaDescricao.setCellValueFactory(new ItemCanceladoCellFactory(new MultiPropertyValueFactory<ItemBean, String>("produto.descricao")));
colunaDescricao.setCellFactory(new ItemCanceladoCellFactory(new ItemCanceladoCellFactory()));
....
Таким образом, вам не нужно повторять "отмененный" код стиля, и вы можете применить его ко всей строке. Обратите внимание, что это не готовый код JavaFX, это общая идея.