Index: /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java
===================================================================
--- /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java	(revision 270)
+++ /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java	(revision 271)
@@ -2,4 +2,5 @@
 
 import java.awt.AWTEvent;
+import java.awt.Component;
 import java.awt.event.AWTEventListener;
 import java.awt.event.KeyEvent;
@@ -10,82 +11,155 @@
 import java.lang.reflect.Method;
 
-import javax.swing.JComponent;
-
+/**
+ * <p>
+ * This class implements monitoring of AWT and Swing mouse and keyboard events.
+ * Each of the events is written to an output stream.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
 public class JFCListener implements AWTEventListener {
 
-	final static String ENDLINE = System.getProperty("line.separator"); 
-	
-	final OutputStreamWriter outputWriter;
-	
+	/**
+	 * <p>
+	 * Convenience variable.
+	 * </p>
+	 */
+	final static private String ENDLINE = System.getProperty("line.separator");
+
+	/**
+	 * <p>
+	 * Writer for logging events.
+	 * </p>
+	 */
+	final private OutputStreamWriter outputWriter;
+
 	public JFCListener(OutputStreamWriter outputWriter) {
 		this.outputWriter = outputWriter;
 	}
-	
+
+	/**
+	 * <p>
+	 * Writes all received {@link MouseEvent}s and {@link KeyEvent}s to the
+	 * {@link #outputWriter}.
+	 * 
+	 * @see java.awt.event.AWTEventListener#eventDispatched(java.awt.AWTEvent)
+	 */
 	@Override
 	public void eventDispatched(AWTEvent event) {
 		StringBuilder builder = new StringBuilder();
-				
-		if( event instanceof MouseEvent ) {
+
+		if (event instanceof MouseEvent) {
 			MouseEvent mouseEvent = (MouseEvent) event;
-			if( !isMouseMovement(event.getID()) ) {
+			if (!isMouseMovement(event.getID())) {
 				builder.append("<event id=\"" + event.getID() + "\">" + ENDLINE);
-				builder.append(" <param name=\"X\" value=\"" + mouseEvent.getX() + "\" />" + ENDLINE);
-				builder.append(" <param name=\"Y\" value=\"" + mouseEvent.getY() + "\" />" + ENDLINE);
-				builder.append(" <param name=\"Button\" value=\"" + mouseEvent.getButton() + "\" />" + ENDLINE);
-				builder.append(" <param name=\"Modifiers\" value=\"" + mouseEvent.getModifiers() + "\" />" + ENDLINE);
+				builder.append(" <param name=\"X\" value=\""
+						+ mouseEvent.getX() + "\" />" + ENDLINE);
+				builder.append(" <param name=\"Y\" value=\""
+						+ mouseEvent.getY() + "\" />" + ENDLINE);
+				builder.append(" <param name=\"Button\" value=\""
+						+ mouseEvent.getButton() + "\" />" + ENDLINE);
+				builder.append(" <param name=\"Modifiers\" value=\""
+						+ mouseEvent.getModifiers() + "\" />" + ENDLINE);
 				addSourceInfo(builder, event);
 				builder.append("</event>" + ENDLINE);
 			}
 		}
-		if( event instanceof KeyEvent ) {
+		if (event instanceof KeyEvent) {
 			KeyEvent keyEvent = (KeyEvent) event;
-			if( keyEvent.getID()==KeyEvent.KEY_TYPED ) {
+			if (keyEvent.getID() == KeyEvent.KEY_TYPED) {
 				builder.append("<event id=\"" + event.getID() + "\">" + ENDLINE);
-				builder.append(" <param name=\"KeyCode\" value=\"" + keyEvent.getKeyCode() + "\" />" + ENDLINE);
-				builder.append(" <param name=\"Modifiers\" value=\"" + keyEvent.getModifiers() + "\" />" + ENDLINE);
+				builder.append(" <param name=\"KeyCode\" value=\""
+						+ keyEvent.getKeyCode() + "\" />" + ENDLINE);
+				builder.append(" <param name=\"Modifiers\" value=\""
+						+ keyEvent.getModifiers() + "\" />" + ENDLINE);
 				addSourceInfo(builder, event);
 				builder.append("</event>" + ENDLINE);
 			}
 		}
-		if( builder.length()>0 && outputWriter!=null ) {
+		if (builder.length() > 0 && outputWriter != null) {
 			try {
 				outputWriter.write(builder.toString());
 				outputWriter.flush();
 			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
+				System.err.println("JFCMONITOR -- Failure writing to log: "
+						+ e.getMessage());
 			}
 		}
 	}
-	
+
+	/**
+	 * <p>
+	 * Appends information about the event to a {@link StringBuilder}.
+	 * </p>
+	 * 
+	 * @param builder
+	 *            {@link StringBuilder} where the information is appended
+	 * @param event
+	 *            event whose information is appended
+	 */
 	private void addSourceInfo(StringBuilder builder, AWTEvent event) {
-		builder.append(" <param name=\"Source\" value=\"" + event.getSource().toString() + "\" />" + ENDLINE);
-		if( event.getSource() instanceof JComponent ) {
-			JComponent source = (JComponent) event.getSource();
-			builder.append(" <param name=\"SourceName\" value=\"" + source.getName() + "\" />" + ENDLINE);
-			for(Method method : source.getClass().getMethods() ) {
-				try {
-					if( method.getName()=="getText" ) {
-						String text = (String) method.invoke(source, new Object[]{});
-						builder.append(" <param name=\"SourceText\" value=\"" + text + "\" />" + ENDLINE);
-					}
-					if( method.getName()=="getTitle" ) {
-						String title = (String) method.invoke(source, new Object[]{});
-						builder.append(" <param name=\"SourceTitle\" value=\"" + title + "\" />" + ENDLINE);
-					}
-				} catch (IllegalArgumentException e) {
-				} catch (IllegalAccessException e) {
-				} catch (InvocationTargetException e) {
-				}
-			}
-			/* TODO should include info about parent
-			builder.append(" <param name=\"Parent\" value=\"" + source.getParent().toString() + "\" />" + ENDLINE);
-			builder.append(" <param name=\"ParentName\" value=\"" + source.getParent().getName() + "\" />" + ENDLINE);
-			*/
+		builder.append(" <param name=\"Source\" value=\""
+				+ event.getSource().toString() + "\" />" + ENDLINE);
+		if (event.getSource() instanceof Component) {
+			Component source = (Component) event.getSource();
+			addComponentInfo(builder, source, "Source");
+			addComponentInfo(builder, source.getParent(), "Parent");
 		}
 	}
-	
+
+	/**
+	 * <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
+	 * @param prefix
+	 *            prefix to give further information about the component
+	 */
+	private void addComponentInfo(StringBuilder builder, Component component,
+			String prefix) {
+		builder.append(" <param name=\"" + prefix + "Name\" value=\""
+				+ component.getName() + "\" />" + ENDLINE);
+		for (Method method : component.getClass().getMethods()) {
+			try {
+				if (method.getName() == "getText") {
+					String text = (String) method.invoke(component,
+							new Object[] {});
+					builder.append(" <param name=\"" + prefix
+							+ "Text\" value=\"" + text + "\" />" + ENDLINE);
+				}
+				if (method.getName() == "getTitle") {
+					String title = (String) method.invoke(component,
+							new Object[] {});
+					builder.append(" <param name=\"" + prefix
+							+ "Title\" value=\"" + title + "\" />" + ENDLINE);
+				}
+			} catch (IllegalArgumentException e) {
+			} catch (IllegalAccessException e) {
+			} catch (InvocationTargetException e) {
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Checks if the Id of an {@link AWTEvent} is a mouse movement Id.
+	 * </p>
+	 * 
+	 * @param eventId
+	 *            id of the {@link AWTEvent}
+	 * @return true, if the event is a mouse movement event; false otherwise
+	 */
 	private boolean isMouseMovement(int eventId) {
-		return eventId==MouseEvent.MOUSE_MOVED || eventId==MouseEvent.MOUSE_DRAGGED || eventId==MouseEvent.MOUSE_ENTERED || eventId==MouseEvent.MOUSE_EXITED;
+		return eventId == MouseEvent.MOUSE_MOVED
+				|| eventId == MouseEvent.MOUSE_DRAGGED
+				|| eventId == MouseEvent.MOUSE_ENTERED
+				|| eventId == MouseEvent.MOUSE_EXITED;
 	}
 
Index: /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java
===================================================================
--- /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java	(revision 270)
+++ /trunk/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java	(revision 271)
@@ -1,20 +1,80 @@
 package de.ugoe.cs.eventbench.jfcmonitor;
+
 import java.awt.AWTEvent;
 import java.awt.Toolkit;
 import java.awt.event.AWTEventListener;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.util.Arrays;
 
-
+/**
+ * <p>
+ * Start-up class of the application.
+ * </p>
+ * <p>
+ * Launches the application under test in the same JVM.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
 public class Runner {
 
-	public static void main(String[] args) throws Exception {
-		AWTEventListener listener = new JFCListener(new OutputStreamWriter(System.out));
-		
-		Toolkit.getDefaultToolkit().addAWTEventListener(listener,
+	/**
+	 * <p>
+	 * Name of the log file.
+	 * </p>
+	 */
+	private final static String logfileName = "jfcmonitor.log";
+
+	/**
+	 * <p>
+	 * Debugging variable. If set to true, the logging is also written to the
+	 * console.
+	 * </p>
+	 */
+	private final static boolean stdOutputWrite = true;
+
+	/**
+	 * <p>
+	 * Main method of the application.
+	 * </p>
+	 * 
+	 * @param args
+	 *            the first parameter defines the Jar file that contains the
+	 *            start-up information of the application under test. The
+	 *            remaining parameters are passed on the toe application under
+	 *            test.
+	 */
+	public static void main(String[] args) {
+		FileWriter writer;
+		try {
+			// the writer is not closed explicitly!
+			writer = new FileWriter(logfileName, true);
+			writer.write("<newsession />");
+		} catch (IOException e) {
+			System.err.println("JFCMONITOR -- failure opening logfile: "
+					+ e.getMessage());
+			return;
+		}
+
+		AWTEventListener listenerFile = new JFCListener(writer);
+		Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile,
 				AWTEvent.KEY_EVENT_MASK);
-		Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.MOUSE_EVENT_MASK);
-		
-		JarLauncher launcher = new JarLauncher(args[0], Arrays.copyOfRange(args, 1, args.length));
+		Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile,
+				AWTEvent.MOUSE_EVENT_MASK);
+
+		if (stdOutputWrite) {
+			AWTEventListener listenerStdOut = new JFCListener(
+					new OutputStreamWriter(System.out));
+			Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
+					AWTEvent.KEY_EVENT_MASK);
+			Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
+					AWTEvent.MOUSE_EVENT_MASK);
+		}
+
+		JarLauncher launcher = new JarLauncher(args[0], Arrays.copyOfRange(
+				args, 1, args.length));
 		launcher.exec();
 	}
