Index: /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCComponent.java
===================================================================
--- /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCComponent.java	(revision 355)
+++ /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCComponent.java	(revision 355)
@@ -0,0 +1,349 @@
+package de.ugoe.cs.eventbench.jfcmonitor;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.InvalidParameterException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.accessibility.AccessibleContext;
+
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * This class manages information about the current GUI. It always contains the
+ * current GUI hierarchy.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCComponent {
+
+	/**
+	 * <p>
+	 * Map of all known GUI components.
+	 * </p>
+	 */
+	private static Map<Component, JFCComponent> knownComponents = new HashMap<Component, JFCComponent>();
+
+	/**
+	 * <p>
+	 * Adds a AWT component to the GUI hierarchy. If the component already
+	 * exists in the hierarchy, it is not added a second time.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component that is added
+	 */
+	public static void add(Component component) {
+		add(component, find(component.getParent()));
+	}
+
+	/**
+	 * <p>
+	 * Adds a AWT component to the GUI hierarchy. If the component already
+	 * exists in the hierarchy, it is not added a second time.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component that is added
+	 * @param parent
+	 *            parent of the component
+	 */
+	public static void add(Component component, JFCComponent parent) {
+		if (!knownComponents.containsKey(component)) {
+			knownComponents.put(component, new JFCComponent(component, parent));
+		}
+	}
+
+	/**
+	 * <p>
+	 * Finds a component in the GUI hierarchy and returns the corresponding
+	 * JFComponent instance. Returns null if the component is not found.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component that is searched for
+	 * @return corresponding JFComponent instance; null if the compenent is not
+	 *         found
+	 */
+	public static JFCComponent find(Component component) {
+		return knownComponents.get(component);
+	}
+
+	/**
+	 * <p>
+	 * Removes a component from the GUI hierarchy. In case the component is not
+	 * part of the known hierachy, nothing happens.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component to be removed
+	 */
+	public static void remove(Component component) {
+		JFCComponent jfcComponent = knownComponents.remove(component);
+		if (jfcComponent != null) {
+			jfcComponent.removeFromParent();
+			jfcComponent.removeChildren();
+		}
+	}
+
+	/**
+	 * <p>
+	 * Parent of the GUI component. null means, that the component has no
+	 * parent.
+	 * </p>
+	 */
+	private JFCComponent parent = null;
+
+	/**
+	 * <p>
+	 * Child components of the component.
+	 * </p>
+	 */
+	private List<JFCComponent> children = new LinkedList<JFCComponent>();
+
+	/**
+	 * <p>
+	 * Reference to the actual GUI component.
+	 * </p>
+	 */
+	private Component component;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the title of the component. Set by
+	 * {@link #setTitle()}.
+	 * </p>
+	 */
+	private String title = null;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the class of the component. Set by
+	 * {@link #setClass()}.
+	 * </p>
+	 */
+	private String componentClass = null;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the icon of the component. Set by
+	 * {@link #setIcon()}.
+	 * </p>
+	 */
+	private String icon = null;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the icon of the component. Set by
+	 * {@link #setIndex()}.
+	 * </p>
+	 */
+	private int index = -1;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new JFCComponent. Only used internally by
+	 * {@link #add(Component, JFCComponent)}.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component associated with the JFCComponent
+	 * @param parent
+	 *            parent of the component; null if there is no parent
+	 */
+	private JFCComponent(Component component, JFCComponent parent) {
+		if (component == null) {
+			throw new InvalidParameterException(
+					"parameter component must not be null");
+		}
+		this.component = component;
+		this.parent = parent;
+		if (parent != null) {
+			parent.addChild(this);
+		}
+
+		if (component instanceof Container) {
+			for (Component childComponent : ((Container) component)
+					.getComponents()) {
+				add(childComponent, this);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a child component to the current component.
+	 * </p>
+	 * 
+	 * @param child
+	 *            child component to be added
+	 */
+	private void addChild(JFCComponent child) {
+		children.add(child);
+	}
+
+	/**
+	 * <p>
+	 * Returns an XML representation of the component.
+	 * </p>
+	 * 
+	 * @return XLM snippet
+	 */
+	public String getXML() {
+		setClass();
+		setIcon();
+		setIndex();
+		setTitle();
+		StringBuilder builder = new StringBuilder();
+		if( parent!=null ) {
+			builder.append(parent.getXML());
+		}
+		builder.append("  <component>" + StringTools.ENDLINE);
+		builder.append("   <param name=\"title\" value=\"" + title + "\" />"
+				+ StringTools.ENDLINE);
+		builder.append("   <param name=\"class\" value=\"" + componentClass
+				+ "\" />" + StringTools.ENDLINE);
+		builder.append("   <param name=\"icon\" value=\"" + icon + "\" />"
+				+ StringTools.ENDLINE);
+		builder.append("   <param name=\"index\" value=\"" + index + "\" />"
+				+ StringTools.ENDLINE);
+		builder.append("  </component>" + StringTools.ENDLINE);
+		return builder.toString();
+	}
+
+	/**
+	 * <p>
+	 * Removes a child component from the current component.
+	 * </p>
+	 * 
+	 * @param child
+	 *            child component to be removed
+	 */
+	private void removeChild(JFCComponent child) {
+		children.remove(child);
+	}
+
+	/**
+	 * <p>
+	 * Removes the component from the list of children of its parent.
+	 * </p>
+	 */
+	private void removeFromParent() {
+		if (parent != null) {
+			parent.removeChild(this);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Triggers the removals of all child components from the GUI hierarchy,
+	 * i.e., calls {@link #remove(Component)} for all child components.
+	 * </p>
+	 */
+	private void removeChildren() {
+		for (JFCComponent child : children) {
+			remove(child.component);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #title} of the component. The title is defined as follows
+	 * (first in the list, that is not null):
+	 * <ul>
+	 * <li>accessible name of the component if available</li>
+	 * <li>{@link #icon} of the component</li>
+	 * <li>name of the component</li>
+	 * <li>coordinates of the component</li>
+	 * </ul>
+	 * </p>
+	 */
+	private void setTitle() {
+		title = null; // reset title
+
+		AccessibleContext accessibleContext = component.getAccessibleContext();
+		if (accessibleContext != null) {
+			title = accessibleContext.getAccessibleName();
+		}
+		if (title == null) {
+			title = icon;
+		}
+		if (title == null) {
+			title = component.getName();
+		}
+		if (title == null) {
+			// use coordinates as last resort
+			title = "Pos(" + component.getX() + "," + component.getY() + ")";
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #componentClass} of the component.
+	 * </p>
+	 */
+	private void setClass() {
+		componentClass = component.getClass().getName();
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #icon} of the component.
+	 * </p>
+	 */
+	private void setIcon() {
+		icon = null; // reset icon
+
+		Method getIconMethod;
+		try {
+			getIconMethod = component.getClass().getMethod("getIcon",
+					new Class[0]);
+			if (getIconMethod != null) {
+				Object iconObject = getIconMethod.invoke(component,
+						new Object[] {});
+				if (iconObject != null) {
+					String iconPath = iconObject.toString();
+					if (!iconPath.contains("@")) {
+						System.out.println("iconPath");
+						String[] splitResult = iconPath
+								.split(File.separatorChar == '\\' ? "\\\\"
+										: File.separator);
+						icon = splitResult[splitResult.length - 1];
+					}
+				}
+			}
+		} catch (SecurityException e) {
+		} catch (NoSuchMethodException e) {
+		} catch (IllegalArgumentException e) {
+		} catch (IllegalAccessException e) {
+		} catch (InvocationTargetException e) {
+			System.err.println("Found method with name " + "getIcon"
+					+ " but could not access it.");
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #index} of the component as the index in the parent, if
+	 * it is accessible.
+	 * </p>
+	 */
+	private void setIndex() {
+		index = -1; // reset index
+
+		AccessibleContext accessibleContext = component.getAccessibleContext();
+		if (accessibleContext != null) {
+			index = accessibleContext.getAccessibleIndexInParent();
+		}
+	}
+
+}
Index: /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java
===================================================================
--- /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java	(revision 354)
+++ /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java	(revision 355)
@@ -8,6 +8,4 @@
 import java.io.IOException;
 import java.io.OutputStreamWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 
 import de.ugoe.cs.util.StringTools;
@@ -128,54 +126,10 @@
 		if (event.getSource() instanceof Component) {
 			Component source = (Component) event.getSource();
-			addComponentInfo(builder, source);
-			builder.append(" <parent>" + ENDLINE);
-			addComponentInfo(builder, source.getParent());
-			builder.append(" </parent>" + ENDLINE);
+			JFCComponent jfcComponent = JFCComponent.find(source);
+			if (jfcComponent != null) {
+				builder.append(jfcComponent.getXML());
+			}
 		}
 		builder.append(" </source>" + ENDLINE);
-	}
-
-	/**
-	 * <p>
-	 * Appends information about the component to the a {@link StringBuilder}.
-	 * The prefix can be used to give further information about the component.
-	 * </p>
-	 * 
-	 * @param builder
-	 *            {@link StringBuilder} where the information is appended
-	 * @param component
-	 *            component whose information is appended
-	 */
-	private void addComponentInfo(StringBuilder builder, Component component) {
-		builder.append("  <param name=\"getName\" value=\""
-				+ StringTools.xmlEntityReplacement(component.getName())
-				+ "\" />" + ENDLINE);
-		for (Method method : component.getClass().getMethods()) {
-			try {
-				if (method.getName() == "getText") {
-					String text = (String) method.invoke(component,
-							new Object[] {});
-					if (text != null) {
-						builder.append("  <param name=\"getText\" value=\""
-								+ StringTools.xmlEntityReplacement(text)
-								+ "\" />" + ENDLINE);
-					}
-				}
-				if (method.getName() == "getTitle") {
-					String title = (String) method.invoke(component,
-							new Object[] {});
-					if (title != null) {
-						builder.append("  <param name=\"getTitle\" value=\""
-								+ StringTools.xmlEntityReplacement(title)
-								+ "\" />" + ENDLINE);
-					}
-				}
-			} catch (IllegalArgumentException e) {
-			} catch (IllegalAccessException e) {
-			} catch (InvocationTargetException e) {
-				System.err.println("Found method with name " + method.getName()
-						+ " but could not access it.");
-			}
-		}
 	}
 
Index: /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java
===================================================================
--- /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java	(revision 354)
+++ /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java	(revision 355)
@@ -63,4 +63,6 @@
 		Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile,
 				AWTEvent.MOUSE_EVENT_MASK);
+		Toolkit.getDefaultToolkit().addAWTEventListener(new WindowMonitor(),
+				AWTEvent.WINDOW_EVENT_MASK);
 
 		if (stdOutputWrite) {
Index: /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/WindowMonitor.java
===================================================================
--- /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/WindowMonitor.java	(revision 355)
+++ /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/WindowMonitor.java	(revision 355)
@@ -0,0 +1,44 @@
+package de.ugoe.cs.eventbench.jfcmonitor;
+
+import java.awt.AWTEvent;
+import java.awt.Window;
+import java.awt.event.AWTEventListener;
+import java.awt.event.WindowEvent;
+
+/**
+ * <p>
+ * An AWT event listener responsible to monitor the window creation and
+ * destruction.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WindowMonitor implements AWTEventListener {
+
+	/**
+	 * <p>
+	 * Adds all created windows (and their child components) to the GUI
+	 * hierarchy maintained by {@link JFCComponent} and removes them if a window
+	 * is destroyed.
+	 * </p>
+	 * </p>
+	 * 
+	 * @see java.awt.event.AWTEventListener#eventDispatched(java.awt.AWTEvent)
+	 */
+	@Override
+	public void eventDispatched(AWTEvent event) {
+		Window window;
+		switch (event.getID()) {
+		case WindowEvent.WINDOW_OPENED:
+			window = ((WindowEvent) event).getWindow();
+			JFCComponent.add(window);
+			break;
+		case WindowEvent.WINDOW_CLOSED:
+			window = ((WindowEvent) event).getWindow();
+			JFCComponent.remove(window);
+			break;
+		}
+	}
+
+}
