JavaFX 2.2: How to force neu/aktualisieren einer ListView
Habe ich ein ListView-Steuerelement in eine JavaFX 2 modales dialog-Fenster.
Dieser ListView zeigt DXAlias Instanzen, die ListCells für die hergestellt werden, indem eine Zelle Fabrik. Die wichtigste Sache, die die Fabrik Objekte tun ist, untersuchen Sie die UserData-Eigenschaft Daten des ListView und vergleichen Sie die entsprechenden Artikel auf der ListCell. Wenn Sie identisch sind, wird der Inhalt des ListCell gerendert in rot, sonst schwarz. Ich Tue dies, um anzugeben, welche Elemente in der ListView aktuell ausgewählt ist als "Standard". Hier ist mein ListCell factory-Klasse, so dass Sie sehen können, was ich meine:
private class AliasListCellFactory implements
Callback<ListView<DXSynonym>, ListCell<DXSynonym>> {
@Override
public ListCell<DXSynonym> call(ListView<DXSynonym> p) {
return new ListCell<DXSynonym>() {
@Override
protected void updateItem(DXSynonym item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
DXSynonym dx = (DXSynonym) lsvAlias.getUserData();
if (dx != null && dx == item) {
this.setStyle("-fx-text-fill: crimson;");
} else { this.setStyle("-fx-text-fill: black;"); }
this.setText(item.getDxName());
} else { this.setText(Census.FORMAT_TEXT_NULL); }
}};
}
Ich habe einen button-handler namens "handleAliasDefault ()", mit dem sich das ausgewählte Element in der ListView-der neue Standard durch das ausgewählte DXAlias Instanz und speichert diese in der ListView: lsvAlias.setUserData( ausgewählte DXAlias ). Hier ist der hf-code:
//Handler for Button[fx:id="btnAliasDefault"] onAction
@FXML
void handleAliasDefault(ActionEvent event) {
int sel = lsvAlias.getSelectionModel().getSelectedIndex();
if (sel >= 0 && sel < lsvAlias.getItems().size()) {
lsvAlias.setUserData(lsvAlias.getItems().get(sel));
}
}
Weil die änderung, die in Reaktion auf einen Klick auf die Schaltfläche Standard Festlegen ändern Sie das ListView UserData (), ohne jede änderung, auf die Unterstützung ObservableList, ist die Liste nicht korrekt anzeigen der neue Standard.
Gibt es eine Möglichkeit zu zwingen, eine ListView neu Rendern seinen ListCells? Es gibt eine Billiarde Fragen von Android-Nutzern zu diesem Thema, aber es scheint kein Glück für JavaFX. Ich kann haben, um eine "sinnlose änderung", um die backing-array force redraw.
Sehe ich, dass das gefragt wurde, für JavaFX 2.1: Javafx ListView erfrischend
InformationsquelleAutor scottb | 2013-06-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht sicher, ob dies funktioniert in JavaFX 2.2, aber es hat in JavaFX 8 und brauchte eine Weile, um herauszufinden. Sie müssen erstellen Sie Ihre eigenen
ListViewSkin
und fügen Sie einerefresh
Methode wie:Diese rufen
updateItem
ohne Austausch der gesamten Beobachtbaren Sammlung.Auch die Verwendung der neuen Haut, müssen Sie instanziieren Sie es und legen Sie es auf die
initialize
- Methode der controller, falls Sie mit FXML:Fand ich diese nach dem Debuggen das Verhalten eines Akkordeons. Diese steuert die Aktualisierung der ListView, es enthält jedesmal, wenn Sie es erweitern.
Hier ist, wie dieses verwendet wird, auf einem meiner OSS-Projekten: github.com/Eldelshell/JobHunter/blob/master/jobhunter/src/main/...
InformationsquelleAutor Eldelshell
Für jeder Körper anders, landet auf dieser Seite:
Den richtigen Weg, dies zu tun ist, um die Versorgung Ihrer beobachten-Liste mit einem "Abzieher" - Rückruf. Das signal für die Liste (und ListView) von der änderung einer Eigenschaft.
Benutzerdefinierten Klasse auf display:
Und Ihrer Haupt-code-Körper:
Sehen (und ähnliche Methoden):
https://docs.oracle.com/javafx/2/api/javafx/collections/FXCollections.html#observableArrayList(javafx.util.Callback)
Ich bin mir nicht ganz sicher, was deine Frage ist, aber lassen Sie mich versuchen zu erklären. In meinem Beispiel habe ich nie explizit den Wert der id, also wäre es standardmäßig auf 0. Dadurch würde die ListView die Zeile anzeigen "Mickey Mouse: 0". Wenn Sie wollte, um den ID-Wert, den Sie verwenden könnten
item.name.set(6)
, zum Beispiel, und Sie würden sehen, die ListValue korrekt aktualisiert. Abhängig von Ihren use-case, mit einem nicht-Standard-Konstruktor auf dieCustom
Klasse wäre wahrscheinlich "besser".InformationsquelleAutor Andrey
Jetzt bin ich in der Lage, um die ListView neu gezeichnet und richtig deuten die gewählte Voreinstellung mithilfe der folgenden Methode, genannt forceListRefreshOn(), in meinem button-handler:
Die helper-Methode nur gewechselt, die ObservableList aus dem ListView und dann tauscht es wieder in, vermutlich zwingt das ListView zu aktualisieren Ihre ListCells:
InformationsquelleAutor scottb
Ich bin nicht sicher, ob ich etwas fehlt, aber ich versuchte zunächst scottb Lösung, aber dann fand ich heraus, dass es ist ein bereits implementiert refresh () - Methode, die hat den trick für mich.
InformationsquelleAutor Dom
Scheint, Sie brauchen nicht zu verwenden updateItem-Methode. Was Sie brauchen - ist die Speicherung Anzeige der aktuell Standard-Zelle (das ist im Benutzer-Daten jetzt), in OblectProperty. Und fügen Sie einen listener hinzu, der auf diese Eigenschaft aus jeder Zelle. Wenn der Wert ändert, weisen einen Stil.
Aber ich denke, solche verbindlichen rufen ein weiteres problem beim scrollen, neue Zellen werden erstellt, aber der alte wird nicht verlassen, die Bindung, die kann zu Speicherverlust. So müssen Sie listener auf Zelle entfernen von der Unfallstelle. Ich denke, es kann getan werden, indem ein listener auf dem parentProperty, wenn es zu einer null - entfernen Sie verbindlich.
UI sollten nicht gezwungen werden, aktualisiert werden. Es aktualisiert automatisch, wenn die Eigenschaften/rendering von vorhandenen Knoten geändert wird. So brauchen Sie nur zu aktualisieren das Aussehen/die Eigenschaft von vorhandenen Knoten (Zellen). Und nicht zu vergessen, dass Zellen erstellt werden können, Massiv, während scrollen/rerendering, etc.
Dies ist die übliche Eigenschaft, wie javafx-2 works: wenn Knoten des scenegraph (bestimmte Zelle) ändert seine Eigenschaften, so dass es wirkt sich auf die visuelle Darstellung, scenegraph zeichnet diesen Knoten (Zellen), wenn nötig. Also, wenn Sie ein update für das visuelle Erscheinungsbild von Zellen - Sie werden gezeichnet durch den scenegraph.
Ich sehe, was du sagst ... aber ich glaube auch nicht, dass ich gezwungen werden sollte, umgestalten, meine Daten-Modell, um eine Eigenschaft, die nicht tatsächlich einen Teil meiner Daten-Modell. Ich will nur die ausgewählten Standard-alias gerendert werden in rot, statt schwarz. Mein problem wäre behoben, wenn es eine einfache Methode, die mir zur Verfügung: lsvAlias.requestRefresh();
Ok, dann können Sie Datei eine RFE, um die javafx-jira =)
Irgendwie ... bezweifle ich sehr, dass Sie es tun würde, mir etwas gutes.
InformationsquelleAutor Alexander Kirov