In Ordnung, es gibt zwei Möglichkeiten, dies zu tun. Die erste ist, Ihre eigene javafx.utils.ObservableList
zu implementieren. Die folgende Implementierung wird in der Dokumentation für ModifiableObservableListBase (leicht modifiziert) zur Verfügung gestellt:
public class ObservableArrayList<T> extends ModifiableObservableListBase<T> {
private final List<E> delegate = new ArrayList<>();
@Override
public E get(final int index) {
return delegate.get(index);
}
@Override
public int size() {
return delegate.size();
}
@Override
protected void doAdd(final int index, final E element) {
delegate.add(index, element);
}
@Override
protected E doSet(final int index, final E element) {
return delegate.set(index, element);
}
@Override
protected E doRemove(final int index) {
return delegate.remove(index);
}
}
JAXB kann dann diese Klasse als Implementierung Listentyp verwenden, um zu den Bindungen des folgenden Zugabe-Datei:
<bindings node="//xsd:element[@name='Item']">
<property name="Items" collectionType="myNamespace.ObservableArrayList">
<baseType name="myNamespace.Item" />
</property>
</bindings>
Die zweite Option, und die, die ich gewählt habe, besteht darin, den JAXB Marshaller/Unmarshaller so zu konfigurieren, dass er benutzerdefinierte Implementierungsklassen verwendet, die von den generierten Klassen erben. Nehmen wir an, dass die XSD einen komplexen Typ mit dem Namen "ItemCollectionType" definiert, der eine Elementdefinition mit dem Namen "Item" und mit unbegrenztem maxOccurs
enthält. Dann füge ich einfach die folgenden auf die JAXB Bindungsdatei:
<bindings node="./xsd:complexType[@name='ItemCollectionType']">
<class implClass="myNamespace.ItemCollection" />
</bindings>
<bindings node="//xsd:element[@name='Item']">
<property name="Items">
<baseType name="myNamespace.Item" />
</property>
</bindings>
Die oben genannten Kräfte jedes Auftreten von ItemCollectionType
im generierten Code mit myNamespace.ItemCollection
Typ sein zu ersetzen. Dann schließt die erzeugte Implementierung von ItemCollectionType
den folgenden Code:
@XmlElement(name = "Item", required = true, type = myNamespace.Item.class)
protected List<myNamespace.Item> items;
public List<myNamespace.Item> getItems() {
if (items == null) {
items = new ArrayList<myNamespace.Item>();
}
return this.items;
}
Dann überschreiben ich diese Methode in myNamespace.ItemCollection
:
@Override
public ObservableList<Item> getItems() {
if (!(super.getItems() instanceof ObservableList)) {
items = FXCollections.observableList(items);
}
return (ObservableList<Item>)items;
}
Natürlich sind diese beiden Optionen sind nicht gegenseitig ausschließen. Ich könnte sie beide einfach implementieren, was die Implementierung von myNamespace.ItemCollection.getItems
zu einem einfachen Cast vereinfachen würde.
Haben Sie versucht FXCollections.observableArrayList(); Erzeugt eine neue leere beobachtbare Liste, die von einer Arraylist unterstützt wird. –
Das Problem ist, dass ich nicht den Code schreibe ... es wird von JAXB generiert. Ich kann dem Code nur den zu instantiierenden Typ mitteilen, und dieser Typ muss einen Standardkonstruktor bereitstellen. –
Können Sie Ihre eigenen erstellen? Erweitern Sie eine der vorhandenen, die Sie gefunden haben, und stellen Sie einen Standardkonstruktor in Ihrer neuen Klasse bereit. – mascoj