Hilfe bei der Verarbeitung von ArrayList

profiler84

Grünschnabel
Hallo,

Ich versuche ein grafisches Inventar für ein Spiel zu bauen.
Das Inventar wird mit Daten aus einer XML gespeist die folgende Struktur hat:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Inventary-List>
	
<Item>
	<Type>Shield</Type>
	<Name>Schild der Rache</Name>
	<Description>Das Schild entstammt aus Gondor</Description>
	<Weight>5</Weight>
	<Attack>1</Attack>
	<Attackreq>0</Attackreq>
	<Defense>3</Defense>
	<Defensereq>2</Defensereq>
	<Heal>0</Heal>
	<Image>src/Test_packages/img/shield-slot.png</Image>
</Item>

<Item>
	<Type>Helmet</Type>
	<Name>Helm der Rache</Name>
	<Description>Der Helm entstammt aus Gondor</Description>
	<Weight>4</Weight>
	<Attack>0</Attack>
	<Attackreq>0</Attackreq>
	<Defense>2</Defense>
	<Defensereq>1</Defensereq>
	<Heal>0</Heal>
	<Image>src/Test_packages/img/helmet-slot.png</Image>
</Item>

<Item>
	<Type>Armor</Type>
	<Name>Rüstung der Furcht</Name>
	<Description>Dieser Armor entstammt aus blub</Description>
	<Weight>8</Weight>
	<Attack>0</Attack>
	<Attackreq>0</Attackreq>
	<Defense>4</Defense>
	<Defensereq>3</Defensereq>
	<Heal>0</Heal>
	<Image>src/Test_packages/img/armor-slot.png</Image>
</Item>

</Inventary-List>

Diese Daten Lese ich aus und speichere sie in einer ArrayList mit folgendem Code:

Code:
package Test_packages;

import java.io.*;
import java.util.ArrayList;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import org.xml.sax.*;

public class GetXMLData{//Start class
	//No generics
	ArrayList<Item> myItemsList;
	Document document;
	
  public GetXMLData (String fName) {//Start constructor
		//create a list to hold the Item objects
		myItemsList = new ArrayList<Item>();
		String fileName = fName;
		readXmlFile(fileName);
	}//End constructor
  
	private ArrayList readXmlFile (String fName) {
    try{// Start try catch
      String xmlFile = fName;
      File file = new File(xmlFile);
      if (file.exists()){
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(xmlFile);
		Element docRoot = document.getDocumentElement();
		
		//get a nodelist of <employee> elements
		NodeList nl = docRoot.getElementsByTagName("Item");
		if(nl != null && nl.getLength() > 0) {
			for(int i = 0 ; i < nl.getLength();i++) {
				
				//get the employee element
				Element el = (Element)nl.item(i);
				
				//get the Employee object
				Item e = getItem(el);
				//add it to list
				myItemsList.add(e);
			}
		}//End if
      }
      else{
        System.out.println("File not found!");
      }
    }//End try
	catch(ParserConfigurationException pce) {
		pce.printStackTrace();
	}catch(SAXException se) {
		se.printStackTrace();
	}catch(IOException ioe) {
		ioe.printStackTrace();
	}//End try catch
     return myItemsList; }//End void readXmlFile
	
	private Item getItem(Element itm) {
		String type = getTextValuebyTag(itm,"Type");
		String name = getTextValuebyTag(itm,"Name");
		String description = getTextValuebyTag(itm,"Description");
		int weight = getIntValuebyTag(itm,"Weight");
		int damage = getIntValuebyTag(itm,"Attack");
		int attreq = getIntValuebyTag(itm,"Attackreq");
		int defense = getIntValuebyTag(itm,"Defense");
		int defreq = getIntValuebyTag(itm,"Defensereq");
		int heal = getIntValuebyTag(itm,"Heal");
		//String type = itm.get
		
		//Create a new Employee with the value read from the xml nodes
		Item i = new Item(type,name,description,weight,damage,attreq,defense,defreq,heal);
		
		return i;
	}
  
	private String getTextValuebyTag(Element ele, String tagName) {
		String textVal = null;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			textVal = el.getFirstChild().getNodeValue();
		}
		return textVal;
	}
	
	private int getIntValuebyTag(Element ele, String tagName) {
		//in production application you would catch the exception
		return Integer.parseInt(getTextValuebyTag(ele,tagName));
	}

}//End class
In weiterer Folge möchte ich die Daten dann über ein Jframe darstellen. Meine konkrete Frage ist wie kann ich die einzelnen Items und ihre Attribute ansprechen, vorallem
was mache ich wenn Item-Typen öfter vorkommen also im XML <Item><Type>Helmet</Type> öfter vorkommt. Wie verweise ich darauf dass ich z.b. das 2. Item haben will.
Ich komme hier überhaupt nicht weiter.

