source: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIElementTree.java @ 1068

Last change on this file since 1068 was 1068, checked in by pharms, 11 years ago
  • added a possibility to determine the id of a given GUI element
  • Property svn:mime-type set to text/plain
File size: 8.8 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.eventcore.guimodel;
16
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21
22import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementFactory;
23import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
24import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModelException;
25import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementFactory;
26
27/**
28 * <p>
29 * This class provides the interfaces for GUI element trees.
30 * </p>
31 * <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.
35 * </p>
36 *
37 * @author Fabian Glaser
38 * @author Steffen Herbold
39 * @version 1.0
40 */
41public class GUIElementTree<T> {
42    /**
43     * <p>
44     * Map of all GUI elements that are part of the tree for efficient searching. The keys of the
45     * map are the ids of the GUI elements.
46     * </p>
47     */
48    private Map<T, IGUIElement> guiElements;
49
50    /**
51     * <p>
52     * Map of all GUI element specifications that are part of the tree for efficient searching. The
53     * keys of the map are the ids of the GUI elements.
54     * </p>
55     */
56    private Map<T, IGUIElementSpec> guiElementSpecs;
57
58    /**
59     * <p>
60     * Map of all children of GUI elements that are part of the tree. The keys of the map are the
61     * ids of the parent GUI elements.
62     * </p>
63     */
64    private Map<T, List<T>> childRelations;
65
66    /**
67     * <p>
68     * Map of all parents of GUI elements that are part of the tree. The keys of the map are the
69     * ids of the child GUI elements.
70     * </p>
71     */
72    private Map<T, T> parentRelations;
73
74    /**
75     * <p>
76     * the internally created GUI model
77     * </p>
78     */
79    private GUIModel guiModel;
80
81    /**
82     * <p>
83     * the GUI element factory used in the model
84     * </p>
85     */
86    private IGUIElementFactory guiElementFactory = GUIElementFactory.getInstance();
87
88 
89
90    /**
91     * <p>
92     * Creates a new GUIElementTree.
93     * </p>
94     */
95    public GUIElementTree() {
96        guiElementSpecs = new HashMap<T, IGUIElementSpec>();
97        childRelations = new HashMap<T, List<T>>();
98        parentRelations = new HashMap<T, T>();
99        guiElements = new HashMap<T, IGUIElement>();
100        guiModel = new GUIModel();
101    }
102   
103    /**
104     * <p>
105     * Creates a GUIElementTree with an already existing guiModel
106     * @param guiModel
107     * </p>
108     */
109    public GUIElementTree(GUIModel guiModel){
110        guiElementSpecs = new HashMap<T, IGUIElementSpec>();
111        childRelations = new HashMap<T, List<T>>();
112        parentRelations = new HashMap<T, T>();
113        guiElements = new HashMap<T, IGUIElement>();
114        this.guiModel = guiModel;
115    }
116
117    /**
118     * <p>
119     * Adds a new GUI element to the tree.
120     * </p>
121     *
122     * @param guiElementID
123     *            id of the GUI element to be created
124     * @param parentID
125     *            id of the parent GUI element
126     * @param guiElementSpec
127     *            the GUI element specification
128     */
129    public void add(T guiElementID,
130                    T parentID,
131                    IGUIElementSpec guiElementSpec)
132    {
133        IGUIElement guiElement = guiElements.get(guiElementID);
134       
135        if (guiElement == null) {
136            IGUIElementSpec parent = guiElementSpecs.get(parentID);
137            if (parent != null) {
138                List<T> otherChildren = childRelations.get(parentID);
139
140                if (otherChildren == null) {
141                    otherChildren = new ArrayList<T>();
142                    childRelations.put(parentID, otherChildren);
143                }
144
145                otherChildren.add(guiElementID);
146
147                parentRelations.put(guiElementID, parentID);
148            }
149            guiElementSpecs.put(guiElementID, guiElementSpec);
150           
151            List<IGUIElementSpec> guiElementPath = new ArrayList<IGUIElementSpec>();
152
153            T currentElementID = guiElementID;
154            while (guiElementSpec != null) {
155                guiElementPath.add(0, guiElementSpec);
156                currentElementID = parentRelations.get(currentElementID);
157                guiElementSpec = guiElementSpecs.get(currentElementID);
158            }
159
160            try {
161                guiElement = guiModel.integratePath(guiElementPath, guiElementFactory);
162            }
163            catch (GUIModelException e) {
164                throw new RuntimeException("could not instantiate GUI element with id " + guiElementID, e);
165            }
166            guiElements.put(guiElementID, guiElement);
167        }
168    }
169
170    /**
171     * <p>
172     * Searches the tree for a GUI element with the specified id and returns its
173     * {@link IGUIElement} .
174     * </p>
175     *
176     * @param id
177     *            id that is looked for
178     * @return {@link IGUIElementSpec} of the GUI element with the given id if found, null otherwise
179     */
180    public IGUIElement find(T id) {
181        return guiElements.get(id);
182    }
183
184    /**
185     * <p>
186     * Returns the id of the provided {@link IGUIElement}. The comparison is performed using the
187     * equals method of the GUI element.
188     * </p>
189     *
190     * @param guiElement
191     *            guiElement that is looked for
192     * @return the id of the GUI element, null if the GUI element can not be found
193     */
194    public T find(IGUIElement guiElement) {
195        for (Map.Entry<T, IGUIElement> entry : guiElements.entrySet()) {
196            if (guiElement.equals(entry.getValue())) {
197                return entry.getKey();
198            }
199        }
200       
201        return null;
202    }
203
204    /**
205     * <p>
206     * Removes a GUI element (defined by its id) from the tree. All children of the GUI element will be
207     * removed recursively.
208     * </p>
209     *
210     * @param id
211     *            id of the GUI element to be removed
212     * @return number of GUI elements that were removed
213     */
214    public int remove(T id) {
215        int removedCounter = 0;
216        IGUIElementSpec node = guiElementSpecs.remove(id);
217
218        if (node != null) {
219            removedCounter++;
220            List<T> nodesToBeRemoved = childRelations.remove(id);
221
222            // remove all children and sub-children, if any
223            if (nodesToBeRemoved != null) {
224                for (int i = 0; i < nodesToBeRemoved.size(); i++) {
225                    T nodeToBeRemoved = nodesToBeRemoved.get(i);
226                    List<T> children =
227                        childRelations.remove(nodeToBeRemoved);
228
229                    if (children != null) {
230                        nodesToBeRemoved.addAll(children);
231                    }
232
233                    guiElementSpecs.remove(nodeToBeRemoved);
234                    parentRelations.remove(nodeToBeRemoved);
235                    removedCounter++;
236                }
237            }
238
239            /* the node may be a child node of a parent. So search for it in the child relations
240            of the parent and remove it */
241            T parent = parentRelations.remove(id);
242            if (parent != null) {
243                List<T> children = childRelations.get(parent);
244
245                if (children != null) {
246                    for (int i = 0; i < children.size(); i++) {
247                        if (children.get(i) == id) {
248                            children.remove(i);
249                            break;
250                        }
251                    }
252
253                    if (children.size() <= 0) {
254                        childRelations.remove(parent);
255                    }
256                }
257            }
258        }
259        return removedCounter;
260    }
261
262    /**
263     * @return the guiModel
264     */
265    public GUIModel getGUIModel() {
266        return guiModel;
267    }
268
269    /**
270     * <p>
271     * Returns the number of nodes contained in the JFCComponentTree.
272     * </p>
273     *
274     * @return number of nodes
275     */
276    public int size() {
277        return guiElementSpecs.size();
278    }
279
280}
Note: See TracBrowser for help on using the repository browser.