Changeset 619 for trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/guimodel/WindowTree.java
- Timestamp:
- 08/27/12 11:45:09 (12 years ago)
- Location:
- trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/guimodel
- Files:
-
- 1 added
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/guimodel/WindowTree.java
r578 r619 1 package de.ugoe.cs.quest.plugin.mfc.eventcore; 2 1 2 package de.ugoe.cs.quest.plugin.mfc.guimodel; 3 4 import java.util.ArrayList; 3 5 import java.util.HashMap; 6 import java.util.HashSet; 4 7 import java.util.List; 5 8 import java.util.Map; 6 import java.util.SortedSet; 7 import java.util.TreeSet; 9 import java.util.Set; 10 11 import de.ugoe.cs.quest.eventcore.guimodel.GUIElementFactory; 12 import de.ugoe.cs.quest.eventcore.guimodel.GUIModel; 13 import de.ugoe.cs.quest.eventcore.guimodel.GUIModelException; 14 import de.ugoe.cs.quest.eventcore.guimodel.IGUIElementFactory; 15 8 16 9 17 /** … … 12 20 * </p> 13 21 * <p> 14 * The window tree represents the hierarchical structure of the windows 15 * "as it is" currently during a session. It may change during the session due 16 * to creation and destruction of windows. 17 * </p> 18 * <p> 19 * The class is implemented as a singleton. The rational behind implementing 20 * this class as a singleton is to ease the access of all class that may request 21 * information about the windows during the parsing of a session. As the tree 22 * may change during the session, it does not make sense to preserve it after a 23 * session. Thus, it can just be deleted. Therefore, as long as only one session 24 * is parsed at a time, a single instance is sufficient. 22 * The window tree represents the hierarchical structure of the windows "as it is" currently during 23 * a session. It may change during the session due to creation and destruction of windows. 25 24 * </p> 26 25 * … … 30 29 public class WindowTree { 31 30 32 /** 33 * <p> 34 * Handle to the window instance. 35 * </p> 36 */ 37 private static WindowTree theInstance = null; 38 39 /** 40 * <p> 41 * Maintains a set of all the target strings of all widgets that were at 42 * some point part of the window tree. 43 * </p> 44 */ 45 private SortedSet<String> targets; 46 47 /** 48 * <p> 49 * Obtain a handle to the window instance. 50 * </p> 51 * 52 * @return instance of the window tree 53 */ 54 public static WindowTree getInstance() { 55 if (theInstance == null) { 56 theInstance = new WindowTree(); 57 } 58 return theInstance; 59 } 60 61 /** 62 * <p> 63 * Resets the tree. Should be used between sessions. 64 * </p> 65 */ 66 public static void resetTree() { 67 theInstance = null; 68 } 69 70 /** 71 * <p> 72 * Map of all windows that are part of the tree for efficient searching. The 73 * keys of the map are the hwnd's of the windows. 74 * </p> 75 */ 76 private Map<Integer, WindowTreeNode> nodes; 77 78 /** 79 * <p> 80 * Creates a new WindowTree. 81 * </p> 82 * <p> 83 * Private, as the class is a singleton. 84 * </p> 85 */ 86 private WindowTree() { 87 nodes = new HashMap<Integer, WindowTreeNode>(); 88 targets = new TreeSet<String>(); 89 } 90 91 /** 92 * <p> 93 * Adds a new window to the tree. 94 * </p> 95 * 96 * @param parentHwnd 97 * hwnd of the parent window 98 * @param childHwnd 99 * hwnd of the window to be created 100 * @param childWindowName 101 * resource id of the window to be created 102 * @param resourceId 103 * resource id of the window to be created 104 * @param className 105 * class name of the window to be created 106 */ 107 public void add(int parentHwnd, int childHwnd, String childWindowName, 108 int resourceId, String className, boolean isModal) { 109 WindowTreeNode parent = nodes.get(parentHwnd); 110 WindowTreeNode child = nodes.get(childHwnd); 111 if (child == null) { 112 if (parent != null) { 113 child = parent.addChild(childHwnd, childWindowName, resourceId, 114 className, isModal); 115 } else { 116 child = new WindowTreeNode(childHwnd, null, childWindowName, 117 resourceId, className, isModal); 118 } 119 nodes.put(childHwnd, child); 120 targets.add(child.xmlRepresentation()); 121 } 122 } 123 124 /** 125 * <p> 126 * Removes a window (defined by its hwnd) from the tree. All children of the 127 * window will be removed recursively. 128 * </p> 129 * 130 * @param hwnd 131 * hwnd of the window to be removed 132 * @return number of windows that were removed 133 */ 134 public int remove(int hwnd) { 135 int removedCounter = 0; 136 WindowTreeNode node = nodes.get(hwnd); 137 if (node != null) { 138 List<WindowTreeNode> nodesToBeRemoved = node.remove(); 139 for (int i = 0; i < nodesToBeRemoved.size(); i++) { 140 WindowTreeNode nodeToBeRemoved = nodesToBeRemoved.get(i); 141 nodesToBeRemoved.addAll(nodeToBeRemoved.getChildren()); 142 nodes.remove(nodeToBeRemoved.getHwnd()); 143 removedCounter++; 144 } 145 nodes.remove(hwnd); 146 removedCounter++; 147 } 148 return removedCounter; 149 } 150 151 /** 152 * <p> 153 * Searches the tree for a window with the specified hwnd and returns its 154 * {@link WindowTreeNode}. 155 * </p> 156 * 157 * @param hwnd 158 * hwnd that is looked for 159 * @return {@link WindowTreeNode} of the window with the given hwnd if 160 * found, null otherwise 161 */ 162 public WindowTreeNode find(int hwnd) { 163 return nodes.get(hwnd); 164 } 165 166 /** 167 * <p> 168 * Returns the number of nodes contained in the WindowTree. 169 * </p> 170 * 171 * @return number of nodes 172 */ 173 public int size() { 174 return nodes.size(); 175 } 176 177 /** 178 * <p> 179 * Returns a sorted set of all targets that existed any time in the window 180 * tree. 181 * </p> 182 * 183 * @return set of targets 184 */ 185 public SortedSet<String> getTargets() { 186 return targets; 187 } 31 /** 32 * <p> 33 * Maintains a set of all the targets of all widgets that were at some point part of the 34 * window tree. 35 * </p> 36 */ 37 private Set<MFCGUIElementSpec> targets; 38 39 /** 40 * <p> 41 * Map of all GUI element specifications that are part of the tree for efficient searching. 42 * The keys of the map are the hwnd's of the GUI elements. 43 * </p> 44 */ 45 private Map<Long, MFCGUIElementSpec> guiElementSpecs; 46 47 /** 48 * <p> 49 * Map of all children of GUI elements that are part of the tree. The keys of the map are 50 * the hwnd's of the parent GUI elements. 51 * </p> 52 */ 53 private Map<Long, List<MFCGUIElementSpec>> childRelations; 54 55 /** 56 * <p> 57 * Map of all parents of GUI elements that are part of the tree. The keys of the map are 58 * the hwnd's of the child GUI elements. 59 * </p> 60 */ 61 private Map<Long, MFCGUIElementSpec> parentRelations; 62 63 /** 64 * <p> 65 * the internally created GUI model 66 * </p> 67 */ 68 private GUIModel guiModel = new GUIModel(); 69 70 /** 71 * <p> 72 * the GUI element factory used in the model 73 * </p> 74 */ 75 private IGUIElementFactory guiElementFactory = GUIElementFactory.getInstance(); 76 77 /** 78 * <p> 79 * Map of all GUI elements that are part of the tree for efficient searching. The keys of the 80 * map are the hwnd's of the GUI elements. 81 * </p> 82 */ 83 private Map<Long, MFCGUIElement> guiElements; 84 85 /** 86 * <p> 87 * Creates a new WindowTree. 88 * </p> 89 * <p> 90 * Private, as the class is a singleton. 91 * </p> 92 */ 93 public WindowTree() { 94 guiElementSpecs = new HashMap<Long, MFCGUIElementSpec>(); 95 targets = new HashSet<MFCGUIElementSpec>(); 96 childRelations = new HashMap<Long, List<MFCGUIElementSpec>>(); 97 parentRelations = new HashMap<Long, MFCGUIElementSpec>(); 98 guiElements = new HashMap<Long, MFCGUIElement>(); 99 } 100 101 /** 102 * <p> 103 * Adds a new window to the tree. 104 * </p> 105 * 106 * @param parentHwnd 107 * hwnd of the parent window 108 * @param childHwnd 109 * hwnd of the window to be created 110 * @param childWindowName 111 * resource id of the window to be created 112 * @param resourceId 113 * resource id of the window to be created 114 * @param className 115 * class name of the window to be created 116 */ 117 public void add(long parentHwnd, 118 long childHwnd, 119 String childWindowName, 120 int resourceId, 121 String className, 122 boolean isModal) 123 { 124 MFCGUIElementSpec parent = guiElementSpecs.get(parentHwnd); 125 MFCGUIElementSpec child = guiElementSpecs.get(childHwnd); 126 if (child == null) { 127 child = 128 new MFCGUIElementSpec(childHwnd, childWindowName, resourceId, className, isModal); 129 if (parent != null) { 130 List<MFCGUIElementSpec> otherChildren = childRelations.get(parentHwnd); 131 132 if (otherChildren == null) { 133 otherChildren = new ArrayList<MFCGUIElementSpec>(); 134 childRelations.put(parentHwnd, otherChildren); 135 } 136 137 otherChildren.add(child); 138 139 parentRelations.put(childHwnd, parent); 140 } 141 guiElementSpecs.put(childHwnd, child); 142 targets.add(child); 143 } 144 } 145 146 /** 147 * <p> 148 * Searches the tree for a window with the specified hwnd and returns its {@link MFCGUIElementSpec} 149 * . 150 * </p> 151 * 152 * @param hwnd 153 * hwnd that is looked for 154 * @return {@link MFCGUIElementSpec} of the window with the given hwnd if found, null otherwise 155 */ 156 public MFCGUIElement find(long hwnd) { 157 MFCGUIElement guiElement = guiElements.get(hwnd); 158 if (guiElement == null) { 159 List<MFCGUIElementSpec> guiElementPath = new ArrayList<MFCGUIElementSpec>(); 160 161 MFCGUIElementSpec child = guiElementSpecs.get(hwnd); 162 163 if (child == null) { 164 throw new RuntimeException("no GUI element found with id " + hwnd); 165 } 166 167 while (child != null) { 168 guiElementPath.add(0, child); 169 child = parentRelations.get(child.getHwnd()); 170 } 171 172 try { 173 guiElement = (MFCGUIElement) 174 guiModel.integratePath(guiElementPath, guiElementFactory); 175 } 176 catch (GUIModelException e) { 177 throw new RuntimeException("could not instantiate GUI element with id " + hwnd, e); 178 } 179 guiElements.put(hwnd, guiElement); 180 } 181 return guiElement; 182 } 183 184 /** 185 * <p> 186 * TODO: comment 187 * </p> 188 * 189 * @param hwnd 190 * @param windowName 191 */ 192 public void setName(long hwnd, String windowName) { 193 MFCGUIElementSpec child = guiElementSpecs.get(hwnd); 194 if (child != null) { 195 child.setName(windowName); 196 197 MFCGUIElement guiElement = guiElements.remove(hwnd); 198 if (guiElement == null) { 199 // we need to update the GUI model as well 200 find(hwnd); 201 } 202 } 203 } 204 205 /** 206 * <p> 207 * Removes a window (defined by its hwnd) from the tree. All children of the window will be 208 * removed recursively. 209 * </p> 210 * 211 * @param hwnd 212 * hwnd of the window to be removed 213 * @return number of windows that were removed 214 */ 215 public int remove(long hwnd) { 216 MFCGUIElementSpec node = guiElementSpecs.remove(hwnd); 217 int removedCounter = 1; 218 219 if (node != null) { 220 List<MFCGUIElementSpec> nodesToBeRemoved = childRelations.remove(hwnd); 221 222 // remove all children and sub-children, if any 223 if (nodesToBeRemoved != null) { 224 for (int i = 0; i < nodesToBeRemoved.size(); i++) { 225 MFCGUIElementSpec nodeToBeRemoved = nodesToBeRemoved.get(i); 226 List<MFCGUIElementSpec> children = 227 childRelations.remove(nodeToBeRemoved.getHwnd()); 228 229 if (children != null) { 230 nodesToBeRemoved.addAll(children); 231 } 232 233 guiElementSpecs.remove(nodeToBeRemoved.getHwnd()); 234 parentRelations.remove(nodeToBeRemoved.getHwnd()); 235 removedCounter++; 236 } 237 } 238 239 // the node may be a child node of a parent. So search for it and remove it 240 MFCGUIElementSpec parent = parentRelations.remove(hwnd); 241 if (parent != null) { 242 List<MFCGUIElementSpec> children = childRelations.get(parent.getHwnd()); 243 244 if (children != null) { 245 for (int i = 0; i < children.size(); i++) { 246 if (children.get(i).getHwnd() == hwnd) { 247 children.remove(i); 248 break; 249 } 250 } 251 252 if (children.size() <= 0) { 253 childRelations.remove(parent.getHwnd()); 254 } 255 } 256 } 257 } 258 return removedCounter; 259 } 260 261 /** 262 * @return the guiModel 263 */ 264 public GUIModel getGUIModel() { 265 return guiModel; 266 } 267 268 /** 269 * <p> 270 * Returns the number of nodes contained in the WindowTree. 271 * </p> 272 * 273 * @return number of nodes 274 */ 275 public int size() { 276 return guiElementSpecs.size(); 277 } 278 279 /** 280 * <p> 281 * Returns a sorted set of all targets that existed any time in the window tree. 282 * </p> 283 * 284 * @return set of targets 285 */ 286 public Set<MFCGUIElementSpec> getTargets() { 287 return targets; 288 } 289 188 290 }
Note: See TracChangeset
for help on using the changeset viewer.