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; /** *

* This class manages information about the current GUI. It always contains the * current GUI hierarchy. *

* * @author Steffen Herbold * @version 1.0 */ public class JFCComponent { /** *

* Map of all known GUI components. *

*/ private static Map knownComponents = new HashMap(); /** *

* Adds a AWT component to the GUI hierarchy. If the component already * exists in the hierarchy, it is not added a second time. *

* * @param component * component that is added */ public static void add(Component component) { add(component, find(component.getParent())); } /** *

* Adds a AWT component to the GUI hierarchy. If the component already * exists in the hierarchy, it is not added a second time. *

* * @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)); } } /** *

* Finds a component in the GUI hierarchy and returns the corresponding * JFComponent instance. Returns null if the component is not found. *

* * @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); } /** *

* Removes a component from the GUI hierarchy. In case the component is not * part of the known hierachy, nothing happens. *

* * @param component * component to be removed */ public static void remove(Component component) { JFCComponent jfcComponent = knownComponents.remove(component); if (jfcComponent != null) { jfcComponent.removeFromParent(); jfcComponent.removeChildren(); } } /** *

* Parent of the GUI component. null means, that the component has no * parent. *

*/ private JFCComponent parent = null; /** *

* Child components of the component. *

*/ private List children = new LinkedList(); /** *

* Reference to the actual GUI component. *

*/ private Component component; /** *

* Helper attribute that contains the title of the component. Set by * {@link #setTitle()}. *

*/ private String title = null; /** *

* Helper attribute that contains the class of the component. Set by * {@link #setClass()}. *

*/ private String componentClass = null; /** *

* Helper attribute that contains the icon of the component. Set by * {@link #setIcon()}. *

*/ private String icon = null; /** *

* Helper attribute that contains the icon of the component. Set by * {@link #setIndex()}. *

*/ private int index = -1; /** *

* Constructor. Creates a new JFCComponent. Only used internally by * {@link #add(Component, JFCComponent)}. *

* * @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); } } } /** *

* Adds a child component to the current component. *

* * @param child * child component to be added */ private void addChild(JFCComponent child) { children.add(child); } /** *

* Returns an XML representation of the component. *

* * @return XLM snippet */ public String getXML() { setClass(); setIcon(); setIndex(); setTitle(); StringBuilder builder = new StringBuilder(); if (parent != null) { builder.append(parent.getXML()); } builder.append(" " + StringTools.ENDLINE); builder.append(" " + StringTools.ENDLINE); builder.append(" " + StringTools.ENDLINE); builder.append(" " + StringTools.ENDLINE); builder.append(" " + StringTools.ENDLINE); builder.append(" " + StringTools.ENDLINE); builder.append(" " + StringTools.ENDLINE); return builder.toString(); } /** *

* Removes a child component from the current component. *

* * @param child * child component to be removed */ private void removeChild(JFCComponent child) { children.remove(child); } /** *

* Removes the component from the list of children of its parent. *

*/ private void removeFromParent() { if (parent != null) { parent.removeChild(this); } } /** *

* Triggers the removals of all child components from the GUI hierarchy, * i.e., calls {@link #remove(Component)} for all child components. *

*/ private void removeChildren() { for (JFCComponent child : children) { remove(child.component); } } /** *

* Sets the {@link #title} of the component. The title is defined as follows * (first in the list, that is not null): *

    *
  • accessible name of the component if available
  • *
  • {@link #icon} of the component
  • *
  • name of the component
  • *
  • coordinates of the component
  • *
*

*/ 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() + ")"; } } /** *

* Sets the {@link #componentClass} of the component. *

*/ private void setClass() { componentClass = component.getClass().getName(); } /** *

* Sets the {@link #icon} of the component. *

*/ 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."); } } /** *

* Sets the {@link #index} of the component as the index in the parent, if * it is accessible. *

*/ private void setIndex() { index = -1; // reset index AccessibleContext accessibleContext = component.getAccessibleContext(); if (accessibleContext != null) { index = accessibleContext.getAccessibleIndexInParent(); } } }