# Visualisierung von XML Dateien in einer Java SwingGui



## TLow (5. Sep 2014)

Hallo zusammen,
und zwar stehe ich vor einem großen Problem. Meine Aufgabe ist es eine beliebige XML Datei in einer Java SwingGui zu visualisieren. Nach längerem recherchieren habe ich leider nichts geeignetes gefunden, was mir helfen könnte.
Ich muss gestehen, dass ich noch noch nicht so fit in Java bin. Deshalb fällt mir das ganze auch so schwer. 

Aufgabe:
Ziel ist es eine Oberfläche mit Swing aufzubauen, die im linken Bereich eine Verzeichnisstruktur der XML-Tags als aufklappbare Ordner anzeigt. Im rechten Bereich sollen dann die Atribute eines gewählten Tag als Eingabefelder angezeigt werden.

Vorerst musste ich mir die Grundlagen der XML aneignen. Hier ist ein XML Code den ich mittels eines JTrees darstellen möchte. 

[xml]
<?xml version="1.0" encoding="UTF-8"  ?>
<!DOCTYPE mensch [
<!ELEMENT mensch (kopf)*>
<!ATTLIST mensch
	name 	CDATA		#REQUIRED
>
<!ELEMENT kopf (haare|augen)>
<!ELEMENT haare EMPTY>
<!ATTLIST haare
	haarfarbe 	CDATA	#REQUIRED
	haarlaenge	NMTOKEN	#REQUIRED
>
<!ELEMENT augen EMPTY>
<!ATTLIST augen
	augenfarbe 	CDATA	#REQUIRED
	sehstaerke	NMTOKEN	#REQUIRED
>
]>
<mensch name="Max">
	<kopf>
		<haare haarfarbe="braun" haarlaenge="3cm" />
		<augen augenfarbe="blau" sehstaerke="-0.75" />
	</kopf>
</mensch>	
[/xml]

(Nur ein einfaches Beispiel. Die Attribute und deren Werte sollen später angezeigt werden).

Kennt ihr vielleicht eine Internetseite, die eine verständliche Einführung in ein solches Thema bietet? 
Ich wäre auch sehr dankbar für Beispiel Codes. Mich würde es vorallem interessieren, wie ich die Attribute und deren Werte durch einen ausgewählten Tag angezeigen kann. Ich komme an dieser Stelle nicht weiter...


```
@Override
	public void valueChanged(TreeSelectionEvent e) {
		JTree tree = (JTree) e.getSource();
	        XMLTreeNode selectedNode = (XMLTreeNode) tree.getSelectionPath().getLastPathComponent();
```

Klicke ich einen bestimmten Tag an wird immer nur die sehstaerke und augenfarbe ausgegeben. Auch dann, wenn ich auf das Element haare klicke. 

Vielen Dank für eure Hilfe.


----------



## evocrossfireX (5. Sep 2014)

Probiers mal mit JDOM2
Ein kleines Beispiel:


```
doc = new SAXBuilder().build(xml_datei);
rootelement = doc.getRootElement();
list = rootelement.getChildren();
System.out.println(list.get(0).getAttributeValue("attribut_name"));
```

Xml Datei:
<xml>
<test attribut_name="bla"> </test>
</xml>


----------



## TLow (8. Sep 2014)

Vielen Dank für dein Beispiel, jedoch ist es nicht genau das was ich möchte. Sobald ich eine beliebige XML-Datei mithilfe des JTrees (Vorgehensweise noch unbekannt) darstelle möchte ich per klick auf ein Tag, dessen Attribute und Werte in einen Textfeld anzeigen.





Bisher funktioniert es noch nicht so richtig. Da immer dasselbe Attribut in der Console angezeigt wird...


----------



## evocrossfireX (8. Sep 2014)

TLow hat gesagt.:


> Vielen Dank für dein Beispiel, jedoch ist es nicht genau das was ich möchte. Sobald ich eine beliebige XML-Datei mithilfe des JTrees (Vorgehensweise noch unbekannt) darstelle möchte ich per klick auf ein Tag, dessen Attribute und Werte in einen Textfeld anzeigen.
> 
> 
> 
> ...



Ich verstehe schon was du möchtest 
Und ich bin mir sicher es geht mit der Lib die ich oben genannt habe.
Du kannst ja mal dein Code posten


----------



## TLow (10. Sep 2014)

Problem hat sich erledigt, jedoch hat sich ein weiteres ergeben:



Ich möchte jetzt die Attribute im JTextArea anzeigen. Jedoch funktioniert das nicht so wirklich... Hier ein bisschen Code:

