Ich versuche, eine benutzerdefinierte ListView
von benutzerdefinierten Cell
basierend auf einer Liste von benutzerdefinierten objects
.JavaFX benutzerdefinierte Zelle Factory mit benutzerdefinierten Objekten
Das benutzerdefinierte Objekt ist Klassenname Message
genannt, die ein paar Felder für die Nachricht enthält Inhalt, Empfänger, Zeitstempel und Status (lesen, gesendet etc.).
Nach auf dieser Frage suchen: Customize ListView in JavaFX with FXML Ich habe erfolgreich:
- einen Listview mit individuellen Zellen geschaffen, in dem das Zellen-Design in einer FXML Datei definiert ist;
- zugeordnet Controller, so dass jede Zelle Daten mit dem aktuellen Element der Sammlung gefüllt werden kann;
aber ich nicht beides verbinden: Ich kann nicht einen Weg zu finden scheinen, so dass das aktuelle Element des Listview die Controller-Zelle gesendet wird.
Hier ist mein Code für die Zellfabrik und die Listview-Füllung der Objekte:
final ObservableList observableList = FXCollections.observableArrayList();
observableList.setAll(myMessages); //assume myMessage is a ArrayList<Message>
conversation.setItems(observableList); //the listview
conversation.setCellFactory(new Callback<ListView<Message>, ListCell<Message>>() {
@Override
public ConversationCell<Message> call(ListView<Message> listView) {
return new ConversationCell();
}
});
Und nun die ConversationCell Klasse:
public final class ConversationCell<Message> extends ListCell<Message> {
@Override
protected void updateItem(Message item, boolean empty) {
super.updateItem(item, empty);
ConversationCellController ccc = new ConversationCellController(null);
setGraphic(ccc.getView());
}
}
ich nicht die ConversationCellController zeigen können, aber alles, was ich sagen kann, , das ist, wo (in seinem Konstruktor) ich die FXML-Datei laden, die die Zelle entwirft, und dann kann ich die Werte mit dem gegebenen Nachrichtenelement füllen.
Die getView()
-Methode gibt den Root-Bereich zurück, der die jetzt ausgefüllte und entworfene Zelle enthält.
Wie ich bereits sagen, die Gestaltung Arbeit, aber ich kann nicht scheinen, um die Listview-Elemente mit dem CellFactory weil in Verfahren
verlinkenprotected void updateItem (Message Artikel, boolean leer)
leer ist auf gesetzt wahr und Artikel ist in der Tat null.
Was kann ich tun, damit dies funktioniert?
Wird 'empty' in allen Instanzen auf true gesetzt? Eine Zelle wird als leer betrachtet, wenn sie kein Objekt hat, dh sie ist nur dazu da, um den Raum unter den eigentlichen Zellen zu füllen. Wenn Ihr ListView groß genug ist, um 10 Objekte anzuzeigen, Sie aber nur 3 Objekte haben, haben Sie 7 'ConversationCell'-Objekte, die leer sind. Nebenbei kann ich nicht sehen, woher 'ConversationCellController' das Element erhalten soll. Wenn Sie immer noch sicher sind, dass Sie auf Zellen mit aktuellen Daten 'empty = true' erhalten, kann es hilfreich sein, ein minimales Beispiel mit diesem Problem zu finden. – Itai
Ich denke, die 'ListView'-Implementierung erstellt zunächst genug Zellen, um die Anzeige zu füllen, und ruft 'updateItem (null, true);' auf allen auf, dann ruft 'updateItem (...)' auf den nicht leeren, mit auf die entsprechenden Daten (obwohl ich nicht sicher bin und keine Zeit habe, den Quellcode zu durchsuchen). Auf jeden Fall müssen alle Zellenimplementierungen den Leerzellenfall handhaben. –
"Ich kann den ConversationCellController nicht anzeigen" Warum nicht? –