I'm having some dificulties to change the appearance of some TableView rows. The line should show the text with a stroke and in red. Actually, I can show it in red color but still can't do the stroke. This is the css class I'm using to change the appearance of the line:
.itemCancelado {
-fx-strikethrough: true;
-fx-text-fill: red;
}
This style class is added when the user mark the item as canceled:
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");
}
};
}
}
There is another problem here, the row marked as canceled only changes the color when the user adds or removes an element from observable list. Is there a way I can force the update of the TableView?
EDITED INFORMATION
I changed the ItemBean class to use BooleanProperty and it solved partially:
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;
}
}
Unfortunately, only the column "cancelado" (that will be hided or removed when this finally work) changes the appearance:
here I configure the columns and the table:
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);
}
...
}
How can I update all columns?
How can I update all columns? If you wish to strike-out entire row, i.e. all cells in a row, every other CellValueFactory should have that condition check:
Or you could implement your callbacks as decorators and have something like this:
This way you don't have to repeat the "canceled" styling code, and you can apply it to entire row. Please note that this is not JavaFX ready code, this is a general idea.
Is there a way I can force the update of the TableView?
Make the
Cancelado
a property of theItemBean
class:Now the default cell implementation for the list view will listen for changes on the
cancelado
property and triggerupdateItem
calls for the relevant list view cell as appropriate.Note that the name of the function which returns the property is important, it must be
canceladoProperty()
as JavaFX extends the standard Java Beans member getter and setter pattern for properties.Property Naming Convention Background
The naming convention for JavaFX property access is demonstrated in this code snippet from the Oracle Using JavaFX Properties and Binding tutorial.
There is a great overview of the JavaFX Property Architecture on the openfx wiki which details naming conventions for properties and various more advanced usage scenarios like read only properties and lazy properties.
Customizing the Appearance of a Row in a TableView
Futher information and an example of customizing table row appearance based on a boolean row value is provided in this gist sample code.
Related
The StackOverflow question Background with 2 colors in JavaFX?, provides a similar solution. The discussion in the answer to that question provides further information on caveats and subtleties of table row highlighting in JavaFX (basically, it's really hard to get the psuedo-class styles - focus rings, selected bars, hover feedback, etc - right with custom row styles).
You must set the strikethrough to the .text class: ;-)