Ignore:
Timestamp:
05/19/17 11:31:29 (7 years ago)
Author:
pharms
Message:
  • refactored GUI model so that hierarchical event target structures can also be used and created by plugins not being strictly for GUIs
Location:
trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore
Files:
7 added
2 deleted
8 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/EventTargetModelException.java

    r2120 r2146  
    1313//   limitations under the License. 
    1414 
    15 package de.ugoe.cs.autoquest.eventcore.guimodel; 
     15package de.ugoe.cs.autoquest.eventcore; 
    1616 
    1717/** 
    1818 * <p> 
    19  * Exception that is thrown if there are problems with the {@link GUIModel}. 
     19 * Exception that is thrown if there are problems with the {@link IHierarchicalEventTargetModel}. 
    2020 * </p> 
    2121 *  
     
    2323 * @author Patrick Harms 
    2424 */ 
    25 public class GUIModelException extends Exception { 
     25public class EventTargetModelException extends Exception { 
    2626 
    2727    /** 
     
    3434    /** 
    3535     * <p> 
    36      * Constructor. Creates a new GUIModelException. 
     36     * Constructor. Creates a new EventTargetModelException. 
    3737     * </p> 
    3838     */ 
    39     public GUIModelException() { 
     39    public EventTargetModelException() { 
    4040        super(); 
    4141    } 
     
    4343    /** 
    4444     * <p> 
    45      * Constructor. Creates a new GUIModelException. 
     45     * Constructor. Creates a new EventTargetModelException. 
    4646     * </p> 
    4747     *  
     
    4949     *            message of the exception 
    5050     */ 
    51     public GUIModelException(String message) { 
     51    public EventTargetModelException(String message) { 
    5252        super(message); 
    5353    } 
     
    5555    /** 
    5656     * <p> 
    57      * Constructor. Creates a new GUIModelException. 
     57     * Constructor. Creates a new EventTargetModelException. 
    5858     * </p> 
    5959     *  
     
    6161     *            cause of the exception 
    6262     */ 
    63     public GUIModelException(Throwable cause) { 
     63    public EventTargetModelException(Throwable cause) { 
    6464        super(cause); 
    6565    } 
     
    6767    /** 
    6868     * <p> 
    69      * Constructor. Creates a new GUIModelException. 
     69     * Constructor. Creates a new EventTargetModelException. 
    7070     * </p> 
    7171     *  
     
    7575     *            cause of the exception 
    7676     */ 
    77     public GUIModelException(String message, Throwable cause) { 
     77    public EventTargetModelException(String message, Throwable cause) { 
    7878        super(message, cause); 
    7979    } 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/HierarchicalEventTargetGroup.java

    r2120 r2146  
    1313//   limitations under the License. 
    1414 
    15 package de.ugoe.cs.autoquest.eventcore.guimodel; 
     15package de.ugoe.cs.autoquest.eventcore; 
    1616 
    1717import java.util.Collections; 
     
    2121/** 
    2222 * <p> 
    23  * This class is a dummy GUI element to represent groups of GUI elements. A group of GUI elements 
    24  * can be integrated in any GUI model using the method 
    25  * {@link GUIModel#groupGUIElements(java.util.List, String)}. A group has the same behavior as 
    26  * any other parent GUI element. 
     23 * This class is a dummy hierarchical event target to represent groups of event targets. A group of 
     24 * event targets can be integrated in any hierarchical event target model using the method 
     25 * {@link HierarchicalEventTargetModel#groupEventTargets(List, String, IEventTargetFactory)}. A 
     26 * group has the same behavior as any other parent hierarchical event target. 
    2727 * </p> 
    2828 *  
    2929 * @author Patrick Harms 
    3030 */ 
    31 public class GUIElementGroup extends AbstractDefaultGUIElement { 
     31public class HierarchicalEventTargetGroup extends AbstractDefaultHierarchicalEventTarget { 
    3232 
    3333    /** 
     
    3939     
    4040    /** 
    41      * the list of grouped GUIElements 
     41     * the list of grouped event targets 
    4242     */ 
    43     private List<IGUIElement> groupedGUIElements = new LinkedList<IGUIElement>(); 
     43    private List<IHierarchicalEventTarget> groupedEventTargets = 
     44        new LinkedList<IHierarchicalEventTarget>(); 
    4445 
    4546    /** 
    4647     * <p> 
    47      * instantiates a GUI element group with a name and its optional parent GUI element 
     48     * instantiates an event target group with a name and its optional parent event target 
    4849     * </p> 
    4950     * 
    50      * @param groupName the name of the GUI element group 
    51      * @param parent    the optional parent GUI element of the group 
    52      * @param guiModel  the GUI model to which the group will belong 
     51     * @param groupName        the name of the event target group 
     52     * @param parent           the optional parent event target of the group 
     53     * @param eventTargetModel the event target model to which the group will belong 
    5354     */ 
    54     public GUIElementGroup(String groupName, IGUIElement parent, GUIModel guiModel) { 
     55    public HierarchicalEventTargetGroup(String                          groupName, 
     56                                        IHierarchicalEventTarget        parent, 
     57                                        HierarchicalEventTargetModel<?> eventTargetModel) 
     58    { 
    5559        super(new GroupSpecification(groupName), parent); 
    56         super.setGUIModel(guiModel); 
    57     } 
    58  
    59     /* (non-Javadoc) 
    60      * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#updateSpecification(IGUIElementSpec) 
    61      */ 
    62     @Override 
    63     public final void updateSpecification(IGUIElementSpec furtherSpec) { 
    64         // do nothing 
     60        super.setEventTargetModel(eventTargetModel); 
    6561    } 
    6662 
     
    9086 
    9187    /* (non-Javadoc) 
    92      * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getView() 
     88     * @see IHierarchicalEventTarget#updateSpecification(IEventTargetSpec) 
    9389     */ 
    9490    @Override 
    95     public IGUIView getView() { 
    96         return null; 
    97     } 
    98  
    99     /* (non-Javadoc) 
    100      * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getDistanceTo(IGUIElement) 
    101      */ 
    102     @Override 
    103     public double getDistanceTo(IGUIElement otherElement) { 
    104         if (equals(otherElement)) { 
    105             return 0.0; 
    106         } 
    107         else if (super.getParent() != null) { 
    108             return super.getParent().getDistanceTo(otherElement); 
    109         } 
    110         else { 
    111             return 1.0; 
    112         } 
     91    public void updateSpecification(IEventTargetSpec furtherSpec) { 
     92        // do nothing 
    11393    } 
    11494 
    11595    /** 
    11696     * <p> 
    117      * returns the list of GUI elements belonging to this group. 
     97     * returns the list of event targets belonging to this group. 
    11898     * </p> 
    11999     *  
    120      * @return the GUI elements belonging to this group 
     100     * @return the event targets belonging to this group 
    121101     *  
    122102     */ 
    123     public List<IGUIElement> getGroupedElements() { 
    124         return Collections.unmodifiableList(groupedGUIElements); 
     103    public List<IHierarchicalEventTarget> getGroupedEventTargets() { 
     104        return Collections.unmodifiableList(groupedEventTargets); 
    125105    } 
    126106     
    127107    /** 
    128108     * <p> 
    129      * allows adding a new GUI element to the group 
     109     * allows adding a new event target to the group 
    130110     * </p> 
    131111     * 
    132      * @param guiElement the new member of the group 
     112     * @param eventTarget the new member of the group 
    133113     */ 
    134     void addToGroup(IGUIElement guiElement) { 
    135         this.groupedGUIElements.add(guiElement); 
     114    void addToGroup(IHierarchicalEventTarget eventTarget) { 
     115        this.groupedEventTargets.add(eventTarget); 
    136116    } 
    137117     
    138118    /** 
    139119     * <p> 
    140      * internally required GUI element specification for a GUI element group. This is just a wrapper 
    141      * for a name of a GUI element group 
     120     * internally required event target specification for an event target group. This is just a 
     121     * wrapper for a name of an event target group 
    142122     * </p> 
    143123     *  
    144124     * @author Patrick Harms 
    145125     */ 
    146     private static class GroupSpecification implements IGUIElementSpec { 
     126    private static class GroupSpecification implements IEventTargetSpec { 
    147127         
    148128        /** 
     
    155135        /** 
    156136         * <p> 
    157          * the name of the GUI element group represented by this specification 
     137         * the name of the event target group represented by this specification 
    158138         * </p> 
    159139         */ 
     
    174154 
    175155        /* (non-Javadoc) 
    176          * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getType() 
     156         * @see IEventTargetSpec#getSimilarity(IEventTargetSpec) 
    177157         */ 
    178158        @Override 
    179         public String getType() { 
    180             return "GUI element group"; 
    181         } 
    182  
    183         /* (non-Javadoc) 
    184          * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getTypeHierarchy() 
    185          */ 
    186         @Override 
    187         public String[] getTypeHierarchy() { 
    188             return new String[] { getType() }; 
    189         } 
    190  
    191         /* (non-Javadoc) 
    192          * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getSimilarity(IGUIElementSpec) 
    193          */ 
    194         @Override 
    195         public boolean getSimilarity(IGUIElementSpec other) { 
     159        public boolean getSimilarity(IEventTargetSpec other) { 
    196160            return 
    197161                (other instanceof GroupSpecification) && 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IEventTarget.java

    r927 r2146  
    2020 * <p> 
    2121 * Common interface for event targets. An event target can, e.g., be an element of a GUI or Web 
    22  * server. A concrete event-driven software platform can define its event targets through the 
     22 * server or VR. A concrete event-driven software platform can define its event targets through the 
    2323 * implementation of this interface. 
    2424 * </p> 
     
    4747     */ 
    4848    public String getStringIdentifier(); 
     49 
    4950} 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java

    r1436 r2146  
    1515package de.ugoe.cs.autoquest.eventcore.guimodel; 
    1616 
    17 import java.util.LinkedList; 
    18 import java.util.List; 
     17import de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget; 
    1918 
    2019/** 
     
    2625 * @author Patrick Harms 
    2726 */ 
    28 public abstract class AbstractDefaultGUIElement implements IGUIElement { 
     27public abstract class AbstractDefaultGUIElement extends AbstractDefaultHierarchicalEventTarget 
     28    implements IGUIElement 
     29{ 
    2930 
    3031    /** 
     
    3435     */ 
    3536    public static final long serialVersionUID = 1L; 
    36  
    37     /** 
    38      * <p> 
    39      * Specification of the GUI element 
    40      * </p> 
    41      */ 
    42     private final IGUIElementSpec specification; 
    43  
    44     /** 
    45      * <p> 
    46      * Reference to the parent element 
    47      * </p> 
    48      */ 
    49     private IGUIElement parent; 
    50      
    51     /** 
    52      * <p> 
    53      * List of other GUI elements being equal to this 
    54      * </p> 
    55      */ 
    56     private List<AbstractDefaultGUIElement> equalGUIElements = null; 
    5737     
    5838    /** 
     
    6242     */ 
    6343    private boolean usageObserved; 
    64  
    65     /** 
    66      * <p> 
    67      * the reference to the GUI model to which this GUI element belongs. 
    68      * </p> 
    69      */ 
    70     private GUIModel guiModel; 
    71      
    72     /** 
    73      * <p> 
    74      * the hash code of this object 
    75      * </p> 
    76      */ 
    77     private int hashCode; 
    7844 
    7945    /** 
     
    8854     */ 
    8955    public AbstractDefaultGUIElement(IGUIElementSpec specification, IGUIElement parent) { 
    90         this.specification = specification; 
    91         this.usageObserved = false; 
    92         setParent(parent); 
    93          
    94         if (specification != null) { 
    95             this.hashCode = specification.hashCode(); 
    96         } 
    97         else { 
    98             this.hashCode = 0; 
    99         } 
    100     } 
    101  
    102     /* 
    103      * (non-Javadoc) 
    104      *  
    105      * @see de.ugoe.cs.tasktree.guimodel.GUIElement#getSpecification() 
    106      */ 
    107     @Override 
    108     public IGUIElementSpec getSpecification() { 
    109         return specification; 
    110     } 
    111  
    112     /* 
    113      * (non-Javadoc) 
    114      *  
    115      * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getParent() 
    116      */ 
    117     @Override 
    118     public IGUIElement getParent() { 
    119         return parent; 
     56        super(specification, parent); 
    12057    } 
    12158 
     
    12562    @Override 
    12663    public GUIModel getGUIModel() { 
    127        return guiModel; 
     64       return (GUIModel) super.getEventTargetModel(); 
    12865    } 
    12966 
    130     /* 
    131      * (non-Javadoc) 
    132      *  
    133      * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#addEqualGUIElement(IGUIElement) 
     67    /* (non-Javadoc) 
     68     * @see de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget#getParent() 
    13469     */ 
    13570    @Override 
    136     public void addEqualGUIElement(IGUIElement equalElement) { 
    137         if (!(equalElement instanceof AbstractDefaultGUIElement)) { 
    138             throw new IllegalArgumentException 
    139                 ("this implementation can only handle other AbstractDefaultGUIElements"); 
    140         } 
    141          
    142         AbstractDefaultGUIElement other = (AbstractDefaultGUIElement) equalElement; 
    143          
    144         synchronized (AbstractDefaultGUIElement.class) { 
    145             if (this.equalGUIElements == null) { 
    146                 if (other.equalGUIElements == null) { 
    147                     this.equalGUIElements = new LinkedList<AbstractDefaultGUIElement>(); 
    148                     this.equalGUIElements.add(this); 
    149                     this.equalGUIElements.add(other); 
    150                     other.equalGUIElements = this.equalGUIElements; 
    151                     other.hashCode = this.hashCode; 
    152                 } 
    153                 else { 
    154                     addIfNotContained(other.equalGUIElements, this); 
    155                     this.equalGUIElements = other.equalGUIElements; 
    156                     this.hashCode = other.hashCode; 
    157                 } 
    158             } 
    159             else { 
    160                 if (other.equalGUIElements == null) { 
    161                     addIfNotContained(this.equalGUIElements, other); 
    162                     other.equalGUIElements = this.equalGUIElements; 
    163                     other.hashCode = this.hashCode; 
    164                 } 
    165                 else if (this.equalGUIElements != other.equalGUIElements) { 
    166                     this.equalGUIElements.addAll(other.equalGUIElements); 
     71    public IGUIElement getParent() { 
     72        return (IGUIElement) super.getParent(); 
     73    } 
    16774 
    168                     // we also have to set this new list for all other elements for which so 
    169                     // far list2 was registered 
    170                     for (AbstractDefaultGUIElement candidate : other.equalGUIElements) { 
    171                         candidate.equalGUIElements = this.equalGUIElements; 
    172                         candidate.hashCode = this.hashCode; 
    173                     } 
     75    /* (non-Javadoc) 
     76     * @see de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget#getSpecification() 
     77     */ 
     78    @Override 
     79    public IGUIElementSpec getSpecification() { 
     80        return (IGUIElementSpec) super.getSpecification(); 
     81    } 
    17482 
    175                     other.equalGUIElements = this.equalGUIElements; 
    176                     other.hashCode = this.hashCode; 
    177                 } 
    178                 // else 
    179                 // in this case, both GUI elements should already be registered with the same 
    180                 // lists. 
    181             } 
    182         } 
     83    /* (non-Javadoc) 
     84     * @see de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget#getEventTargetModel() 
     85     */ 
     86    @Override 
     87    public GUIModel getEventTargetModel() { 
     88        return (GUIModel) super.getEventTargetModel(); 
    18389    } 
    18490 
     
    203109    } 
    204110 
    205     /* 
    206      * (non-Javadoc) 
    207      *  
    208      * @see GUIElement#equals(GUIElement) 
    209      */ 
    210     public final boolean equals(Object other) { 
    211         // implement final, as GUI elements are all singletons and they equal only if they are the 
    212         // same object or if they are in the list of equal GUI elements 
    213         if (super.equals(other)) { 
    214             return true; 
    215         } 
    216         else if (other instanceof AbstractDefaultGUIElement) { 
    217             synchronized (AbstractDefaultGUIElement.class) { 
    218                 if (equalGUIElements != null) { 
    219                     for (IGUIElement candidate : equalGUIElements) { 
    220                         if (candidate == other) { 
    221                             return true; 
    222                         } 
    223                     } 
    224                 } 
    225             } 
    226         } 
    227  
    228         return false; 
    229     } 
    230  
    231     /* 
    232      * (non-Javadoc) 
    233      *  
    234      * @see java.lang.Object#hashCode() 
    235      */ 
    236     @Override 
    237     public final int hashCode() { 
    238         // implement final, as GUI elements are all singletons and they equal only if they are the 
    239         // same object. If there are several GUI element objects that represent the same GUI element 
    240         // then they are stored in the list of equal elements. But at least their type is expected 
    241         // to be equal, so return the hash code of the type. 
    242         return hashCode; 
    243     } 
    244      
    245     /** 
    246      * <p> 
    247      * updates the parent node of this node if required due to model restructuring 
    248      * </p> 
    249      */ 
    250     void setParent(IGUIElement newParent) { 
    251         synchronized (AbstractDefaultGUIElement.class) { 
    252             // all equal GUI elements must have the same parent. Otherwise, they are not equal 
    253             // anymore and we would have discrepancies on the return value of getParent() on 
    254             // equal GUI elements. 
    255             this.parent = newParent; 
    256             if (equalGUIElements != null) { 
    257                 for (AbstractDefaultGUIElement candidate : equalGUIElements) { 
    258                     candidate.parent = newParent; 
    259                 } 
    260             } 
    261         } 
    262     } 
    263  
    264     /** 
    265      * <p> 
    266      * used to set the GUI model to which this GUI element belongs. Will be set automatically, if 
    267      * used in combination with {@link GUIModel}; 
    268      * </p> 
    269      * 
    270      * @param guiModel 
    271      */ 
    272     void setGUIModel(GUIModel guiModel) { 
    273         this.guiModel = guiModel; 
    274     } 
    275  
    276     /** 
    277      * <p> 
    278      * Adds an {@link AbstractDefaultGUIElement} as equal to a list of 
    279      * {@link AbstractDefaultGUIElement}s if and only if it is not already contained. 
    280      * </p> 
    281      *  
    282      * @param equalElementsList 
    283      *            list of {@link AbstractDefaultGUIElement} to which the GUI element is added 
    284      * @param guiElement 
    285      *            GUI element to be added 
    286      */ 
    287     private void addIfNotContained(List<AbstractDefaultGUIElement> equalElementsList, 
    288                                    AbstractDefaultGUIElement       guiElement) 
    289     { 
    290         for (IGUIElement candidate : equalElementsList) { 
    291             if (candidate == guiElement) { 
    292                 return; 
    293             } 
    294         } 
    295  
    296         equalElementsList.add(guiElement); 
    297     } 
    298  
    299111} 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIElementFactory.java

    r1796 r2146  
    2525import java.util.logging.Level; 
    2626 
     27import de.ugoe.cs.autoquest.eventcore.EventTargetModelConfigurationException; 
     28import de.ugoe.cs.autoquest.eventcore.HierarchicalEventTargetModel; 
     29import de.ugoe.cs.autoquest.eventcore.IEventTargetFactory; 
     30import de.ugoe.cs.autoquest.eventcore.IEventTargetSpec; 
     31import de.ugoe.cs.autoquest.eventcore.IHierarchicalEventTarget; 
    2732import de.ugoe.cs.util.console.Console; 
    2833 
     
    3540 * @author Patrick Harms 
    3641 */ 
    37 public class GUIElementFactory implements IGUIElementFactory { 
     42public class GUIElementFactory implements IEventTargetFactory { 
    3843 
    3944    /** 
     
    6469    /** 
    6570     * <p> 
    66      * A property mapping that defines to which Java class is created given the type of the GUI 
     71     * A property mapping that defines which Java class is created given the type of the GUI 
    6772     * element found in the specification. 
    6873     * </p> 
     
    7176 
    7277     
    73     /* 
    74      * (non-Javadoc) 
    75      *  
    76      * @see 
    77      * de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementFactory#instantiateGUIElement(de.ugoe.cs.autoquest 
    78      * .eventcore.guimodel.IGUIElementSpec, de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement) 
    79      */ 
     78    /* (non-Javadoc) 
     79     * @see IEventTargetFactory#instantiateEventTarget(IEventTargetSpec, IHierarchicalEventTarget) 
     80     */ 
     81    @SuppressWarnings("unchecked") 
    8082    @Override 
    81     public IGUIElement instantiateGUIElement(IGUIElementSpec specification, IGUIElement parent) 
    82         throws GUIModelConfigurationException 
     83    public <T extends IHierarchicalEventTarget> T instantiateEventTarget(IEventTargetSpec specification, 
     84                                                                         T                parent) 
     85        throws EventTargetModelConfigurationException 
     86    { 
     87        if (!(specification instanceof IGUIElementSpec)) { 
     88            throw new IllegalArgumentException("can only handle IGUIElementSpecs as specification"); 
     89        } 
     90         
     91        if ((parent != null) && !(parent instanceof IGUIElement)) { 
     92            throw new IllegalArgumentException("can only handle IGUIElements as parent"); 
     93        } 
     94         
     95       return (T) instantiateEventTarget((IGUIElementSpec) specification, (IGUIElement) parent); 
     96    } 
     97         
     98     
     99    /** 
     100     * concrete implementation of {@link #instantiateEventTarget(IEventTargetSpec, IHierarchicalEventTarget)} 
     101     */ 
     102    public IGUIElement instantiateEventTarget(IGUIElementSpec specification, 
     103                                              IGUIElement     parent) 
     104        throws EventTargetModelConfigurationException 
    83105    { 
    84106        Properties mappings = getMappingsFromConfiguration(); 
     
    155177                Console.traceln(Level.WARNING, "configured GUI element representing class " + 
    156178                                className + " can not be loaded."); 
    157                 throw new GUIModelConfigurationException 
     179                throw new EventTargetModelConfigurationException 
    158180                    ("configured GUI element representing class " + className + 
    159181                     " can not be loaded.", e); 
     
    162184                Console.traceln(Level.WARNING, "configured GUI element representing class " + 
    163185                                className + " can not be instantiated due to security reasons."); 
    164                 throw new GUIModelConfigurationException 
     186                throw new EventTargetModelConfigurationException 
    165187                    ("configured GUI element representing class " + className + 
    166188                     " can not be instantiated due to security reasons.", e); 
     
    169191                Console.traceln(Level.WARNING, "configured GUI element representing class " + 
    170192                                className + " does not provide an appropriate constructor."); 
    171                 throw new GUIModelConfigurationException 
     193                throw new EventTargetModelConfigurationException 
    172194                    ("configured GUI element representing class " + className + 
    173195                     " does not provide an appropriate constructor.", e); 
     
    177199                                className + " does not provide an appropriate constructor " + 
    178200                                "accepting the provided parameters."); 
    179                 throw new GUIModelConfigurationException 
     201                throw new EventTargetModelConfigurationException 
    180202                    ("configured GUI element representing class " + className + " does not " + 
    181203                     "provide an appropriate constructor accepting the provided parameters.", e); 
     
    184206                Console.traceln(Level.WARNING, "configured GUI element representing class " + 
    185207                                className + " can not be instantiated."); 
    186                 throw new GUIModelConfigurationException 
     208                throw new EventTargetModelConfigurationException 
    187209                    ("configured GUI element representing class " + className + 
    188210                     " can not be instantiated.", e); 
     
    191213                Console.traceln(Level.WARNING, "configured GUI element representing class " + 
    192214                                className + " can not be instantiated."); 
    193                 throw new GUIModelConfigurationException 
     215                throw new EventTargetModelConfigurationException 
    194216                    ("configured GUI element representing class " + className + 
    195217                     " can not be instantiated.", e); 
     
    198220                Console.traceln(Level.WARNING, "configured GUI element representing class " + 
    199221                                className + " can not be instantiated."); 
    200                 throw new GUIModelConfigurationException 
     222                throw new EventTargetModelConfigurationException 
    201223                    ("configured GUI element representing class " + className + 
    202224                     " can not be instantiated.", e); 
     
    208230                            specification.getType() + " found. Please extend GUI element " + 
    209231                            "mapping files."); 
    210             throw new GUIModelConfigurationException 
     232            throw new EventTargetModelConfigurationException 
    211233                ("no class representing GUI elements of type " + specification.getType() + 
    212234                 " found. Please extend GUI element mapping files"); 
     
    214236 
    215237        return guiElement; 
     238    } 
     239 
     240    /* (non-Javadoc) 
     241     * @see IEventTargetFactory#instantiateGroup(String, IHierarchicalEventTarget, HierarchicalEventTargetModel) 
     242     */ 
     243    @SuppressWarnings("unchecked") 
     244    @Override 
     245    public <T extends IHierarchicalEventTarget> T instantiateGroup(String                          groupName, 
     246                                                                   T                               parent, 
     247                                                                   HierarchicalEventTargetModel<T> hierarchicalEventTargetModel) 
     248    { 
     249        if (!(hierarchicalEventTargetModel instanceof GUIModel)) { 
     250            throw new IllegalArgumentException("can only handle GUI elements as event targets"); 
     251        } 
     252         
     253        if (!(parent instanceof IGUIElement)) { 
     254            throw new IllegalArgumentException("can only handle GUI elements as event targets"); 
     255        } 
     256         
     257        return (T) new GUIElementGroup 
     258              (groupName, (IGUIElement) parent, (GUIModel) hierarchicalEventTargetModel); 
    216259    } 
    217260 
     
    226269     */ 
    227270    private synchronized Properties getMappingsFromConfiguration() 
    228         throws GUIModelConfigurationException 
     271        throws EventTargetModelConfigurationException 
    229272    { 
    230273        if (mappingsFromConfiguration != null) { 
     
    249292                        } 
    250293                        catch (FileNotFoundException e) { 
    251                             throw new GUIModelConfigurationException( 
    252                                                                      "could not read mapping configuration file " + 
    253                                                                          mappingsFile, e); 
     294                            throw new EventTargetModelConfigurationException 
     295                                ("could not read mapping configuration file " + mappingsFile, e); 
    254296                        } 
    255297                        catch (IOException e) { 
    256                             throw new GUIModelConfigurationException( 
    257                                                                      "could not read mapping configuration file " + 
    258                                                                          mappingsFile, e); 
     298                            throw new EventTargetModelConfigurationException 
     299                                ("could not read mapping configuration file " + mappingsFile, e); 
    259300                        } 
    260301                        finally { 
     
    272313            } 
    273314            else { 
    274                 throw new GUIModelConfigurationException( 
    275                                                          "no GUI mappings file provided in folder " + 
    276                                                              mappingsFolder); 
     315                throw new EventTargetModelConfigurationException 
     316                    ("no GUI mappings file provided in folder " + mappingsFolder); 
    277317            } 
    278318 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIElementGroup.java

    • Property svn:mime-type set to text/plain
    r1876 r2146  
    1 //   Copyright 2012 Georg-August-Universität Göttingen, Germany 
     1//   Copyright 2015 Georg-August-Universität Göttingen, Germany 
    22// 
    33//   Licensed under the Apache License, Version 2.0 (the "License"); 
     
    1515package de.ugoe.cs.autoquest.eventcore.guimodel; 
    1616 
    17 import java.util.Collections; 
    18 import java.util.LinkedList; 
    19 import java.util.List; 
     17import de.ugoe.cs.autoquest.eventcore.HierarchicalEventTargetGroup; 
     18import de.ugoe.cs.autoquest.eventcore.IEventTargetSpec; 
    2019 
    2120/** 
    2221 * <p> 
    23  * This class is a dummy GUI element to represent groups of GUI elements. A group of GUI elements 
    24  * can be integrated in any GUI model using the method 
    25  * {@link GUIModel#groupGUIElements(java.util.List, String)}. A group has the same behavior as 
    26  * any other parent GUI element. 
     22 * implementation of event target groups for GUI elements 
    2723 * </p> 
    2824 *  
    2925 * @author Patrick Harms 
    3026 */ 
    31 public class GUIElementGroup extends AbstractDefaultGUIElement { 
     27public class GUIElementGroup extends HierarchicalEventTargetGroup implements IGUIElement { 
    3228 
    33     /** 
    34      * <p> 
    35      * default serial version UID 
    36      * </p> 
    37      */ 
     29    /**  */ 
    3830    private static final long serialVersionUID = 1L; 
    3931     
    40     /** 
    41      * the list of grouped GUIElements 
    42      */ 
    43     private List<IGUIElement> groupedGUIElements = new LinkedList<IGUIElement>(); 
     32    /** the internal fake event target specification */ 
     33    private GroupSpecification groupSpecification; 
     34     
     35    /** stores if the usage of the group was observed (just to match the implemented interface */ 
     36    private boolean usageObserved = false; 
    4437 
    4538    /** 
     
    4841     * </p> 
    4942     * 
    50      * @param groupName the name of the GUI element group 
    51      * @param parent    the optional parent GUI element of the group 
    52      * @param guiModel the GUI model to which the group will belong 
     43     * @param groupName        the name of the GUI element group 
     44     * @param parent           the optional parent GUI element of the group 
     45     * @param eventTargetModel the GUI model to which the group will belong 
    5346     */ 
    54     public GUIElementGroup(String groupName, IGUIElement parent, GUIModel guiModel) { 
    55         super(new GroupSpecification(groupName), parent); 
    56         super.setGUIModel(guiModel); 
     47    public GUIElementGroup(String      groupName, 
     48                           IGUIElement parent, 
     49                           GUIModel    guiModel) 
     50    { 
     51        super(groupName, parent, guiModel); 
     52        groupSpecification = new GroupSpecification(groupName); 
    5753    } 
    5854 
    5955    /* (non-Javadoc) 
    60      * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#updateSpecification(IGUIElementSpec) 
     56     * @see de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget#getSpecification() 
    6157     */ 
    6258    @Override 
    63     public final void updateSpecification(IGUIElementSpec furtherSpec) { 
    64         // do nothing 
    65     } 
    66  
    67     /* (non-Javadoc) 
    68      * @see de.ugoe.cs.autoquest.eventcore.IEventTarget#getPlatform() 
    69      */ 
    70     @Override 
    71     public String getPlatform() { 
    72         return "none"; 
     59    public IGUIElementSpec getSpecification() { 
     60        return groupSpecification; 
    7361    } 
    7462 
     
    7866    @Override 
    7967    public String getStringIdentifier() { 
    80         return ((GroupSpecification) super.getSpecification()).name; 
     68        return groupSpecification.name; 
    8169    } 
    8270 
    8371    /* (non-Javadoc) 
    84      * @see java.lang.Object#toString() 
     72     * @see de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget#getParent() 
    8573     */ 
    8674    @Override 
    87     public String toString() { 
    88         return getStringIdentifier(); 
     75    public IGUIElement getParent() { 
     76        return (IGUIElement) super.getParent(); 
    8977    } 
    9078 
     
    9886 
    9987    /* (non-Javadoc) 
     88     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getGUIModel() 
     89     */ 
     90    @Override 
     91    public GUIModel getGUIModel() { 
     92        return (GUIModel) super.getEventTargetModel(); 
     93    } 
     94 
     95    /* (non-Javadoc) 
     96     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#isUsed() 
     97     */ 
     98    @Override 
     99    public boolean isUsed() { 
     100        return usageObserved; 
     101    } 
     102 
     103    /* (non-Javadoc) 
     104     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#markUsed() 
     105     */ 
     106    @Override 
     107    public void markUsed() { 
     108        usageObserved = true; 
     109    } 
     110 
     111    /* (non-Javadoc) 
    100112     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getDistanceTo(IGUIElement) 
    101113     */ 
     
    105117            return 0.0; 
    106118        } 
    107         else if (super.getParent() != null) { 
    108             return super.getParent().getDistanceTo(otherElement); 
     119        else if (getParent() != null) { 
     120            return getParent().getDistanceTo(otherElement); 
    109121        } 
    110122        else { 
    111123            return 1.0; 
    112124        } 
    113     } 
    114  
    115     /** 
    116      * <p> 
    117      * returns the list of GUI elements belonging to this group. 
    118      * </p> 
    119      *  
    120      * @return the GUI elements belonging to this group 
    121      *  
    122      */ 
    123     public List<IGUIElement> getGroupedElements() { 
    124         return Collections.unmodifiableList(groupedGUIElements); 
    125     } 
    126      
    127     /** 
    128      * <p> 
    129      * allows adding a new GUI element to the group 
    130      * </p> 
    131      * 
    132      * @param guiElement the new member of the group 
    133      */ 
    134     void addToGroup(IGUIElement guiElement) { 
    135         this.groupedGUIElements.add(guiElement); 
    136125    } 
    137126     
     
    174163 
    175164        /* (non-Javadoc) 
     165         * @see de.ugoe.cs.autoquest.eventcore.IEventTargetSpec#getSimilarity(IEventTargetSpec) 
     166         */ 
     167        @Override 
     168        public boolean getSimilarity(IEventTargetSpec other) { 
     169            return 
     170                (other instanceof GroupSpecification) && 
     171                name.equals(((GroupSpecification) other).name); 
     172        } 
     173 
     174        /* (non-Javadoc) 
    176175         * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getType() 
    177176         */ 
     
    189188        } 
    190189 
    191         /* (non-Javadoc) 
    192          * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getSimilarity(IGUIElementSpec) 
    193          */ 
    194         @Override 
    195         public boolean getSimilarity(IGUIElementSpec other) { 
    196             return 
    197                 (other instanceof GroupSpecification) && 
    198                 name.equals(((GroupSpecification) other).name); 
    199         } 
    200  
    201190    } 
    202  
    203191} 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIElementTree.java

    r1084 r2146  
    2020import java.util.Map; 
    2121 
     22import de.ugoe.cs.autoquest.eventcore.EventTargetModelException; 
     23import de.ugoe.cs.autoquest.eventcore.IEventTargetFactory; 
    2224import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementFactory; 
    2325import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel; 
    24 import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModelException; 
    25 import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementFactory; 
    2626 
    2727/** 
     
    3030 * </p> 
    3131 * <p> 
    32  * The GUIElementTree represents the hierarchical structure of the GUI elements "as it is" currently during 
    33  * a session. It may change during the session due to creation and destruction of GUI elements. The parameter 
    34  * T represents the id type of the GUI elements that are handled internally. 
     32 * The GUIElementTree represents the hierarchical structure of the GUI elements "as it is" 
     33 * currently during a session. It may change during the session due to creation and destruction 
     34 * of GUI elements. The parameter T represents the id type of the GUI elements that are handled 
     35 * internally. 
    3536 * </p> 
    3637 *  
     
    8485     * </p> 
    8586     */ 
    86     private IGUIElementFactory guiElementFactory = GUIElementFactory.getInstance(); 
    87  
    88   
     87    private IEventTargetFactory guiElementFactory = GUIElementFactory.getInstance(); 
    8988 
    9089    /** 
     
    127126     *            the GUI element specification 
    128127     *             
    129      * @throws GUIModelException if the GUI element can not be added to the underlying GUI model 
     128     * @throws EventTargetModelException if the GUI element can not be added to the underlying GUI model 
    130129     */ 
    131130    public void add(T guiElementID, 
    132131                    T parentID, 
    133132                    IGUIElementSpec guiElementSpec) 
    134         throws GUIModelException 
     133        throws EventTargetModelException 
    135134    { 
    136135        IGUIElement guiElement = guiElements.get(guiElementID); 
     
    161160            } 
    162161 
    163             guiElement = guiModel.integratePath(guiElementPath, guiElementFactory); 
     162            guiElement = (IGUIElement) guiModel.integratePath(guiElementPath, guiElementFactory); 
    164163            guiElements.put(guiElementID, guiElement); 
    165164        } 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModel.java

    • Property svn:mime-type set to text/plain
    r1436 r2146  
    1515package de.ugoe.cs.autoquest.eventcore.guimodel; 
    1616 
    17 import java.io.OutputStream; 
    18 import java.io.PrintStream; 
    1917import java.io.Serializable; 
    20 import java.io.UnsupportedEncodingException; 
    21 import java.util.ArrayList; 
    22 import java.util.HashMap; 
    23 import java.util.LinkedList; 
    2418import java.util.List; 
    25 import java.util.Map; 
    26 import java.util.Stack; 
    27 import java.util.logging.Level; 
    2819 
    29 import de.ugoe.cs.util.console.Console; 
     20import de.ugoe.cs.autoquest.eventcore.HierarchicalEventTargetModel; 
    3021 
    3122/** 
     
    3425 * platform independent. It may have several root nodes, as some GUIs are made up of several Frames 
    3526 * being independent from each other. The GUI model is filled using the 
    36  * {@link #integratePath(List, IGUIElementFactory)} method. 
     27 * {@link #integratePath(List, de.ugoe.cs.autoquest.eventcore.IEventTargetFactory)} method. 
    3728 * </p> 
    3829 *  
     
    4031 * @author Patrick Harms, Steffen Herbold 
    4132 */ 
    42 public class GUIModel implements Serializable { 
     33public class GUIModel extends HierarchicalEventTargetModel<IGUIElement> 
     34    implements Serializable 
     35{ 
    4336 
    4437    /**  */ 
     
    4740    /** 
    4841     * <p> 
    49      * The root node of the tree not provided externally. 
    50      * </p> 
    51      */ 
    52     private TreeNode root = new TreeNode(); 
    53  
    54     /** 
    55      * <p> 
    56      * A map with all nodes currently known 
    57      * </p> 
    58      */ 
    59     private Map<IGUIElement, TreeNode> allNodes = new HashMap<IGUIElement, TreeNode>(); 
    60      
    61     /** 
    62      * <p> 
    63      * true, if internal validation is switched on, false else 
    64      * </p> 
    65      */ 
    66     private boolean validate = false; 
    67  
    68     /** 
    69      * <p> 
    70      * Default constructor to create a GUI model without internal validation 
     42     * instantiate a default unvalidated model 
    7143     * </p> 
    7244     * 
    7345     */ 
    7446    public GUIModel() { 
    75         this(false); 
     47        super(); 
    7648    } 
    7749 
    7850    /** 
    7951     * <p> 
    80      * creates a GUI model, that internally validates itself by checking on access to nodes, 
    81      * if several GUI elements pretend to be equal or if several distinct GUI elements have the 
    82      * same child. 
     52     * instantiate a model that will validate itself internally if the provided parameters is set 
     53     * to true. This is typically rather slow.  
    8354     * </p> 
    84      * 
    85      * @param validate 
    86      *            true if internal validation shall be switched on (bad performance), false else 
    87      * 
    8855     */ 
    8956    public GUIModel(boolean validate) { 
    90         this.validate = validate; 
     57        super(validate); 
    9158    } 
    9259 
    93     /** 
    94      * <p> 
    95      * Integrates a path of GUI elements into the GUI model. The GUI model itself is a tree and 
    96      * therefore a set of different paths through the tree that start with a root node and end with 
    97      * a leaf node. Such a path can be added to the tree. The method checks, if any of the GUI 
    98      * elements denoted by the path already exists. If so, it reuses it. It may therefore also 
    99      * return an existing GUI element being the leaf node of the provided path. If a GUI element of 
    100      * the path does not exist yet, it creates a new one using the provided GUI element factory. 
    101      * </p> 
    102      * <p> 
    103      * If a GUI element specification describes an existing GUI element or not is determined through 
    104      * comparing the GUI element specifications of the existing GUI elements with the ones provided 
    105      * in the path. The comparison is done using the 
    106      * {@link IGUIElementSpec#getSimilarity(IGUIElementSpec)} method. The comparison is only done on 
    107      * the correct levels. I.e. the currently known root elements of the tree are only compared to 
    108      * the first element in the path. If the correct one is found or created, its children are 
    109      * compared only to the second specification in the path, and so on. 
    110      * </p> 
    111      * <p> 
    112      * The returned GUI elements are singletons. I.e. it is tried to return always the identical 
    113      * object for the same denoted element. However, while creating the GUI model, the similarity of 
    114      * GUI elements may change. Therefore, the method might determine, that two formerly different 
    115      * nodes are now similar. (This may happen, e.g. if GUI elements do not have initial names which 
    116      * are set afterwards. Therefore, first they are handled differently and later they can be 
    117      * identified as being the same.) In such a case, there are already several GUI element objects 
    118      * instantiated for the same GUI element. The singleton paradigm gets broken. Therefore, such 
    119      * GUI element objects are registered with each other, so that their equal method can determine 
    120      * equality again correctly, although the objects are no singletons anymore. 
    121      * </p> 
    122      *  
    123      * @param guiElementPath 
    124      *            the path to integrate into the model 
    125      * @param guiElementFactory 
    126      *            the GUI element factory to be used for instantiating GUI element objects 
    127      *  
    128      * @return The GUI element object representing the GUI element denoted by the provided path 
    129      *  
    130      * @throws GUIModelException 
    131      *             thrown in cases such as the GUI element object could not be instantiated 
    132      * @throws IllegalArgumentException 
    133      *             if the provided path is invalid. 
    134      */ 
    135     public IGUIElement integratePath(List<? extends IGUIElementSpec> guiElementPath, 
    136                                      IGUIElementFactory guiElementFactory) 
    137         throws GUIModelException, IllegalArgumentException 
    138     { 
    139         if ((guiElementPath == null) || (guiElementPath.size() <= 0)) { 
    140             throw new IllegalArgumentException("GUI element path must contain at least one element"); 
    141         } 
    142  
    143         List<IGUIElementSpec> remainingPath = new LinkedList<IGUIElementSpec>(guiElementPath); 
    144  
    145         return integratePath(root, remainingPath, guiElementFactory); 
    146     } 
    147  
    148     /** 
    149      * <p> 
    150      * Returns all children of the provided GUI element or null, if it does not have any or the node 
    151      * is unknown. 
    152      * </p> 
    153      *  
    154      * @param guiElement 
    155      *            the GUI element of which the children shall be returned 
    156      *  
    157      * @return As described 
    158      */ 
    159     public List<IGUIElement> getChildren(IGUIElement guiElement) { 
    160         TreeNode node = findNode(guiElement); 
    161          
    162         List<IGUIElement> result = null; 
    163         if (node != null) { 
    164             result = new LinkedList<IGUIElement>(); 
    165             if (node.children != null) { 
    166                 for (TreeNode child : node.children) { 
    167                     result.add(child.guiElement); 
    168                 } 
    169             } 
    170         } 
    171         else { 
    172             System.out.println("problem"); 
    173             boolean found = false; 
    174             for (Map.Entry<IGUIElement, TreeNode> entry : allNodes.entrySet()) { 
    175                 if (entry.getKey().equals(guiElement)) { 
    176                     if (!found) { 
    177                         System.out.println(guiElement.hashCode() + "  " + entry.getKey().hashCode()); 
    178                         found = true; 
    179                     } 
    180                     else { 
    181                         Console.traceln(Level.SEVERE, "Multiple nodes in the internal GUI model " + 
    182                                         "match the same GUI element. This should not be the case " + 
    183                                         "and the GUI model is probably invalid."); 
    184                     } 
    185                 } 
    186             } 
    187              
    188             if (!found) { 
    189                 Console.traceln(Level.SEVERE, "GUI element belonging to model not found in model"); 
    190             } 
    191         } 
    192   
    193         return result; 
    194     } 
    195  
    196     /** 
    197      * <p> 
    198      * Returns the parent GUI element of the provided GUI element or null, if it does not have a 
    199      * parent (i.e. if it is a root node) or if the node is unknown. 
    200      * </p> 
    201      *  
    202      * @param guiElement 
    203      *            the GUI element of which the parent shall be returned 
    204      *  
    205      * @return As described 
    206      */ 
    207     public IGUIElement getParent(IGUIElement guiElement) { 
    208         IGUIElement parent = null; 
    209  
    210         for (Map.Entry<IGUIElement, TreeNode> entry : allNodes.entrySet()) { 
    211             if (entry.getValue().children != null) { 
    212                 for (TreeNode child : entry.getValue().children) { 
    213                     if (child.guiElement.equals(guiElement)) { 
    214                         if (parent == null) { 
    215                             parent = entry.getKey(); 
    216                             if (!validate) { 
    217                                 break; 
    218                             } 
    219                         } 
    220                         else { 
    221                             Console 
    222                             .traceln(Level.SEVERE, 
    223                                      "Multiple nodes in the internal GUI model match the same GUI element. " 
    224                                              + "This should not be the case and the GUI model is probably invalid."); 
    225                         } 
    226                     } 
    227                 } 
    228             } 
    229         } 
    230  
    231         return parent; 
    232     } 
    233  
    234     /** 
    235      * <p> 
    236      * Returns all root GUI elements of the model or an empty list, if the model is empty 
    237      * </p> 
    238      *  
    239      * @return As described 
    240      */ 
    241     public List<IGUIElement> getRootElements() { 
    242         List<IGUIElement> roots = new ArrayList<IGUIElement>(); 
    243  
    244         if (root.children != null) { 
    245             for (TreeNode rootChild : root.children) { 
    246                 roots.add(rootChild.guiElement); 
    247             } 
    248         } 
    249  
    250         return roots; 
    251     } 
    252      
    253     /** 
    254      * returns a traverser for the GUI model to have efficient access to the tree of GUI elements 
    255      * without having direct access. 
    256      *  
    257      * @return a traverser 
    258      */ 
    259     public Traverser getTraverser() { 
    260         return new Traverser(); 
    261     } 
    262  
    263     /** 
    264      * returns a traverser for the GUI model starting at the given GUI element. Returns null, if 
    265      * the GUI element is not part of the model. 
    266      *  
    267      * @return a traverser 
    268      */ 
    269     public Traverser getTraverser(IGUIElement startingAt) { 
    270         TreeNode node = findNode(startingAt); 
    271          
    272         if (node != null) { 
    273             Traverser traverser = new Traverser(); 
    274             traverser.navigateTo(node); 
    275             return traverser; 
    276         } 
    277         else { 
    278             return null; 
    279         } 
    280     } 
    281  
    282     /** 
    283      * <p> 
    284      * dumps the GUI model to the provided stream. Each node is represented through its toString() 
    285      * method. If a node has children, those are dumped indented and surrounded by braces. 
    286      * </p> 
    287      *  
    288      * @param out 
    289      *            The stream to dump the textual representation of the model to 
    290      * @param encoding 
    291      *            The encoding to be used while dumping 
    292      */ 
    293     public void dump(OutputStream out, String encoding) { 
    294         PrintStream stream; 
    295  
    296         if (out instanceof PrintStream) { 
    297             stream = (PrintStream) out; 
    298         } 
    299         else { 
    300             String enc = encoding == null ? "UTF-8" : encoding; 
    301             try { 
    302                 stream = new PrintStream(out, true, enc); 
    303             } 
    304             catch (UnsupportedEncodingException e) { 
    305                 throw new IllegalArgumentException("encodind " + enc + " not supported"); 
    306             } 
    307         } 
    308  
    309         for (TreeNode node : root.children) { 
    310             dumpGUIElement(stream, node, ""); 
    311         } 
    312     } 
    313  
    314     /** 
    315      * <p> 
    316      * This method groups the provided GUI elements under a common parent GUI element. The current 
    317      * parent GUI element of the GUI elements to group must be the same. If the GUI elements to 
    318      * be grouped are the whole list of children of the same parent, nothing is changed.  
    319      * </p> 
    320      *  
    321      * @param guiElements the list of GUI elements to be grouped 
    322      * @param groupName   the name of the GUI element group to be created 
    323      *  
    324      * @return the GUI element representing the group, or null, if the provided list of GUI elements 
    325      *         is empty 
    326      *  
    327      * @throws IllegalArgumentException 
    328      *             if not all GUI elements to be merged share the same parent, if one of the 
    329      *             parameters is null, or if one of the provided GUI elements does not belong to 
    330      *             the model 
    331      */ 
    332     public IGUIElement groupGUIElements(List<IGUIElement> guiElements, String groupName) 
    333         throws IllegalArgumentException 
    334     { 
    335         if ((guiElements == null) || (groupName == null)) { 
    336             throw new IllegalArgumentException("parameters must not be null"); 
    337         } 
    338          
    339         if (guiElements.size() <= 0) { 
    340             // do nothing 
    341             return null; 
    342         } 
    343          
    344         TreeNode parent = findNode(guiElements.get(0).getParent()); 
    345         if (parent == null) { 
    346             throw new IllegalArgumentException("GUI elements to group must have a parent: parent " + 
    347                                                "of " + guiElements.get(0) + " is " + 
    348                                                guiElements.get(0).getParent() + " and not found " + 
    349                                                "in the model"); 
    350         } 
    351          
    352         List<TreeNode> nodesToGroup = new LinkedList<TreeNode>(); 
    353          
    354         for (IGUIElement element : guiElements) { 
    355             if (!(element instanceof AbstractDefaultGUIElement)) { 
    356                 throw new IllegalArgumentException 
    357                     ("can only group nodes of type AbstractDefaultGUIElement"); 
    358             } 
    359              
    360             TreeNode node = findNode(element); 
    361             if (node == null) { 
    362                 throw new IllegalArgumentException 
    363                     ("GUI element " + element + " is not part of the model"); 
    364             } 
    365              
    366             if (!nodesToGroup.contains(node)) { 
    367                 nodesToGroup.add(node); 
    368             } 
    369              
    370             TreeNode parentNode = findNode(element.getParent()); 
    371              
    372             if (!parent.equals(parentNode)) { 
    373                 throw new IllegalArgumentException("GUI elements do not share the same parent: " + 
    374                                                    parent + " (parent of " + guiElements.get(0) + 
    375                                                    ") <> " + parentNode + " (parent of " + 
    376                                                    element + ")"); 
    377             } 
    378         } 
    379          
    380         TreeNode replacement = new TreeNode(); 
    381         replacement.guiElement = new GUIElementGroup(groupName, parent.guiElement, this); 
    382          
    383         for (TreeNode child : nodesToGroup) { 
    384             ((GUIElementGroup) replacement.guiElement).addToGroup(child.guiElement); 
    385             replacement.addChildNode(child); 
    386             ((AbstractDefaultGUIElement) child.guiElement).setParent(replacement.guiElement); 
    387             parent.children.remove(child); 
    388         } 
    389  
    390         parent.children.add(replacement); 
    391  
    392         // finally, update the known nodes list 
    393         // if you don't do this getChildren will return wrong things and very bad things happen! 
    394         allNodes.put(replacement.guiElement, replacement); 
    395          
    396         return replacement.guiElement; 
    397     } 
    398      
    399     /** 
    400      * <p> 
    401      * By calling this method, the GUIModel is traversed and similar nodes are merged. 
    402      * </p> 
    403      *  
    404      */ 
    405     public void condenseModel() { 
    406         mergeSubTree(root); 
    407     } 
    408      
    409     /** 
    410      * <p> 
    411      * Merges the tree nodes of two GUI elements. The GUI elements need to have the same parent. 
    412      * They are merged recursively, i.e. also their children are merged.  
    413      * </p> 
    414      *  
    415      * @param guiElement1 
    416      *            the first merge GUI element 
    417      * @param guiElement2 
    418      *            the second merge GUI element 
    419      *             
    420      * @return the result of the merge 
    421      *             
    422      * @throws IllegalArgumentException 
    423      *             thrown if the two GUI elements do not have the same parent 
    424      */ 
    425     public IGUIElement mergeGUIElements(IGUIElement guiElement1, IGUIElement guiElement2) 
    426         throws IllegalArgumentException 
    427     { 
    428         return mergeGUIElements(guiElement1, guiElement2, true); 
    429     } 
    430      
    431     /** 
    432      * <p> 
    433      * Merges the tree nodes of two GUI elements. The GUI elements need to have the same parent. 
    434      * If the <code>recursively</code> parameter is set to true, the children of the GUI elements 
    435      * are merged, as well, as long as they are similar. If the parameter is false, the children 
    436      * are not merged. In this case the resulting GUI element has all children of both merged GUI 
    437      * elements. 
    438      * </p> 
    439      *  
    440      * @param guiElement1 
    441      *            the first merge GUI element 
    442      * @param guiElement2 
    443      *            the second merge GUI element 
    444      * @param recursively 
    445      *            if true, the merge is done also for similar children, if false, not. 
    446      *             
    447      * @return the result of the merge 
    448      *             
    449      * @throws IllegalArgumentException 
    450      *             thrown if the two GUI elements do not have the same parent 
    451      */ 
    452     public IGUIElement mergeGUIElements(IGUIElement guiElement1, 
    453                                         IGUIElement guiElement2, 
    454                                         boolean     recursively) 
    455         throws IllegalArgumentException 
    456     { 
    457         // check if both nodes have the same parent 
    458         IGUIElement parentElement = guiElement1.getParent(); 
    459         boolean sameParent = (parentElement != null) ? 
    460             parentElement.equals(guiElement2.getParent()) : (guiElement2.getParent() == null); 
    461              
    462         if (!sameParent) { 
    463             throw new IllegalArgumentException("can only merge nodes with the same parent"); 
    464         } 
    465  
    466         // get the TreeNode of the parent of the GUI elements 
    467         TreeNode parent = findNode(parentElement); 
    468          
    469         if ((parent == null) && (parentElement == null)) { 
    470             // merging root nodes. The parent is the root node of the GUI element tree 
    471             parent = root; 
    472         } 
    473  
    474         // get the TreeNodes for both GUI elements 
    475         TreeNode node1 = findNode(guiElement1); 
    476         TreeNode node2 = findNode(guiElement2); 
    477  
    478         if (node1 == null || node2 == null) { 
    479             throw new IllegalArgumentException 
    480                 ("Error while merging nodes: one element is not part of the GUI model!"); 
    481         } 
    482  
    483         TreeNode replacement = mergeTreeNodes(node1, node2, recursively); 
    484  
    485         if (parent != null) { 
    486             // remove node1 and node2 from the parent's children and add the replacement instead 
    487             // assumes that there are no duplicates of node1 and node2 
    488             if (parent.children != null) { 
    489                 parent.children.set(parent.children.indexOf(node1), replacement); 
    490                 parent.children.remove(node2); 
    491             } 
    492         } 
    493  
    494         return replacement.guiElement; 
    495     } 
    496  
    497     /** 
    498      * <p> 
    499      * internally integrates a path as the children of the provided parent node. This method is 
    500      * recursive and calls itself, for the child of the parent node, that matches the first element 
    501      * in the remaining path. 
    502      * </p> 
    503      *  
    504      * @param parentNode 
    505      *            the parent node to add children for 
    506      * @param guiElementPath 
    507      *            the path of children to be created starting with the parent node 
    508      * @param guiElementFactory 
    509      *            the GUI element factory to be used for instantiating GUI element objects 
    510      *  
    511      * @return The GUI element object representing the GUI element denoted by the provided path 
    512      *  
    513      * @throws GUIModelException 
    514      *             thrown in cases such as the GUI element object could not be instantiated 
    515      */ 
    516     private IGUIElement integratePath(TreeNode                        parentNode, 
    517                                       List<? extends IGUIElementSpec> remainingPath, 
    518                                       IGUIElementFactory              guiElementFactory) 
    519         throws GUIModelException 
    520     { 
    521         IGUIElementSpec specToIntegrateElementFor = remainingPath.remove(0); 
    522  
    523         TreeNode child = findEqualChild(parentNode, specToIntegrateElementFor); 
    524         if (child == null) { 
    525             IGUIElement newElement = 
    526                 guiElementFactory.instantiateGUIElement(specToIntegrateElementFor, 
    527                                                         parentNode.guiElement); 
    528  
    529             if (newElement instanceof AbstractDefaultGUIElement) { 
    530                 ((AbstractDefaultGUIElement) newElement).setGUIModel(this); 
    531             } 
    532              
    533             child = parentNode.addChild(newElement); 
    534             allNodes.put(child.guiElement, child); 
    535         } 
    536  
    537         if (remainingPath.size() > 0) { 
    538             return integratePath(child, remainingPath, guiElementFactory); 
    539         } 
    540         else { 
    541             return child.guiElement; 
    542         } 
    543     } 
    544  
    545     /** 
    546      * <p> 
    547      * Searches the children of a tree node to see if the {@link IGUIElementSpec} of equals the 
    548      * specification of the {@link TreeNode#guiElement} of the child. If a match is found, the child 
    549      * is returned. 
    550      * </p> 
    551      *  
    552      * @param parentNode 
    553      *            parent node whose children are searched 
    554      * @param specToMatch 
    555      *            specification that is searched for 
    556      * @return matching child node or null if no child matches 
    557      */ 
    558     private TreeNode findEqualChild(TreeNode parentNode, IGUIElementSpec specToMatch) { 
    559         if (parentNode.children != null) { 
    560             for (TreeNode child : parentNode.children) { 
    561                 if (specToMatch.equals(child.guiElement.getSpecification())) { 
    562                     return child; 
    563                 } 
    564             } 
    565         } 
    566         return null; 
    567     } 
    568  
    569     /** 
    570      * <p> 
    571      * Merges all similar nodes in the sub-tree of the GUI model defined by the subTreeRoot. 
    572      * </p> 
    573      * <p> 
    574      * The merging order is a bottom-up. This means, that we first call mergeSubTree recursively for 
    575      * the grand children of the subTreeRoot, before we merge subTreeRoot. 
    576      * </p> 
    577      * <p> 
    578      * The merging strategy is top-down. This means, that every time we merge two child nodes, we 
    579      * call mergeSubTree recursively for all children of the merged nodes in order to check if we 
    580      * can merge the children, too. 
    581      * </p> 
    582      *  
    583      * @param subTreeRoot 
    584      *            root node of the sub-tree that is merged 
    585      */ 
    586     private void mergeSubTree(TreeNode subTreeRoot) { 
    587         if (subTreeRoot.children == null || subTreeRoot.children.isEmpty()) { 
    588             return; 
    589         } 
    590  
    591         // lets first merge the grand children of the parentNode 
    592         for (TreeNode child : subTreeRoot.children) { 
    593             mergeSubTree(child); 
    594         } 
    595  
    596         boolean performedMerge; 
    597  
    598         do { 
    599             performedMerge = false; 
    600             for (int i = 0; !performedMerge && i < subTreeRoot.children.size(); i++) { 
    601                 IGUIElementSpec elemSpec1 = 
    602                     subTreeRoot.children.get(i).guiElement.getSpecification(); 
    603                 for (int j = i + 1; !performedMerge && j < subTreeRoot.children.size(); j++) { 
    604                     IGUIElementSpec elemSpec2 = 
    605                         subTreeRoot.children.get(j).guiElement.getSpecification(); 
    606                     if (elemSpec1.getSimilarity(elemSpec2)) { 
    607                         TreeNode replacement = mergeTreeNodes 
    608                             (subTreeRoot.children.get(i), subTreeRoot.children.get(j), true); 
    609  
    610                         subTreeRoot.children.set(i, replacement); 
    611                         subTreeRoot.children.remove(j); 
    612                         performedMerge = true; 
    613                         i--; 
    614                         break; 
    615                     } 
    616                 } 
    617             } 
    618         } 
    619         while (performedMerge); 
    620     } 
    621  
    622     /** 
    623      * <p> 
    624      * merges two nodes with each other. Merging means registering the GUI element objects with each 
    625      * other for equality checks. Further it adds all children of both nodes to a new replacing 
    626      * node. Afterwards, all similar nodes of the replacement node are merged as well as long 
    627      * the recursive parameter is set to true. 
    628      * </p> 
    629      *  
    630      * @param treeNode1 
    631      *            the first of the two nodes to be merged 
    632      * @param treeNode2 
    633      *            the second of the two nodes to be merged 
    634      * @param recursively 
    635      *            if true, the merging also merges child nodes 
    636      *             
    637      * @return a tree node being the merge of the two provided nodes. 
    638      */ 
    639     private TreeNode mergeTreeNodes(TreeNode treeNode1, TreeNode treeNode2, boolean recursively) { 
    640         // and now a replacement node that is the merge of treeNode1 and treeNode2 is created 
    641         TreeNode replacement = new TreeNode(); 
    642         replacement.guiElement = treeNode1.guiElement; 
    643         if (treeNode1.children != null) { 
    644             for (TreeNode child : treeNode1.children) { 
    645                 replacement.addChildNode(child); 
    646             } 
    647         } 
    648         if (treeNode2.children != null) { 
    649             for (TreeNode child : treeNode2.children) { 
    650                 replacement.addChildNode(child); 
    651             } 
    652         } 
    653  
    654         if (recursively) { 
    655             mergeSubTree(replacement); 
    656         } 
    657  
    658         replacement.guiElement.updateSpecification(treeNode2.guiElement.getSpecification()); 
    659  
    660         // finally, update the known nodes list 
    661         // if you don't do this getChildren will return wrong things and very bad things happen! 
    662         allNodes.remove(treeNode1.guiElement); 
    663         allNodes.remove(treeNode2.guiElement); 
    664  
    665         // the following two lines are needed to preserve the references to the existing GUI 
    666         // elements. If two elements are the same, one should be deleted to make the elements 
    667         // singletons again. However, there may exist references to both objects. To preserve 
    668         // these, we simply register the equal GUI elements with each other so that an equals 
    669         // check can return true. 
    670         treeNode1.guiElement.addEqualGUIElement(treeNode2.guiElement); 
    671         treeNode2.guiElement.addEqualGUIElement(treeNode1.guiElement); 
    672          
    673         allNodes.put(replacement.guiElement, replacement); 
    674          
    675         return replacement; 
    676     } 
    677  
    678     /** 
    679      * <p> 
    680      * dumps a GUI element to the stream. A dump contains the toString() representation of the GUI 
    681      * element as well as a indented list of its children surrounded by braces. Therefore, not the 
    682      * GUI element itself but its tree node is provided to have an efficient access to its children 
    683      * </p> 
    684      *  
    685      * @param out 
    686      *            {@link PrintStream} where the guiElement is dumped to 
    687      * @param node 
    688      *            the guiElement's tree node of which the string representation is dumped 
    689      * @param indent 
    690      *            indent string of the dumping 
    691      */ 
    692     private void dumpGUIElement(PrintStream out, TreeNode node, String indent) { 
    693         out.print(indent); 
    694         out.print(node.guiElement); 
    695  
    696         if ((node.children != null) && (node.children.size() > 0)) { 
    697             out.println(" {"); 
    698  
    699             for (TreeNode child : node.children) { 
    700                 dumpGUIElement(out, child, indent + "  "); 
    701             } 
    702  
    703             out.print(indent); 
    704             out.print("}"); 
    705         } 
    706  
    707         out.println(); 
    708     } 
    709      
    710     /** 
    711      * <p> 
    712      * Retrieves the TreeNode associated with a GUI element. Returns null if no such TreeNode is 
    713      * found. 
    714      * </p> 
    715      *  
    716      * @param element 
    717      *            the GUI element 
    718      * @return associated TreeNode; null if no such node exists 
    719      */ 
    720     private TreeNode findNode(IGUIElement element) { 
    721         if (element == null) { 
    722             return null; 
    723         } 
    724  
    725         TreeNode result = null; 
    726          
    727         if (!validate) { 
    728             result = allNodes.get(element); 
    729         } 
    730         else { 
    731             for (Map.Entry<IGUIElement, TreeNode> entry : allNodes.entrySet()) { 
    732                 if (entry.getKey().equals(element)) { 
    733                     if (result == null) { 
    734                         result = entry.getValue(); 
    735                     } 
    736                     else { 
    737                         Console.traceln(Level.SEVERE, "Multiple nodes in the internal GUI model " + 
    738                                         "match the same GUI element. This should not be the case " + 
    739                                         "and the GUI model is probably invalid."); 
    740                     } 
    741                 } 
    742             } 
    743         } 
    744         return result; 
    745     } 
    746  
    747     /** 
    748      * <p> 
    749      * Used externally for tree traversal without providing direct access to the tree nodes 
    750      * </p> 
    751      *  
    752      * @version 1.0 
    753      * @author Patrick Harms, Steffen Herbold 
    754      */ 
    755     public class Traverser { 
    756          
    757         /** 
    758          * <p> 
    759          * the stack of nodes on which the traverser currently works 
    760          * </p> 
    761          */ 
    762         private Stack<StackEntry> nodeStack = new Stack<StackEntry>(); 
    763          
    764         /** 
    765          * <p> 
    766          * initializes the traverser by adding the root node of the GUI model to the stack 
    767          * </p> 
    768          */ 
    769         private Traverser() { 
    770             nodeStack.push(new StackEntry(root, 0)); 
    771         } 
    772          
    773         /** 
    774          * <p> 
    775          * returns the first child of the current GUI element. On the first call of this method on 
    776          * the traverser the first of the root GUI elements of the GUI model is returned. If the 
    777          * current GUI element does not have children, the method returns null. If the GUI model 
    778          * is empty, then a call to this method will return null. The returned GUI element is the 
    779          * next one the traverser points to. 
    780          * </p> 
    781          * 
    782          * @return as described. 
    783          */ 
    784         public IGUIElement firstChild() { 
    785             return pushChild(0); 
    786         } 
    787          
    788         /** 
    789          * <p> 
    790          * returns true, if the current GUI element has a first child, i.e. if the next call to the 
    791          * method {@link #firstChild()} would return a GUI element or null. 
    792          * </p> 
    793          * 
    794          * @return as described 
    795          */ 
    796         public boolean hasFirstChild() { 
    797             return 
    798                 (nodeStack.peek().treeNode.children != null) && 
    799                 (nodeStack.peek().treeNode.children.size() > 0); 
    800         } 
    801          
    802         /** 
    803          * <p> 
    804          * returns the next sibling of the current GUI element. If there is no further sibling, 
    805          * null is returned. If the current GUI element is one of the root nodes, the next root 
    806          * node of the GUI model is returned. The returned GUI element is the next one the 
    807          * traverser points to. 
    808          * </p> 
    809          * 
    810          * @return as described 
    811          */ 
    812         public IGUIElement nextSibling() { 
    813             int lastIndex = nodeStack.pop().index; 
    814              
    815             IGUIElement retval = pushChild(lastIndex + 1); 
    816             if (retval == null) { 
    817                 pushChild(lastIndex); 
    818             } 
    819              
    820             return retval; 
    821         } 
    822          
    823         /** 
    824          * <p> 
    825          * returns true, if the current GUI element has a further sibling, i.e. if a call to the 
    826          * method {@link #nextSibling()} will return a GUI element; 
    827          * </p> 
    828          * 
    829          * @return as described 
    830          */ 
    831         public boolean hasNextSibling() { 
    832             boolean result = false; 
    833             if (nodeStack.size() > 1) { 
    834                 StackEntry entry = nodeStack.pop(); 
    835                 result = nodeStack.peek().treeNode.children.size() > (entry.index + 1); 
    836                 pushChild(entry.index); 
    837             } 
    838              
    839             return result; 
    840         } 
    841          
    842         /** 
    843          * <p> 
    844          * returns the parent GUI element of the current GUI element. If the current GUI element 
    845          * is a root node, null is returned. If there is no current GUI element yet as the method 
    846          * {@link #firstChild()} was not called yet, null is returned. 
    847          * </p> 
    848          * 
    849          * @return as described 
    850          */ 
    851         public IGUIElement parent() { 
    852             IGUIElement retval = null; 
    853              
    854             if (nodeStack.size() > 1) { 
    855                 nodeStack.pop(); 
    856                 retval = nodeStack.peek().treeNode.guiElement; 
    857             } 
    858              
    859             return retval; 
    860         } 
    861          
    862         /** 
    863          * <p> 
    864          * internal method used for changing the state of the traverser. I.e. to switch to a 
    865          * specific child GUI element of the current one. 
    866          * </p> 
    867          */ 
    868         private IGUIElement pushChild(int index) { 
    869             IGUIElement retVal = null; 
    870              
    871             if ((nodeStack.peek().treeNode.children != null) && 
    872                 (nodeStack.peek().treeNode.children.size() > index)) 
    873             { 
    874                 nodeStack.push 
    875                     (new StackEntry(nodeStack.peek().treeNode.children.get(index), index)); 
    876                 retVal = nodeStack.peek().treeNode.guiElement; 
    877             } 
    878              
    879             return retVal; 
    880         } 
    881          
    882         /** 
    883          * <p> 
    884          * navigates the traverser to the given node in the GUI model 
    885          * </p> 
    886          */ 
    887         private boolean navigateTo(TreeNode node) { 
    888             if (hasFirstChild()) { 
    889                 IGUIElement childElement = firstChild(); 
    890              
    891                 while (childElement != null) { 
    892                     if (childElement.equals(node.guiElement)) { 
    893                         return true; 
    894                     } 
    895                     else if (navigateTo(node)) { 
    896                         return true; 
    897                     } 
    898                     else { 
    899                         childElement = nextSibling(); 
    900                     } 
    901                 } 
    902              
    903                 parent(); 
    904             } 
    905              
    906             return false; 
    907         } 
    908  
    909         /** 
    910          * <p> 
    911          * internal class needed to fill the stack with nodes of the GUI models and their 
    912          * respective index in the children of the parent node. 
    913          * </p> 
    914          */ 
    915         private class StackEntry { 
    916              
    917             /** */ 
    918             private TreeNode treeNode; 
    919              
    920             /** */ 
    921             private int index; 
    922              
    923             /** 
    924              * <p> 
    925              * creates a new stack entry. 
    926              * </p> 
    927              */ 
    928             private StackEntry(TreeNode treeNode, int index) { 
    929                 this.treeNode = treeNode; 
    930                 this.index = index; 
    931             } 
    932         } 
    933     } 
    934  
    935     /** 
    936      * <p> 
    937      * Used internally for building up the tree of GUI elements. 
    938      * </p> 
    939      *  
    940      * @version 1.0 
    941      * @author Patrick Harms, Steffen Herbold 
    942      */ 
    943     private static class TreeNode implements Serializable { 
    944  
    945         /**  */ 
    946         private static final long serialVersionUID = 1L; 
    947  
    948         /** 
    949          * <p> 
    950          * GUI element associated with the TreeNode. 
    951          * </p> 
    952          */ 
    953         private IGUIElement guiElement; 
    954  
    955         /** 
    956          * <p> 
    957          * Children of the TreeNode. 
    958          * </p> 
    959          */ 
    960         private List<TreeNode> children; 
    961  
    962         /** 
    963          * <p> 
    964          * Adds a child to the current node while keeping all lists of nodes up to date 
    965          * </p> 
    966          *  
    967          * @param guiElement 
    968          *            GUI element that will be associated with the new child 
    969          * @return the added child 
    970          */ 
    971         private TreeNode addChild(IGUIElement guiElement) { 
    972             if (children == null) { 
    973                 children = new ArrayList<TreeNode>(); 
    974             } 
    975  
    976             TreeNode child = new TreeNode(); 
    977             child.guiElement = guiElement; 
    978             children.add(child); 
    979  
    980             return child; 
    981         } 
    982  
    983         /** 
    984          *  
    985          * <p> 
    986          * Adds a TreeNode as child to the current node. This way, the whole sub-tree is added. 
    987          * </p> 
    988          *  
    989          * @param node 
    990          *            child node that is added 
    991          * @return node that has been added 
    992          */ 
    993         private TreeNode addChildNode(TreeNode node) { 
    994             if (children == null) { 
    995                 children = new ArrayList<TreeNode>(); 
    996             } 
    997             children.add(node); 
    998             return node; 
    999         } 
    1000  
    1001         /* 
    1002          * (non-Javadoc) 
    1003          *  
    1004          * @see java.lang.Object#toString() 
    1005          */ 
    1006         @Override 
    1007         public String toString() { 
    1008             return guiElement.toString(); 
    1009         } 
    1010  
    1011     } 
    101260} 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElement.java

    r1876 r2146  
    1515package de.ugoe.cs.autoquest.eventcore.guimodel; 
    1616 
    17 import de.ugoe.cs.autoquest.eventcore.IEventTarget; 
     17import de.ugoe.cs.autoquest.eventcore.IHierarchicalEventTarget; 
    1818 
    1919/** 
     
    2525 * @author Patrick Harms 
    2626 */ 
    27 public interface IGUIElement extends IEventTarget { 
    28      
     27public interface IGUIElement extends IHierarchicalEventTarget { 
     28 
    2929    /** 
    3030     * <p> 
     
    9999    /** 
    100100     * <p> 
    101      * Updates the specification of a GUI element with another specification, e.g., to add further 
    102      * known names of the GUI element. 
    103      * </p> 
    104      *  
    105      * @param furtherSpec 
    106      *            additional specification 
    107      */ 
    108     public void updateSpecification(IGUIElementSpec furtherSpec); 
    109  
    110     /** 
    111      * <p> 
    112      * The {@link IGUIElement} that is passed by this function is equal to the current GUI element 
    113      * and will hereafter be treated as such. 
    114      * </p> 
    115      *  
    116      * @param guiElement 
    117      *            GUI element that is equal 
    118      */ 
    119     public void addEqualGUIElement(IGUIElement equalElement); 
    120  
    121     /** 
    122      * <p> 
    123101     * Returns a measure for the distance of this {@link IGUIElement} to the provided one. Distance 
    124102     * means a measure for the distance in display of the rendered GUI. The returned values must be 
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElementSpec.java

    r990 r2146  
    1717import java.io.Serializable; 
    1818 
     19import de.ugoe.cs.autoquest.eventcore.IEventTargetSpec; 
     20 
    1921/** 
    2022 * <p> 
     
    2527 * @author Patrick Harms, Steffen Herbold 
    2628 */ 
    27 public interface IGUIElementSpec extends Serializable { 
     29public interface IGUIElementSpec extends Serializable, IEventTargetSpec { 
    2830 
    2931    /** 
     
    5153    public String[] getTypeHierarchy(); 
    5254 
    53     /** 
    54      * <p> 
    55      * Evaluates if two GUI specifications are similar. Similar means that a heuristic determines 
    56      * that the two GUI specifications describe the same GUI element. 
    57      * </p> 
    58      *  
    59      * @param other 
    60      *            specification whose similarity to this is evaluated 
    61      * @return true if the specifications are similar; false otherwise 
    62      */ 
    63     public boolean getSimilarity(IGUIElementSpec other); 
    64  
    65     /** 
    66      * <p> 
    67      * Defines that {@link IGUIElement} implementations have to define equals. 
    68      * </p> 
    69      *  
    70      * @see Object#equals(Object) 
    71      */ 
    72     @Override 
    73     public boolean equals(Object other); 
    74  
    75     /** 
    76      * <p> 
    77      * Defines that {@link IGUIElement} implementations have to define hashCode. 
    78      * </p> 
    79      *  
    80      * @see Object#hashCode() 
    81      */ 
    82     @Override 
    83     public int hashCode(); 
    8455} 
Note: See TracChangeset for help on using the changeset viewer.