JMenu mittels XML Datei aufbauen

Thomas Darimont

Erfahrenes Mitglied
Hallo!

Hier mal ein Beispiel wie man sein JMenu mittels einer XML-Datei aufbauen kann...

Die Klasse Main verwendet die Methode buildJMenuFromXML(JMenuBar, Class clazz) der Klasse JMenuConfigurator:
Code:
package de.tutorials;

import javax.swing.JFrame;
import javax.swing.JMenuBar;

public class Main extends JFrame {

	public Main() {
		super("Main");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		JMenuBar bar = new JMenuBar();
		JMenuConfigurator.buildJMenuFromXML(bar, Main.class);
		setJMenuBar(bar);
		pack();
		setVisible(true);
	}

	public static void main(String[] args) {
		new Main();
	}
}

JMenuConfigurator:
(hier baue ich mal wieder mit meinem "lieben" TreeWalk rekursiv die Menustruktur auf)
Code:
package de.tutorials;

import java.io.IOException;

import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class JMenuConfigurator{
	public static void buildJMenuFromXML(JMenuBar bar, Class clazz) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();

			Document doc = builder.parse(clazz.getResourceAsStream(clazz
					.getName()
					+ "_jmenu.xml"));

			treeWalk(doc.getFirstChild(), bar);

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param doc
	 */
	private static void treeWalk(Node node, JComponent component) {

		String name = node.getNodeName();
		if (node.hasChildNodes()) {
			if (name.equals("jmenu")) {
				Element e = (Element) node;
				JMenu mnu = new JMenu(e.getAttribute("caption"));
				NodeList list = node.getChildNodes();
				component.add(mnu);
				int len = list.getLength();
				for (int i = 0; i < len; i++) {
					treeWalk(list.item(i), mnu);
				}
			}
		} else {
			if (name.equals("jmenuitem")) {
				Element e = (Element) node;
				JMenuItem item = new JMenuItem();
				try {
					Action action = (Action) Thread.currentThread()
							.getContextClassLoader().loadClass(
									e.getAttribute("action-class"))
							.newInstance();
					item.setAction(action);
					item.setText(e.getAttribute("caption"));
				} catch (InstantiationException e1) {
					e1.printStackTrace();
				} catch (IllegalAccessException e1) {
					e1.printStackTrace();
				} catch (ClassNotFoundException e1) {
					e1.printStackTrace();
				}
				component.add(item);
			} else if (name.equals("separator")) {
				component.add(new JSeparator());
			}
		}
	}
}

Hier das dazugehörige XML File:
de.tutorials.Main_jmenu.xml

Code:
<?xml version="1.0"?>
<jmenu caption="File">
	<jmenu caption="A">
		<jmenuitem caption="actionA" action-class="de.tutorials.actions.AActionImpl"/>
	</jmenu>
	<jmenu caption="B">
		<jmenuitem caption="actionB" action-class="de.tutorials.actions.BActionImpl"/>		
	</jmenu>
	<jmenu caption="C">
		<jmenuitem caption="actionC" action-class="de.tutorials.actions.CActionImpl"/>
	</jmenu>
	<separator/>
	<jmenuitem caption="actionD" action-class="de.tutorials.actions.DActionImpl"/>
</jmenu>

und hier mal noch eine Beispiel Action-Class:
Code:
package de.tutorials.actions;

import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;

public class AActionImpl extends AbstractAction{
	public void actionPerformed(ActionEvent e) {
		System.out.println("A->Action");
	}
}

Gruß Tom
 
Hallo Thomas!

Danke für das Beispiel - hat mir die ewige Fragerrei erspart und ich konnte es an mein Problem anpassen ! :)

Gruß

Luxor
 
Hallo Tom,

ist das die übliche Weise in einem professionellem Programm? Sollte man Menüs und Toolbars mit XML aufbauen?


Vg Erdal
 
Moin,
ich würde das höchstens in Erwägung ziehen, wenn es evtl. benutzerabhängige Menüs geben soll o.ä. wo die Menüs wie Properties behandelt werden könnten. Aber für normale Anwendungen habe ich sowas bisher weder gebraucht noch vermisst. XML ist sicher nett, aber weder Allheilmittel noch Wunderwaffe für alles.
 
Hallo!

ist das die übliche Weise in einem professionellem Programm? Sollte man Menüs und Toolbars mit XML aufbauen?
Ich wuerde das naechste mal statt einem DOM Parser einen SAX Parser zum aufbauen des Menues verwenden. Aber ansonsten ist diese Art und Weise ein Menu dynamisch aufzubauen sehr flexibel fuer spaetere Erweiterungen (ohne den Code wieder neu kompilieren zu muessen). Das is beispielsweise dann gut, wenn man fuer seine Anwendung weitere Module die man dann dem User wie Plugins einfach nur zur Verfuegung stellen muss.

Gruss Tom
 
Zurück