Über einen Vorschlag zur Umsetzung würde ich mich riesig freuen.
Danke.
 
Du könntest beispielsweise alle Items eines Typs in einer eigenen ArrayList speichern, also alle Helme in einer ArrayList, alle Schilde in einer anderen etc. Und die ArrayList's speicherst du in einer Hashmap und verwendest als key den Typnamen, also "Helm", "Schild" usw.
Wenn du die Möglichkeit hast, kannst du sie auch in Datentabellen speichern, weil sie alle dieselben Attribute haben.
 
In weiterer Folge möchte ich die Daten dann über ein Jframe darstellen. Meine konkrete Frage ist wie kann ich die einzelnen Items und ihre Attribute ansprechen, vorallem
was mache ich wenn Item-Typen öfter vorkommen also im XML <Item><Type>Helmet</Type> öfter vorkommt. Wie verweise ich darauf dass ich z.b. das 2. Item haben will.

Die "großen" Spiele nutzen dazu meistens IDs zur Verwaltung, d.h jedes Item hat eine eigene ID, auch wenn vllt der Name oder ähnliches gleich ist, können diese dennoch getrennt verwaltet werden. Und ich würde auch eine HashMap nehmen mit den IDs als Key. Darüber kannst du dir dann auch das Item holen.
 
Vielen vielen Dank für eure Vorschläge, ich werde mal versuchen das umzusetzen. Ich hoffe ich kann noch weiterfragen, wenn ich wieder auf Probleme stoße.
 
Also ich habe mal eine Liste der Typen generiert mit :
Code:
		NodeList itnl = docRoot.getElementsByTagName("Type");
		for (int i=0; i<itnl.getLength(); i++) {
	           // Get element
	           Node n = (Element)itnl.item(i);
	           System.out.println(n.getFirstChild().getNodeValue());	
		}
Wie kann ich für jeden Itemtyp die elemente in eine ArrayList speichern?
 
Ich habe jetzt aus allen Items die gleichen Typs sind in einer ArrayList und diese Lists in eine Hashmap gepackt, wo ich als key den typ definiert habe. Anbei der Code:
Code:
package Test_packages;

import java.io.*;
import java.util.ArrayList;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import java.util.*;

public class XmlDataList {//Start class
	//No generics
	ArrayList<Item> WeaponList;
	ArrayList<Item> ArmorList;
	ArrayList<Item> HelmetList;
	ArrayList<Item> ShieldList;
	ArrayList<Item> BootList;
	ArrayList<Item> HealList;
	Document document;
	Map<String, ArrayList> map = new HashMap<String, ArrayList>();

	
	public static void main(String [] args) {
		XmlDataList xml = new XmlDataList("src/Test_packages/test.xml");
	}
	
	
  public XmlDataList (String fName) {//Start constructor
		//create a list to hold the Item objects
		String fileName = fName;
		readXmlFile(fileName);
		
	}//End constructor
  
	private void readXmlFile (String fName) {
    try{// Start try catch
      String xmlFile = fName;
      File file = new File(xmlFile);
	  WeaponList = new ArrayList<Item>();
	  ArmorList = new ArrayList<Item>();
	  HelmetList = new ArrayList<Item>();
	  ShieldList = new ArrayList<Item>();
	  BootList = new ArrayList<Item>();
	  HealList = new ArrayList<Item>();
      if (file.exists()){
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(xmlFile);
		Element docRoot = document.getDocumentElement();
		
		//get a nodelist of Itemtypes elements
		NodeList itnl = docRoot.getElementsByTagName("Type");
		NodeList nl = docRoot.getElementsByTagName("Item");
		for (int i=0; i<itnl.getLength(); i++) {
			  // The node containing the item i
	           Node n = (Element)itnl.item(i);    
	           String type = n.getFirstChild().getNodeValue();			
				//get the Item element
				Element el = (Element)nl.item(i);
				//get the Item object
				Item e = getItem(el);
				//add it to the right list  
				if (type.equals("Weapon")){
				WeaponList.add(e);	
				}
				else if (type.equals("Armor")){
				ArmorList.add(e);		
				}
				else if (type.equals("Helmet")){
				HelmetList.add(e);		
				}
				else if (type.equals("Shield")){
				ShieldList.add(e);		
				}
				else if (type.equals("Boot")){
				BootList.add(e);		
				}
				else if (type.equals("Heal")){
				BootList.add(e);		
					}
				else  {
				HealList.add(e);
				}
			}//End for
		map.put("Weapon", WeaponList);
		map.put("Armor", ArmorList);
		map.put("Helmet", HelmetList);
		map.put("Shield", ShieldList);
		map.put("Boot", BootList);
		map.put("Heal", HealList);

      }//End if
      else{
        System.out.println("File not found!");
      }
    }//End try
	catch(ParserConfigurationException pce) {
		pce.printStackTrace();
	}catch(SAXException se) {
		se.printStackTrace();
	}catch(IOException ioe) {
		ioe.printStackTrace();
	}//End try catch
    }//End void readXmlFile
	
