2016-05-18 19 views
0

JAXBを使用してXSDから生成されるクラスがあります。 JAXBカスタムバインディングのオプションの1つは、java.util.Listクラスを実装することです。例えば、私は、JAXBクラスjava.util.LinkedListを使用し、生成されたコードは、以下が含まれる指定することができます。JavaFX ObservableList具体的な実装

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

私は実装がjavafx.collections.ObservableListを返したいと思いますが、そのインターフェイスを実装する任意の具象クラスを見つけることができませんデフォルトのコンストラクタを持っています。誰でもデフォルトのコンストラクタを持つjavafx.collections.ObservableListの具体的な実装を知っていますか?

+0

FXCollections.observableArrayList()を試したことがありますか? Arraylistによってサポートされている新しい空の観測可能リストを作成します。 –

+0

問題は、私がコードを書いていないということです。それはJAXBによって生成されます。私は、コードの型をインスタンス化することだけを伝えることができ、その型はデフォルトのコンストラクタを提供する必要があります。 –

+0

自分で作ることはできますか?見つかった既存のものの1つを拡張し、新しいクラスにデフォルトのコンストラクタを提供します。 – mascoj

答えて

0

申し訳ありませんが、これを行う方法は2通りあります。最初は独自の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> 

2番目のオプションと、私が使用することを決めたのは、生成されたクラスを継承するカスタム実装クラスを使用するようにJAXB marshaller/unmarshallerを設定することです。 XSDは、 "ItemCollectionType"という名前の複合型を定義します。複合型は、 "Item"という名前の要素定義を含み、無制限の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のあらゆるのoccuranceを生成されたコードでタイプ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の実装を単純化します。

関連する問題