```
public class SwingGUI extends javax.swing.JFrame {

	{
		//Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	private String holder = "";
	private JMenuBar jMenuBar;
	private JScrollPane scrollPane;
	private JTextField jTextField;
	private JMenu jMAuswahl;
	private JMenuItem jMISchließen, jMIOeffnen;
	private JTextArea jTextArea;
	private JPanel panel;

	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				SwingGUI inst = new SwingGUI();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public SwingGUI() {
		super();
		 initGUI();
	}
	
	private void initGUI() {
	
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
					{
				
				panel = new JPanel();
				panel.setBorder(new EmptyBorder(5,5,5,5));
				setContentPane(panel);
				panel.setLayout(new GridLayout(1,2,5,5));
				
				scrollPane = new JScrollPane();
				panel.add(scrollPane);
			
			
				{
					/*jTextField = new JTextField();
					panel.add(jTextField);*/
					
					
				}
				{
					jTextArea = new JTextArea();
					jTextArea.setEditable(false);
					panel.add(jTextArea);
				}
				
			}

				jMenuBar = new JMenuBar();
				setJMenuBar(jMenuBar);
				{
					jMAuswahl = new JMenu("Auswahl");
					jMenuBar.add(jMAuswahl);
					{
						jMISchließen = new JMenuItem();
						jMAuswahl.add(jMISchließen);
						jMISchließen.setText("Schließen");
						jMISchließen.addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent evt) {
								jMISchließenActionPerformed(evt);
							}
						});
					}
					
						
						
						jMIOeffnen = new JMenuItem();
						jMAuswahl.add(jMIOeffnen);
						jMIOeffnen.setText("XML öffnen...");
						jMIOeffnen.addActionListener(new ActionListener(){
							public void actionPerformed(ActionEvent evt){
								
								
								
								JFileChooser fc = new JFileChooser();
								 FileNameExtensionFilter xmlfilter = new FileNameExtensionFilter(
							                "xml files (*.xml)", "xml");
							            fc.setFileFilter(xmlfilter);
								int state = fc.showOpenDialog(null);
								if(state == JFileChooser.APPROVE_OPTION){
									File selFile =  fc.getSelectedFile();
						
								try {
									
									SAXParserFactory factory = SAXParserFactory.newInstance();
									SAXParser saxParser = factory.newSAXParser();
									SimpleXMLHandler handler = new SimpleXMLHandler();
									InputStream input = new FileInputStream(new File(selFile.getPath()));
									saxParser.parse(input, handler);
									scrollPane.setViewportView(handler.getTree());
									
									
								} catch (Exception e) {
									e.printStackTrace();
								}
								
							
									
							}
							}
						});
						
					}
				
				
				
			pack();
			setSize(400, 300);
		} catch (Exception e) {
		    //add your error handling code here
			e.printStackTrace();
		}
	}
	
	private void jMISchließenActionPerformed(ActionEvent evt) {
		System.exit(0);
	}
	
	public void treeSelectionEvent(TreeSelectionEvent e){
		
		JTree tree = (JTree) e.getSource();
		
		XMLTreeNode selectedNode = (XMLTreeNode) tree.getLastSelectedPathComponent();
		
		
				if (selectedNode.getMap() != null) {
					Map<String, String> map = selectedNode.getMap();
					Set<String> keys = map.keySet();
					for(String key : keys){
						
						holder = "Attribut: " + key + " - " + map.get(key);
						System.out.println(holder);
						
						//System.out.println("Attribut: " + key + " - " + map.get(key));
					//jTextField.setText("Attribut: " + key + " - " + map.get(key));
					
					
			}
					jTextArea.setText(holder);
					panel.repaint();
					//JOptionPane.showMessageDialog(null,holder);
		
	}
				
	}
}
```

Code von einer anderen Klasse:


```
public JTree getTree() {

		JTree tree = new JTree(rootNode);
		tree.setRootVisible(false);
		tree.addTreeSelectionListener(new TreeSelectionListener() {

			
			public void valueChanged(TreeSelectionEvent e) {
			
				
			SwingGUI bsp = new SwingGUI();
			bsp.treeSelectionEvent(e);
				
			}

		});
		return tree;
	}
```

Das Ausgeben der Attribute und deren Werte verläuft in der Konsole reibungslos. Jedoch nicht das Hinzufügen in die Komponente JTextArea. Wo liegt hier der Fehler?


----------



## Harry Kane (10. Sep 2014)

In der valueChanged Methode von "der anderen Klasse" legst du jedesmal eine neue Instanz von SwingGUI an. Da auf dieser neuen Instanz nie setVisible(true) aufgerufen wird, siehst du sie nicht.
Entweder gibst du "der anderen Klasse" eine Referenz auf eine existierende und sichtbar SwingGUI, oder du machst die SwingGUI gleich zum TreeSelectionListener deines JTree.


----------



## TLow (10. Sep 2014)

Ich bin grad etwas neben der Spur, wie bekomme ich den TreeSelectionListener in meine SwingGui? Ich arbeite schon 6 Stunden daran und kann das Problem nicht lösen....


----------



## Harry Kane (10. Sep 2014)

