JavaFX ObservableList具体实现

mm9b1k5b  于 2023-04-10  发布在  Java
关注(0)|答案(2)|浏览(141)

我有一些使用JAXB从XSD生成的类。JAXB自定义绑定的一个选项是指定java.util.List实现类。例如,我可以指定JAXB使用类java.util.LinkedList,生成的代码将包括以下内容:

if (myList == null)
    myList = new java.util.LinkedList();

我希望实现返回一个javafx.collections.ObservableList,但找不到任何实现该接口并具有默认构造函数的具体类。有人知 prop 有默认构造函数的javafx.collections.ObservableList的具体实现吗?

ddarikpa

ddarikpa1#

此静态函数将为您提供ObservableList的具体实现:

FXCollections.observableArrayList();
ubof19bj

ubof19bj2#

好了,有两种方法可以做到这一点。第一种是实现自己的javafx.utils.ObservableList。以下实现在ModifiableObservableListBase的文档中提供(略有修改):

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可以使用这个类作为实现列表类型,方法是将以下内容添加到绑定文件中:

<bindings node="//xsd:element[@name='Item']">
  <property name="Items" collectionType="myNamespace.ObservableArrayList">
    <baseType name="myNamespace.Item" />
  </property>
</bindings>

第二个选项,也是我决定使用的选项,是配置JAXB marshaller/unmarshaller以使用从生成的类继承的自定义实现类。假设XSD定义了一个名为“ItemCollectionType”的复杂类型,它包含一个名为“Item”的元素定义和unbounded maxOccurs。然后我只需将以下内容添加到JAXB绑定文件:

<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>

上面强制生成的代码中的每个ItemCollectionType被替换为类型myNamespace.ItemCollection。然后,生成的ItemCollectionType的实现包括以下代码:

@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;
}

然后,我在myNamespace.ItemCollection中覆盖这个方法:

@Override
public ObservableList<Item> getItems() {
    if (!(super.getItems() instanceof ObservableList)) {
        items = FXCollections.observableList(items);
    }
    return (ObservableList<Item>)items;
}

当然,这两个选项并不相互排斥,我可以很容易地实现它们,这将把myNamespace.ItemCollection.getItems的实现简化为一个简单的强制转换。

相关问题