Custom row style - java

I have a tableview tbvAlumnos which two tablecolumns: tbcNombre, tbcApellidos.
I mapped a list from pojo:
public class Alumno
{
private boolean activo;
private String nombre;
private String apellidos;
}
Where I mapped alumnos's list to tableview I want to text fill row with red colour where alumno activo is false and text fill row with green when is true.
I tried but I don't know how to get each alumno to check if is active or not because follow code fails because I pass Alumno item rather than String.
tbcNombre.setCellFactory(column -> {
return new TableCell<Alumno, Alumno>() {
#Override
protected void updateItem(Alumno item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setStyle("");
} else {
// Format date.
setText(item.toString());
setStyle("-fx-text-fill: red");
}
}
};
});
So How can I add style to all row fields based on condition of each item of each row.

Related

Is this a Bug in my code or a problem with cellfactory

todoitemsListview.setCellFactory(new Callback<ListView<ToDoItems>, ListCell<ToDoItems>>() {
#Override
public ListCell<ToDoItems> call(ListView<ToDoItems> toDoItemsListView) {
ListCell<ToDoItems> cell= new ListCell<ToDoItems>(){
#Override
protected void updateItem(ToDoItems items, boolean empty) {
super.updateItem(items, empty);
if(empty){
setText(null);
}else {
setText(items.getItemName());
if (items.getDeadline().equals(LocalDate.now())){
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.RED);
}else if (items.getDeadline().equals(LocalDate.now().plusDays(1))){
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.BLUE);
}else if (items.getDeadline().equals(LocalDate.now().plusDays(2))){
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.GREEN);
}else if(items.getDeadline().isBefore(LocalDate.now())){
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.GREY);
}
}
}
};
return cell;
}
});
I used a cellfactory in listview to set text color to different values based on their due date. But when i add new items to the list, items which doesn't satisfy the if - else conditions is also highlighted.
This is part of a basic ToDo application based on a ObservabelList , Where ToDoItems class has three attributes, itemName,ItemDesription,Deadline.
Cells in a ListView are reused when needed. So in your case, you have set a specific cell with a red fill, but when that same cell is reused for a different ToDoItems instance (because you scrolled down or added a new item in the list), and that new ToDoItems instance doesn't fullfil any of your conditions that change the fill color, the cell is gonna keep its previous fill color incorrectly.
What you need to do is make sure you fall back to a default color if none of the conditions in your example are met:
todoitemsListview.setCellFactory(new Callback<ListView<ToDoItems>, ListCell<ToDoItems>>() {
#Override
public ListCell<ToDoItems> call(ListView<ToDoItems> toDoItemsListView) {
ListCell<ToDoItems> cell = new ListCell<ToDoItems>() {
#Override
protected void updateItem(ToDoItems items, boolean empty) {
super.updateItem(items, empty);
if (empty) {
setText(null);
setTextFill(Color.BLACK);
} else {
setText(items.getItemName());
if (items.getDeadline().equals(LocalDate.now())) {
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.RED);
} else if (items.getDeadline().equals(LocalDate.now().plusDays(1))) {
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.BLUE);
} else if (items.getDeadline().equals(LocalDate.now().plusDays(2))) {
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.GREEN);
} else if (items.getDeadline().isBefore(LocalDate.now())) {
System.out.println(items.getDeadline().toString());
System.out.println(items.getItemName());
setTextFill(Color.GREY);
} else {
setTextFill(Color.BLACK);
}
}
}
};
return cell;
}
});

How to reference cell data on CellFactory?