Die "andere Klasse", von der du die getTree() methode gepostet hast, ist offenbar der SimpleXMLhandler, der in der initGui-Methode vion SwingGUI verwendet wird.
Sorge einfach dafür, das SwingGUI TreeSelectionListener implementiert, hänge ihn an den von handler.getTree() zurückgegebenen JTree, und schreibe in die valueChanged-Methode von SwingGUI (du musst diese Methoe erstellen, wenn SwingGUI TreeSelectionListener implementieren soll) einfach den Code rein, der zur Zeit noch in treeSelectionEvent-methode von SwingGUI steht.
nach welchem Buch/Kurs lernst du Java?


----------



## TLow (11. Sep 2014)

Vielen Dank, jedoch wenn ich ihn an den von handler.getTree() zurückgegebenen JTree hänge, gibt es einen Fehler.

```
scrollPane.setViewportView(handler.getTree());
```
Der Fehler lautet:
The method setViewportView(Component) in the type JScrollPane is not applicable for the arguments (void)

Außerdem, wie genau ist das gemeint? Ich habe den TreeSelectionListener implementiert und habe nach der Aufforderung die abstrakte Methode valueChanged implementiert. Den Inhalt von der anderen Methode treeSelectionEvent habe ich kopiert und in die valueChanged methode eingefügt. Nun kommt es aber zu komplikationen, entweder ich lese und verstehe deinen Satz nicht so richtig, oder ich mache was falsch.



Harry Kane hat gesagt.:


> Sorge einfach dafür, das SwingGUI TreeSelectionListener implementiert, hänge ihn an den von handler.getTree() zurückgegebenen JTree



Muss ich bei handler.getTree() nach der Klammer noch was einfügen? Z.B. handler.getTree().addTreeSelectionListener()... oder ist mein Ansatz falsch?


Zu deiner Frage, wie ich Java lerne:
Ich habe bereits 4 Bücher gelesen, die meisten aber nach 3/4 abgebrochen.
Mit folgenden Büchern habe ich mich beschäftigt:
-Einstieg in Java 7 (hat mir leider nicht gefallen, da zu wenige beispiel Codes vorhanden waren)
-Schrödinger programmiert Java (Tolles Buch, jedoch verliert man sehr schnell den Überblick, weshalb ich ein neues Buch besorgte)
-Programmieren lernen mit Java: Aktuell zu Java 7
-Java, Der umfassende Programmierkurs (noch dabei)

Video2Brain: Java 7 - Einstieg für Anspruchsvolle https://www.video2brain.com/de/videotraining/java-7

Ich habe mich die letzten Monate/Wochen sehr mit Java beschäftigt, jedoch habe ich die schlechte Eigenschaft, dass ich schnell die Sachen wieder vergesse...


----------



## Harry Kane (11. Sep 2014)

Dann hast du offenbar den Rückgabetyp von handler.getTree() von JTree auf void geändert. Davon war aber in meinem Post nicht die Rede.
Und ja, nach handler.getTree() muss noch was stehen, und zwar handler.getTree().addTreeSelectionListener(this).
Dir fehlen offenbar noch ein paar grundlegende Sachen. Hast du schon mal etwas kleineres programmiert? Woher stammen die Codes, die du uns bisher gezeigt hast?


----------



## TLow (11. Sep 2014)

Die Codes wurden mir von einem Kollegen zur Verfügung gestellt.
Ich mache derzeit mein Studium und komme (vielleicht) ins 3 Semester. Je nach dem wie die Studienarbeit verläuft... Unser Dozent hat damals gesagt, wer hier studieren tut (DHBW) muss schon Programmiererfahrung mitbringen. Da ich auf einem Ernährungswissenschaftlichen Gymnasium war kam ich kaum mit Programmierung in Kontakt. 

Wir haben in einer 3 stündigen Vorlesung Objektorientierung theoretisch vermittelt bekommen und das Thema abgeschlossen. So ging es die ganzen 2 Semester lang. Im 2 Semester haben wir eine Programmieraufgabe bekommen, die wir in Gruppen erledigen sollten. Jedoch war das keine Gruppenarbeit, sondern eher ne Einzelarbeit und die Klassen wurden dann später in einem Projekt zusammengefügt. Somit konnte ich wiederrum nichts von den anderen lernen und kaum einen Beitrag leisten.

Meine Programmierkenntnisse sind nicht wirklich gut, deshalb war ich auch nicht in der Lage selber diese Klassen zu schreiben. Mein Betreuer hat mir schließlich diese Codes zur Verfügung gestellt (3 Klassen). Für mich ist es schwer weiter daran zu arbeiten, da mir keinerlei Codes mit diesem Thema bekannt sind. (Die 3 Klassen dienten lediglich dazu eine XML-Datei in einem JFrame als JTree darzustellen. Den Rest habe ich selber gemacht).


----------



## Harry Kane (11. Sep 2014)

Ok, das erklärt zur Genüge die Unsicherheiten.
Konntest du denn mit meinem letzten Post was anfangen?


----------

