1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javafx.scene.control.test.treeview; 26 27 import java.util.ArrayList; 28 import java.util.HashMap; 29 import java.util.HashSet; 30 import java.util.Iterator; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.logging.Level; 34 import java.util.logging.Logger; 35 import javafx.collections.ObservableList; 36 import javafx.event.EventHandler; 37 import javafx.geometry.Orientation; 38 import javafx.scene.Node; 39 import javafx.scene.Scene; 40 import javafx.scene.control.Control; 41 import javafx.scene.control.IndexedCell; 42 import javafx.scene.control.ScrollBar; 43 import javafx.scene.control.SelectionMode; 44 import javafx.scene.control.TreeCell; 45 import javafx.scene.control.TreeItem; 46 import javafx.scene.control.TreeTableCell; 47 import javafx.scene.control.TreeTableColumn; 48 import javafx.scene.control.TreeTableView; 49 import javafx.scene.control.TreeView; 50 import javafx.scene.control.test.treetable.TreeTableNewApp; 51 import static javafx.scene.control.test.treetable.TreeTableNewApp.*; 52 import javafx.scene.control.test.treeview.TreeViewCommonFunctionality.Properties; 53 import static javafx.scene.control.test.treeview.TreeViewConstants.EDIT_BUTTON_ID; 54 import static javafx.scene.control.test.treeview.TreeViewConstants.EDIT_TEXT_FIELD_ID; 55 import static javafx.scene.control.test.treeview.TreeViewConstants.GET_CONTROL_OVER_TREEITEM_BUTTON_ID; 56 import static javafx.scene.control.test.treeview.TreeViewConstants.GET_CONTROL_OVER_TREEITEM_TEXTFIELD_ID; 57 import static javafx.scene.control.test.treeview.TreeViewConstants.REMOVE_ITEM_BUTTON_ID; 58 import static javafx.scene.control.test.treeview.TreeViewConstants.REMOVE_ITEM_TEXT_FIELD_ID; 59 import static javafx.scene.control.test.treeview.TreeViewConstants.SCROLL_TO_BUTTON_ID; 60 import static javafx.scene.control.test.treeview.TreeViewConstants.SCROLL_TO_TEXT_FIELD_ID; 61 import javafx.scene.control.test.util.MultipleSelectionHelper; 62 import javafx.scene.control.test.util.UtilTestFunctions; 63 import javafx.scene.control.test.utils.ptables.AbstractPropertyController.SettingType; 64 import static javafx.scene.control.test.utils.ptables.NodeControllerFactory.TreeItemControllers.*; 65 import static javafx.scene.control.test.utils.ptables.PropertyValueListener.LISTENER_SUFFIX; 66 import static javafx.scene.control.test.utils.ptables.SpecialTablePropertiesProvider.ForTreeItem.*; 67 import javafx.scene.layout.StackPane; 68 import javafx.scene.text.Text; 69 import org.jemmy.Point; 70 import org.jemmy.action.GetAction; 71 import org.jemmy.control.Wrap; 72 import org.jemmy.env.Environment; 73 import org.jemmy.env.Timeout; 74 import org.jemmy.fx.ByID; 75 import org.jemmy.fx.ByStyleClass; 76 import org.jemmy.fx.NodeWrap; 77 import org.jemmy.fx.Root; 78 import org.jemmy.interfaces.Keyboard; 79 import org.jemmy.interfaces.Parent; 80 import org.jemmy.lookup.Lookup; 81 import org.jemmy.lookup.LookupCriteria; 82 import org.jemmy.timing.State; 83 import org.jemmy.timing.Waiter; 84 import org.junit.*; 85 import static org.junit.Assert.*; 86 import org.junit.runner.RunWith; 87 import test.javaclient.shared.FilteredTestRunner; 88 import static test.javaclient.shared.TestUtil.isEmbedded; 89 90 /** 91 * @author Alexander Kirov, Dmitry Zinkevich 92 */ 93 @RunWith(FilteredTestRunner.class) 94 public class TestBase extends UtilTestFunctions { 95 96 protected Wrap<? extends Scene> scene; 97 protected Wrap<? extends Control> testedControl; 98 protected static boolean isTreeTests = true; 99 protected boolean resetHardByDefault = true;//switcher of hard and soft reset mode. 100 protected boolean doNextResetHard = resetHardByDefault; 101 protected static MultipleSelectionHelper selectionHelper; 102 protected static int DATA_ITEMS_NUM = 0; 103 104 @BeforeClass 105 public static void setUpClass() throws Exception { 106 if (isTreeTests) { 107 System.out.println("Starting a TreeView applications with properties control."); 108 TreeViewNewApp.main(null); 109 } else { 110 System.out.println("Starting a TreeTable application with properties control."); 111 TreeTableNewApp.main(null); 112 } 113 } 114 115 @Before 116 public void setUp() { 117 TreeViewCommonFunctionality.setCheckFocus(true); 118 initWrappers(); 119 setContentSize(1, 21); 120 selectionHelper.setPageWidth(1); 121 if (selectionHelper.pageHeight != 7) { 122 selectionHelper.setPageHeight(10); 123 } 124 Environment.getEnvironment().setTimeout("wait.state", isEmbedded() ? 60000 : 2000); 125 Environment.getEnvironment().setTimeout("wait.control", isEmbedded() ? 60000 : 1000); 126 scene.mouse().move(new Point(0, 0)); 127 } 128 129 @After 130 public void tearDown() { 131 if (doNextResetHard) { 132 resetSceneHard(); 133 } else { 134 resetSceneSoft(); 135 } 136 137 doNextResetHard = resetHardByDefault; 138 currentSettingOption = SettingOption.PROGRAM; 139 } 140 141 protected static void setContentSize(int x, int y) { 142 DATA_ITEMS_NUM = y; 143 selectionHelper = new MultipleSelectionHelper(x, y); 144 } 145 146 protected void initWrappers() { 147 scene = Root.ROOT.lookup().wrap(); 148 parent = scene.as(Parent.class, Node.class); 149 if (isTreeTests) { 150 testedControl = (Wrap<? extends TreeView>) parent.lookup(TreeView.class, new ByID<TreeView>(TreeViewNewApp.TESTED_TREEVIEW_ID)).wrap(); 151 } else { 152 testedControl = (Wrap<? extends TreeTableView>) parent.lookup(TreeTableView.class, new ByID<TreeTableView>(TreeTableNewApp.TESTED_TREETABLEVIEW_ID)).wrap(); 153 } 154 } 155 156 protected void getControlOverTreeItem(String treeItemName) { 157 setText(findTextField(GET_CONTROL_OVER_TREEITEM_TEXTFIELD_ID), treeItemName); 158 clickButtonForTestPurpose(GET_CONTROL_OVER_TREEITEM_BUTTON_ID); 159 } 160 161 /** 162 * Set size if tested control using bidirectional bindings. 163 */ 164 protected void setSize(double width, double height) throws InterruptedException { 165 setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.prefHeight, height); 166 setPropertyBySlider(SettingType.BIDIRECTIONAL, Properties.prefWidth, width); 167 } 168 169 protected void doIntermediateStateCheck() { 170 arrowsChecker(); 171 } 172 173 protected void scrollTo(final int inXCoord, final int inYCoord) { 174 TreeViewCommonFunctionality.scrollTo(testedControl, inXCoord, inYCoord); 175 } 176 177 protected void switchOnMultiple() { 178 setPropertyByChoiceBox(SettingType.BIDIRECTIONAL, SelectionMode.MULTIPLE, Properties.selectionMode); 179 } 180 181 protected void clickOnFirstCell() { 182 TreeViewCommonFunctionality.clickOnFirstCell(testedControl); 183 } 184 185 protected void keyboardCheck(Keyboard.KeyboardButtons btn, Keyboard.KeyboardModifiers... modifier) { 186 if (btn == Keyboard.KeyboardButtons.PAGE_DOWN || btn == Keyboard.KeyboardButtons.PAGE_UP) { 187 selectionHelper.setVisibleRange(TreeViewCommonFunctionality.getVisibleRange(testedControl)); 188 } 189 testedControl.keyboard().pushKey(btn, modifier); 190 selectionHelper.push(btn, modifier); 191 checkSelection(); 192 } 193 194 /** 195 * Be extremely careful, changing this function, don't change amount of 196 * content. 197 */ 198 protected void adjustControl() { 199 DATA_ITEMS_NUM = 21; 200 if (!isTreeTests) { 201 switchToPropertiesTab(TREE_TABLE_VIEW_TAB_NAME); 202 } 203 TreeViewCommonFunctionality.adjustControl(DATA_ITEMS_NUM); 204 } 205 206 protected void editItem(int index) { 207 setText(findTextField(EDIT_TEXT_FIELD_ID), String.valueOf(index)); 208 clickButtonForTestPurpose(EDIT_BUTTON_ID); 209 } 210 211 protected void scrollTo(int position) { 212 setText(findTextField(SCROLL_TO_TEXT_FIELD_ID), position); 213 clickButtonForTestPurpose(SCROLL_TO_BUTTON_ID); 214 try {//"Animation" time. 215 Thread.sleep(500); 216 } catch (InterruptedException ex) { 217 Logger.getLogger(TestBase.class.getName()).log(Level.SEVERE, null, ex); 218 } 219 } 220 221 /** 222 * @return wrapper over required data item which can be used for mouse 223 * actions 224 */ 225 protected Wrap<Text> getCellWrap(final Integer item) { 226 final String content = new GetAction<String>() { 227 @Override 228 public void run(Object... os) throws Exception { 229 if (isTreeTests) { 230 setResult(((TreeView) testedControl.getControl()).getTreeItem(item).getValue().toString()); 231 } else { 232 setResult(((TreeTableView) testedControl.getControl()).getTreeItem(item).getValue().toString()); 233 } 234 } 235 }.dispatch(Root.ROOT.getEnvironment()); 236 237 return getCellWrap(content); 238 } 239 240 protected Wrap<Text> getCellWrap(String item) { 241 return TreeViewCommonFunctionality.getCellWrap(testedControl, item); 242 } 243 244 protected void checkLeafness(String itemName, boolean leaf) { 245 intermediateStateCheck(); 246 switchToPropertiesTab(itemName); 247 checkTextFieldText(Properties.leaf, leaf ? "true" : "false"); 248 } 249 250 private void resetSceneHard() { 251 clickButtonForTestPurpose(HARD_RESET_BUTTON_ID); 252 // initWrappers(); 253 } 254 255 private void resetSceneSoft() { 256 clickButtonForTestPurpose(SOFT_RESET_BUTTON_ID); 257 // initWrappers(); 258 } 259 260 protected void checkSiblings(String expectedPreviousSibling, String expectedNextSibling) { 261 clickButtonForTestPurpose(GET_NEXT_SIBLING_TREEITEM_BUTTON_ID); 262 checkText(GET_NEXT_SIBLING_TREEITEM_TEXTFIELD_ID, expectedNextSibling); 263 clickButtonForTestPurpose(GET_PREVIOUS_SIBLING_TREEITEM_BUTTON_ID); 264 checkText(GET_PREVIOUS_SIBLING_TREEITEM_TEXTFIELD_ID, expectedPreviousSibling); 265 } 266 267 protected void checkParent(final String expectedParentValue) { 268 new Waiter(new Timeout("s", 20000)).ensureState(new State() { 269 public Object reached() { 270 String text = findTextField("PARENT" + LISTENER_SUFFIX).getControl().getText(); 271 if (text.equals("null")) { 272 if ((expectedParentValue == null) || expectedParentValue.equals("null")) { 273 return true; 274 } else { 275 return null; 276 } 277 } else { 278 if (text.substring(text.indexOf("value:") + "value:".length(), text.indexOf("]")).trim().equals(expectedParentValue)) { 279 return true; 280 } else { 281 return null; 282 } 283 } 284 } 285 }); 286 } 287 288 protected void checkExpandedCounter(String itemName, int expectedCounterValue) { 289 switchToPropertiesTab(itemName); 290 intermediateStateCheck(); 291 checkCounterValue(BRANCH_EXPANDED_EVENT_COUNTER, expectedCounterValue); 292 } 293 294 protected void checkCollapsedCounter(String itemName, int expectedCounterValue) { 295 switchToPropertiesTab(itemName); 296 intermediateStateCheck(); 297 checkCounterValue(BRANCH_COLLAPSED_EVENT_COUNTER, expectedCounterValue); 298 } 299 300 /* 301 * It is supposed, that there is a unique TreeItem in the tested treeView, 302 * with written itemName. 303 */ 304 protected void removeItem(String itemName) { 305 setText(findTextField(REMOVE_ITEM_TEXT_FIELD_ID), itemName); 306 clickButtonForTestPurpose(REMOVE_ITEM_BUTTON_ID); 307 } 308 309 protected HashSet<Point> getSelected() { 310 return TreeViewCommonFunctionality.getSelected(testedControl); 311 } 312 313 protected Point getSelectedItem() { 314 return TreeViewCommonFunctionality.getSelectedItem(testedControl); 315 } 316 317 protected void checkSelection() { 318 TreeViewCommonFunctionality.checkSelection(testedControl, selectionHelper, DATA_ITEMS_NUM); 319 } 320 321 protected void checkScrollingState(final double scrollValue, boolean beginVisible, boolean endVisible, int size) { 322 testedControl.waitState(new State() { 323 public Object reached() { 324 Wrap<? extends ScrollBar> sb = findScrollBar((Parent<Node>)testedControl.as(Parent.class, Node.class), Orientation.VERTICAL, true); 325 if (Math.abs(sb.getControl().getValue() - scrollValue) < 0.01) { 326 return true; 327 } else { 328 return null; 329 } 330 } 331 }); 332 333 if (beginVisible) { 334 assertTrue(isCellShown(0)); 335 } 336 if (endVisible) { 337 assertTrue(isCellShown(size - 1)); 338 } 339 } 340 341 /** 342 * This function will find all arrows, and check, that their orientation 343 * corresponds to the expanded/collapsed value of TreeItem 344 */ 345 protected void arrowsChecker() { 346 final List<Throwable> lastThrown = new ArrayList<Throwable>(); 347 try { 348 testedControl.waitState(new State<Boolean>() { 349 public Boolean reached() { 350 try { 351 final Map<String, TreeItem> treeItemsStringRepresentation = new GetAction<Map<String, TreeItem>>() { 352 @Override 353 public void run(Object... os) throws Exception { 354 Map<String, TreeItem> treeItemsToString = new HashMap<String, TreeItem>(); 355 try { 356 final List<TreeItem> allTreeItems = new ArrayList<TreeItem>(); 357 TreeItem root; 358 if (testedControl.getControl() instanceof TreeView) { 359 root = ((TreeView) testedControl.getControl()).getRoot(); 360 } else { 361 root = ((TreeTableView) testedControl.getControl()).getRoot(); 362 } 363 recursiveActionMaker(root, new ActionMaker<TreeItem>() { 364 public void act(TreeItem argument) { 365 allTreeItems.add(argument); 366 } 367 }); 368 369 for (TreeItem item : allTreeItems) { 370 treeItemsToString.put(item.getValue().toString(), item); 371 } 372 } catch (Exception ex) { 373 System.err.println(ex.getMessage()); 374 ex.printStackTrace(System.err); 375 376 } 377 378 setResult(treeItemsToString); 379 } 380 }.dispatch(Root.ROOT.getEnvironment()); 381 382 final Lookup<Text> allTextNodes = testedControl.as(Parent.class, Node.class).lookup(Text.class); 383 final int nodesCount = allTextNodes.size(); 384 final Map<String, Boolean> textOnExpandedMatching = new GetAction<Map<String, Boolean>>() { 385 @Override 386 public void run(Object... os) throws Exception { 387 Map<String, Boolean> toReturn = new HashMap<String, Boolean>(); 388 try { 389 for (int i = 0; i < nodesCount; i++) { 390 TreeItem correspondingItem = treeItemsStringRepresentation.get(allTextNodes.get(i).getText()); 391 if (correspondingItem == null || correspondingItem.getChildren().size() == 0) { 392 toReturn.put(allTextNodes.get(i).getText(), null); 393 } else { 394 toReturn.put(allTextNodes.get(i).getText(), correspondingItem.isExpanded()); 395 } 396 } 397 } catch (Exception ex) { 398 System.err.println(ex.getMessage()); 399 ex.printStackTrace(System.err); 400 } 401 setResult(toReturn); 402 } 403 }.dispatch(Root.ROOT.getEnvironment()); 404 405 Lookup<TreeCell> allVisibleCells = testedControl.as(Parent.class, Node.class).lookup(TreeCell.class); 406 final int cellsCount = allVisibleCells.size(); 407 for (int i = 0; i < cellsCount; i++) { 408 final Lookup lookup = allVisibleCells.wrap(i).as(Parent.class, Node.class).lookup(Text.class); 409 Text text = null; 410 if (lookup.size() > 1) { 411 for (int j = 0; j < lookup.size(); j++) { 412 if ("This is custom node".equals(((Text) lookup.get(j)).getText())) continue; 413 text = (Text) lookup.get(j); 414 } 415 } else { 416 text = (Text) lookup.get(); 417 } 418 Boolean expectedExpandedState = textOnExpandedMatching.get(text.getText()); 419 420 Lookup<StackPane> foundStackPanes = allVisibleCells.wrap(i).as(Parent.class, Node.class).lookup(StackPane.class, new ByStyleClass("arrow")); 421 final int foundStackPanesCount = foundStackPanes.size(); 422 423 Boolean foundArrowExpandedState; 424 if (foundStackPanesCount == 0) { 425 foundArrowExpandedState = null; 426 } else { 427 if (foundStackPanesCount > 1) { 428 throw new IllegalStateException("There are too many stack panes with the same style class under the same TreeCell."); 429 } else { 430 //Be careful: this could become different. 431 //Also, if it fails, this means, that there is an arrow with strange size. 432 //it needs evaluation. 433 Assert.assertEquals("For " + text.getText(), foundStackPanes.get().getBoundsInLocal().getWidth(), 7.0, 2.01); 434 Assert.assertEquals("For " + text.getText(), foundStackPanes.get().getBoundsInLocal().getHeight(), 7.0, 2.01); 435 foundArrowExpandedState = foundStackPanes.get().getRotate() == 90 ? Boolean.TRUE : Boolean.FALSE; 436 } 437 } 438 439 Assert.assertEquals("For " + text.getText(), expectedExpandedState, foundArrowExpandedState); 440 } 441 } catch (Throwable ex) { 442 lastThrown.add(ex); 443 return null; 444 } 445 return Boolean.TRUE; 446 } 447 }); 448 } catch (Throwable ex) { 449 //We couldn't reach the state, when all arrows are correctly shown. 450 for (Throwable thrown : lastThrown) { 451 thrown.printStackTrace(System.err); 452 } 453 throw new IllegalStateException("Could reach the state of arrows correctness", ex); 454 } 455 } 456 457 private void recursiveActionMaker(TreeItem rootItem, ActionMaker<TreeItem> actionForThatItem) { 458 if (rootItem != null) { 459 actionForThatItem.act(rootItem); 460 for (TreeItem item : (ObservableList<TreeItem>) rootItem.getChildren()) { 461 recursiveActionMaker(item, actionForThatItem); 462 } 463 } 464 } 465 466 protected boolean isCellShown(final int item) { 467 Wrap<Text> cellWrap = getCellWrap(item); 468 org.jemmy.Rectangle cellRect = cellWrap.getScreenBounds(); 469 org.jemmy.Rectangle control = testedControl.getScreenBounds(); 470 return control.contains(cellRect); 471 } 472 473 /** 474 * This function checks some thing, which should be actual during the whole 475 * time of control's functioning. 476 */ 477 protected void intermediateStateCheck() { 478 arrowsChecker(); 479 } 480 481 /** 482 * This function modify standart selection helper's state, according to the 483 * expansion or collapsing of some TreeItem. 484 * 485 * Rules: 486 * 487 * 1) if focus|anchor was into collapsed branch, focus|anchor is moved to 488 * the according branch's root (treeItem). 489 * 490 * 2) if some selection was done into collapsed branch, this selection will 491 * be lost. 492 * 493 * 3) no changes happen out of the collapsed branch. 494 * 495 * @param treeItemContent string - which represents the treeItem. 496 * @param expanding true - for expanding, false - for collapsing. 497 */ 498 protected void modifySelectionHelper(final String treeItemContent, boolean wasExpanded) { 499 int treeItemRowIndex = new GetAction<Integer>() { 500 @Override 501 public void run(Object... os) throws Exception { 502 int row; 503 final Control control = testedControl.getControl(); 504 if (control instanceof TreeView) { 505 final TreeView treeView = (TreeView) control; 506 row = treeView.getRow(TreeViewNewApp.searchTreeItem(treeView, treeItemContent)); 507 } else { 508 final TreeTableView treeTableView = (TreeTableView) control; 509 row = treeTableView.getRow(TreeTableNewApp.searchTreeItem(treeTableView, treeItemContent)); 510 } 511 setResult(row); 512 } 513 }.dispatch(Root.ROOT.getEnvironment()); 514 515 int subtreeSize = subtreeVisibleSize(treeItemContent); 516 517 if (selectionHelper.ctrlA) { 518 //Some nodes inside will be added, so we need to convert ctrlA 519 //into selection set with all items, and after that work with 520 //the set. 521 selectionHelper.selectedSet.clear(); 522 selectionHelper.ctrlA = false; 523 524 for (int i = 0; i < selectionHelper.rows; i++) { 525 selectionHelper.selectedSet.add(new Point(-1, i)); 526 } 527 } 528 529 if (wasExpanded) { 530 for (Point point : selectionHelper.selectedSet) { 531 if (point.y > treeItemRowIndex) { 532 point.y += subtreeSize; 533 } 534 } 535 536 if (selectionHelper.focus.y > treeItemRowIndex) { 537 selectionHelper.focus.y += subtreeSize; 538 } 539 540 if (selectionHelper.anchor.y > treeItemRowIndex) { 541 selectionHelper.anchor.y += subtreeSize; 542 } 543 //Because now we have more cells then there exist 544 //we need to remove those which are redundant. 545 Iterator<Point> it = selectionHelper.selectedSet.iterator(); 546 while (it.hasNext()) { 547 Point pt = it.next(); 548 if (pt.y > selectionHelper.rows - 1) { 549 it.remove(); 550 } 551 } 552 553 } else {//was collapsed 554 Point[] copy = selectionHelper.selectedSet.toArray(new Point[0]); 555 for (Point point : copy) { 556 if (point.y > treeItemRowIndex) { 557 if (point.y > treeItemRowIndex + subtreeSize) { 558 point.y -= subtreeSize; 559 } else { 560 //All other points in the selection will be lost, except 561 //anchor and focus. They jump to the treeItem, and 562 //selection is moved with them 563 removePointFromSet(point.y); 564 if ((selectionHelper.anchor.y == point.y) || (selectionHelper.focus.y == point.y)) { 565 removePointFromSet(treeItemRowIndex); 566 selectionHelper.selectedSet.add(new Point(-1, treeItemRowIndex)); 567 } 568 } 569 } 570 } 571 572 if (selectionHelper.focus.y > treeItemRowIndex) { 573 if (selectionHelper.focus.y > treeItemRowIndex + subtreeSize) { 574 selectionHelper.focus.y -= subtreeSize; 575 } else { 576 selectionHelper.focus.y = treeItemRowIndex; 577 } 578 } 579 580 if (selectionHelper.anchor.y > treeItemRowIndex) { 581 if (selectionHelper.anchor.y > treeItemRowIndex + subtreeSize) { 582 selectionHelper.anchor.y -= subtreeSize; 583 } else { 584 selectionHelper.anchor.y = treeItemRowIndex; 585 } 586 } 587 } 588 589 //Invalidate: 590 selectionHelper.bottomVisible = -1; 591 selectionHelper.topVisible = -1; 592 } 593 594 private void removePointFromSet(int y) { 595 Point[] copy = selectionHelper.selectedSet.toArray(new Point[0]); 596 for (Point point : copy) { 597 if (point.y == y) { 598 selectionHelper.selectedSet.remove(point); 599 } 600 } 601 } 602 603 /** 604 * Founds the size of subtree, which is found under the specified data item, 605 * not depending on the expanded or collapsed state of specified treeItem. 606 * 607 * @param treeItemName 608 * @return - size 609 */ 610 private int subtreeVisibleSize(final String treeItemName) { 611 return new GetAction<Integer>() { 612 @Override 613 public void run(Object... os) throws Exception { 614 TreeItem item; 615 if (testedControl.getControl() instanceof TreeView) { 616 item = TreeViewNewApp.searchTreeItem((TreeView) testedControl.getControl(), treeItemName); 617 } else { 618 item = TreeTableNewApp.searchTreeItem((TreeTableView) testedControl.getControl(), treeItemName); 619 } 620 setResult(countSubItemSize(item)); 621 } 622 }.dispatch(Root.ROOT.getEnvironment()); 623 } 624 625 private static int countSubItemSize(TreeItem item) { 626 if (item == null) { 627 throw new NullPointerException("Null pointer."); 628 } 629 630 int counter = item.getChildren().size(); 631 632 for (TreeItem i : (ObservableList<TreeItem>) item.getChildren()) { 633 if (i.isExpanded()) { 634 counter += countSubItemSize(i); 635 } 636 } 637 638 return counter; 639 } 640 641 private interface ActionMaker<ArgumentType> { 642 643 public void act(ArgumentType argument); 644 } 645 646 protected Wrap<? extends IndexedCell> getIndexedCellWrap(final String text) { 647 648 final String styleClass = isTreeTests ? "tree-cell" : "tree-table-cell"; 649 650 Lookup<IndexedCell> lookup = testedControl.as(Parent.class, IndexedCell.class) 651 .lookup(IndexedCell.class, new LookupCriteria<IndexedCell>() { 652 public boolean check(IndexedCell cell) { 653 return text.equals(cell.getText()) && cell.getStyleClass().contains(styleClass); 654 } 655 }); 656 657 final int size = lookup.size(); 658 659 testedControl.waitState(new State<Boolean>() { 660 public Boolean reached() { 661 if (1 == size) { 662 return Boolean.TRUE; 663 } else { 664 return null; 665 } 666 } 667 }); 668 669 return lookup.wrap(); 670 } 671 672 protected Wrap getDisclosureNode(final Wrap<? extends IndexedCell> cellWrap) { 673 674 final IndexedCell cell = cellWrap.getControl(); 675 final String arrowStyle = "tree-disclosure-node"; 676 677 if (TreeCell.class.isAssignableFrom(cell.getClass())) { 678 return cellWrap.as(Parent.class, Node.class).lookup(new ByStyleClass(arrowStyle)).wrap(); 679 } else if (TreeTableCell.class.isAssignableFrom(cell.getClass())) { 680 final NodeWrap<IndexedCell> nodeWrap = new NodeWrap(cellWrap.getEnvironment(), cellWrap.getControl().getParent()); 681 Parent cellAsParent = nodeWrap.as(Parent.class, IndexedCell.class); 682 return cellAsParent.lookup(new ByStyleClass(arrowStyle)).wrap(); 683 } else { 684 throw new IllegalStateException(); 685 } 686 } 687 688 protected Wrap<Node> levelWrapUp(Wrap<? extends Node> wrap) { 689 return (Wrap<Node>) new NodeWrap(wrap.getEnvironment(), wrap.getControl().getParent()); 690 } 691 692 EventHandler getOnEditStart(final int columnIndex) { 693 return new GetAction<EventHandler>() { 694 @Override 695 public void run(Object... os) throws Exception { 696 if (isTreeTests) { 697 setResult(((TreeView) (testedControl.getControl())).getOnEditStart()); 698 } else { 699 TreeTableView treeTable = (TreeTableView) (testedControl.getControl()); 700 setResult(((TreeTableColumn) treeTable.getColumns().get(columnIndex)).getOnEditStart()); 701 } 702 } 703 }.dispatch(testedControl.getEnvironment()); 704 } 705 706 EventHandler getOnEditCancel(final int columnIndex) { 707 return new GetAction<EventHandler>() { 708 @Override 709 public void run(Object... os) throws Exception { 710 if (isTreeTests) { 711 setResult(((TreeView) (testedControl.getControl())).getOnEditCancel()); 712 } else { 713 TreeTableView treeTable = (TreeTableView) (testedControl.getControl()); 714 setResult(((TreeTableColumn) treeTable.getColumns().get(columnIndex)).getOnEditCancel()); 715 } 716 } 717 }.dispatch(testedControl.getEnvironment()); 718 } 719 720 EventHandler getOnEditCommit(final int columnIndex) { 721 return new GetAction<EventHandler>() { 722 @Override 723 public void run(Object... os) throws Exception { 724 if (isTreeTests) { 725 setResult(((TreeView) (testedControl.getControl())).getOnEditCommit()); 726 } else { 727 TreeTableView treeTable = (TreeTableView) (testedControl.getControl()); 728 setResult(((TreeTableColumn) treeTable.getColumns().get(columnIndex)).getOnEditCommit()); 729 } 730 } 731 }.dispatch(testedControl.getEnvironment()); 732 } 733 734 void setOnEditStart(EventHandler handler, final int columnIndex) { 735 new GetAction<Void>() { 736 @Override 737 public void run(Object... args) throws Exception { 738 if (isTreeTests) { 739 ((TreeView) (testedControl.getControl())).setOnEditStart((EventHandler) args[0]); 740 } else { 741 TreeTableView treeTable = (TreeTableView) (testedControl.getControl()); 742 ((TreeTableColumn) treeTable.getColumns().get(columnIndex)).setOnEditStart((EventHandler) args[0]); 743 } 744 } 745 }.dispatch(testedControl.getEnvironment(), handler); 746 } 747 748 void setOnEditCancel(EventHandler handler, final int columnIndex) { 749 new GetAction<Void>() { 750 @Override 751 public void run(Object... args) throws Exception { 752 if (isTreeTests) { 753 ((TreeView) (testedControl.getControl())).setOnEditCancel((EventHandler) args[0]); 754 } else { 755 TreeTableView treeTable = (TreeTableView) (testedControl.getControl()); 756 ((TreeTableColumn) treeTable.getColumns().get(columnIndex)).setOnEditCancel((EventHandler) args[0]); 757 } 758 } 759 }.dispatch(testedControl.getEnvironment(), handler); 760 } 761 762 void setOnEditCommit(EventHandler handler, final int columnIndex) { 763 new GetAction<Void>() { 764 @Override 765 public void run(Object... args) throws Exception { 766 if (isTreeTests) { 767 ((TreeView) (testedControl.getControl())).setOnEditCommit((EventHandler) args[0]); 768 } else { 769 TreeTableView treeTable = (TreeTableView) (testedControl.getControl()); 770 ((TreeTableColumn) treeTable.getColumns().get(columnIndex)).setOnEditCommit((EventHandler) args[0]); 771 } 772 } 773 }.dispatch(testedControl.getEnvironment(), handler); 774 } 775 776 }