I have a TableView where the last column is an "Action" column, containing a custom ActionBox object, with buttons for several actions. To add behaviour to this ActionBox, I need to pass a Data object to it. However, I don't know how to reference the object.
class TableViewWithActionColumn() {
#FXML TableColumn<Data, Void> actionColumn;
public TableViewWithActionColumn() {
// Code for loading custom component...
}
#FXML
public void initialize() {
populateActionColumn();
}
private void populateActionColumn() {
Callback<TableColumn<Data, Void>, TableCell<Data, Void>> cellFactory = new Callback<TableColumn<Data, Void>, TableCell<Data, Void>>() {
#Override
public TableCell<Data, Void> call(final TableColumn<Data, Void> param) {
return new TableCell<Data, Void>() {
private final ActionBox actionBox = new ActionBox();
#Override
public void updateItem(Void item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(actionBox);
}
}
};
}
};
actionColumn.setCellFactory(cellFactory);
}
}
I assumed that the reference to the object was in Void item, so I tried replacing all occurrences of Void with Data, and doing setGraphic(new ActionBox(item));, but this led to a NullPointerException, so I suppose that's not the right way to do it. So, how do I reference row's data in CellFactory context?
TableCell has a getTableRow() method, that gives you a reference to the TableRow that contains the cell. The TableRow is itself a cell implementation, so you can call its getItem() method to get the data represented by the row.
In context (and removing all the unnecessary boilerplate from your code):
private void populateActionColumn() {
actionColumn.setCellFactory(col -> new TableCell<Data, Void>() {
private final ActionBox actionBox = new ActionBox();
#Override
public void updateItem(Void item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
Data rowData = getTableRow().getItem();
// ... something like: actionBox.setData(rowData) ;
setGraphic(actionBox);
}
}
});
}

Click event on ImageView inside TableCell in JavaFX

I have a JavaFX TableView populated with many TableColumns, one of which is matImageColumn. The code for it looks like:
matImageColumn.setCellFactory(new Callback<TableColumn<CustomObject, ImageView>, TableCell<CustomObject, ImageView>>() {
#Override
public TableCell call(final TableColumn<CustomObject, ImageView> param) {
final TableCell<CustomObject, ImageView> cell = new TableCell<CustomObject, ImageView>() {
ImageView img = new ImageView();
#Override
public void updateItem(ImageView item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else {
CustomObject co = getTableView().getItems().get(getIndex());
img = co.getImageViewOfMat();
setGraphic(img);
setText(null);
}
}
};
return cell;
}
});
Now as it is, I am looking to include a click event on my imageview but I am clueless from where to start.Can you show me possible solutions to this issue? Thanks in advance.

Not able to get javafx Listview variable height of rows

view.setCellFactory(lst ->
new ListCell<AnchorPane>() {
int k=1;
#Override
protected void updateItem(AnchorPane item,boolean empty) {
super.updateItem(item, empty);
if (empty) {
setPrefHeight(0.0);
setGraphic(null);
} else {
if(k == 1){
setPrefHeight(100.00);
k++;
}
else{
setPrefHeight(10.00);
}
setGraphic(item);
}
}
});
Setting different height of row by overriding the update Item and passing anchor pane but not getting different height for the rows.

How to get row value inside updateItem() of CellFactory

ageColumn.setCellFactory(param -> new TableCell<Person, String>(){
#Override
protected void updateItem(String item, boolean empty) {
param.getCellFactory().
super.updateItem(item, empty);
setText(empty ? null : String.valueOf(item));
if(person.getName.equals("MATEUS")) {
setStyle("-fx-background-color: red;");
}
}
});
How to get this "Person" which is the row value from the Table? I can only get the value from the cell, but not the entire object.
You can do
Person person = getTableView().getItems().get(getIndex());
You can also do
Person person = (Person) getTableRow().getItem();
but this is less desirable (in my opinion) because getTableRow() returns a raw type, and consequently it requires the unchecked downcast.
Obviously either of these only works if empty is false, so they should be inside a check for that:
ageColumn.setCellFactory(param -> new TableCell<Person, String>(){
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setStyle("");
} else {
setText(item);
Person person = getTableView().getItems().get(getIndex());
if(person.getName.equals("MATEUS")) {
setStyle("-fx-background-color: red;");
} else {
setStyle("");
}
}
}
});

Categories