	private Item getItem(Element itm) {
		String type = getTextValuebyTag(itm,"Type");
		String id = getTextValuebyTag(itm,"Id");
		String name = getTextValuebyTag(itm,"Name");
		String description = getTextValuebyTag(itm,"Description");
		int weight = getIntValuebyTag(itm,"Weight");
		int damage = getIntValuebyTag(itm,"Attack");
		int attreq = getIntValuebyTag(itm,"Attackreq");
		int defense = getIntValuebyTag(itm,"Defense");
		int defreq = getIntValuebyTag(itm,"Defensereq");
		int heal = getIntValuebyTag(itm,"Heal");
		//String type = itm.get
		
		//Create a new Employee with the value read from the xml nodes
		Item i = new Item(type,id,name,description,weight,damage,attreq,defense,defreq,heal);
		
		return i;
	}
  
	private String getTextValuebyTag(Element ele, String tagName) {
		String textVal = null;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			textVal = el.getFirstChild().getNodeValue();
		}
		return textVal;
	}
	
	private int getIntValuebyTag(Element ele, String tagName) {
		//in production application you would catch the exception
		return Integer.parseInt(getTextValuebyTag(ele,tagName));
	}

}//End class
Wie kann ich in meiner Mainmethode auf diese hashmaps zu greifen? Könnt ihr mir da weiterhelfen?
 
So ich habe jetzt geschafft die Hashmap irgendeiner Klasse zu übergeben.
Trenne die gesuchte Arraylist heraus.
Code:
package Test_packages;
import java.util.*;

public class test {

	public static void main(String [] args) {
		XmlDataList xml = new XmlDataList("src/Test_packages/test.xml");
		Map map = xml.getHashMap();
		//System.out.println(map);
		Object i2 = map.get("Weapon");
		ArrayList al = new ArrayList();
		al.add(i2);
		
}
}
Wie greife ich jetzt auf die Item-Attribute zu die ich vorher aus der xml ausgelesen habe?
 
Wie greife ich jetzt auf die Item-Attribute zu die ich vorher aus der xml ausgelesen habe?

Ein Item aus der ArrayList holen und Getter-Methoden von der Item-Klasse nutzen. Ich frage mich nur, woher du weißt, welches Item aus der ArrayList du holen möchtest...

Java:
Object get(int index) 
          Returns the element at the specified position in this list.

Edit:

Java:
Object i2 = map.get("Weapon");
ArrayList al = new ArrayList();
al.add(i2);

Willst du das wirklich so machen?

Ich glaub du möchtest eher etwas in die Richtung schreiben:

Java:
ArrayList al = (ArrayList)map.get("Weapon");
 
Zuletzt bearbeitet:
Hallo,

Ich bin jetzt endlich soweit dass ich die einzelnen Items aus der Arraylist holen kann:
Code:
package Test_packages;
import java.util.*;

public class test {

	public static void main(String [] args) {
		XmlDataList xml = new XmlDataList("src/Test_packages/test.xml");
		Map map = xml.getHashMap();
		ArrayList<Item> i2 = (ArrayList)map.get("Armor");
		Item item = i2.get(0); // 1. Item aus der Arraylist
		System.out.println (item.getDamage() ) ;
               System.out.println (item.getId() ) ;
}
}
Zurzeit hole ich die Items sowie du geschrieben hast über den index
Code:
Item item = i2.get(0);
Ich habe in der xml bei einem Item einfach den Tag <Id> eingefügt und jedes item eine unique id gegeben, womit ich sie dann direkt ansprechen kann. Ich denke dass das so funktioniert oder?
 
Ich habe in der xml bei einem Item einfach den Tag <Id> eingefügt und jedes item eine unique id gegeben, womit ich sie dann direkt ansprechen kann. Ich denke dass das so funktioniert oder?

Sollte, wie gesagt, der Vorschlag orientiert sich an den Vorlagen der "großen" Spiele. Die arbeiten alle mit IDs, um Verwechslungen mit Items gleichen Namens etc. auszuschließen.
 

Neue Beiträge

Zurück