Changeset 1260
- Timestamp:
- 07/25/13 14:45:00 (11 years ago)
- Location:
- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModel.java
r1181 r1260 20 20 import java.io.UnsupportedEncodingException; 21 21 import java.util.ArrayList; 22 import java.util.HashMap; 22 23 import java.util.LinkedList; 23 24 import java.util.List; 25 import java.util.Map; 24 26 import java.util.Stack; 25 27 import java.util.logging.Level; … … 52 54 /** 53 55 * <p> 54 * A list with all nodes currently known 55 * </p> 56 */ 57 private List<TreeNode> allNodes = new ArrayList<TreeNode>(); 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 71 * </p> 72 * 73 */ 74 public GUIModel() { 75 this(false); 76 } 77 78 /** 79 * <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. 83 * </p> 84 * 85 * @param validate 86 * true if internal validation shall be switched on (bad performance), false else 87 * 88 */ 89 public GUIModel(boolean validate) { 90 this.validate = validate; 91 } 58 92 59 93 /** … … 107 141 } 108 142 109 List<IGUIElementSpec> remainingPath = new LinkedList<IGUIElementSpec>(); 110 111 for (IGUIElementSpec spec : guiElementPath) { 112 remainingPath.add(spec); 113 } 143 List<IGUIElementSpec> remainingPath = new LinkedList<IGUIElementSpec>(guiElementPath); 114 144 115 145 return integratePath(root, remainingPath, guiElementFactory); … … 128 158 */ 129 159 public List<IGUIElement> getChildren(IGUIElement guiElement) { 160 TreeNode node = findNode(guiElement); 161 130 162 List<IGUIElement> result = null; 131 for (TreeNode node : allNodes) { 132 if (node.guiElement.equals(guiElement)) { 133 if (result == null) { 134 result = new ArrayList<IGUIElement>(); 135 136 if (node.children != null) { 137 for (TreeNode child : node.children) { 138 result.add(child.guiElement); 139 } 140 } 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); 141 168 } 142 else { 143 Console 144 .traceln(Level.SEVERE, 145 "Multiple nodes in the internal GUI model match the same GUI element. " 146 + "This should not be the case and the GUI model is probably invalid."); 147 } 148 } 149 } 150 169 } 170 } 171 151 172 return result; 152 173 } … … 166 187 IGUIElement parent = null; 167 188 168 for ( TreeNode node : allNodes) {169 if ( node.children != null) {170 for (TreeNode child : node.children) {189 for (Map.Entry<IGUIElement, TreeNode> entry : allNodes.entrySet()) { 190 if (entry.getValue().children != null) { 191 for (TreeNode child : entry.getValue().children) { 171 192 if (child.guiElement.equals(guiElement)) { 172 if (parent != null) { 173 parent = node.guiElement; 193 if (parent == null) { 194 parent = entry.getKey(); 195 if (!validate) { 196 break; 197 } 174 198 } 175 199 else { … … 269 293 /** 270 294 * <p> 295 * This method groups the provided GUI elements under a common parent GUI element. The current 296 * parent GUI element of the GUI elements to group must be the same. If the GUI elements to 297 * be grouped are the whole list of children of the same parent, nothing is changed. 298 * </p> 299 * 300 * @param guiElements the list of GUI elements to be grouped 301 * @param groupName the name of the GUI element group to be created 302 * 303 * @return the GUI element representing the group, or null, if the provided list of GUI elements 304 * is empty 305 * 306 * @throws IllegalArgumentException 307 * if not all GUI elements to be merged share the same parent, if one of the 308 * parameters is null, or if one of the provided GUI elements does not belong to 309 * the model 310 */ 311 public IGUIElement groupGUIElements(List<IGUIElement> guiElements, String groupName) 312 throws IllegalArgumentException 313 { 314 if ((guiElements == null) || (groupName == null)) { 315 throw new IllegalArgumentException("parameters must not be null"); 316 } 317 318 if (guiElements.size() <= 0) { 319 // do nothing 320 return null; 321 } 322 323 TreeNode parent = findNode(guiElements.get(0).getParent()); 324 325 List<TreeNode> nodesToGroup = new LinkedList<TreeNode>(); 326 327 for (IGUIElement element : guiElements) { 328 if (!(element instanceof AbstractDefaultGUIElement)) { 329 throw new IllegalArgumentException 330 ("can only group nodes of type AbstractDefaultGUIElement"); 331 } 332 333 TreeNode node = findNode(element); 334 if (node == null) { 335 throw new IllegalArgumentException 336 ("GUI element " + element + " is not part of the model"); 337 } 338 339 if (!nodesToGroup.contains(node)) { 340 nodesToGroup.add(node); 341 } 342 343 TreeNode parentNode = findNode(element.getParent()); 344 345 if (!parent.equals(parentNode)) { 346 throw new IllegalArgumentException("GUI elements do not share the same parent: " + 347 parent + " <> " + parentNode); 348 } 349 } 350 351 TreeNode replacement = new TreeNode(); 352 replacement.guiElement = new GUIElementGroup(groupName, parent.guiElement); 353 354 for (TreeNode child : nodesToGroup) { 355 ((GUIElementGroup) replacement.guiElement).addToGroup(child.guiElement); 356 replacement.addChildNode(child); 357 ((AbstractDefaultGUIElement) child.guiElement).setParent(replacement.guiElement); 358 parent.children.remove(child); 359 } 360 361 parent.children.add(replacement); 362 363 // finally, update the known nodes list 364 // if you don't do this getChildren will return wrong things and very bad things happen! 365 allNodes.put(replacement.guiElement, replacement); 366 367 return replacement.guiElement; 368 } 369 370 /** 371 * <p> 271 372 * By calling this method, the GUIModel is traversed and similar nodes are merged. 272 373 * </p> … … 280 381 * <p> 281 382 * Merges the tree nodes of two GUI elements. The GUI elements need to have the same parent. 383 * They are merged recursively, i.e. also their children are merged. 282 384 * </p> 283 385 * … … 286 388 * @param guiElement2 287 389 * the second merge GUI element 390 * 391 * @return the result of the merge 392 * 288 393 * @throws IllegalArgumentException 289 394 * thrown if the two GUI elements do not have the same parent 290 395 */ 291 public void mergeGUIElements(IGUIElement guiElement1, IGUIElement guiElement2) 396 public IGUIElement mergeGUIElements(IGUIElement guiElement1, IGUIElement guiElement2) 397 throws IllegalArgumentException 398 { 399 return mergeGUIElements(guiElement1, guiElement2, true); 400 } 401 402 /** 403 * <p> 404 * Merges the tree nodes of two GUI elements. The GUI elements need to have the same parent. 405 * If the <code>recursively</code> parameter is set to true, the children of the GUI elements 406 * are merged, as well, as long as they are similar. If the parameter is false, the children 407 * are not merged. In this case the resulting GUI element has all children of both merged GUI 408 * elements. 409 * </p> 410 * 411 * @param guiElement1 412 * the first merge GUI element 413 * @param guiElement2 414 * the second merge GUI element 415 * @param recursively 416 * if true, the merge is done also for similar children, if false, not. 417 * 418 * @return the result of the merge 419 * 420 * @throws IllegalArgumentException 421 * thrown if the two GUI elements do not have the same parent 422 */ 423 public IGUIElement mergeGUIElements(IGUIElement guiElement1, 424 IGUIElement guiElement2, 425 boolean recursively) 292 426 throws IllegalArgumentException 293 427 { … … 310 444 } 311 445 312 TreeNode replacement = mergeTreeNodes(node1, node2 );446 TreeNode replacement = mergeTreeNodes(node1, node2, recursively); 313 447 314 448 if (parent != null) { … … 321 455 } 322 456 457 return replacement.guiElement; 323 458 } 324 459 … … 356 491 357 492 child = parentNode.addChild(newElement); 358 allNodes. add(child);493 allNodes.put(child.guiElement, child); 359 494 } 360 495 … … 429 564 subTreeRoot.children.get(j).guiElement.getSpecification(); 430 565 if (elemSpec1.getSimilarity(elemSpec2)) { 431 TreeNode replacement = 432 mergeTreeNodes(subTreeRoot.children.get(i), subTreeRoot.children.get(j));566 TreeNode replacement = mergeTreeNodes 567 (subTreeRoot.children.get(i), subTreeRoot.children.get(j), true); 433 568 434 569 subTreeRoot.children.set(i, replacement); … … 447 582 * <p> 448 583 * merges two nodes with each other. Merging means registering the GUI element objects with each 449 * other for equality checks. Further it add all children of both nodes to a new replacing node. 450 * Afterwards, all similar nodes of the replacement node are merged as well. 584 * other for equality checks. Further it adds all children of both nodes to a new replacing 585 * node. Afterwards, all similar nodes of the replacement node are merged as well as long 586 * the recursive parameter is set to true. 451 587 * </p> 452 588 * … … 455 591 * @param treeNode2 456 592 * the second of the two nodes to be merged 593 * @param recursively 594 * if true, the merging also merges child nodes 595 * 457 596 * @return a tree node being the merge of the two provided nodes. 458 597 */ 459 private TreeNode mergeTreeNodes(TreeNode treeNode1, TreeNode treeNode2) { 598 private TreeNode mergeTreeNodes(TreeNode treeNode1, TreeNode treeNode2, boolean recursively) { 599 // and now a replacement node that is the merge of treeNode1 and treeNode2 is created 600 TreeNode replacement = new TreeNode(); 601 replacement.guiElement = treeNode1.guiElement; 602 if (treeNode1.children != null) { 603 for (TreeNode child : treeNode1.children) { 604 replacement.addChildNode(child); 605 } 606 } 607 if (treeNode2.children != null) { 608 for (TreeNode child : treeNode2.children) { 609 replacement.addChildNode(child); 610 } 611 } 612 613 if (recursively) { 614 mergeSubTree(replacement); 615 } 616 617 replacement.guiElement.updateSpecification(treeNode2.guiElement.getSpecification()); 618 619 // finally, update the known nodes list 620 // if you don't do this getChildren will return wrong things and very bad things happen! 621 allNodes.remove(treeNode1.guiElement); 622 allNodes.remove(treeNode2.guiElement); 623 460 624 // the following two lines are needed to preserve the references to the existing GUI 461 625 // elements. If two elements are the same, one should be deleted to make the elements … … 466 630 treeNode2.guiElement.addEqualGUIElement(treeNode1.guiElement); 467 631 468 // and now a replacement node that is the merge of treeNode1 and treeNode2 is created 469 TreeNode replacement = new TreeNode(); 470 replacement.guiElement = treeNode1.guiElement; 471 if (treeNode1.children != null) { 472 for (TreeNode child : treeNode1.children) { 473 replacement.addChildNode(child); 474 } 475 } 476 if (treeNode2.children != null) { 477 for (TreeNode child : treeNode2.children) { 478 replacement.addChildNode(child); 479 } 480 } 481 482 mergeSubTree(replacement); 483 484 replacement.guiElement.updateSpecification(treeNode2.guiElement.getSpecification()); 485 486 // finally, update the known nodes list 487 // if you don't do this getChildren will return wrong things and very bad things happen! 488 allNodes.remove(treeNode1); 489 allNodes.remove(treeNode2); 490 allNodes.add(replacement); 632 allNodes.put(replacement.guiElement, replacement); 491 633 492 634 return replacement; … … 541 683 542 684 TreeNode result = null; 543 for (TreeNode node : allNodes) { 544 if (node.guiElement.equals(element)) { 545 if (result == null) { 546 result = node; 547 } 548 else { 549 Console 550 .traceln(Level.SEVERE, 551 "Multiple nodes in the internal GUI model match the same GUI element. " 552 + "This should not be the case and the GUI model is probably invalid."); 685 686 if (!validate) { 687 result = allNodes.get(element); 688 } 689 else { 690 for (Map.Entry<IGUIElement, TreeNode> entry : allNodes.entrySet()) { 691 if (entry.getKey().equals(element)) { 692 if (result == null) { 693 result = entry.getValue(); 694 } 695 else { 696 Console.traceln(Level.SEVERE, "Multiple nodes in the internal GUI model " + 697 "match the same GUI element. This should not be the case " + 698 "and the GUI model is probably invalid."); 699 } 553 700 } 554 701 } … … 820 967 return guiElement.toString(); 821 968 } 969 822 970 } 823 971 }
Note: See TracChangeset
for help on using the changeset viewer.