1 /*
   2  * Copyright (c) 2011, 2017, 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 
  26 package test.javafx.scene.control;
  27 
  28 import com.sun.javafx.scene.control.behavior.ListCellBehavior;
  29 import javafx.collections.FXCollections;
  30 import javafx.collections.ListChangeListener;
  31 import javafx.collections.ObservableList;
  32 import javafx.scene.Group;
  33 import javafx.scene.control.Button;
  34 import javafx.scene.input.KeyCode;
  35 import java.util.List;
  36 import com.sun.javafx.PlatformUtil;
  37 import com.sun.javafx.util.Utils;
  38 import test.com.sun.javafx.scene.control.behavior.ListViewAnchorRetriever;
  39 import test.com.sun.javafx.scene.control.infrastructure.ControlTestUtils;
  40 import test.com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
  41 import test.com.sun.javafx.scene.control.infrastructure.KeyModifier;
  42 import test.com.sun.javafx.scene.control.infrastructure.StageLoader;
  43 import test.com.sun.javafx.scene.control.infrastructure.VirtualFlowTestUtils;
  44 import com.sun.javafx.tk.Toolkit;
  45 import javafx.scene.control.FocusModel;
  46 import javafx.scene.control.FocusModelShim;
  47 import javafx.scene.control.IndexedCell;
  48 import javafx.scene.control.ListView;
  49 import javafx.scene.control.MultipleSelectionModel;
  50 import javafx.scene.control.SelectionMode;
  51 import javafx.scene.layout.HBox;
  52 import org.junit.After;
  53 import org.junit.Before;
  54 import org.junit.Ignore;
  55 import org.junit.Test;
  56 import static org.junit.Assert.assertEquals;
  57 import static org.junit.Assert.assertFalse;
  58 import static org.junit.Assert.assertNotSame;
  59 import static org.junit.Assert.assertNull;
  60 import static org.junit.Assert.assertTrue;
  61 import static org.junit.Assert.fail;
  62 
  63 public class ListViewKeyInputTest {
  64     private ListView<String> listView;
  65     private MultipleSelectionModel<String> sm;
  66     private FocusModel<String> fm;
  67 
  68     private KeyEventFirer keyboard;
  69 
  70     private StageLoader stageLoader;
  71 
  72     @Before public void setup() {
  73         listView = new ListView<>();
  74         sm = listView.getSelectionModel();
  75         fm = listView.getFocusModel();
  76 
  77         sm.setSelectionMode(SelectionMode.MULTIPLE);
  78 
  79         keyboard = new KeyEventFirer(listView);
  80         stageLoader = new StageLoader(listView);
  81 
  82         listView.getItems().setAll("1", "2", "3", "4", "5", "6", "7", "8", "9", "10");
  83     }
  84 
  85     @After public void tearDown() {
  86         listView.getSkin().dispose();
  87         stageLoader.dispose();
  88     }
  89 
  90 
  91     /***************************************************************************
  92      * Util methods
  93      **************************************************************************/
  94 
  95     private String debug() {
  96         StringBuilder sb = new StringBuilder("Selected Indices: [");
  97 
  98         List<Integer> indices = sm.getSelectedIndices();
  99         for (Integer index : indices) {
 100             sb.append(index);
 101             sb.append(", ");
 102         }
 103 
 104         sb.append("] \nFocus: " + fm.getFocusedIndex());
 105         sb.append(" \nAnchor: " + getAnchor());
 106         return sb.toString();
 107     }
 108 
 109     // Returns true if ALL indices are selected
 110     private boolean isSelected(int... indices) {
 111         for (int index : indices) {
 112             if (! sm.isSelected(index)) {
 113                 System.out.println("Index " + index + " is not selected, but it is expected to be");
 114                 return false;
 115             }
 116         }
 117         return true;
 118     }
 119 
 120     // Returns true if ALL indices are NOT selected
 121     private boolean isNotSelected(int... indices) {
 122         for (int index : indices) {
 123             if (sm.isSelected(index)) {
 124                 System.out.println("Index " + index + " is selected, but it is not expected to be");
 125                 return false;
 126             }
 127         }
 128         return true;
 129     }
 130 
 131     private int getAnchor() {
 132         return ListViewAnchorRetriever.getAnchor(listView);
 133     }
 134 
 135     private boolean isAnchor(int index) {
 136         return getAnchor() == index;
 137     }
 138 
 139 
 140     /***************************************************************************
 141      * General tests
 142      **************************************************************************/
 143 
 144     @Test public void testInitialState() {
 145         assertTrue(sm.getSelectedIndices().isEmpty());
 146         assertTrue(sm.getSelectedItems().isEmpty());
 147     }
 148 
 149     /***************************************************************************
 150      * Tests for row-based single selection
 151      **************************************************************************/
 152 
 153     @Test public void testDownArrowChangesSelection() {
 154         sm.clearAndSelect(0);
 155         keyboard.doDownArrowPress();
 156         assertFalse(sm.isSelected(0));
 157         assertTrue(sm.isSelected(1));
 158     }
 159 
 160     @Test public void testDownArrowDoesNotChangeSelectionWhenAtLastIndex() {
 161         int endIndex = listView.getItems().size() - 1;
 162         sm.clearAndSelect(endIndex);
 163         assertTrue(sm.isSelected(endIndex));
 164         keyboard.doDownArrowPress();
 165         assertTrue(sm.isSelected(endIndex));
 166     }
 167 
 168     @Test public void testUpArrowDoesNotChangeSelectionWhenAt0Index() {
 169         sm.clearAndSelect(0);
 170         keyboard.doUpArrowPress();
 171         assertTrue(sm.isSelected(0));
 172         assertEquals(1, sm.getSelectedIndices().size());
 173         assertEquals(1, sm.getSelectedItems().size());
 174     }
 175 
 176     @Test public void testUpArrowChangesSelection() {
 177         sm.clearAndSelect(1);
 178         keyboard.doUpArrowPress();
 179         assertFalse(sm.isSelected(1));
 180         assertTrue(sm.isSelected(0));
 181     }
 182 
 183     @Test public void testLeftArrowDoesNotChangeState() {
 184         keyboard.doLeftArrowPress();
 185         testInitialState();
 186     }
 187 
 188     @Test public void testRightArrowDoesNotChangeState() {
 189         keyboard.doRightArrowPress();
 190         testInitialState();
 191     }
 192 
 193     // test 19
 194     @Test public void testCtrlDownMovesFocusButLeavesSelectionAlone() {
 195         sm.clearAndSelect(0);
 196         assertTrue(fm.isFocused(0));
 197         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 198         assertTrue(fm.isFocused(1));
 199         assertTrue(sm.isSelected(0));
 200         assertFalse(sm.isSelected(1));
 201     }
 202 
 203     // test 20
 204     @Test public void testCtrlUpDoesNotMoveFocus() {
 205         sm.clearAndSelect(0);
 206         assertTrue(fm.isFocused(0));
 207         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 208         assertTrue(fm.isFocused(0));
 209         assertTrue(sm.isSelected(0));
 210     }
 211 
 212     // test 21
 213     @Test public void testCtrlLeftDoesNotMoveFocus() {
 214         sm.clearAndSelect(0);
 215         assertTrue(fm.isFocused(0));
 216         keyboard.doLeftArrowPress(KeyModifier.getShortcutKey());
 217         assertTrue(fm.isFocused(0));
 218         assertTrue(sm.isSelected(0));
 219     }
 220 
 221     // test 22
 222     @Test public void testCtrlRightDoesNotMoveFocus() {
 223         sm.clearAndSelect(0);
 224         assertTrue(fm.isFocused(0));
 225         keyboard.doRightArrowPress(KeyModifier.getShortcutKey());
 226         assertTrue(debug(), fm.isFocused(0));
 227         assertTrue(sm.isSelected(0));
 228     }
 229 
 230     // test 23
 231     @Test public void testCtrlUpMovesFocus() {
 232         sm.clearAndSelect(1);
 233         assertTrue(fm.isFocused(1));
 234         assertTrue(sm.isSelected(1));
 235         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 236         assertTrue(fm.isFocused(0));
 237 
 238     }
 239 
 240     // test 24
 241     @Test public void testCtrlDownDoesNotMoveFocusWhenAtLastIndex() {
 242         int endIndex = listView.getItems().size() - 1;
 243         sm.clearAndSelect(endIndex);
 244         assertTrue(fm.isFocused(endIndex));
 245         assertTrue(sm.isSelected(endIndex));
 246         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 247         assertTrue(fm.isFocused(endIndex));
 248         assertTrue(sm.isSelected(endIndex));
 249     }
 250 
 251     // test 25
 252     @Test public void testCtrlDownArrowWithSpaceChangesAnchor() {
 253         sm.clearAndSelect(0);
 254         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 255         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 256         keyboard.doKeyPress(KeyCode.SPACE,
 257                 KeyModifier.getShortcutKey(),
 258                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 2
 259 
 260         assertTrue(isSelected(0, 2));
 261         assertTrue(isNotSelected(1));
 262         assertTrue(isAnchor(2));
 263     }
 264 
 265     // test 26
 266     @Test public void testCtrlUpArrowWithSpaceChangesAnchor() {
 267         sm.clearAndSelect(2);
 268         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 269         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 270         keyboard.doKeyPress(KeyCode.SPACE,
 271                 KeyModifier.getShortcutKey(),
 272                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 0
 273 
 274         assertTrue(isSelected(0, 2));
 275         assertTrue(isNotSelected(1));
 276         assertTrue(isAnchor(0));
 277     }
 278 
 279     // test 44
 280     @Test public void testHomeKey() {
 281         sm.clearAndSelect(3);
 282         keyboard.doKeyPress(KeyCode.HOME);
 283         assertTrue(debug(), isSelected(0));
 284         assertTrue(isNotSelected(1,2,3));
 285     }
 286 
 287     // test 45
 288     @Test public void testEndKey() {
 289         sm.clearAndSelect(3);
 290         keyboard.doKeyPress(KeyCode.END);
 291         assertTrue(isSelected(listView.getItems().size() - 1));
 292         assertTrue(isNotSelected(1,2,3));
 293     }
 294 
 295     // test 53
 296     @Test public void testCtrlHome() {
 297         sm.clearAndSelect(5);
 298         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.getShortcutKey());
 299         assertTrue(isSelected(5));
 300         assertTrue(fm.isFocused(0));
 301     }
 302 
 303     // test 54
 304     @Test public void testCtrlEnd() {
 305         sm.clearAndSelect(5);
 306         keyboard.doKeyPress(KeyCode.END, KeyModifier.getShortcutKey());
 307         assertTrue(isSelected(5));
 308         assertTrue(fm.isFocused(listView.getItems().size() - 1));
 309     }
 310 
 311     // test 68
 312     @Test public void testCtrlSpaceToClearSelection() {
 313         sm.clearAndSelect(5);
 314         assertTrue(isSelected(5));
 315         assertTrue(fm.isFocused(5));
 316 
 317         keyboard.doKeyPress(KeyCode.SPACE,
 318                 KeyModifier.getShortcutKey(),
 319                 (Utils.isMac() ? KeyModifier.CTRL : null));
 320 
 321         assertTrue(isNotSelected(5));
 322         assertTrue(debug(), fm.isFocused(5));
 323         assertTrue(isAnchor(5));
 324     }
 325 
 326 
 327 
 328     /***************************************************************************
 329      * Tests for row-based multiple selection
 330      **************************************************************************/
 331 
 332     @Test public void testShiftDownArrowIncreasesSelection() {
 333         sm.clearAndSelect(0);
 334         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 335         assertTrue(sm.isSelected(0));
 336         assertTrue(sm.isSelected(1));
 337     }
 338 
 339     @Test public void testShiftDownArrowDoesNotChangeSelectionWhenAtLastIndex() {
 340         int endIndex = listView.getItems().size() - 1;
 341         sm.clearAndSelect(endIndex);
 342         assertTrue(sm.isSelected(endIndex));
 343         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 344         assertTrue(sm.isSelected(endIndex));
 345     }
 346 
 347     @Test public void testShiftUpArrowIncreasesSelection() {
 348         sm.clearAndSelect(1);
 349         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 350         assertTrue(sm.isSelected(0));
 351         assertTrue(sm.isSelected(1));
 352     }
 353 
 354     @Test public void testShiftUpArrowWhenAt0Index() {
 355         sm.clearAndSelect(0);
 356         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 357         assertTrue(sm.isSelected(0));
 358     }
 359 
 360     @Test public void testShiftLeftArrowWhenAt0Index() {
 361         sm.clearAndSelect(0);
 362         keyboard.doLeftArrowPress(KeyModifier.SHIFT);
 363         assertTrue(sm.isSelected(0));
 364         assertFalse(sm.isSelected(1));
 365     }
 366 
 367     @Test public void testShiftRightArrowWhenAt0Index() {
 368         sm.clearAndSelect(0);
 369         keyboard.doRightArrowPress(KeyModifier.SHIFT);
 370         assertTrue(sm.isSelected(0));
 371         assertFalse(sm.isSelected(1));
 372     }
 373 
 374     @Test public void testShiftDownTwiceThenShiftUp() {
 375         sm.clearAndSelect(0);
 376         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 377         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 378         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 379         assertTrue(debug(), sm.isSelected(0));
 380         assertTrue(sm.isSelected(1));
 381         assertFalse(sm.isSelected(2));
 382     }
 383 
 384     @Test public void testShiftUpTwiceThenShiftDownFrom0Index() {
 385         sm.clearAndSelect(0);
 386         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 387         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 388         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 389         assertTrue(sm.isSelected(0));
 390         assertTrue(sm.isSelected(1));
 391         assertFalse(sm.isSelected(2));
 392     }
 393 
 394     @Test public void testShiftLeftTwiceThenShiftRight() {
 395         sm.clearAndSelect(0);
 396         keyboard.doLeftArrowPress(KeyModifier.SHIFT);
 397         keyboard.doLeftArrowPress(KeyModifier.SHIFT);
 398         keyboard.doRightArrowPress(KeyModifier.SHIFT);
 399         assertTrue(sm.isSelected(0));
 400         assertFalse(sm.isSelected(1));
 401         assertFalse(sm.isSelected(2));
 402     }
 403 
 404     @Test public void testShiftRightTwiceThenShiftLeft() {
 405         sm.clearAndSelect(0);
 406         keyboard.doRightArrowPress(KeyModifier.SHIFT);
 407         keyboard.doRightArrowPress(KeyModifier.SHIFT);
 408         keyboard.doLeftArrowPress(KeyModifier.SHIFT);
 409         assertTrue(sm.isSelected(0));
 410         assertFalse(sm.isSelected(1));
 411         assertFalse(sm.isSelected(2));
 412     }
 413 
 414     @Test public void testShiftUpTwiceThenShiftDown() {
 415         sm.clearAndSelect(2);
 416         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 417         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 418         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 419         assertFalse(sm.isSelected(0));
 420         assertTrue(sm.isSelected(1));
 421         assertTrue(sm.isSelected(2));
 422         assertFalse(sm.isSelected(3));
 423     }
 424 
 425     // test 18 from Jindra's testcases.rtf file
 426     @Test public void testShiftDownTwiceThenShiftUpWhenAtLastIndex() {
 427         int endIndex = listView.getItems().size() - 1;
 428         sm.clearAndSelect(endIndex);
 429         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 430         keyboard.doDownArrowPress(KeyModifier.SHIFT);
 431         keyboard.doUpArrowPress(KeyModifier.SHIFT);
 432         assertTrue(sm.isSelected(endIndex));
 433         assertTrue(sm.isSelected(endIndex - 1));
 434         assertFalse(sm.isSelected(endIndex - 2));
 435     }
 436 
 437     // test 27
 438     @Test public void testCtrlDownArrowWithSpaceChangesAnchor_extended() {
 439         sm.clearAndSelect(0);
 440         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 441         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 442         keyboard.doKeyPress(KeyCode.SPACE,
 443                 KeyModifier.getShortcutKey(),
 444                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 2
 445 
 446         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 447         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 448         keyboard.doKeyPress(KeyCode.SPACE,
 449                 KeyModifier.getShortcutKey(),
 450                 (Utils.isMac() ? KeyModifier.CTRL : null));  // deselect 0
 451         assertTrue(isSelected(2));
 452         assertTrue(isNotSelected(0, 1));
 453         assertTrue(isAnchor(0));
 454     }
 455 
 456     // test 28
 457     @Test public void testCtrlUpArrowWithSpaceChangesAnchor_extended() {
 458         sm.clearAndSelect(2);
 459         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 460         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 461         keyboard.doKeyPress(KeyCode.SPACE,
 462                 KeyModifier.getShortcutKey(),
 463                 Utils.isMac() ? KeyModifier.CTRL : null);  // select 0
 464 
 465         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 466         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 467         keyboard.doKeyPress(KeyCode.SPACE,
 468                 KeyModifier.getShortcutKey(),
 469                 Utils.isMac() ? KeyModifier.CTRL : null);  // deselect 2
 470         assertTrue(isSelected(0));
 471         assertTrue(isNotSelected(1, 2));
 472         assertTrue(isAnchor(2));
 473     }
 474 
 475     // test 29
 476     @Test public void testCtrlDownArrowWithSpaceChangesAnchor_extended2() {
 477         sm.clearAndSelect(0);
 478         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 479         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 480         keyboard.doKeyPress(KeyCode.SPACE,
 481                 KeyModifier.getShortcutKey(),
 482                 Utils.isMac() ? KeyModifier.CTRL : null);  // select 2
 483 
 484         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 485         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 486         keyboard.doKeyPress(KeyCode.SPACE,
 487                 KeyModifier.getShortcutKey(),
 488                 Utils.isMac() ? KeyModifier.CTRL : null);  // select 4
 489         assertTrue(isSelected(0, 2, 4));
 490         assertTrue(isNotSelected(1, 3, 5));
 491         assertTrue(isAnchor(4));
 492     }
 493 
 494     // test 30
 495     @Test public void testCtrlUpArrowWithSpaceChangesAnchor_extended2() {
 496         sm.clearAndSelect(4);
 497         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 498         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 499         keyboard.doKeyPress(KeyCode.SPACE,
 500                 KeyModifier.getShortcutKey(),
 501                 Utils.isMac() ? KeyModifier.CTRL : null);  // select 2
 502 
 503         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 504         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 505         keyboard.doKeyPress(KeyCode.SPACE,
 506                 KeyModifier.getShortcutKey(),
 507                 Utils.isMac() ? KeyModifier.CTRL : null);  // select 0
 508         assertTrue(isSelected(0, 2, 4));
 509         assertTrue(isNotSelected(1, 3));
 510         assertTrue(isAnchor(0));
 511     }
 512 
 513     // test 31
 514     @Test public void testCtrlDownArrowThenShiftSpaceToSelectRange() {
 515         sm.clearAndSelect(0);
 516         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 517         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 518         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.SHIFT);  // select 0,1,2
 519         assertTrue(isSelected(0, 1, 2));
 520         assertTrue(isNotSelected(3));
 521         assertTrue(isAnchor(0));
 522     }
 523 
 524     // test 32
 525     @Test public void testCtrlUpArrowThenShiftSpaceToSelectRange() {
 526         sm.clearAndSelect(2);
 527         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 528         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 529         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.SHIFT);  // select 0,1,2
 530         assertTrue(isSelected(0, 1, 2));
 531         assertTrue(isNotSelected(3));
 532         assertTrue(debug(), isAnchor(2));
 533     }
 534 
 535     // test 33
 536     @Test public void testCtrlDownArrowThenSpaceToChangeSelection() {
 537         sm.clearAndSelect(0);
 538         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 539         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 540         keyboard.doKeyPress(KeyCode.SPACE,
 541                 KeyModifier.getShortcutKey(),
 542                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 2, keeping 0 selected
 543         assertTrue(isSelected(0, 2));
 544         assertTrue(isNotSelected(1, 3));
 545         assertTrue(isAnchor(2));
 546 
 547         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 548         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 549         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.SHIFT);  // select 2,3,4
 550         assertTrue(isSelected(2, 3, 4));
 551         assertTrue(isNotSelected(0, 1));
 552         assertTrue(isAnchor(2));
 553     }
 554 
 555     // test 34
 556     @Test public void testCtrlUpArrowThenSpaceToChangeSelection() {
 557         sm.clearAndSelect(4);
 558         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 559         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 560         keyboard.doKeyPress(KeyCode.SPACE,
 561                 KeyModifier.getShortcutKey(),
 562                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 2, keeping 4 selected
 563         assertTrue(isSelected(2, 4));
 564         assertTrue(isNotSelected(0, 1, 3));
 565         assertTrue(isAnchor(2));
 566 
 567         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 568         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 569         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.SHIFT);  // select 0,1,2
 570         assertTrue(isSelected(0, 1, 2));
 571         assertTrue(isNotSelected(3, 4));
 572         assertTrue(debug(), isAnchor(2));
 573     }
 574 
 575     // test 35
 576     @Test public void testCtrlDownTwiceThenShiftDown() {
 577         sm.clearAndSelect(0);
 578         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 579         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 580         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.SHIFT);  // select 0,1,2,3
 581         assertTrue(isSelected(0, 1, 2, 3));
 582     }
 583 
 584     // test 36
 585     @Test public void testCtrlUpThriceThenShiftDown() {
 586         sm.clearAndSelect(3);
 587         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 588         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 589         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 590         keyboard.doDownArrowPress(KeyModifier.SHIFT);  // select 1,2,3
 591         assertTrue(debug(), isSelected(1, 2, 3));
 592         assertTrue(isNotSelected(0));
 593     }
 594 
 595     // test 37
 596     @Test public void testCtrlDownThriceThenShiftUp() {
 597         sm.clearAndSelect(0);
 598         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 599         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 600         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 601         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT);  // select 0,1,2
 602         assertTrue(isSelected(0, 1, 2));
 603         assertTrue(isNotSelected(3, 4));
 604     }
 605 
 606     // test 38
 607     @Test public void testCtrlUpTwiceThenShiftUp() {
 608         sm.clearAndSelect(3);
 609         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 610         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 611         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT);  // select 0,1,2,3
 612         assertTrue(isSelected(0, 1, 2, 3));
 613         assertTrue(isNotSelected(4));
 614     }
 615 
 616     // test 39
 617     @Test public void testCtrlDownTwiceThenSpace_extended() {
 618         sm.clearAndSelect(0);
 619         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 620         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 621         keyboard.doKeyPress(KeyCode.SPACE,
 622                 KeyModifier.getShortcutKey(),
 623                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 0,2
 624         assertTrue(isSelected(0, 2));
 625         assertTrue(isNotSelected(1, 3));
 626         assertTrue(isAnchor(2));
 627 
 628         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 629         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 630         keyboard.doDownArrowPress(KeyModifier.SHIFT);   // select 2,3,4,5
 631         assertTrue(isSelected(2, 3, 4, 5));
 632         assertTrue(isNotSelected(0, 1));
 633         assertTrue(isAnchor(2));
 634     }
 635 
 636     // test 40
 637     @Test public void testCtrlUpTwiceThenSpace_extended() {
 638         sm.clearAndSelect(5);
 639         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 640         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 641         keyboard.doKeyPress(KeyCode.SPACE,
 642                 KeyModifier.getShortcutKey(),
 643                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 3,5
 644         assertTrue(isSelected(3,5));
 645         assertTrue(isNotSelected(0,1,2,4));
 646         assertTrue(isAnchor(3));
 647 
 648         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 649         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 650         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 0
 651         keyboard.doDownArrowPress(KeyModifier.SHIFT);   // select 1,2,3
 652         assertTrue(isSelected(1,2,3));
 653         assertTrue(isNotSelected(0,4,5));
 654         assertTrue(isAnchor(3));
 655     }
 656 
 657     // test 41
 658     @Test public void testCtrlDownTwiceThenSpace_extended2() {
 659         sm.clearAndSelect(0);
 660         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 661         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 662         keyboard.doKeyPress(KeyCode.SPACE,
 663                 KeyModifier.getShortcutKey(),
 664                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 0,2
 665         assertTrue(isSelected(0,2));
 666         assertTrue(isNotSelected(1,3,4));
 667         assertTrue(isAnchor(2));
 668 
 669         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 670         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 671         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 5
 672         keyboard.doUpArrowPress(KeyModifier.SHIFT);     // select 2,3,4
 673         assertTrue(isSelected(2,3,4));
 674         assertTrue(isNotSelected(0,1,5));
 675         assertTrue(isAnchor(2));
 676     }
 677 
 678     // test 50
 679     @Test public void testCtrlDownThenShiftHome() {
 680         sm.clearAndSelect(0);
 681         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 682         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 683         keyboard.doKeyPress(KeyCode.SPACE,
 684                 KeyModifier.getShortcutKey(),
 685                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 0,2
 686         assertTrue(isSelected(0,2));
 687         assertTrue(isNotSelected(1,3,4));
 688         assertTrue(isAnchor(2));
 689 
 690         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 691         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 692         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT);
 693         assertTrue(isSelected(0,1,2));
 694         assertTrue(isNotSelected(3,4));
 695         assertTrue(debug(),isAnchor(2));
 696     }
 697 
 698     // test 51
 699     @Test public void testCtrlUpThenShiftEnd() {
 700         sm.clearAndSelect(5);
 701         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 702         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 703         keyboard.doKeyPress(KeyCode.SPACE,
 704                 KeyModifier.getShortcutKey(),
 705                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 3,5
 706         assertTrue(isSelected(3,5));
 707         assertTrue(isNotSelected(1,2,4));
 708         assertTrue(isAnchor(3));
 709 
 710         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 711         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 712         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
 713         assertTrue(isSelected(3,4,5,6,7,8,9));
 714         assertTrue(isNotSelected(0,1,2));
 715         assertTrue(debug(),isAnchor(3));
 716     }
 717 
 718     // test 42
 719     @Test public void testCtrlUpTwiceThenSpace_extended2() {
 720         sm.clearAndSelect(5);
 721         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 4
 722         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 3
 723         keyboard.doKeyPress(KeyCode.SPACE,
 724                 KeyModifier.getShortcutKey(),
 725                 (Utils.isMac() ? KeyModifier.CTRL : null));  // select 3,5
 726         assertTrue(isSelected(3,5));
 727         assertTrue(isNotSelected(0,1,2,4));
 728         assertTrue(isAnchor(3));
 729 
 730         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 2
 731         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());    // move focus to 1
 732         keyboard.doUpArrowPress(KeyModifier.SHIFT);     // select 0,1,2,3
 733         assertTrue(isSelected(0,1,2,3));
 734         assertTrue(isNotSelected(4,5));
 735         assertTrue(isAnchor(3));
 736     }
 737 
 738     // test 46
 739     @Test public void testHomeKey_withSelectedItems() {
 740         sm.clearSelection();
 741         sm.selectRange(4, 11);
 742         keyboard.doKeyPress(KeyCode.HOME);
 743         assertTrue(isSelected(0));
 744         assertTrue(isNotSelected(1,2,3,4,5,6,7,8,9,10,11));
 745     }
 746 
 747     // test 47
 748     @Test public void testEndKey_withSelectedItems() {
 749         sm.clearSelection();
 750         sm.selectRange(4, 11);
 751         keyboard.doKeyPress(KeyCode.END);
 752         assertTrue(isSelected(listView.getItems().size() - 1));
 753         assertTrue(isNotSelected(1,2,3,4,5,6,7,8));
 754     }
 755 
 756     // test 48
 757     @Test public void testShiftHome() {
 758         sm.clearAndSelect(3);
 759         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT);
 760         assertTrue(isSelected(0,1,2,3));
 761         assertTrue(isNotSelected(4,5));
 762         assertTrue(debug(), isAnchor(3));
 763     }
 764 
 765     // test 49
 766     @Test public void testShiftEnd() {
 767         sm.clearAndSelect(3);
 768         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
 769         assertTrue(isSelected(3,4,5,6,7,8,9));
 770         assertTrue(isNotSelected(0,1,2));
 771         assertTrue(isAnchor(3));
 772     }
 773 
 774     // test 52
 775     @Test public void testShiftHomeThenShiftEnd() {
 776         sm.clearAndSelect(5);
 777         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT);
 778         assertTrue(isSelected(0,1,2,3,4,5));
 779         assertTrue(isAnchor(5));
 780 
 781         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
 782         assertTrue(isSelected(5,6,7,8,9));
 783         assertTrue(isAnchor(5));
 784     }
 785 
 786     // test 65
 787     @Test public void testShiftPageUp() {
 788         sm.clearAndSelect(0);
 789         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 790         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 791         keyboard.doKeyPress(KeyCode.SPACE,
 792                 KeyModifier.getShortcutKey(),
 793                 (Utils.isMac() ? KeyModifier.CTRL : null));
 794         assertTrue(isSelected(0,2));
 795         assertTrue(isAnchor(2));
 796 
 797         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 798         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 799         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
 800         assertTrue(isSelected(0,1,2));
 801         assertTrue(isAnchor(2));
 802     }
 803 
 804     // test 67
 805     @Test public void testCtrlAToSelectAll() {
 806         sm.clearAndSelect(5);
 807         keyboard.doKeyPress(KeyCode.A, KeyModifier.getShortcutKey());
 808         assertTrue(isSelected(0,1,2,3,4,5,6,7,8,9));
 809     }
 810 
 811 
 812 
 813     /***************************************************************************
 814      * Tests for discontinuous multiple selection (RT-18953)
 815      **************************************************************************/
 816 
 817     // Test 1
 818     @Test public void test_rt18593_1() {
 819         sm.clearAndSelect(0);
 820         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 821         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 822         keyboard.doKeyPress(KeyCode.SPACE,
 823                 KeyModifier.getShortcutKey(),
 824                 (Utils.isMac() ? KeyModifier.CTRL : null));
 825         assertTrue(isSelected(0,2));
 826         assertTrue(isAnchor(2));
 827 
 828         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 829         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 830         assertTrue(debug(),isSelected(0,2,3,4));
 831         assertTrue(isAnchor(2));
 832     }
 833 
 834     // Test 2
 835     @Test public void test_rt18593_2() {
 836         sm.clearAndSelect(5);
 837         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 838         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 839         keyboard.doKeyPress(KeyCode.SPACE,
 840                 KeyModifier.getShortcutKey(),
 841                 (Utils.isMac() ? KeyModifier.CTRL : null));
 842         assertTrue(isSelected(3,5));
 843         assertTrue(isAnchor(3));
 844 
 845         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 846         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 847         assertTrue(isSelected(1,2,3,5));
 848         assertTrue(isAnchor(3));
 849     }
 850 
 851     // Test 3
 852     @Test public void test_rt18593_3() {
 853         sm.clearAndSelect(0);
 854         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 855         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 856         keyboard.doKeyPress(KeyCode.SPACE,
 857                 KeyModifier.getShortcutKey(),
 858                 (Utils.isMac() ? KeyModifier.CTRL : null));
 859         assertTrue(isSelected(0,2));
 860         assertTrue(isAnchor(2));
 861 
 862         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 863         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 864         assertTrue(isSelected(0,2,3,4));
 865         assertTrue(isAnchor(2));
 866 
 867         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 868         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 869         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 870         assertTrue(isSelected(0,1,2,3,4));
 871         assertTrue(isAnchor(2));
 872     }
 873 
 874     // Test 4
 875     @Test public void test_rt18593_4() {
 876         sm.clearAndSelect(5);
 877         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 878         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 879         keyboard.doKeyPress(KeyCode.SPACE,
 880                 KeyModifier.getShortcutKey(),
 881                 (Utils.isMac() ? KeyModifier.CTRL : null));
 882         assertTrue(isSelected(3,5));
 883         assertTrue(isAnchor(3));
 884 
 885         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 886         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 887         assertTrue(isSelected(1,2,3,5));
 888         assertTrue(isAnchor(3));
 889 
 890         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 891         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 892         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 893         assertTrue(isSelected(1,2,3,4,5));
 894         assertTrue(isAnchor(3));
 895     }
 896 
 897     // TODO skipped some tests here (5-8)
 898 
 899     // Test 9
 900     @Test public void test_rt18593_9() {
 901         sm.clearAndSelect(0);
 902         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 903         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 904         keyboard.doKeyPress(KeyCode.SPACE,
 905                 KeyModifier.getShortcutKey(),
 906                 (Utils.isMac() ? KeyModifier.CTRL : null));
 907         assertTrue(isSelected(0,2));
 908         assertTrue(isAnchor(2));
 909 
 910         keyboard.doKeyPress(KeyCode.END, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 911         assertTrue(isSelected(0,2,3,4,5,6,7,8,9));
 912         assertTrue(isAnchor(2));
 913     }
 914 
 915     // Test 10
 916     @Test public void test_rt18593_10() {
 917         sm.clearAndSelect(9);
 918         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 919         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 920         keyboard.doKeyPress(KeyCode.SPACE,
 921                 KeyModifier.getShortcutKey(),
 922                 (Utils.isMac() ? KeyModifier.CTRL : null));
 923         assertTrue(isSelected(7,9));
 924         assertTrue(isAnchor(7));
 925 
 926         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 927         assertTrue(isSelected(0,1,2,3,4,5,6,7,9));
 928         assertTrue(isAnchor(7));
 929     }
 930 
 931     // Test 11
 932     @Test public void test_rt18593_11() {
 933         sm.clearAndSelect(5);
 934         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 935         assertTrue(isSelected(0,1,2,3,4,5));
 936         assertTrue(isAnchor(5));
 937 
 938         keyboard.doKeyPress(KeyCode.END, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 939         assertTrue(isSelected(0,1,2,3,4,5,6,7,8,9));
 940         assertTrue(isAnchor(5));
 941     }
 942 
 943     // Test 12
 944     @Test public void test_rt18593_12() {
 945         sm.clearAndSelect(0);
 946         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 947         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
 948         keyboard.doKeyPress(KeyCode.SPACE,
 949                 KeyModifier.getShortcutKey(),
 950                 (Utils.isMac() ? KeyModifier.CTRL : null));
 951         assertTrue(isSelected(0,2));
 952         assertTrue(isAnchor(2));
 953 
 954         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 955         keyboard.doDownArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 956         assertTrue(isSelected(0,2,3,4));
 957         assertTrue(isAnchor(2));
 958 
 959         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 960         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 961         keyboard.doUpArrowPress(KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
 962         assertTrue(isSelected(0,1,2,3,4));
 963         assertTrue(isAnchor(2));
 964 
 965         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
 966         keyboard.doKeyPress(KeyCode.SPACE,
 967                 KeyModifier.getShortcutKey(),
 968                 (Utils.isMac() ? KeyModifier.CTRL : null));
 969         assertTrue(isSelected(1,2,3,4));
 970         assertTrue(fm.isFocused(0));
 971         assertTrue(isAnchor(0));
 972     }
 973 
 974 
 975     /***************************************************************************
 976      * Tests for editing
 977      **************************************************************************/
 978 
 979     // test 43 (part 1)
 980     @Test public void testF2EntersEditModeAndEscapeCancelsEdit_part1() {
 981         listView.setEditable(true);
 982 
 983         sm.clearAndSelect(0);
 984         assertEquals(-1, listView.getEditingIndex());
 985         keyboard.doKeyPress(KeyCode.F2);
 986         assertEquals(0, listView.getEditingIndex());
 987 
 988         keyboard.doKeyPress(KeyCode.ESCAPE);
 989         assertEquals(-1, listView.getEditingIndex());
 990     }
 991 
 992 //    // test 43 (part 2)
 993 //    @Test public void testF2EntersEditModeAndEscapeCancelsEdit_part2() {
 994 //        listView.setEditable(true);
 995 //
 996 //        sm.clearAndSelect(0);
 997 //        keyboard.doKeyPress(KeyCode.F2);
 998 //
 999 //
1000 //    }
1001 
1002     /***************************************************************************
1003      * Tests for specific bug reports
1004      **************************************************************************/
1005 
1006     @Test public void test_rt18642() {
1007         sm.clearAndSelect(1);                          // select 1
1008         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());   // shift focus to 2
1009         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());   // shift focus to 3
1010         keyboard.doKeyPress(KeyCode.SPACE,
1011                 KeyModifier.getShortcutKey(),
1012                 (Utils.isMac() ? KeyModifier.CTRL : null)); // set anchor, and also select, 3
1013         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());   // shift focus to 4
1014         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());   // shift focus to 5
1015         keyboard.doKeyPress(KeyCode.SPACE,
1016                 KeyModifier.getShortcutKey(),
1017                 (Utils.isMac() ? KeyModifier.CTRL : null)); // set anchor, and also select, 5
1018 
1019         assertTrue(isSelected(1, 3, 5));
1020         assertTrue(isNotSelected(0, 2, 4));
1021 
1022         // anchor is at 5, so shift+UP should select rows 4 and 5 only
1023         keyboard.doUpArrowPress(KeyModifier.SHIFT);
1024         assertTrue(isSelected(4, 5));
1025         assertTrue(isNotSelected(0, 1, 2, 3));
1026     }
1027 
1028     @Test public void test_rt14451_1() {
1029         sm.clearAndSelect(5);
1030 
1031         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT);
1032         assertTrue(isSelected(0,1,2,3,4,5));
1033         assertTrue(isNotSelected(6,7,8,9));
1034 
1035         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
1036         assertTrue(isNotSelected(0,1,2,3,4));
1037         assertTrue(isSelected(5,6,7,8,9));
1038 
1039         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT);
1040         assertTrue(isSelected(0,1,2,3,4,5));
1041         assertTrue(debug(), isNotSelected(6,7,8,9));
1042     }
1043 
1044     @Test public void test_rt14451_2() {
1045         sm.clearAndSelect(5);
1046 
1047         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
1048         assertTrue(isNotSelected(0,1,2,3,4));
1049         assertTrue(isSelected(5,6,7,8,9));
1050 
1051         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT);
1052         assertTrue(isSelected(0,1,2,3,4,5));
1053         assertTrue(debug(), isNotSelected(6,7,8,9));
1054 
1055         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
1056         assertTrue(isNotSelected(0,1,2,3,4));
1057         assertTrue(isSelected(5,6,7,8,9));
1058     }
1059 
1060     @Test public void test_rt26835_1() {
1061         sm.clearAndSelect(5);
1062         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.getShortcutKey());
1063         assertTrue(fm.isFocused(0));
1064     }
1065 
1066     @Test public void test_rt26835_2() {
1067         sm.clearAndSelect(5);
1068         keyboard.doKeyPress(KeyCode.END, KeyModifier.getShortcutKey());
1069         assertTrue(debug(), fm.isFocused(listView.getItems().size() - 1));
1070     }
1071 
1072     @Test public void test_rt27175() {
1073         sm.clearAndSelect(5);
1074         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT, KeyModifier.getShortcutKey());
1075         assertTrue(debug(), fm.isFocused(0));
1076         assertTrue(isSelected(0,1,2,3,4,5));
1077     }
1078 
1079     @Test public void test_rt28065() {
1080         sm.setSelectionMode(SelectionMode.MULTIPLE);
1081         listView.getItems().setAll("Apple", "Orange", "Banana");
1082 
1083         listView.getSelectionModel().select(0);
1084         assertEquals(0, listView.getSelectionModel().getSelectedIndex());
1085         assertEquals("Apple", listView.getSelectionModel().getSelectedItem());
1086         assertEquals(0, listView.getFocusModel().getFocusedIndex());
1087         assertEquals("Apple", listView.getFocusModel().getFocusedItem());
1088 
1089         keyboard.doKeyPress(KeyCode.A, KeyModifier.getShortcutKey());
1090         assertEquals(0, listView.getSelectionModel().getSelectedIndex());
1091         assertEquals("Apple", listView.getSelectionModel().getSelectedItem());
1092         assertEquals(0, listView.getFocusModel().getFocusedIndex());
1093         assertEquals("Apple", listView.getFocusModel().getFocusedItem());
1094     }
1095 
1096     @Test public void test_rt29930() {
1097         sm.setSelectionMode(SelectionMode.MULTIPLE);
1098 
1099         sm.clearAndSelect(0);
1100 
1101         keyboard.doDownArrowPress(KeyModifier.SHIFT); // select rows [0,1]
1102         keyboard.doDownArrowPress(KeyModifier.SHIFT); // select rows [0,1,2]
1103         assertTrue(isSelected(0,1,2));
1104         assertEquals(2, fm.getFocusedIndex());
1105         assertEquals(0, getAnchor());
1106 
1107         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.getShortcutKey(), PlatformUtil.isMac() ? KeyModifier.CTRL : null); // set new anchor point
1108         assertTrue(isSelected(0,1));
1109         assertEquals(2, fm.getFocusedIndex());
1110         assertEquals(2, getAnchor());
1111 
1112         keyboard.doDownArrowPress(KeyModifier.SHIFT); // select rows [2,3]
1113         assertTrue(isSelected(2,3));
1114         assertTrue(isNotSelected(0,1));
1115         assertEquals(3, fm.getFocusedIndex());
1116         assertEquals(2, getAnchor());
1117     }
1118 
1119     private int rt29849_start_count = 0;
1120     private int rt29849_cancel_count = 0;
1121     @Test public void test_rt29849() {
1122         listView.setEditable(true);
1123 
1124         listView.setOnEditStart(t -> rt29849_start_count++);
1125         listView.setOnEditCancel(t -> rt29849_cancel_count++);
1126 
1127         // initially the counts should be zero
1128         assertEquals(0, rt29849_start_count);
1129         assertEquals(0, rt29849_cancel_count);
1130 
1131         IndexedCell cell = VirtualFlowTestUtils.getCell(listView, 0);
1132         assertTrue(cell.isEditable());
1133         assertFalse(cell.isEditing());
1134         assertEquals(0, cell.getIndex());
1135 
1136         // do an edit, start count should be one, cancel still zero
1137         listView.edit(0);
1138         assertTrue(cell.isEditing());
1139         assertEquals(1, rt29849_start_count);
1140         assertEquals(0, rt29849_cancel_count);
1141 
1142         // cancel edit, now both counts should be 1
1143         keyboard.doKeyPress(KeyCode.ESCAPE);
1144         assertFalse(cell.isEditing());
1145         assertEquals(1, rt29849_start_count);
1146         assertEquals(1, rt29849_cancel_count);
1147     }
1148 
1149     private int rt31577_count = 0;
1150     @Test public void test_rt31577() {
1151         final MultipleSelectionModel sm = listView.getSelectionModel();
1152         sm.setSelectionMode(SelectionMode.SINGLE);
1153         sm.clearSelection();
1154 
1155         // the actual bug is that the selectedItem property does not fire an
1156         // event when the selected items list changes (due to deselection).
1157         // It actually does always contain the right value - it just doesn't
1158         // let anyone know it!
1159         sm.selectedItemProperty().addListener(observable -> {
1160             rt31577_count++;
1161         });
1162 
1163         assertTrue(sm.getSelectedItems().isEmpty());
1164         assertFalse(sm.isSelected(1));
1165         assertEquals(0, rt31577_count);
1166 
1167         // select the first row
1168         keyboard.doKeyPress(KeyCode.KP_DOWN);
1169         assertEquals(1, sm.getSelectedItems().size());
1170         assertTrue(sm.isSelected(0));
1171         assertTrue(sm.getSelectedItems().contains("1"));
1172         assertEquals("1", sm.getSelectedItem());
1173         assertEquals(1, rt31577_count);
1174 
1175         // deselect the row
1176         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.CTRL,
1177                 Utils.isMac() ? KeyModifier.getShortcutKey() : null);
1178         assertTrue(sm.getSelectedItems().isEmpty());
1179         assertFalse(sm.isSelected(1));
1180         assertNull(sm.getSelectedItem());
1181         assertEquals(2, rt31577_count);
1182     }
1183 
1184     @Test public void test_rt32383_pageDown() {
1185         // this test requires a lot of data
1186         listView.getItems().clear();
1187         for (int i = 0; i < 100; i++) {
1188             listView.getItems().add("Row " + i);
1189         }
1190 
1191         final MultipleSelectionModel sm = listView.getSelectionModel();
1192         sm.setSelectionMode(SelectionMode.SINGLE);
1193         sm.clearAndSelect(0);
1194 
1195         final String initialFocusOwner = fm.getFocusedItem();
1196 
1197         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
1198         Toolkit.getToolkit().firePulse();
1199         final String newFocusOwner = fm.getFocusedItem();
1200         assertNotSame(initialFocusOwner, newFocusOwner);
1201 
1202         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
1203         Toolkit.getToolkit().firePulse();
1204         final String nextFocusOwner = fm.getFocusedItem();
1205         assertNotSame(initialFocusOwner, nextFocusOwner);
1206         assertNotSame(newFocusOwner, nextFocusOwner);
1207     }
1208 
1209     @Test public void test_rt32383_pageUp() {
1210         // this test requires a lot of data
1211         listView.getItems().clear();
1212         for (int i = 0; i < 100; i++) {
1213             listView.getItems().add("Row " + i);
1214         }
1215 
1216         final int lastIndex = 99;
1217 
1218         final MultipleSelectionModel sm = listView.getSelectionModel();
1219         sm.setSelectionMode(SelectionMode.SINGLE);
1220         sm.clearAndSelect(lastIndex);
1221 
1222         // need to make sure we scroll down to the bottom!
1223         listView.scrollTo(lastIndex);
1224         Toolkit.getToolkit().firePulse();
1225 
1226         assertEquals(lastIndex, sm.getSelectedIndex());
1227         assertEquals(lastIndex, fm.getFocusedIndex());
1228 
1229         final String initialFocusOwner = fm.getFocusedItem();
1230 
1231         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
1232         Toolkit.getToolkit().firePulse();
1233         final String newFocusOwner = fm.getFocusedItem();
1234         assertNotSame(initialFocusOwner, newFocusOwner);
1235 
1236         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
1237         Toolkit.getToolkit().firePulse();
1238         final String nextFocusOwner = fm.getFocusedItem();
1239         assertNotSame(initialFocusOwner, nextFocusOwner);
1240         assertNotSame(newFocusOwner, nextFocusOwner);
1241     }
1242 
1243     @Test public void test_rt19053_pageUp() {
1244         final int items = 8;
1245         listView.getItems().clear();
1246         for (int i = 0; i < items; i++) {
1247             listView.getItems().add("Row " + i);
1248         }
1249 
1250         final int middleIndex = items / 2;
1251 
1252         final MultipleSelectionModel sm = listView.getSelectionModel();
1253         sm.setSelectionMode(SelectionMode.SINGLE);
1254         sm.clearAndSelect(middleIndex);
1255 
1256         assertEquals(middleIndex, sm.getSelectedIndex());
1257 
1258         final Object initialSelectionOwner = sm.getSelectedItem();
1259 
1260         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1261         Toolkit.getToolkit().firePulse();
1262         final Object newSelectionOwner = sm.getSelectedItem();
1263         assertNotSame(initialSelectionOwner, newSelectionOwner);
1264 
1265         // selection should go all the way to the top, but this bug
1266         // shows that instead it seems to stop midway - where the anchor is
1267         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1268         Toolkit.getToolkit().firePulse();
1269         assertEquals(0, fm.getFocusedIndex());
1270         assertEquals(0, sm.getSelectedIndex());
1271         final Object nextSelectionOwner =  sm.getSelectedItem();
1272         assertNotSame(initialSelectionOwner, nextSelectionOwner);
1273         assertNotSame(newSelectionOwner, nextSelectionOwner);
1274     }
1275 
1276     @Test public void test_rt19053_pageDown() {
1277         final int items = 8;
1278         listView.getItems().clear();
1279         for (int i = 0; i < items; i++) {
1280             listView.getItems().add("Row " + i);
1281         }
1282 
1283         final int middleIndex = items / 2;
1284 
1285         final MultipleSelectionModel sm = listView.getSelectionModel();
1286         sm.setSelectionMode(SelectionMode.SINGLE);
1287         sm.clearAndSelect(middleIndex);
1288 
1289         assertEquals(middleIndex, sm.getSelectedIndex());
1290 
1291         final Object initialSelectionOwner = sm.getSelectedItem();
1292 
1293         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1294         Toolkit.getToolkit().firePulse();
1295         final Object newSelectionOwner = sm.getSelectedItem();
1296         assertNotSame(initialSelectionOwner, newSelectionOwner);
1297 
1298         // selection should go all the way to the bottom, but this bug
1299         // shows that instead it seems to stop midway - where the anchor is
1300         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1301         Toolkit.getToolkit().firePulse();
1302         assertEquals(items - 1, fm.getFocusedIndex());
1303         assertEquals(items - 1, sm.getSelectedIndex());
1304         final Object nextSelectionOwner =  sm.getSelectedItem();
1305         assertNotSame(initialSelectionOwner, nextSelectionOwner);
1306         assertNotSame(newSelectionOwner, nextSelectionOwner);
1307     }
1308 
1309     @Ignore("Fix not yet implemented")
1310     @Test public void test_rt20641_pageUp() {
1311         final int items = 20;
1312         listView.getItems().clear();
1313         for (int i = 0; i < items; i++) {
1314             listView.getItems().add("Row " + i);
1315         }
1316 
1317         final MultipleSelectionModel sm = listView.getSelectionModel();
1318         sm.setSelectionMode(SelectionMode.MULTIPLE);
1319         sm.clearAndSelect(0);
1320         assertEquals(0, sm.getSelectedIndex());
1321 
1322         final int selectedIndex0 = sm.getSelectedIndex();
1323 
1324         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1325         Toolkit.getToolkit().firePulse();
1326         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1327         Toolkit.getToolkit().firePulse();
1328         final int selectedIndex1 = sm.getSelectedIndex();
1329         assertNotSame(selectedIndex0, selectedIndex1);
1330         assertTrue(selectedIndex0 < selectedIndex1);
1331 
1332         // selection should go up one page, but bug shows it goes right back
1333         // to start
1334         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1335         Toolkit.getToolkit().firePulse();
1336         final int selectedIndex2 = sm.getSelectedIndex();
1337         assertNotSame(selectedIndex0, selectedIndex1);
1338         assertNotSame(selectedIndex0, selectedIndex2);
1339         assertTrue(selectedIndex2 < selectedIndex1);
1340         assertTrue(selectedIndex0 < selectedIndex2);
1341     }
1342 
1343     @Ignore("Fix not yet implemented")
1344     @Test public void test_rt20641_pageDown() {
1345         final int items = 100;
1346         listView.getItems().clear();
1347         for (int i = 0; i < items; i++) {
1348             listView.getItems().add("Row " + i);
1349         }
1350 
1351         final MultipleSelectionModel sm = listView.getSelectionModel();
1352         sm.setSelectionMode(SelectionMode.MULTIPLE);
1353         sm.clearAndSelect(items - 1);
1354         FocusModelShim.setFocusedIndex(fm, items - 1);
1355         assertEquals(items - 1, sm.getSelectedIndex());
1356         assertEquals(items - 1, fm.getFocusedIndex());
1357 
1358         final int selectedIndex0 = sm.getSelectedIndex();
1359 
1360         // need to make sure we scroll down to the bottom!
1361         listView.scrollTo(items - 1);
1362         Toolkit.getToolkit().firePulse();
1363 
1364         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1365         Toolkit.getToolkit().firePulse();
1366         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1367         Toolkit.getToolkit().firePulse();
1368         final int selectedIndex1 = sm.getSelectedIndex();
1369         assertNotSame(selectedIndex0, selectedIndex1);
1370         assertTrue(selectedIndex0 > selectedIndex1);
1371 
1372         // selection should go up down page, but bug shows it goes right back
1373         // to end (where selection started)
1374         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1375         Toolkit.getToolkit().firePulse();
1376         final int selectedIndex2 = sm.getSelectedIndex();
1377         assertNotSame(selectedIndex0, selectedIndex1);
1378         assertNotSame(selectedIndex0, selectedIndex2);
1379         assertTrue(selectedIndex2 > selectedIndex1);
1380         assertTrue(selectedIndex0 > selectedIndex2);
1381     }
1382 
1383     @Test public void test_rt21375_scenario_1a_down() {
1384         final int items = 8;
1385         listView.getItems().clear();
1386         for (int i = 1; i <= items; i++) {
1387             listView.getItems().add("Row " + i);
1388         }
1389 
1390         final MultipleSelectionModel sm = listView.getSelectionModel();
1391         sm.setSelectionMode(SelectionMode.MULTIPLE);
1392         sm.clearAndSelect(0);
1393 
1394         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1395         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1396         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.SHIFT);
1397         Toolkit.getToolkit().firePulse();
1398         assertTrue(isSelected(0,1,2,3));
1399         assertEquals(4, sm.getSelectedItems().size());
1400     }
1401 
1402     @Test public void test_rt21375_scenario_1b_down() {
1403         final int items = 8;
1404         listView.getItems().clear();
1405         for (int i = 1; i <= items; i++) {
1406             listView.getItems().add("Row " + i);
1407         }
1408 
1409         final MultipleSelectionModel sm = listView.getSelectionModel();
1410         sm.setSelectionMode(SelectionMode.MULTIPLE);
1411         sm.clearAndSelect(0);
1412 
1413         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1414         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1415         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1416         Toolkit.getToolkit().firePulse();
1417         assertTrue(isSelected(0,1,2,3));
1418         assertEquals(4, sm.getSelectedItems().size());
1419     }
1420 
1421     @Test public void test_rt21375_scenario_2_down() {
1422         final int items = 8;
1423         listView.getItems().clear();
1424         for (int i = 1; i <= items; i++) {
1425             listView.getItems().add("Row " + i);
1426         }
1427 
1428         final MultipleSelectionModel sm = listView.getSelectionModel();
1429         sm.setSelectionMode(SelectionMode.MULTIPLE);
1430         sm.clearAndSelect(0);
1431 
1432         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey());
1433         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey());
1434         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.getShortcutKey(), PlatformUtil.isMac() ? KeyModifier.CTRL : null);
1435         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey());
1436         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.SHIFT);
1437         Toolkit.getToolkit().firePulse();
1438         assertTrue(isSelected(2,3,4));
1439         assertEquals(3, sm.getSelectedItems().size());
1440     }
1441 
1442     @Test public void test_rt21375_scenario_3_down() {
1443         final int items = 8;
1444         listView.getItems().clear();
1445         for (int i = 1; i <= items; i++) {
1446             listView.getItems().add("Row " + i);
1447         }
1448 
1449         final MultipleSelectionModel sm = listView.getSelectionModel();
1450         sm.setSelectionMode(SelectionMode.MULTIPLE);
1451         sm.clearAndSelect(0);
1452 
1453         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey());
1454         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey());
1455         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.getShortcutKey(), PlatformUtil.isMac() ? KeyModifier.CTRL : null);
1456         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey());
1457         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1458         Toolkit.getToolkit().firePulse();
1459         assertTrue(isSelected(0,2,3,4));
1460         assertEquals(4, sm.getSelectedItems().size());
1461     }
1462 
1463     @Test public void test_rt21375_scenario_1a_up() {
1464         final int items = 8;
1465         listView.getItems().clear();
1466         for (int i = 1; i <= items; i++) {
1467             listView.getItems().add("Row " + i);
1468         }
1469 
1470         final MultipleSelectionModel sm = listView.getSelectionModel();
1471         sm.setSelectionMode(SelectionMode.MULTIPLE);
1472         sm.clearAndSelect(7);
1473 
1474         keyboard.doKeyPress(KeyCode.UP, KeyModifier.getShortcutKey());
1475         keyboard.doKeyPress(KeyCode.UP, KeyModifier.getShortcutKey());
1476         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT);
1477         Toolkit.getToolkit().firePulse();
1478         assertTrue(isSelected(7,6,5,4));
1479         assertEquals(4, sm.getSelectedItems().size());
1480     }
1481 
1482     @Test public void test_rt21375_scenario_1b_up() {
1483         final int items = 8;
1484         listView.getItems().clear();
1485         for (int i = 1; i <= items; i++) {
1486             listView.getItems().add("Row " + i);
1487         }
1488 
1489         final MultipleSelectionModel sm = listView.getSelectionModel();
1490         sm.setSelectionMode(SelectionMode.MULTIPLE);
1491         sm.clearAndSelect(7);
1492 
1493         keyboard.doKeyPress(KeyCode.UP, KeyModifier.getShortcutKey());
1494         keyboard.doKeyPress(KeyCode.UP, KeyModifier.getShortcutKey());
1495         keyboard.doKeyPress(KeyCode.UP, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1496         Toolkit.getToolkit().firePulse();
1497         assertTrue(isSelected(7,6,5,4));
1498         assertEquals(4, sm.getSelectedItems().size());
1499     }
1500 
1501     @Test public void test_rt21375_scenario_2_up() {
1502         final int items = 8;
1503         listView.getItems().clear();
1504         for (int i = 1; i <= items; i++) {
1505             listView.getItems().add("Row " + i);
1506         }
1507 
1508         final MultipleSelectionModel sm = listView.getSelectionModel();
1509         sm.setSelectionMode(SelectionMode.MULTIPLE);
1510         sm.clearAndSelect(7);
1511 
1512         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey());
1513         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey());
1514         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.getShortcutKey(), PlatformUtil.isMac() ? KeyModifier.CTRL : null);
1515         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey());
1516         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.SHIFT);
1517         Toolkit.getToolkit().firePulse();
1518         assertTrue(isSelected(5,4,3));
1519         assertEquals(3, sm.getSelectedItems().size());
1520     }
1521 
1522     @Test public void test_rt21375_scenario_3_up() {
1523         final int items = 8;
1524         listView.getItems().clear();
1525         for (int i = 1; i <= items; i++) {
1526             listView.getItems().add("Row " + i);
1527         }
1528 
1529         final MultipleSelectionModel sm = listView.getSelectionModel();
1530         sm.setSelectionMode(SelectionMode.MULTIPLE);
1531         sm.clearAndSelect(7);
1532 
1533         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey());
1534         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey());
1535         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.getShortcutKey(), PlatformUtil.isMac() ? KeyModifier.CTRL : null);
1536         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey());
1537         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1538         Toolkit.getToolkit().firePulse();
1539         assertTrue(isSelected(7,5,4,3));
1540         assertEquals(4, sm.getSelectedItems().size());
1541     }
1542 
1543     @Test public void test_rt33301_multipleSelection_down() {
1544         final int items = 5;
1545         listView.getItems().clear();
1546         for (int i = 0; i < items; i++) {
1547             listView.getItems().add("Row " + i);
1548         }
1549 
1550         final FocusModel fm = listView.getFocusModel();
1551         final MultipleSelectionModel sm = listView.getSelectionModel();
1552         sm.setSelectionMode(SelectionMode.MULTIPLE);
1553         sm.clearAndSelect(2);
1554 
1555         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 3
1556         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 4
1557         Toolkit.getToolkit().firePulse();
1558         assertTrue(isNotSelected(0,1));
1559         assertTrue(isSelected(2,3,4));
1560         assertEquals(3, sm.getSelectedItems().size());
1561         assertTrue(fm.isFocused(4));
1562 
1563         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 4
1564         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 4
1565         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 4
1566         Toolkit.getToolkit().firePulse();
1567         assertTrue(isNotSelected(0,1));
1568         assertTrue(isSelected(2,3,4));
1569         assertEquals(3, sm.getSelectedItems().size());
1570         assertTrue("Focus index incorrectly at: " + fm.getFocusedIndex(), fm.isFocused(4));
1571     }
1572 
1573     @Test public void test_rt33301_multipleSelection_up() {
1574         final int items = 5;
1575         listView.getItems().clear();
1576         for (int i = 0; i < items; i++) {
1577             listView.getItems().add("Row " + i);
1578         }
1579 
1580         final FocusModel fm = listView.getFocusModel();
1581         final MultipleSelectionModel sm = listView.getSelectionModel();
1582         sm.setSelectionMode(SelectionMode.MULTIPLE);
1583         sm.clearAndSelect(2);
1584 
1585         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 1
1586         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 0
1587         Toolkit.getToolkit().firePulse();
1588         assertTrue(isNotSelected(3,4));
1589         assertTrue(isSelected(0,1,2));
1590         assertEquals(3, sm.getSelectedItems().size());
1591         assertTrue(fm.isFocused(0));
1592 
1593         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 0
1594         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 0
1595         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 0
1596         Toolkit.getToolkit().firePulse();
1597         assertTrue(isNotSelected(3,4));
1598         assertTrue(isSelected(0,1,2));
1599         assertEquals(3, sm.getSelectedItems().size());
1600         assertTrue(fm.isFocused(0));
1601     }
1602 
1603     @Test public void test_rt33301_singleSelection_down() {
1604         final int items = 5;
1605         listView.getItems().clear();
1606         for (int i = 0; i < items; i++) {
1607             listView.getItems().add("Row " + i);
1608         }
1609 
1610         final FocusModel fm = listView.getFocusModel();
1611         final MultipleSelectionModel sm = listView.getSelectionModel();
1612         sm.setSelectionMode(SelectionMode.SINGLE);
1613         sm.clearAndSelect(2);
1614 
1615         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 3
1616         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 4
1617         Toolkit.getToolkit().firePulse();
1618         assertTrue(isNotSelected(0,1,2,3));
1619         assertTrue(isSelected(4));
1620         assertEquals(1, sm.getSelectedItems().size());
1621         assertTrue(fm.isFocused(4));
1622 
1623         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 4
1624         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 4
1625         keyboard.doKeyPress(KeyCode.DOWN,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 4
1626         Toolkit.getToolkit().firePulse();
1627         assertTrue(isNotSelected(0,1,2,3));
1628         assertTrue(isSelected(4));
1629         assertEquals(1, sm.getSelectedItems().size());
1630         assertTrue(fm.isFocused(4));
1631     }
1632 
1633     @Test public void test_rt33301_singleSelection_up() {
1634         final int items = 5;
1635         listView.getItems().clear();
1636         for (int i = 0; i < items; i++) {
1637             listView.getItems().add("Row " + i);
1638         }
1639 
1640         final FocusModel fm = listView.getFocusModel();
1641         final MultipleSelectionModel sm = listView.getSelectionModel();
1642         sm.setSelectionMode(SelectionMode.SINGLE);
1643         sm.clearAndSelect(2);
1644 
1645         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 1
1646         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // row 0
1647         Toolkit.getToolkit().firePulse();
1648         assertTrue(isNotSelected(1,2,3,4));
1649         assertTrue(isSelected(0));
1650         assertEquals(1, sm.getSelectedItems().size());
1651         assertTrue(fm.isFocused(0));
1652 
1653         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 0
1654         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 0
1655         keyboard.doKeyPress(KeyCode.UP,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT); // should stay at row 0
1656         Toolkit.getToolkit().firePulse();
1657         assertTrue(isNotSelected(1,2,3,4));
1658         assertTrue(isSelected(0));
1659         assertEquals(1, sm.getSelectedItems().size());
1660         assertTrue(fm.isFocused(0));
1661     }
1662 
1663     @Test public void test_rt20915() {
1664         final FocusModel fm = listView.getFocusModel();
1665         final MultipleSelectionModel sm = listView.getSelectionModel();
1666 
1667         sm.clearAndSelect(0);
1668         assertEquals(0, getAnchor());
1669 
1670         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1671         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1672         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1673         Toolkit.getToolkit().firePulse();
1674         assertTrue(isNotSelected(1,2,3));
1675         assertTrue(isSelected(0));
1676         assertEquals(1, sm.getSelectedItems().size());
1677         assertTrue(fm.isFocused(3));
1678 
1679         keyboard.doKeyPress(KeyCode.SPACE,  KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1680         Toolkit.getToolkit().firePulse();
1681         assertTrue(isSelected(0,1,2,3));
1682         assertEquals(4, sm.getSelectedItems().size());
1683         assertTrue(fm.isFocused(3));
1684     }
1685 
1686     @Test public void test_rt34200() {
1687         final int items = 100;
1688         listView.getItems().clear();
1689         for (int i = 0; i < items; i++) {
1690             listView.getItems().add("Row " + i);
1691         }
1692 
1693         sm.clearAndSelect(99);
1694         listView.scrollTo(99);
1695         assertEquals(99, getAnchor());
1696         assertEquals(99, fm.getFocusedIndex());
1697 
1698         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1699         Toolkit.getToolkit().firePulse();
1700         assertEquals(99, getAnchor());
1701         assertTrue(fm.getFocusedIndex() < 99);
1702     }
1703 
1704     @Test public void test_rt34369() {
1705         final int items = 100;
1706         listView.getItems().clear();
1707         for (int i = 0; i < items; i++) {
1708             listView.getItems().add("Row " + i);
1709         }
1710 
1711         sm.clearAndSelect(99);
1712         listView.scrollTo(99);
1713         assertEquals(99, getAnchor());
1714         assertEquals(99, fm.getFocusedIndex());
1715 
1716         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1717         Toolkit.getToolkit().firePulse();
1718         assertEquals(99, getAnchor());
1719         assertTrue(fm.getFocusedIndex() < 99);
1720     }
1721 
1722     @Test public void test_rt33894() {
1723         final int items = 5;
1724         listView.getItems().clear();
1725         for (int i = 0; i < items; i++) {
1726             listView.getItems().add("Row " + i);
1727         }
1728 
1729         sm.clearAndSelect(1);
1730         assertEquals(1, getAnchor());
1731         assertEquals(1, fm.getFocusedIndex());
1732         assertEquals(1, sm.getSelectedIndex());
1733 
1734         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1735         Toolkit.getToolkit().firePulse();
1736         assertEquals(1, getAnchor());
1737         assertEquals(2, fm.getFocusedIndex());
1738         assertEquals(1, sm.getSelectedIndex());
1739 
1740         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1741         Toolkit.getToolkit().firePulse();
1742         assertEquals(2, getAnchor());
1743         assertEquals(2, fm.getFocusedIndex());
1744         assertEquals(2, sm.getSelectedIndex());
1745         assertTrue(isSelected(1, 2));
1746 
1747         keyboard.doKeyPress(KeyCode.UP, KeyModifier.getShortcutKey());
1748         keyboard.doKeyPress(KeyCode.UP, KeyModifier.getShortcutKey());
1749         Toolkit.getToolkit().firePulse();
1750         assertEquals(2, getAnchor());
1751         assertEquals(0, fm.getFocusedIndex());
1752         assertEquals(2, sm.getSelectedIndex());
1753         assertTrue(isSelected(1, 2));
1754 
1755         keyboard.doKeyPress(KeyCode.SPACE, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
1756         Toolkit.getToolkit().firePulse();
1757         assertEquals(0, getAnchor());
1758         assertEquals(0, fm.getFocusedIndex());
1759         assertEquals(0, sm.getSelectedIndex());
1760         assertTrue(isSelected(0, 1, 2));
1761     }
1762 
1763     @Test public void test_rt34425() {
1764         final int items = 5;
1765         listView.getItems().clear();
1766         for (int i = 0; i < items; i++) {
1767             listView.getItems().add("Row " + i);
1768         }
1769 
1770         sm.clearAndSelect(1);
1771         assertEquals(1, getAnchor());
1772         assertEquals(1, fm.getFocusedIndex());
1773         assertEquals(1, sm.getSelectedIndex());
1774 
1775         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.getShortcutKey());
1776         Toolkit.getToolkit().firePulse();
1777         assertEquals(1, getAnchor());
1778         assertEquals(2, fm.getFocusedIndex());
1779         assertEquals(1, sm.getSelectedIndex());
1780 
1781         keyboard.doKeyPress(KeyCode.SPACE);
1782         Toolkit.getToolkit().firePulse();
1783         assertEquals(2, getAnchor());
1784         assertEquals(2, fm.getFocusedIndex());
1785         assertEquals(2, sm.getSelectedIndex());
1786         assertTrue(isSelected(1, 2));
1787     }
1788 
1789     @Test public void test_rt34407_down_down_up() {
1790         final int items = 100;
1791         listView.getItems().clear();
1792         for (int i = 0; i < items; i++) {
1793             listView.getItems().add("Row " + i);
1794         }
1795         listView.setPrefHeight(130); // roughly room for four rows
1796 
1797         // this stageLoader is needed....although right now I'm not sure why
1798         StageLoader sl = new StageLoader(listView);
1799         final FocusModel fm = listView.getFocusModel();
1800         final MultipleSelectionModel sm = listView.getSelectionModel();
1801         sm.setSelectionMode(SelectionMode.MULTIPLE);
1802 
1803         sm.clearAndSelect(0);
1804         fm.focus(0);
1805         assertEquals(0, getAnchor());
1806         assertTrue(fm.isFocused(0));
1807         assertTrue(sm.isSelected(0));
1808         assertFalse(sm.isSelected(1));
1809 
1810         // we expect the final Page-up to return us back to this selected index and with the same number of selected indices
1811         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1812         final int leadSelectedIndex = sm.getSelectedIndex();
1813         final int selectedIndicesCount = sm.getSelectedIndices().size();
1814         assertEquals(6, leadSelectedIndex);
1815         assertEquals(6, fm.getFocusedIndex());
1816         assertEquals(7, selectedIndicesCount);
1817 
1818         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1819         assertEquals(leadSelectedIndex * 2, sm.getSelectedIndex());
1820         assertEquals(leadSelectedIndex * 2, fm.getFocusedIndex());
1821         assertEquals(selectedIndicesCount * 2 - 1, sm.getSelectedIndices().size());
1822 
1823         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1824         assertEquals(leadSelectedIndex, sm.getSelectedIndex());
1825         assertEquals(leadSelectedIndex, fm.getFocusedIndex());
1826         assertEquals(selectedIndicesCount, sm.getSelectedIndices().size());
1827 
1828         sl.dispose();
1829     }
1830 
1831     @Test public void test_rt34407_up_up_down() {
1832         final int items = 100;
1833         listView.getItems().clear();
1834         for (int i = 0; i < items; i++) {
1835             listView.getItems().add("Row " + i);
1836         }
1837         listView.setPrefHeight(130); // roughly room for four rows
1838 
1839         sm.setSelectionMode(SelectionMode.MULTIPLE);
1840 
1841         sm.clearAndSelect(99);
1842         fm.focus(99);
1843         listView.scrollTo(99);
1844         Toolkit.getToolkit().firePulse();
1845 
1846         assertEquals(99, getAnchor());
1847         assertTrue(fm.isFocused(99));
1848         assertTrue(sm.isSelected(99));
1849         assertFalse(sm.isSelected(98));
1850 
1851         // we expect the final Page-down to return us back to this selected index and with the same number of selected indices
1852         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1853         final int leadSelectedIndex = sm.getSelectedIndex();
1854         final int selectedIndicesCount = sm.getSelectedIndices().size();
1855         final int diff = 99 - leadSelectedIndex;
1856         assertEquals(99 - diff, leadSelectedIndex);
1857         assertEquals(99 - diff, fm.getFocusedIndex());
1858         assertEquals(7, selectedIndicesCount);
1859 
1860         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
1861         assertEquals(99 - diff * 2, sm.getSelectedIndex());
1862         assertEquals(selectedIndicesCount * 2 - 1, sm.getSelectedIndices().size());
1863 
1864         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
1865         assertEquals(leadSelectedIndex, sm.getSelectedIndex());
1866         assertEquals(selectedIndicesCount, sm.getSelectedIndices().size());
1867     }
1868 
1869     @Test public void test_rt34768() {
1870         listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
1871         listView.getItems().clear();
1872 
1873         // no need for an assert here - we're testing for an AIOOBE
1874         keyboard.doKeyPress(KeyCode.A, KeyModifier.getShortcutKey());
1875     }
1876 
1877     @Test public void test_rt35853_multipleSelection_shiftDown() {
1878         final int items = 10;
1879         listView.getItems().clear();
1880         for (int i = 0; i < items; i++) {
1881             listView.getItems().add("Row " + i);
1882         }
1883 
1884         sm.setSelectionMode(SelectionMode.MULTIPLE);
1885 
1886         sm.clearAndSelect(5);
1887         assertEquals(5, getAnchor());
1888         assertTrue(fm.isFocused(5));
1889         assertTrue(sm.isSelected(5));
1890 
1891         sm.selectedIndexProperty().addListener(observable -> {
1892             // we expect only one selected index change event, from 5 to 4
1893             assertEquals(4, sm.getSelectedIndex());
1894         });
1895 
1896         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT);
1897         assertEquals(5, getAnchor());
1898         assertTrue(fm.isFocused(4));
1899         assertTrue(sm.isSelected(4));
1900         assertTrue(sm.isSelected(5));
1901     }
1902 
1903     @Test public void test_rt35853_multipleSelection_noShiftDown() {
1904         final int items = 10;
1905         listView.getItems().clear();
1906         for (int i = 0; i < items; i++) {
1907             listView.getItems().add("Row " + i);
1908         }
1909 
1910         sm.setSelectionMode(SelectionMode.MULTIPLE);
1911 
1912         sm.clearAndSelect(5);
1913         assertEquals(5, getAnchor());
1914         assertTrue(fm.isFocused(5));
1915         assertTrue(sm.isSelected(5));
1916 
1917         sm.selectedIndexProperty().addListener(observable -> {
1918             // we expect only one selected index change event, from 5 to 4
1919             assertEquals(4, sm.getSelectedIndex());
1920         });
1921 
1922         keyboard.doKeyPress(KeyCode.UP);
1923         assertEquals(4, getAnchor());
1924         assertTrue(fm.isFocused(4));
1925         assertTrue(sm.isSelected(4));
1926         assertFalse(sm.isSelected(5));
1927     }
1928 
1929     @Test public void test_rt35853_singleSelection_shiftDown() {
1930         final int items = 10;
1931         listView.getItems().clear();
1932         for (int i = 0; i < items; i++) {
1933             listView.getItems().add("Row " + i);
1934         }
1935 
1936         sm.setSelectionMode(SelectionMode.SINGLE);
1937 
1938         sm.clearAndSelect(5);
1939         assertEquals(5, getAnchor());
1940         assertTrue(fm.isFocused(5));
1941         assertTrue(sm.isSelected(5));
1942 
1943         sm.selectedIndexProperty().addListener(observable -> {
1944             // we expect only one selected index change event, from 5 to 4
1945             assertEquals(4, sm.getSelectedIndex());
1946         });
1947 
1948         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT);
1949         assertEquals(4, getAnchor());
1950         assertTrue(fm.isFocused(4));
1951         assertTrue(sm.isSelected(4));
1952         assertFalse(sm.isSelected(5));
1953     }
1954 
1955     @Test public void test_rt35853_singleSelection_noShiftDown() {
1956         final int items = 10;
1957         listView.getItems().clear();
1958         for (int i = 0; i < items; i++) {
1959             listView.getItems().add("Row " + i);
1960         }
1961 
1962         sm.setSelectionMode(SelectionMode.SINGLE);
1963 
1964         sm.clearAndSelect(5);
1965         assertEquals(5, getAnchor());
1966         assertTrue(fm.isFocused(5));
1967         assertTrue(sm.isSelected(5));
1968 
1969         sm.selectedIndexProperty().addListener(observable -> {
1970             // we expect only one selected index change event, from 5 to 4
1971             assertEquals(4, sm.getSelectedIndex());
1972         });
1973 
1974         keyboard.doKeyPress(KeyCode.UP);
1975         assertEquals(4, getAnchor());
1976         assertTrue(fm.isFocused(4));
1977         assertTrue(sm.isSelected(4));
1978         assertFalse(sm.isSelected(5));
1979     }
1980 
1981     @Test public void test_rt36800() {
1982         final int items = 10;
1983         listView.getItems().clear();
1984         for (int i = 0; i < items; i++) {
1985             listView.getItems().add("Row " + i);
1986         }
1987 
1988         sm.setSelectionMode(SelectionMode.SINGLE);
1989 
1990         sm.clearAndSelect(5);
1991         assertEquals(5, getAnchor());
1992         assertTrue(fm.isFocused(5));
1993         assertTrue(sm.isSelected(5));
1994 
1995         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT); // 4
1996         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT); // 3
1997         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT); // 2
1998         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT); // 1
1999         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT); // 0
2000 
2001         ControlTestUtils.runWithExceptionHandler(() -> {
2002             keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT); // bug time?
2003         });
2004 
2005         assertEquals(0, getAnchor());
2006         assertTrue(fm.isFocused(0));
2007         assertTrue(sm.isSelected(0));
2008         assertFalse(sm.isSelected(1));
2009         assertFalse(sm.isSelected(2));
2010         assertFalse(sm.isSelected(3));
2011         assertFalse(sm.isSelected(4));
2012         assertFalse(sm.isSelected(5));
2013     }
2014 
2015     @Test public void test_rt_36942() {
2016         final int items = 3;
2017         listView.getItems().clear();
2018         for (int i = 0; i < items; i++) {
2019             listView.getItems().add("Row " + i);
2020         }
2021 
2022         MultipleSelectionModel<String> sm = listView.getSelectionModel();
2023         sm.setSelectionMode(SelectionMode.MULTIPLE);
2024         ObservableList<String> selectedItems = sm.getSelectedItems();
2025 
2026         ListView<String> selectedItemsListView = new ListView<>(selectedItems);
2027 
2028         HBox root = new HBox(5, listView, selectedItemsListView);
2029 
2030         StageLoader sl = new StageLoader(root);
2031 
2032         sm.select(0);
2033         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.SHIFT); // 0,1
2034         keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.SHIFT); // 0,1,2
2035 
2036         ControlTestUtils.runWithExceptionHandler(() -> {
2037             keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.SHIFT); // 0,1,2,Exception?
2038         });
2039 
2040         sl.dispose();
2041     }
2042 
2043     @Test public void test_rt_37130_pageUpAtTop() {
2044         final int items = 100;
2045         listView.getItems().clear();
2046         for (int i = 0; i < items; i++) {
2047             listView.getItems().add("Row " + i);
2048         }
2049 
2050         MultipleSelectionModel<String> sm = listView.getSelectionModel();
2051         sm.setSelectionMode(SelectionMode.MULTIPLE);
2052 
2053         StageLoader sl = new StageLoader(listView);
2054 
2055         sm.select(5);
2056         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
2057         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
2058 
2059         sl.dispose();
2060     }
2061 
2062     @Test public void test_rt_37130_pageUpAtBottom() {
2063         final int items = 100;
2064         listView.getItems().clear();
2065         for (int i = 0; i < items; i++) {
2066             listView.getItems().add("Row " + i);
2067         }
2068 
2069         MultipleSelectionModel<String> sm = listView.getSelectionModel();
2070         sm.setSelectionMode(SelectionMode.MULTIPLE);
2071 
2072         StageLoader sl = new StageLoader(listView);
2073 
2074         sm.select(95);
2075         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
2076         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.SHIFT);
2077 
2078         sl.dispose();
2079     }
2080 
2081     @Test public void test_rt_37130_pageDownAtTop() {
2082         final int items = 100;
2083         listView.getItems().clear();
2084         for (int i = 0; i < items; i++) {
2085             listView.getItems().add("Row " + i);
2086         }
2087 
2088         MultipleSelectionModel<String> sm = listView.getSelectionModel();
2089         sm.setSelectionMode(SelectionMode.MULTIPLE);
2090 
2091         StageLoader sl = new StageLoader(listView);
2092 
2093         sm.select(5);
2094         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
2095         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
2096 
2097         sl.dispose();
2098     }
2099 
2100     @Test public void test_rt_37130_pageDownAtBottom() {
2101         final int items = 100;
2102         listView.getItems().clear();
2103         for (int i = 0; i < items; i++) {
2104             listView.getItems().add("Row " + i);
2105         }
2106 
2107         MultipleSelectionModel<String> sm = listView.getSelectionModel();
2108         sm.setSelectionMode(SelectionMode.MULTIPLE);
2109 
2110         StageLoader sl = new StageLoader(listView);
2111 
2112         sm.select(95);
2113         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
2114         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.SHIFT);
2115 
2116         sl.dispose();
2117     }
2118 
2119     private int rt_39088_indices_event_count = 0;
2120     private int rt_39088_items_event_count = 0;
2121     @Test public void test_rt_39088() {
2122         listView.getItems().clear();
2123         for (int i = 0; i < 4; i++) {
2124             listView.getItems().add("Row " + i);
2125         }
2126 
2127         MultipleSelectionModel<String> sm = listView.getSelectionModel();
2128         sm.setSelectionMode(SelectionMode.MULTIPLE);
2129 
2130         ObservableList<Integer> indices = sm.getSelectedIndices();
2131         ObservableList<String> items = sm.getSelectedItems();
2132 
2133         indices.addListener((ListChangeListener<Integer>) change -> rt_39088_indices_event_count++);
2134         items.addListener((ListChangeListener<String>) change -> rt_39088_items_event_count++);
2135 
2136         StageLoader sl = new StageLoader(listView);
2137 
2138         assertEquals(0, rt_39088_indices_event_count);
2139         assertEquals(0, rt_39088_items_event_count);
2140         assertEquals(0, indices.size());
2141         assertEquals(0, items.size());
2142 
2143         sm.select(3);
2144         assertEquals(1, rt_39088_indices_event_count);
2145         assertEquals(1, rt_39088_items_event_count);
2146         assertEquals(1, indices.size());
2147         assertEquals(1, items.size());
2148 
2149         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT);
2150         assertEquals(2, rt_39088_indices_event_count);
2151         assertEquals(2, rt_39088_items_event_count);
2152         assertEquals(2, indices.size());
2153         assertEquals(2, items.size());
2154 
2155         // this is where the test fails...
2156         keyboard.doKeyPress(KeyCode.UP, KeyModifier.SHIFT);
2157         assertEquals(3, rt_39088_indices_event_count);
2158         assertEquals(3, rt_39088_items_event_count);
2159         assertEquals(3, indices.size());
2160         assertEquals(3, items.size());
2161 
2162         sl.dispose();
2163     }
2164 
2165     @Test public void test_rt_27709_singleSelection_rowSelection() {
2166         test_rt_27709(SelectionMode.SINGLE, false);
2167     }
2168 
2169     @Test public void test_rt_27709_multipleSelection_rowSelection() {
2170         test_rt_27709(SelectionMode.MULTIPLE, false);
2171     }
2172 
2173     @Test public void test_rt_27709_singleSelection_rowSelection_resetSelection() {
2174         test_rt_27709(SelectionMode.SINGLE, true);
2175     }
2176 
2177     @Test public void test_rt_27709_multipleSelection_rowSelection_resetSelection() {
2178         test_rt_27709(SelectionMode.MULTIPLE, true);
2179     }
2180 
2181     private void test_rt_27709(SelectionMode mode, boolean resetSelection) {
2182         ObservableList<String> itemsList = FXCollections.observableArrayList();
2183         for (int i = 0; i < 10; i++) {
2184             itemsList.add("Row " + i);
2185         }
2186 
2187         listView.setItems(itemsList);
2188 
2189         MultipleSelectionModel<String> sm = listView.getSelectionModel();
2190         sm.setSelectionMode(mode);
2191 
2192         ObservableList<Integer> indices = sm.getSelectedIndices();
2193 
2194         int expectedSize = mode == SelectionMode.SINGLE ? 1 : 10;
2195         int lookupIndex = mode == SelectionMode.SINGLE ? 0 : 9;
2196 
2197         sm.select(0);
2198         assertEquals(1, indices.size());
2199 
2200         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
2201         assertEquals(expectedSize, indices.size());
2202         assertEquals(9, (int) indices.get(lookupIndex));
2203 
2204         if (resetSelection) {
2205             sm.clearAndSelect(9);
2206             int anchor = ListCellBehavior.getAnchor(listView, null);
2207             assertEquals(9, anchor);
2208         } else {
2209             expectedSize = 1;
2210         }
2211 
2212         keyboard.doKeyPress(KeyCode.HOME, KeyModifier.SHIFT);
2213         assertEquals(expectedSize, indices.size());
2214         assertTrue(debug(),sm.isSelected(0));
2215 
2216         if (resetSelection) {
2217             sm.clearAndSelect(0);
2218 
2219             int anchor = ListCellBehavior.getAnchor(listView, null);
2220             assertEquals(0, anchor);
2221         } else {
2222             expectedSize = mode == SelectionMode.SINGLE ? 1 : 10;
2223         }
2224 
2225         keyboard.doKeyPress(KeyCode.END, KeyModifier.SHIFT);
2226         assertEquals(expectedSize, indices.size());
2227         assertTrue(sm.isSelected(9));
2228     }
2229 
2230     @Test public void test_rt_24865_moveDownwards() {
2231         listView.getItems().clear();
2232         for (int i = 0; i < 100; i++) {
2233             listView.getItems().add("Row " + i);
2234         }
2235 
2236         Toolkit.getToolkit().firePulse();
2237 
2238         ObservableList<Integer> indices = sm.getSelectedIndices();
2239 
2240         sm.select(0);
2241         assertTrue(isSelected(0));
2242         assertTrue(fm.isFocused(0));
2243         assertEquals(1, indices.size());
2244         assertEquals(0, (int) ListCellBehavior.getAnchor(listView, -1));
2245 
2246         keyboard.doDownArrowPress(KeyModifier.SHIFT);
2247         keyboard.doDownArrowPress(KeyModifier.SHIFT);
2248         keyboard.doDownArrowPress(KeyModifier.SHIFT);
2249         assertTrue(isSelected(0, 1, 2, 3));
2250         assertTrue(fm.isFocused(3));
2251         assertEquals(4, indices.size());
2252         assertEquals(0, (int) ListCellBehavior.getAnchor(listView, -1));
2253 
2254         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
2255         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
2256         keyboard.doDownArrowPress(KeyModifier.getShortcutKey());
2257         assertTrue(isSelected(0, 1, 2, 3));
2258         assertTrue(isNotSelected(4, 5, 6, 7, 8, 9));
2259         assertTrue(fm.isFocused(6));
2260         assertEquals(4, indices.size());
2261         assertEquals(0, (int) ListCellBehavior.getAnchor(listView, -1));
2262 
2263         // main point of test: selection between the last index (3) and the focus
2264         // index (6) should now be true
2265         keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
2266         final int selectedRowCount = indices.size();
2267         for (int i = 0; i < selectedRowCount; i++) {
2268             assertTrue(isSelected(i));
2269         }
2270         assertTrue(fm.isFocused(selectedRowCount - 1));
2271         assertEquals(0, (int) ListCellBehavior.getAnchor(listView, -1));
2272 
2273         keyboard.doDownArrowPress(KeyModifier.SHIFT);
2274         int newSelectedRowCount = selectedRowCount + 1;
2275         for (int i = 0; i < newSelectedRowCount; i++) {
2276             assertTrue(isSelected(i));
2277         }
2278         assertTrue(fm.isFocused(newSelectedRowCount - 1));
2279         assertEquals(0, (int) ListCellBehavior.getAnchor(listView, -1));
2280     }
2281 
2282     @Test public void test_rt_24865_moveUpwards() {
2283         listView.getItems().clear();
2284         for (int i = 0; i < 100; i++) {
2285             listView.getItems().add("Row " + i);
2286         }
2287 
2288         Toolkit.getToolkit().firePulse();
2289 
2290         ObservableList<Integer> indices = sm.getSelectedIndices();
2291 
2292         sm.select(50);
2293         listView.scrollTo(50);
2294 
2295         Toolkit.getToolkit().firePulse();
2296 
2297         assertTrue(isSelected(50));
2298         assertTrue(fm.isFocused(50));
2299         assertEquals(1, indices.size());
2300         assertEquals(50, (int) ListCellBehavior.getAnchor(listView, -1));
2301 
2302         keyboard.doUpArrowPress(KeyModifier.SHIFT);
2303         keyboard.doUpArrowPress(KeyModifier.SHIFT);
2304         keyboard.doUpArrowPress(KeyModifier.SHIFT);
2305         assertTrue(isSelected(50, 49, 48, 47));
2306         assertTrue(fm.isFocused(47));
2307         assertEquals(4, indices.size());
2308         assertEquals(50, (int) ListCellBehavior.getAnchor(listView, -1));
2309 
2310         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
2311         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
2312         keyboard.doUpArrowPress(KeyModifier.getShortcutKey());
2313         assertTrue(isSelected(50, 49, 48, 47));
2314         assertTrue(isNotSelected(46, 45, 44, 43, 42, 41));
2315         assertTrue(fm.isFocused(44));
2316         assertEquals(4, indices.size());
2317         assertEquals(50, (int) ListCellBehavior.getAnchor(listView, -1));
2318 
2319         // main point of test: selection between the last index (47) and the focus
2320         // index (44) should now be true
2321         keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey(), KeyModifier.SHIFT);
2322         final int selectedRowCount = indices.size();
2323         for (int i = 0; i < selectedRowCount; i++) {
2324             assertTrue(isSelected(50 - i));
2325         }
2326         assertTrue(fm.isFocused(50 - selectedRowCount + 1));
2327         assertEquals(50, (int) ListCellBehavior.getAnchor(listView, -1));
2328 
2329         keyboard.doUpArrowPress(KeyModifier.SHIFT);
2330         int newSelectedRowCount = selectedRowCount + 1;
2331         for (int i = 0; i < newSelectedRowCount; i++) {
2332             assertTrue(isSelected(50 - i));
2333         }
2334         assertTrue(fm.isFocused(50 - newSelectedRowCount + 1));
2335         assertEquals(50, (int) ListCellBehavior.getAnchor(listView, -1));
2336     }
2337 
2338     @Test public void test_jdk_8160858() {
2339         listView.getItems().clear();
2340         for (int i = 0; i < 10; i++) {
2341             listView.getItems().add("Row " + i);
2342         }
2343 
2344         // create a button to move focus over to
2345         Button btn = new Button("Button");
2346         ((Group)listView.getScene().getRoot()).getChildren().add(btn);
2347 
2348         listView.requestFocus();
2349         Toolkit.getToolkit().firePulse();
2350         assertEquals(stageLoader.getStage().getScene().getFocusOwner(), listView);
2351 
2352         // we expect initially that selection is on -1, and focus is on 0
2353         assertEquals(-1, sm.getSelectedIndex());
2354         assertEquals(0, fm.getFocusedIndex());
2355 
2356         keyboard.doDownArrowPress();
2357         assertEquals(1, sm.getSelectedIndex());
2358         assertEquals(1, fm.getFocusedIndex());
2359 
2360         btn.requestFocus();
2361         Toolkit.getToolkit().firePulse();
2362         assertEquals(stageLoader.getStage().getScene().getFocusOwner(), btn);
2363 
2364         listView.requestFocus();
2365         Toolkit.getToolkit().firePulse();
2366         assertEquals(stageLoader.getStage().getScene().getFocusOwner(), listView);
2367 
2368         assertEquals(1, sm.getSelectedIndex());
2369         assertEquals(1, fm.getFocusedIndex());
2370     }
2371 }