JavaFX benutzerdefinierte Zelle Fabrik mit benutzerdefinierten Objekten
Ich versuche, ein custom ListView
aus Gewohnheit Cell
basiert auf einer Liste von benutzerdefinierten objects
.
Das benutzerdefinierte Objekt der Klasse namens Message
enthält ein paar Felder für die Nachricht Inhalt, Empfänger, timestamp und status (Lesen, gesendete usw).
Nach einem Blick auf diese Frage : Anpassen ListView in JavaFX mit FXML habe ich erfolgreich :
- erstellt eine ListView mit benutzerdefinierte Zellen, wo die Zelle-design definiert ist, in einem FXML-Datei ;
- verbunden controller so dass jede Zelle Daten gefüllt werden kann, mit der das aktuelle Element der Sammlung ;
Allerdings, ich konnte nicht verbinden : ich kann nicht scheinen zu finden ein Weg, so dass das aktuelle Element der ListView gesendet, die Cell Controller.
Hier ist mein code für die Zelle Fabrik und der ListView Befüllung der Elemente:
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 jetzt, 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());
}
}
Kann ich nicht zeigen, die ConversationCellController aber ich kann nur sagen, dies ist wo (im Konstruktor) I laden der FXML-Datei, die designs der Zelle und dann kann ich füllen Sie die Werte mit der angegebenen Message-Element.
Den getView()
Methode gibt die root-Bereich enthält, die nun-gefüllt-und-konzipiert Zelle.
Als ich vorher sagen, die Gestaltung der Arbeit, aber ich kann nicht scheinen, um link die ListView-Elemente mit der CellFactory, weil in der Methode
protected void updateItem(Message-Element, boolean leer)
leer eingestellt ist wahr und die Sache ist in der Tat null.
Was kann ich tun, um diese Arbeit zu machen ?
- Ist
empty
auf true gesetzt, die auf alle Instanzen? eine Zelle wird als leer, wenn es keinen Gegenstand hat, das ist - es ist einfach da, um zu füllen den Raum unterhalb der eigentlichen Zellen. Wenn Ihr ListView ist groß genug, um zu zeigen, 10 Elemente, aber Sie haben nur 3 haben Sie 7ConversationCell
Objekte, die leer sind. Als ein beiseite, ich kann nicht sehen, woConversationCellController
sollte erhalten die Artikel aus. Wenn Sie immer noch sicher, dass Sie immerempty = true
auf die Zellen mit den eigentlichen Daten kann es hilfreich sein, wenn Sie kommen könnte mit einem minimal-Beispiel, auf dieses problem. - Ich denke, die
ListView
Umsetzung zunächst schafft genügend Zellen zu füllen, die Anzeige und fordertupdateItem(null, true);
auf alle von Ihnen, dann ruftupdateItem(...)
auf die nicht-leer sind, mit den entsprechenden Daten (obwohl ich bin nicht sicher, und habe keine Zeit zu Graben, durch den source-code jetzt). Jedenfalls sind alle cell-Implementierungen behandeln müssen, die leere Zelle, Fall. - "Ich kann nicht zeigen, die ConversationCellController" Warum nicht?
- Ich danke Ihnen allen, Sie hatten Recht ! Weiß ich endlich, warum JavaFX Lasten leere Zelle. Ich dachte mir nur "was zur Hölle" ? Aber es macht Sinn für das füllen leerer Räume sichtbar. So funktioniert es jetzt 🙂 aber jetzt bin ich auf der Suche für databinding und mehr spezifisch, Ereignis-Trigger wie in der Windows-WPF-ViewModel-Paradigma, so dass mein Handy aktualisiert werden kann (in meinem Fall, Update-Status, mit dem Fortschritt -> Nachricht wird gesendet, empfangen, gelesen, etc.)
- Ich würde lieber nicht zeigen alle mein code aus privaten Gründen, aber ich will nicht zu klingen respektlos zu Euch, die Ihr versucht, mir zu helfen 😉 also habe ich gesammelt, ich könnte summup die Inhalte der ConversationCellController, weil ich nicht denke, das problem kam aus, dass ich Recht hatte '^^
- Sie können immer erstellen ein ganz neues Projekt welches genau das tut, was Sie brauchen, um eine Frage stellen. So können Sie zeigen keine private Gesellschaft code, und Sie können auch am Ende mit einem Beispiel, das direkt auf den Punkt.
- das ist in der Tat ein sehr guter Punkt ! Ich habe nicht daran gedacht ! 🙂 Nächstes mal 😉
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alle benutzerdefinierten Zelle Implementierungen überschreiben
updateItem(...)
müssen sich mit dem Fall, wo die Zelle leer ist in der Methode. Also könnte man einen naiv-fix mitDies ist jedoch keine gute Lösung aus Sicht der performance. Sie sind das laden der FXML jedes mal
updateItem(...)
heißt mit einem nicht-leere Zelle, und das ist ein ziemlich aufwändiger Vorgang (eventuell mit Datei-i/o, entpacken der FXML-Datei aus einer jar-Datei Parsen der Datei, Menge der Reflexion, neue UI-Elemente, etc). Sie wollen nicht zu Fragen, die FX Application Thread zu tun, all die Arbeit jedes mal, wenn der Benutzer führt einen Bildlauf der Listenansicht um ein paar Pixel. Stattdessen Ihr Handy Zwischenspeichern soll der Knoten und es aktualisieren sollten, in derupdateItem
Methode:Sollten Sie definieren eine
setItem(...)
Methode in derConversationCellController
dass aktualisiert die Ansicht (setzt text auf Etiketten, etc etc) entsprechend.Message
Klasse und erstellen Sie die Elemente der Liste mit einem Extraktor. Siehe stackoverflow.com/questions/23822550ccc.setItem
mehrfach aufgerufen wird, also ich mußte eine boolean inConversationCellController
zu vermeiden, die einen Blick auf viele der Zeit. War ich richtig zu tun ? Für jetzt es funktioniert, aber ich Frage mich... danke!