I have the following piece of code to update both the color of a column cell and its corresponding row:
calltypel.setCellFactory(column -> {
return new TableCell<CallLogs, String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? "" : getItem().toString());
setGraphic(null);
TableRow currentRow = getTableRow();
//This doesn't work
if(item.equals("a")){
item.setTextFill(Color.RED);
currentRow.setTextFill(Color.PINK);
}
else{
item.setTextFill(Color.GREEN);
currentRow.setTextFill(Color.BLUE);
}
}
};
});
The code segment of 'if' condition doesn't work. I am unable to identify the correct references to objects and also what is the best way to do this.
Thanks!
We’ll go through each selector individually before exploring how to create your own selectors for additional customization. A JavaFX TableView can be styled with CSS by applying CSS styles to selectors for columns, rows and cells. By applying consistent styles to a series of selectors, every aspect of a TableView can be customised.
The downside is that for pre-fab constructs like the TableView if you don’t know the selectors, you’re stuffed. We’ll go through each selector individually before exploring how to create your own selectors for additional customization. A JavaFX TableView can be styled with CSS by applying CSS styles to selectors for columns, rows and cells.
Actually, it is what does the trick and applies formatting to the whole row based on a value in a given cell. Click the " Format… " button and switch to Fill tab to choose the background color. If the default colors do not suffice, click the " More Colors… " button to pick the one to your liking, and then click OK twice.
You may want to shade the rows in different colors based on the cell value in the Qty. column to see the most important orders at a glance. This can be easily done using Excel Conditional Formatting. Start with selecting the cells the background color of which you want to change.
private void customiseFactory(TableColumn<CallLogs, String> calltypel) {
calltypel.setCellFactory(column -> {
return new TableCell<CallLogs, String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? "" : getItem().toString());
setGraphic(null);
TableRow<CallLogs> currentRow = getTableRow();
if (!isEmpty()) {
if(item.equals("a"))
currentRow.setStyle("-fx-background-color:lightcoral");
else
currentRow.setStyle("-fx-background-color:lightgreen");
}
}
};
});
}
This works!
The correct approach is to use setRowFactory
of the Table:
table.setRowFactory(tv -> new TableRow<CustomItem>() {
@Override
protected void updateItem(CustomItem item, boolean empty) {
super.updateItem(item, empty);
if (item == null || item.getValue() == null)
setStyle("");
else if (item.getValue() > 0)
setStyle("-fx-background-color: #baffba;");
else if (item.getValue() < 0)
setStyle("-fx-background-color: #ffd7d1;");
else
setStyle("");
}
});
I recently did a little research about this subject. With the following code you can change the row color of a TableView based on a column value (I will try to explain it the best I can).
The first thing we have to do is to define the TableView and the Columns of this TableView:
private TableView<Person> personTable;
private TableColumn<Person, String> nameColumn;
private TableColumn<Person, String> lastNameColumn;
The next step is to define the Cell Factory of one of the columns:
nameColumn.setCellFactory(column -> {
return new TableCell<Person, String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty); //This is mandatory
if (item == null || empty) { //If the cell is empty
setText(null);
setStyle("");
} else { //If the cell is not empty
setText(item); //Put the String data in the cell
//We get here all the info of the Person of this row
Person auxPerson = getTableView().getItems().get(getIndex());
// Style all persons wich name is "Edgard"
if (auxPerson.getName().equals("Edgard")) {
setTextFill(Color.RED); //The text in red
setStyle("-fx-background-color: yellow"); //The background of the cell in yellow
} else {
//Here I see if the row of this cell is selected or not
if(getTableView().getSelectionModel().getSelectedItems().contains(auxPerson))
setTextFill(Color.WHITE);
else
setTextFill(Color.BLACK);
}
}
}
};
});
The logic of the code: the updateItem() method that we overwrite, it's called automatically when the underlying item changes.
We receive the data item (a String in this case) that has to be rendered. If the item is empty or null (an empty cell for example), we don't apply any style. Otherwise, we format the item, set the text of the cell, and also the colour and the background, depending on the Name of the Person.
If you want to apply this colour of the cell in the other columns of the table, we have to use 'Row Factory' instead of 'Cell Factory', but the logic of the code is similar:
personTable.setRowFactory(row -> new TableRow<Person>(){
@Override
public void updateItem(Person item, boolean empty){
super.updateItem(item, empty);
if (item == null || empty) {
setStyle("");
} else {
//Now 'item' has all the info of the Person in this row
if (item.getName().equals("Edgar")) {
//We apply now the changes in all the cells of the row
for(int i=0; i<getChildren().size();i++){
((Labeled) getChildren().get(i)).setTextFill(Color.RED);
((Labeled) getChildren().get(i)).setStyle("-fx-background-color: yellow");
}
} else {
if(getTableView().getSelectionModel().getSelectedItems().contains(item)){
for(int i=0; i<getChildren().size();i++){
((Labeled) getChildren().get(i)).setTextFill(Color.WHITE);;
}
}
else{
for(int i=0; i<getChildren().size();i++){
((Labeled) getChildren().get(i)).setTextFill(Color.BLACK);;
}
}
}
}
}
});
This is the best way I found to apply the change of style in all the cells of the row. If you use the method "getTableRow()" inside the Cell Factory, you can't modify their cell children.
NOTE 1: If you want to change the style of the text, you have to work in the cell. If you try to do this changes directly on the row, has no effect.
NOTE 2: If you are using a separated CSS file, don't write something like this:
.table-cell {
-fx-text-fill: Black;
}
Because if you do this, all the Java code has no effect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With