Reputation: 23
I have a custom control consisting of a few Label controls: date, title, text, etc. The control has fxml file and a controller. I want to use this control as a cell of ListView. I created a custom ListCell
public class NoteTextCell extends ListCell<Note>{
//....
protected void updateItem(Note note, boolean isEmpty){
if(isEmpty|| note == null){
//....
}
else {
FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/note.fxml"));
Node node = loader.load();
setGraphic(node);
}
}
}
But I am not sure it is a correct way to do it. The ListView in my app can potentially have thousands of items. In my understanding on every cell update it will have to load fxml, do parsing and other operations before graphical Node is created. Is there a better way to solve this problem?
Upvotes: 2
Views: 1332
Reputation: 209225
Load the FXML once for each cell, and just configure it as you need in the updateItem(...)
method:
public class NoteTextCell extends ListCell<Note>{
private final Node graphic ;
private final NoteController controller ;
public NoteTextCell() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/note.fxml"));
graphic = loader.load();
controller = loader.getController();
}
@Override
protected void updateItem(Note note, boolean isEmpty){
if(isEmpty|| note == null){
setGraphic(null);
}
else {
// configure based on note:
controller.setText(...);
controller.setXXX(...);
setGraphic(graphic);
}
}
}
Here I am assuming that the FXML file declares a controller class NoteController
and that you define the methods in it that you need in order to configure the UI for a particular Note
.
This way, the FXML is only loaded once for each cell created (which will likely be no more than 20 or so, no matter how many items in the list), and the (relatively efficient) methods to update it are called as needed when the user scrolls or the cells are otherwise reused.
Upvotes: 3