currently I'm developing at a big software project and I need some help.
I added a FilteredTree so display a tree I created myself.
Following code is used to initialize it:
PatternFilter patternFilter = new PatternFilter();
dataTree = new FilteredTree(comp1, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL, patternFilter, true);
dataTreeViewer = signalTree.getViewer();
dataTreeViewer.setContentProvider(getDataTreeContentProvider());
dataTreeViewer.setLabelProvider(getDataTreeLabelProvider());
dataTreeViewer.setInput(data);
The input is a tree represented by a single node, which has childs and so on.
If I fill in some words in the filter literally nothing happens. I can write weird stuff but still everything will be shown.
I will also add some code for my label provider. Maybe you see the mistake. This is driving me nuts because I'm wasting hours and hours for this little thing.
public String getText(Object element) {
if (element != null) {
// MatTreeNode
if (element instanceof MatTreeNode) {
MatTreeNode node = (MatTreeNode) element;
return node.getName();
}
// OtherData
if (element instanceof OtherData) {
OtherData data = (OtherData) element;
return data.getName();
}
}
return null;
}
In my code OtherData is a different named class. I'm not allowed to post this code due to copyright reasons.
I hope someone of you can help me.
Have a great weekend!
Best regards
LouBen3010
Complete ContentProvider:
public class RawdataTreeContentProvider extends TreeNodeContentProvider implements IContentProvider {
final static String[] EMPTY_ARRAY = {};
#Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
#Override
public Object[] getChildren(Object parentElement) {
// MatTreeNode
if (parentElement instanceof MatTreeNode) {
MatTreeNode parent = (MatTreeNode) parentElement;
LinkedList<MatTreeNode> children = parent.getChildren();
Iterator<MatTreeNode> iterator = children.iterator();
MatTreeNode[] res = new MatTreeNode[children.size()];
int i = 0;
while (iterator.hasNext()) {
MatTreeNode node = iterator.next();
res[i] = node;
i++;
}
return res;
}
// SimpleTreeNode
if (parentElement instanceof SimpleTreeNode) {
SimpleTreeNode treeNode = (SimpleTreeNode) parentElement;
return treeNode.getChildren().toArray();
}
return EMPTY_ARRAY;
}
#Override
public Object getParent(Object element) {
if (element instanceof MatTreeNode) {
return ((MatTreeNode) element).getParent();
}
if (element instanceof SimpleTreeNode) {
return ((SimpleTreeNode) element).getParent();
}
return null;
}
#Override
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
}
Complete LabelProvider:
public class RawdataTreeLabelProvider extends LabelProvider implements ILabelProvider {
private Map<ImageDescriptor, Image> imageCache = new HashMap<ImageDescriptor, Image>();
#Override
public String getText(Object element) {
if (element != null) {
// MatTreeNode
if (element instanceof MatTreeNode) {
MatTreeNode node = (MatTreeNode) element;
return node.getName();
}
// SimpleTreeNode
if (element instanceof SimpleTreeNode) {
SimpleTreeNode signal = (SimpleTreeNode) element;
return signal.getName();
}
}
return null;
}
#Override
public Image getImage(Object element) {
// SimpleTreeNode
if (element instanceof SimpleTreeNode) {
ImageDescriptor descriptor = null;
SimpleTreeNode treeNode = (SimpleTreeNode) element;
SignalData signalData = treeNode.getContent();
// Chose image by signal type
if (signalData.getType() == 0) {
// Input
descriptor = getImageDescriptor("login-16.png");
}
else if (signalData.getType() == 1) {
// Output
descriptor = getImageDescriptor("logout-16.png");
}
// Try to get the image from cache
Image image = (Image) imageCache.get(descriptor);
// If not in cache load the corresponding image
if (image == null) {
image = descriptor.createImage();
imageCache.put(descriptor, image);
}
return image;
}
else {
return super.getImage(element);
}
}
/*
* Custom methods
*/
public ImageDescriptor getImageDescriptor(String name) {
ClassLoader loader = getClass().getClassLoader();
URL url = loader.getResource(name);
return ImageDescriptor.createFromURL(url);
}
}
Related
I am currently working on a "code parser" parsing Valve Map Format (.vmf files) into a java readable Object.
In vmf files,
there are 2 types of objects: Classes and Properties.
classes have a name and can contain other classes and properties.
properties have a name and an unlimited number of values.
Therefore I created a VMFClass Object Class and a VMFProperty Object Class.
I created a List with self-created HierarchyObjects, containing the VMFClass/VMFProperty Object, an UUID and the parentUUID.
The VMFClass Object Contains 2 Lists one with sub-VMFClasses, one with properties.
My Problem is that I have no clue on how to achieve that a Class contains all of its subclasses, since I can't tell how much subclasses the subclasses have and so on...
Here is my Code (Github):
HierachyObject:
package net.minecraft.sourcecraftreloaded.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HierarchyObject {
private static Map<Long, Long> usedUUIDs = new HashMap<>();
private long parentUUID;
private long UUID;
private Object object;
/**
*
* #param Object
* #param parent -1 is maximum level
*/
public HierarchyObject(Object object, long parent) {
this.object = object;
this.parentUUID = parent;
while (true) {
long random = (long) (Math.random() * Long.MAX_VALUE);
if (usedUUIDs.containsKey(random)) {
this.UUID = random;
usedUUIDs.put(random, parent);
break;
}
}
}
public long getUUID() {
return UUID;
}
public long getParentUUID() {
return parentUUID;
}
public static long getParentUUIDbyUUID(long UUID) {
if (usedUUIDs.containsKey(UUID)) {
return usedUUIDs.get(UUID);
}
return -1;
}
public Object getObject() {
return object;
}
public static boolean hasChild(long UUID){
if(usedUUIDs.containsValue(UUID)){
return true;
}
if(UUID == -1){
return true;
}
return false;
}
public boolean hasChild(){
return hasChild(this.UUID);
}
public static long[] getChildUUIDs(long UUID){
if(hasChild(UUID)){
List<Long> cUUIDs = new ArrayList<>();
for(int i = 0; i < usedUUIDs.size(); i++){
for (Map.Entry<Long, Long> e : usedUUIDs.entrySet()) {
if(e.getValue().longValue() == UUID){
cUUIDs.add(e.getKey());
}
}
}
return ListUtils.toPrimitivebyList(cUUIDs);
}
return null;
}
}
VMFProperty:
package net.minecraft.sourcecraftreloaded.source;
public class VMFProperty{
private String name;
private String[] values;
public VMFProperty(String name, String... values) {
this.name = name;
this.values = values;
}
public String getName() {
return name;
}
public String[] getValues() {
return values;
}
#Override
public boolean equals(Object paramObject){
if(paramObject instanceof VMFProperty){
return ((VMFProperty)paramObject).name.equals(this.name) && ((VMFProperty)paramObject).values.equals(this.values);
}
return false;
}
}
VMFClass:
package net.minecraft.sourcecraftreloaded.source;
import java.util.List;
public class VMFClass{
private List<VMFClass> classes;
private List<VMFProperty> properties;
private String name;
public VMFClass(String name, List<VMFClass> classes, List<VMFProperty> properties) {
this.name = name;
this.classes = classes;
this.properties = properties;
}
public String getName() {
return name;
}
public List<VMFClass> getClasses() {
return classes;
}
public List<VMFProperty> getProperties() {
return properties;
}
public void add(VMFClass vmfclass) {
classes.add(vmfclass);
}
public void add(VMFProperty vmfproperty) {
properties.add(vmfproperty);
}
public void remove(VMFClass vmfclass) {
classes.remove(vmfclass);
}
public void remove(VMFProperty vmfproperty) {
properties.remove(vmfproperty);
}
#Override
public boolean equals(Object paramObject){
if(paramObject instanceof VMFClass){
return ((VMFClass)paramObject).properties.equals(this.properties) && ((VMFClass)paramObject).classes.equals(this.classes) && ((VMFClass)paramObject).name.equals(this.name);
}
return false;
}
}
VMFObject (the class executing all the code):
package net.minecraft.sourcecraftreloaded.source;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.sourcecraftreloaded.utils.HierarchyObject;
public class VMFObject {
private String rawfile = "";
private List<VMFClass> toplevelclasses;
private static final String INVALID_CHARS = "\\*,;<>|?=`´#'+~^°!§$%&()[].:-_";
public VMFObject(List<VMFClass> toplevelclasses) {
this.toplevelclasses = toplevelclasses;
}
public VMFObject() {
this(new ArrayList<VMFClass>());
}
public void write(File file) {
VMFWriter.write(file, rawfile);
}
public VMFObject read(File file) throws VMFParsingException {
this.rawfile = VMFReader.read(file);
parse();
return this;
}
public List<VMFClass> getClasses() {
return toplevelclasses;
}
private void parse() throws VMFParsingException {
evaluate();
get();
}
private void evaluate() throws VMFParsingException {
char[] textchars = rawfile.toCharArray();
int[] c = new int[]{0, 0, 0};
int line = 0;
int linepos = 0;
for (int i : textchars) {
linepos++;
if (textchars[i] == '\n') {
line++;
linepos = 0;
c[3] = 0;
if (c[3] % 2 != 0) {
throw new VMFParsingException("Invalid quotes on line" + line + ":" + linepos);
}
}
if (textchars[i] == '{') {
c[1]++;
}
if (textchars[i] == '}') {
c[2]++;
}
if (textchars[i] == '"') {
c[3]++;
if (c[1] - c[2] == 0) {
}
}
if (textchars[i] == '/' && textchars[i + 1] == '/') {
while (true) {
i++;
if (textchars[i] == '\n') {
break;
}
}
}
if (textchars[i] == '/' && textchars[i + 1] == ' ') {
throw new VMFParsingException("Invalid Character '/' on line" + line + ":" + linepos);
}
if (INVALID_CHARS.indexOf(textchars[i]) != -1) {
throw new VMFParsingException("Invalid Character '" + textchars[i] + "' on line" + line + ":" + linepos);
}
}
if (c[1] != c[2]) {
throw new VMFParsingException("Unbalanced brackets in vmf File");
}
}
public void add(VMFClass vmfclass) {
toplevelclasses.add(vmfclass);
}
private void get() throws VMFParsingException {
List<HierarchyObject> content = new ArrayList<>();
long curparent = -1;
String[] text = rawfile.split("\n");
for (int i = 0; i < text.length; i++) {
String line = text[i].trim();
if (line.startsWith("//")) {
continue;
} else {
byte quotec = 0;
char[] linechar = line.toCharArray();
boolean readp = false;
List<String> reads = new ArrayList<>();
byte creads = 0;
for (int y = 0; y < linechar.length; y++) {
if (linechar[y] == '/' && linechar[y + 1] == '/') {
break;
}
if (linechar[y] == '"') {
quotec++;
if (quotec % 2 == 0) {
readp = false;
creads++;
} else {
readp = true;
}
}
if (readp) {
reads.set(creads, reads.get(creads) + linechar[y]);
}
if (linechar[y] == '{') {
HierarchyObject object = new HierarchyObject(new VMFClass(line.substring(line.substring(0, y).lastIndexOf(' '), y).trim(), null, null), curparent);
content.add(object);
curparent = object.getUUID();
}
if (linechar[y] == '}') {
curparent = HierarchyObject.getParentUUIDbyUUID(curparent);
}
}
content.add(new HierarchyObject(new VMFProperty(reads.remove(0), reads.toArray(new String[reads.size()])), curparent));
}
}
buildObject(content);
}
private void buildObject(List<HierarchyObject> content) {
long curUUID = -1;
for(int i = 0; i < HierarchyObject.getChildUUIDs(curUUID).length; i++){
HierarchyObject.getChildUUIDs(curUUID);
}
//TODO implement
}
}
the //TODO part is where the Hierachy Object should get "converted" to the actual object.
Overview
It seems to me that your class layout is overcomplicated.
Let's try to simplify it...
What you have described with the VMF model is essentially a linked-list Tree.
Here's what the model looks like:
[.vmf file] (root)
/ \
_____/ \ _____
/ \
/ \
(VMFClass) (VMFClass)
/ \ / \
/ \ / \
/ \ / \
(VMFClass) (VMFProperties) (VMFClass) (VMFProperties)
/ \
/ \
/ \
(VMFClass) (VMFProperties)
What you need:
A Parser class (in your case, you have VMFObject, but lets call this class VMFParser).
The VMFClass and VMFProperty classes which you have are fine.
What you don't need:
The HierarchyObject class. The VMFParser can be the main controller and container for the hierarchy (e.g. the linked-list Tree model).
All the UUIDs (parent, child, etc.) These are just complicated things, but I see why you have them. You don't need them to track the hierarchy - Java will do this for us!!
VMFClass
public class VMFClass
{
// name of the class
private String name;
// reference back up to the parent
private VMFClass parentClass = null;
// all direct children go here
private List<VMFClass> children = new ArrayList<VMFClass>();
// I don't think you need a list of properties here since your VMFProperty class holds onto an array of properties
private VMFProperty properties;
// set the parent of this class
public void setParent (VMFClass parent)
{
this.parentClass = parent;
}
// get the direct children
public List<VMFClass> getChildren()
{
return this.children;
}
// rest of methods...
}
VMFParser
class VMFParser
{
private String rawfile = "";
// this is really the container for everything - think of it as the file shell
private VMFClass root = new VMFClass("root", null, null);
// construct yourself with the file
public VMFParser (String fileName)
{
this.rawfile = fileName;
}
public void parse ()
{
// all the parsing code goes here
read();
evaluate();
get();
// now at this point your hierarchy is built and stored in the
// root object in this class.
// Use the traverse method to go through it
}
private void get() throws VMFParsingException
{
// keep a reference to the current VMFClass parent
// starts out as root
VMFClass currParentClass = root;
// main parse loop
for (...)
{
// if you find a class
VMFClass currClass = new VMFClass(/* params here */);
// add this class to the parent
currParentClass.add(currClass);
// set the parent of this class
currClass.setParent(currParentClass);
// if you find a property
// parse and add all the properties to the property
VMFProperty property = new VMFProperty (/* value params here */);
// attach this property to the last VMF class that got parsed
currClass.setPoperties(property);
// If you nest deeper into classes, then the parent becomes the current class
currParentClass = currClass;
// If you go back out of a class
currParentClass = currClass.getParent();
}
}
// Traverse the hierarchy
public void traverse ()
{
traverseTree(root);
}
private void traverseTree (VMFClass root)
{
System.out.println("Class Name: " + root.getName());
// print out any properties
VMFProperty prop = root.getProperty();
if (prop != null)
{
System.out.println("Property Name: " + prop.getName());
String [] props = prop.getValues();
for (String s: props)
{
System.out.println("Value: " + s);
}
}
// get all child classes
List<VMFClass> children = root.getChildren();
for (VMFClass c: children)
{
traverseTree(c);
}
}
}
Client Code
Example
public static void main(String[] args)
{
VMFParser vmfParser = null;
try
{
vmfParser = new VMFParser("myFile.vmf");
vmfParser.parse();
// access the vmfParser for the hierarchy
vmfParser.traverse();
}
catch (VMFParsingException vpe)
{
// do something here
vpe.printStackTrace();
}
finally
{
// clean up...
}
}
If you are just looking to find all sub classes of particular class or interface , this might help you,
How can I get a list of all the implementations of an interface programmatically in Java?
My try (gave me a NullPointerException):
public Karte giveFirst(BinarySearchTree<Karte> t){
if(t.getLeftTree() != null) {
return giveFirst(t.getLeftTree());
}else{
return t.getContent();
}
}
Complete Binary Search Tree Code:
package Model;
private class BSTNode<CT extends ComparableContent<CT>> {
private CT content;
private BinarySearchTree<CT> left, right;
public BSTNode(CT pContent) {
this.content = pContent;
left = new BinarySearchTree<CT>();
right = new BinarySearchTree<CT>();
}
}
private BSTNode<ContentType> node;
public BinarySearchTree() {
this.node = null;
}
public void insert(ContentType pContent) {
if (pContent != null) {
if (isEmpty()) {
this.node = new BSTNode<ContentType>(pContent);
} else if (pContent.isLess(this.node.content)) {
this.node.left.insert(pContent);
} else if(pContent.isGreater(this.node.content)) {
this.node.right.insert(pContent);
}
}
}
public BinarySearchTree<ContentType> getLeftTree() {
if (this.isEmpty()) {
return null;
} else {
return this.node.left;
}
}
public ContentType getContent() {
if (this.isEmpty()) {
return null;
} else {
return this.node.content;
}
}
public BinarySearchTree<ContentType> getRightTree() {
if (this.isEmpty()) {
return null;
} else {
return this.node.right;
}
}
public void remove(ContentType pContent) {
if (isEmpty()) {
return;
}
if (pContent.isLess(node.content)) {
node.left.remove(pContent);
} else if (pContent.isGreater(node.content)) {
node.right.remove(pContent);
} else {
if (node.left.isEmpty()) {
if (node.right.isEmpty()) {
node = null;
} else {
node = getNodeOfRightSuccessor();
}
} else if (node.right.isEmpty()) {
node = getNodeOfLeftSuccessor();
} else {
if (getNodeOfRightSuccessor().left.isEmpty()) {
node.content = getNodeOfRightSuccessor().content;
node.right = getNodeOfRightSuccessor().right;
} else {
BinarySearchTree<ContentType> previous = node.right
.ancestorOfSmallRight();
BinarySearchTree<ContentType> smallest = previous.node.left;
this.node.content = smallest.node.content;
previous.remove(smallest.node.content);
}
}
}
}
public ContentType search(ContentType pContent) {
if (this.isEmpty() || pContent == null) {
return null;
} else {
ContentType content = this.getContent();
if (pContent.isLess(content)) {
return this.getLeftTree().search(pContent);
} else if (pContent.isGreater(content)) {
return this.getRightTree().search(pContent);
} else if (pContent.isEqual(content)) {
return content;
} else {
return null;
}
}
}
private BinarySearchTree<ContentType> ancestorOfSmallRight() {
if (getNodeOfLeftSuccessor().left.isEmpty()) {
return this;
} else {
return node.left.ancestorOfSmallRight();
}
}
private BSTNode<ContentType> getNodeOfLeftSuccessor() {
return node.left.node;
}
private BSTNode<ContentType> getNodeOfRightSuccessor() {
return node.right.node;
}
}
How can I change/rewrite my code for it to work?
Think what would happen when you reach the left most leaf node.
Its left tree will be null which means you will break out of the while loop. You are returning null after this and so any attempt to access the state of the return value will throw an exception.
You must return this node when it has no more left children as that will be the smallest element in the tree
Also, I don't know why you have BinarySearchTree and BSTNode. A BSTNode should be good enough to construct a tree. Please go through some tutorial/lessons for a better understanding.
How to get the first element when going through a binary search tree with inorder?
Keep going left till you can't go left anymore... If a node has a left child, go for it. Keep doing this till you get to a node that does not have a left child. When you are there, you know you are in the left-most part of the tree. Following code snippet shows an idea of how this can be achieved given the root of a BST.
public BSTNode getSmallest(BSTNode root) {
if(root.left != null)
return getSmallest(root.left);
return root;
}
I'm new to eclipse development and I'm working on a custom namepatternfilter for Jface tree viewer. I have the below code in my filter which recursively goes through children of a node element.
public boolean isChildMatch(final Object element) {
boolean value = false;
// Object[] children = this.contentProvider.getChildren(element);
Object[] items = null;
if (((HashMap<Object, String>) getTreeMap().get(element)) == null) {
final Object[] children = this.contentProvider.getChildren(element);
items = children;
new Thread(new Runnable() {
#Override
public void run() {
final HashMap<Object, String> childrenMap = new HashMap<Object, String>();
for (Object object : children) {
childrenMap.put(object, null);
}
NamePatternFilter.this.getTreeMap().put(element, childrenMap);
}
}).start();
}
else {
items = ((HashMap<Object, String>) getTreeMap().get(element)).keySet().toArray();
}
for (Object child : items) {
if (isElementMatch(child)) {
value = true;
break;
}
else if (isChildMatch(child)) {
this.visibleElements.add(child);
value = true;
break;
}
}
return value;
}
When i run the code, I'm getting stackoverflow exception
org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.StackOverflowError)
at org.eclipse.swt.SWT.error(SWT.java:4441)
at org.eclipse.swt.SWT.error(SWT.java:4356)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:139)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4147)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3764)
What am I missing here?
I have some problems with java(Dobly Linked List). i must add first node before last node. at first tried to build it, but not works. hier is my dobly linked list:
public class DoublyLinkedList<T>
{
private Element<T> first, last;
private int size;
public DoublyLinkedList()
{
first = last = null;
size = 0;
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size == 0;
}
// --- hier is Problem!!! I have changed just hier. ---
public void apply( T o ) {
Element<T> e = new Element<T>(o);
Element<T> current = first;
Element<T> save = first;
for(int i = 0; i < size; i++){
current = current.getNext();
}
current.connectAsPrevious(e);
e.connectAsNext(save);
size++;
}
// --- bekannte Methoden ---
public void add( T content )
{
Element<T> e = new Element<T>( content );
if ( isEmpty() )
{
first = last = e;
}
else
{
last.connectAsNext( e );
last = e;
}
size++;
}
public void showAll()
{
Element<T> current = first;
while ( current != null )
{
if ( current.getContent() != null )
{
System.out.print( current.getContent().toString() );
if ( current != last )
{
System.out.print(", ");
}
}
current = current.getNext();
}
System.out.println();
}
// --- weitere Methoden zum Testen ---
public void build( T[] elems )
{
for ( T e : elems ) { add( e ); }
}
public String toString()
{
String result = "";
Element current = first;
while ( current != null )
{
result += current.getContent().toString();
if ( current != last )
{
result += ", ";
}
current = current.getNext();
}
return result;
}
// Element
private static class Element<E>
{
private E content;
private Element<E> previous, next;
public Element( E c )
{
content = c;
previous = next = null;
}
public E getContent()
{
return content;
}
public void setContent( E c )
{
content = c;
}
public boolean hasNext()
{
return next != null;
}
public Element<E> getNext()
{
return next;
}
public void disconnectNext()
{
if ( hasNext() )
{
next.previous = null;
next = null;
}
}
public void connectAsNext( Element<E> e)
{
disconnectNext();
next = e;
if ( e != null )
{
e.disconnectPrevious();
e.previous = this;
}
}
public boolean hasPrevious()
{
return previous != null;
}
public Element<E> getPrevious()
{
return previous;
}
public void disconnectPrevious()
{
if ( hasPrevious() )
{
previous.next = null;
previous = null;
}
}
public void connectAsPrevious( Element<E> e )
{
disconnectPrevious();
previous = e;
if ( e != null )
{
e.disconnectNext();
e.next = this;
}
}
}
}
I think i must add whileloop. because if size 0 is, it stops on it and comes error NullPointerException. sorry for my bad english.
The reason you get a NullPointerException is that if you have an empty list then current is null (because it's assigned the value of first which is null) and current.connectAsPrevious will throw the exception.
Without knowing what the method is supposed to do it's difficult to suggest an alternative. However you can avoid the exception by putting if (current != null) before current.connectAsPrevious.
If it is supposed to add the item before the last item in the list (rather than as the last item) then you should just use your last reference rather than iterating through the list from the start:
e.connectAsNext(last);
e.connectAsPrevious(last.getPrevious());
last.connectAsPrevious(e);
Within the <Images> tag, this API call returns a mix of different types: fanart, boxart, banner, screenshot, clearlogo.
Using SimpleXML Framework, what is the best way to go about parsing those into separate Lists? I'd like a List<FanArt>, List<BoxArt>, List<Banner> etc. The examples on the site do not seem to cover this situation. I've fumbled about with a few different ideas, but I'm not even sure SimpleXML Framework can handle this in a straight forward way.
For example, the below throws this exception: org.simpleframework.xml.core.PersistenceException: Duplicate annotation of name 'Images' on field 'clearLogos'.....
#ElementList(name = "Images", entry = "clearlogo")
private List<ClearLogo> clearLogos;
#ElementList(name = "Images", entry = "boxart")
private List<BoxArt> boxart;
In case anyone comes across this and needs some sort of solution, I've done this for now to get it working. Does the job but it's not really what I was after.
#Root
public class Images {
#ElementListUnion({
#ElementList(entry = "fanart", type = FanArt.class, inline = true),
#ElementList(entry = "boxart", type = BoxArt.class, inline = true),
#ElementList(entry = "screenshot", type = ScreenShot.class, inline = true),
#ElementList(entry = "banner", type = Banner.class, inline = true),
#ElementList(entry = "clearlogo", type = ClearLogo.class, inline = true)
})
private List<Object> images;
private List<FanArt> fanarts;
private List<BoxArt> boxarts;
private List<ScreenShot> screenshots;
private List<Banner> banners;
private List<ClearLogo> clearlogos;
public List<FanArt> getFanarts() {
if (fanarts == null) {
fanarts = new ArrayList<FanArt>();
for (Object image : images) {
if (image instanceof FanArt) {
fanarts.add((FanArt) image);
}
}
}
return fanarts;
}
public List<BoxArt> getBoxarts() {
if (boxarts == null) {
boxarts = new ArrayList<BoxArt>();
for (Object image : images) {
if (image instanceof BoxArt) {
boxarts.add((BoxArt) boxarts);
}
}
}
return boxarts;
}
public List<ScreenShot> getScreenshots() {
if (screenshots == null) {
screenshots = new ArrayList<ScreenShot>();
for (Object image : images) {
if (image instanceof ScreenShot) {
screenshots.add((ScreenShot) image);
}
}
}
return screenshots;
}
public List<Banner> getBanners() {
if (banners == null) {
banners = new ArrayList<Banner>();
for (Object image : images) {
if (image instanceof Banner) {
banners.add((Banner) image);
}
}
}
return banners;
}
public List<ClearLogo> getClearLogos() {
if (clearlogos == null) {
clearlogos = new ArrayList<ClearLogo>();
for (Object image : images) {
if (image instanceof ClearLogo) {
clearlogos.add((ClearLogo) image);
}
}
}
return clearlogos;
}
}