1 /* 2 * Copyright (c) 2011, 2015, 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 javafx.scene.control; 27 28 import static com.sun.javafx.scene.control.infrastructure.ControlTestUtils.assertStyleClassContains; 29 import static org.junit.Assert.assertArrayEquals; 30 import static org.junit.Assert.assertEquals; 31 import static org.junit.Assert.assertFalse; 32 import static org.junit.Assert.assertNotNull; 33 import static org.junit.Assert.assertNull; 34 import static org.junit.Assert.assertSame; 35 import static org.junit.Assert.assertTrue; 36 import static org.junit.Assert.fail; 37 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.Collections; 41 import java.util.List; 42 43 import com.sun.javafx.scene.control.behavior.ListCellBehavior; 44 import com.sun.javafx.scene.control.behavior.TableCellBehavior; 45 import com.sun.javafx.scene.control.infrastructure.KeyEventFirer; 46 import com.sun.javafx.scene.control.infrastructure.KeyModifier; 47 import javafx.application.Platform; 48 import javafx.beans.binding.Bindings; 49 import javafx.beans.property.ObjectProperty; 50 import javafx.beans.property.ReadOnlyBooleanWrapper; 51 import javafx.beans.property.ReadOnlyStringWrapper; 52 import javafx.beans.property.SimpleObjectProperty; 53 import javafx.collections.FXCollections; 54 import javafx.collections.ListChangeListener; 55 import javafx.collections.ObservableList; 56 import javafx.event.ActionEvent; 57 import javafx.scene.Parent; 58 import javafx.scene.Scene; 59 import javafx.scene.control.cell.CheckBoxListCell; 60 import javafx.scene.control.cell.ComboBoxListCell; 61 import javafx.scene.control.cell.TextFieldListCell; 62 import javafx.scene.control.cell.TextFieldTableCell; 63 import javafx.scene.image.ImageView; 64 import javafx.scene.input.KeyCode; 65 import javafx.scene.layout.HBox; 66 import javafx.scene.layout.VBox; 67 import javafx.scene.paint.Color; 68 import javafx.scene.shape.Rectangle; 69 import javafx.util.Callback; 70 71 import org.junit.Before; 72 import org.junit.Ignore; 73 import org.junit.Test; 74 75 import com.sun.javafx.scene.control.infrastructure.VirtualFlowTestUtils; 76 import com.sun.javafx.scene.control.infrastructure.StageLoader; 77 import com.sun.javafx.scene.control.skin.VirtualScrollBar; 78 import com.sun.javafx.scene.control.test.Person; 79 import com.sun.javafx.scene.control.test.RT_22463_Person; 80 import com.sun.javafx.tk.Toolkit; 81 82 public class ListViewTest { 83 private ListView<String> listView; 84 private MultipleSelectionModel<String> sm; 85 private FocusModel<String> fm; 86 87 @Before public void setup() { 88 listView = new ListView<>(); 89 sm = listView.getSelectionModel(); 90 fm = listView.getFocusModel(); 91 } 92 93 94 /********************************************************************* 95 * Tests for the constructors * 96 ********************************************************************/ 97 98 @Test public void noArgConstructorSetsTheStyleClass() { 99 assertStyleClassContains(listView, "list-view"); 100 } 101 102 @Test public void noArgConstructorSetsNonNullSelectionModel() { 103 assertNotNull(sm); 104 } 105 106 @Test public void noArgConstructorSetsNonNullItems() { 107 assertNotNull(listView.getItems()); 108 } 109 110 @Test public void noArgConstructor_selectedItemIsNull() { 111 assertNull(sm.getSelectedItem()); 112 } 113 114 @Test public void noArgConstructor_selectedIndexIsNegativeOne() { 115 assertEquals(-1, sm.getSelectedIndex()); 116 } 117 118 @Test public void singleArgConstructorSetsTheStyleClass() { 119 final ListView<String> b2 = new ListView<>(FXCollections.observableArrayList("Hi")); 120 assertStyleClassContains(b2, "list-view"); 121 } 122 123 @Test public void singleArgConstructorSetsNonNullSelectionModel() { 124 final ListView<String> b2 = new ListView<>(FXCollections.<String>observableArrayList("Hi")); 125 assertNotNull(b2.getSelectionModel()); 126 } 127 128 @Test public void singleArgConstructorAllowsNullItems() { 129 final ListView<String> b2 = new ListView<String>(null); 130 assertNull(b2.getItems()); 131 } 132 133 @Test public void singleArgConstructorTakesItems() { 134 ObservableList<String> items = FXCollections.observableArrayList("Hi"); 135 final ListView<String> b2 = new ListView<>(items); 136 assertSame(items, b2.getItems()); 137 } 138 139 @Test public void singleArgConstructor_selectedItemIsNull() { 140 final ListView<String> b2 = new ListView<>(FXCollections.observableArrayList("Hi")); 141 assertNull(b2.getSelectionModel().getSelectedItem()); 142 } 143 144 @Test public void singleArgConstructor_selectedIndexIsNegativeOne() { 145 final ListView<String> b2 = new ListView<>(FXCollections.observableArrayList("Hi")); 146 assertEquals(-1, b2.getSelectionModel().getSelectedIndex()); 147 } 148 149 /********************************************************************* 150 * Tests for selection model * 151 ********************************************************************/ 152 153 @Test public void selectionModelCanBeNull() { 154 listView.setSelectionModel(null); 155 assertNull(listView.getSelectionModel()); 156 } 157 158 @Test public void selectionModelCanBeBound() { 159 MultipleSelectionModel<String> sm = new ListView.ListViewBitSetSelectionModel<String>(listView); 160 ObjectProperty<MultipleSelectionModel<String>> other = new SimpleObjectProperty<MultipleSelectionModel<String>>(sm); 161 listView.selectionModelProperty().bind(other); 162 assertSame(sm, sm); 163 } 164 165 @Test public void selectionModelCanBeChanged() { 166 MultipleSelectionModel<String> sm = new ListView.ListViewBitSetSelectionModel<String>(listView); 167 listView.setSelectionModel(sm); 168 assertSame(sm, sm); 169 } 170 171 @Test public void canSetSelectedItemToAnItemEvenWhenThereAreNoItems() { 172 final String randomString = new String("I AM A CRAZY RANDOM STRING"); 173 sm.select(randomString); 174 assertEquals(-1, sm.getSelectedIndex()); 175 assertSame(randomString, sm.getSelectedItem()); 176 } 177 178 @Test public void canSetSelectedItemToAnItemNotInTheDataModel() { 179 listView.getItems().addAll("Apple", "Orange", "Banana"); 180 final String randomString = new String("I AM A CRAZY RANDOM STRING"); 181 sm.select(randomString); 182 assertEquals(-1, sm.getSelectedIndex()); 183 assertSame(randomString, sm.getSelectedItem()); 184 } 185 186 @Test public void settingTheSelectedItemToAnItemInItemsResultsInTheCorrectSelectedIndex() { 187 listView.getItems().addAll("Apple", "Orange", "Banana"); 188 sm.select("Orange"); 189 assertEquals(1, sm.getSelectedIndex()); 190 assertSame("Orange", sm.getSelectedItem()); 191 } 192 193 @Test public void settingTheSelectedItemToANonexistantItemAndThenSettingItemsWhichContainsItResultsInCorrectSelectedIndex() { 194 sm.select("Orange"); 195 listView.getItems().addAll("Apple", "Orange", "Banana"); 196 assertEquals(1, sm.getSelectedIndex()); 197 assertSame("Orange", sm.getSelectedItem()); 198 } 199 200 @Test public void ensureSelectionClearsWhenAllItemsAreRemoved_selectIndex0() { 201 listView.getItems().addAll("Apple", "Orange", "Banana"); 202 sm.select(0); 203 listView.getItems().clear(); 204 assertEquals(-1, sm.getSelectedIndex()); 205 assertEquals(null, sm.getSelectedItem()); 206 } 207 208 @Test public void ensureSelectionClearsWhenAllItemsAreRemoved_selectIndex2() { 209 listView.getItems().addAll("Apple", "Orange", "Banana"); 210 sm.select(2); 211 listView.getItems().clear(); 212 assertEquals(-1, sm.getSelectedIndex()); 213 assertEquals(null, sm.getSelectedItem()); 214 } 215 216 @Test public void ensureSelectedItemRemainsAccurateWhenItemsAreCleared() { 217 listView.getItems().addAll("Apple", "Orange", "Banana"); 218 sm.select(2); 219 listView.getItems().clear(); 220 assertNull(sm.getSelectedItem()); 221 assertEquals(-1, sm.getSelectedIndex()); 222 223 listView.getItems().addAll("Kiwifruit", "Mandarin", "Pineapple"); 224 sm.select(2); 225 assertEquals("Pineapple", sm.getSelectedItem()); 226 } 227 228 @Test public void ensureSelectionShiftsDownWhenOneNewItemIsAdded() { 229 listView.getItems().addAll("Apple", "Orange", "Banana"); 230 sm.select(1); 231 assertEquals(1, sm.getSelectedIndex()); 232 assertEquals("Orange", sm.getSelectedItem()); 233 234 listView.getItems().add(0, "Kiwifruit"); 235 assertEquals(2, sm.getSelectedIndex()); 236 assertEquals("Orange", sm.getSelectedItem()); 237 } 238 239 @Test public void ensureSelectionShiftsDownWhenMultipleNewItemAreAdded() { 240 listView.getItems().addAll("Apple", "Orange", "Banana"); 241 sm.select(1); 242 assertEquals(1, sm.getSelectedIndex()); 243 assertEquals("Orange", sm.getSelectedItem()); 244 245 listView.getItems().addAll(0, Arrays.asList("Kiwifruit", "Pineapple", "Mandarin")); 246 assertEquals("Orange", sm.getSelectedItem()); 247 assertEquals(4, sm.getSelectedIndex()); 248 } 249 250 @Test public void ensureSelectionShiftsUpWhenOneItemIsRemoved() { 251 listView.getItems().addAll("Apple", "Orange", "Banana"); 252 sm.select(1); 253 assertEquals(1, sm.getSelectedIndex()); 254 assertEquals("Orange", sm.getSelectedItem()); 255 256 listView.getItems().remove("Apple"); 257 assertEquals(0, sm.getSelectedIndex()); 258 assertEquals("Orange", sm.getSelectedItem()); 259 } 260 261 @Test public void ensureSelectionShiftsUpWheMultipleItemsAreRemoved() { 262 listView.getItems().addAll("Apple", "Orange", "Banana"); 263 sm.select(2); 264 assertEquals(2, sm.getSelectedIndex()); 265 assertEquals("Banana", sm.getSelectedItem()); 266 267 listView.getItems().removeAll(Arrays.asList("Apple", "Orange")); 268 assertEquals(0, sm.getSelectedIndex()); 269 assertEquals("Banana", sm.getSelectedItem()); 270 } 271 272 @Test public void ensureSelectionIsCorrectWhenItemsChange() { 273 listView.setItems(FXCollections.observableArrayList("Item 1")); 274 sm.select(0); 275 assertEquals("Item 1", sm.getSelectedItem()); 276 277 listView.setItems(FXCollections.observableArrayList("Item 2")); 278 assertEquals(-1, sm.getSelectedIndex()); 279 assertNull(sm.getSelectedItem()); 280 assertEquals(0, fm.getFocusedIndex()); 281 assertEquals("Item 2", fm.getFocusedItem()); 282 } 283 284 @Test public void test_rt15793() { 285 // ListView selectedIndex is 0 although the items list is empty 286 final ListView lv = new ListView(); 287 final ObservableList list = FXCollections.observableArrayList(); 288 lv.setItems(list); 289 list.add("toto"); 290 lv.getSelectionModel().select(0); 291 assertEquals(0, lv.getSelectionModel().getSelectedIndex()); 292 list.remove(0); 293 assertEquals(-1, lv.getSelectionModel().getSelectedIndex()); 294 } 295 296 @Test public void test_rt17522_focusShouldMoveWhenItemAddedAtFocusIndex() { 297 final ListView lv = new ListView(); 298 FocusModel fm = lv.getFocusModel(); 299 lv.getItems().add("row1"); 300 fm.focus(0); 301 assertTrue(fm.isFocused(0)); 302 303 lv.getItems().add(0, "row0"); 304 assertTrue(fm.isFocused(1)); 305 } 306 307 @Test public void test_rt17522_focusShouldMoveWhenItemAddedBeforeFocusIndex() { 308 final ListView lv = new ListView(); 309 FocusModel fm = lv.getFocusModel(); 310 lv.getItems().addAll("row1", "row2"); 311 fm.focus(1); 312 assertTrue(fm.isFocused(1)); 313 assertEquals("row2", fm.getFocusedItem()); 314 315 lv.getItems().add(1, "row0"); 316 assertTrue(fm.isFocused(2)); 317 assertEquals("row2", fm.getFocusedItem()); 318 assertFalse(fm.isFocused(1)); 319 } 320 321 @Test public void test_rt17522_focusShouldNotMoveWhenItemAddedAfterFocusIndex() { 322 final ListView lv = new ListView(); 323 FocusModel fm = lv.getFocusModel(); 324 lv.getItems().addAll("row1"); 325 fm.focus(0); 326 assertTrue(fm.isFocused(0)); 327 assertEquals("row1", fm.getFocusedItem()); 328 329 lv.getItems().add(1, "row2"); 330 assertTrue(fm.isFocused(0)); 331 assertEquals("row1", fm.getFocusedItem()); 332 assertFalse(fm.isFocused(1)); 333 } 334 335 @Test public void test_rt17522_focusShouldBeResetWhenFocusedItemIsRemoved() { 336 final ListView lv = new ListView(); 337 FocusModel fm = lv.getFocusModel(); 338 lv.getItems().add("row1"); 339 fm.focus(0); 340 assertTrue(fm.isFocused(0)); 341 342 lv.getItems().remove("row1"); 343 assertTrue(fm.getFocusedIndex() == -1); 344 assertNull(fm.getFocusedItem()); 345 } 346 347 @Test public void test_rt17522_focusShouldMoveWhenItemRemovedBeforeFocusIndex() { 348 final ListView lv = new ListView(); 349 FocusModel fm = lv.getFocusModel(); 350 lv.getItems().addAll("row1", "row2"); 351 fm.focus(1); 352 assertTrue(fm.isFocused(1)); 353 assertEquals("row2", fm.getFocusedItem()); 354 355 lv.getItems().remove("row1"); 356 assertTrue(fm.isFocused(0)); 357 assertEquals("row2", fm.getFocusedItem()); 358 } 359 360 @Test public void test_rt17522_focusShouldNotMoveWhenItemRemovedAfterFocusIndex() { 361 final ListView lv = new ListView(); 362 FocusModel fm = lv.getFocusModel(); 363 lv.getItems().addAll("row1", "row2"); 364 fm.focus(0); 365 assertTrue(fm.isFocused(0)); 366 assertEquals("row1", fm.getFocusedItem()); 367 368 lv.getItems().remove("row2"); 369 assertTrue(fm.isFocused(0)); 370 assertEquals("row1", fm.getFocusedItem()); 371 } 372 373 @Test public void test_rt18385() { 374 listView.getItems().addAll("row1", "row2", "row3"); 375 sm.select(1); 376 listView.getItems().add("Another Row"); 377 assertEquals(1, sm.getSelectedIndices().size()); 378 assertEquals(1, sm.getSelectedItems().size()); 379 } 380 381 @Test public void test_rt18339_onlyEditWhenListViewIsEditable_editableIsFalse() { 382 listView.setEditable(false); 383 listView.edit(1); 384 assertEquals(-1, listView.getEditingIndex()); 385 } 386 387 @Test public void test_rt18339_onlyEditWhenListViewIsEditable_editableIsTrue() { 388 listView.setEditable(true); 389 listView.edit(1); 390 assertEquals(1, listView.getEditingIndex()); 391 } 392 393 @Test public void test_rt14451() { 394 listView.getItems().addAll("Apple", "Orange", "Banana"); 395 sm.setSelectionMode(SelectionMode.MULTIPLE); 396 sm.selectRange(0, 2); // select from 0 (inclusive) to 2 (exclusive) 397 assertEquals(2, sm.getSelectedIndices().size()); 398 } 399 400 private int rt_18969_hitCount = 0; 401 @Test public void test_rt18969() { 402 rt_18969_hitCount = 0; 403 ObservableList<String> emptyModel = FXCollections.observableArrayList(); 404 listView.setItems(emptyModel); 405 assertTrue(listView.getItems().isEmpty()); 406 407 sm.selectedItemProperty().addListener((observable, oldValue, newValue) -> { 408 rt_18969_hitCount++; 409 }); 410 411 ObservableList<String> mod = FXCollections.observableArrayList(); 412 mod.add(System.currentTimeMillis()+""); 413 listView.getItems().setAll(mod); 414 415 sm.select(0); 416 assertTrue(sm.isSelected(0)); 417 assertEquals(1, rt_18969_hitCount); 418 419 // sleep for 100ms so that the currentTimeMillis is guaranteed to be 420 // a different value than the first one 421 try { 422 Thread.sleep(100); 423 } catch (InterruptedException ex) { 424 ex.printStackTrace(); 425 } 426 427 // the list is totally changing (it is being cleared), so we should 428 // be nulling out the selection model state 429 mod = FXCollections.observableArrayList(); 430 mod.add(System.currentTimeMillis()+""); 431 listView.getItems().setAll(mod); 432 433 // it should be two, as there is no null event in between (although there 434 // used to be, so the test used to be for three hits) 435 assertEquals(2, rt_18969_hitCount); 436 } 437 438 @Test public void test_rt21586() { 439 listView.getItems().setAll("Apple", "Orange", "Banana"); 440 listView.getSelectionModel().select(1); 441 assertEquals(1, listView.getSelectionModel().getSelectedIndex()); 442 assertEquals("Orange", listView.getSelectionModel().getSelectedItem()); 443 444 listView.getItems().setAll("Kiwifruit", "Pineapple", "Grape"); 445 assertEquals(-1, listView.getSelectionModel().getSelectedIndex()); 446 assertNull(listView.getSelectionModel().getSelectedItem()); 447 } 448 449 @Test public void test_rt27820_1() { 450 listView.getItems().setAll("Apple", "Orange"); 451 listView.getSelectionModel().select(0); 452 assertEquals(1, listView.getSelectionModel().getSelectedItems().size()); 453 assertEquals("Apple", listView.getSelectionModel().getSelectedItem()); 454 455 listView.getItems().clear(); 456 assertEquals(0, listView.getSelectionModel().getSelectedItems().size()); 457 assertNull(listView.getSelectionModel().getSelectedItem()); 458 } 459 460 @Test public void test_rt27820_2() { 461 listView.getItems().setAll("Apple", "Orange"); 462 listView.getSelectionModel().select(1); 463 assertEquals(1, listView.getSelectionModel().getSelectedItems().size()); 464 assertEquals("Orange", listView.getSelectionModel().getSelectedItem()); 465 466 listView.getItems().clear(); 467 assertEquals(0, listView.getSelectionModel().getSelectedItems().size()); 468 assertNull(listView.getSelectionModel().getSelectedItem()); 469 } 470 471 @Test public void test_rt28534() { 472 ListView<Person> list = new ListView<Person>(); 473 list.setItems(FXCollections.observableArrayList( 474 new Person("Jacob", "Smith", "jacob.smith@example.com"), 475 new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 476 new Person("Ethan", "Williams", "ethan.williams@example.com"), 477 new Person("Emma", "Jones", "emma.jones@example.com"), 478 new Person("Michael", "Brown", "michael.brown@example.com"))); 479 480 VirtualFlowTestUtils.assertRowsNotEmpty(list, 0, 5); // rows 0 - 5 should be filled 481 VirtualFlowTestUtils.assertRowsEmpty(list, 5, -1); // rows 5+ should be empty 482 483 // now we replace the data and expect the cells that have no data 484 // to be empty 485 list.setItems(FXCollections.observableArrayList( 486 new Person("*_*Emma", "Jones", "emma.jones@example.com"), 487 new Person("_Michael", "Brown", "michael.brown@example.com"))); 488 489 VirtualFlowTestUtils.assertRowsNotEmpty(list, 0, 2); // rows 0 - 2 should be filled 490 VirtualFlowTestUtils.assertRowsEmpty(list, 2, -1); // rows 2+ should be empty 491 } 492 493 @Test public void test_rt22463() { 494 final ListView<RT_22463_Person> list = new ListView<RT_22463_Person>(); 495 496 // before the change things display fine 497 RT_22463_Person p1 = new RT_22463_Person(); 498 p1.setId(1l); 499 p1.setName("name1"); 500 RT_22463_Person p2 = new RT_22463_Person(); 501 p2.setId(2l); 502 p2.setName("name2"); 503 list.setItems(FXCollections.observableArrayList(p1, p2)); 504 VirtualFlowTestUtils.assertCellTextEquals(list, 0, "name1"); 505 VirtualFlowTestUtils.assertCellTextEquals(list, 1, "name2"); 506 507 // now we change the persons but they are still equal as the ID's don't 508 // change - but the items list is cleared so the cells should update 509 RT_22463_Person new_p1 = new RT_22463_Person(); 510 new_p1.setId(1l); 511 new_p1.setName("updated name1"); 512 RT_22463_Person new_p2 = new RT_22463_Person(); 513 new_p2.setId(2l); 514 new_p2.setName("updated name2"); 515 list.getItems().clear(); 516 list.setItems(FXCollections.observableArrayList(new_p1, new_p2)); 517 VirtualFlowTestUtils.assertCellTextEquals(list, 0, "updated name1"); 518 VirtualFlowTestUtils.assertCellTextEquals(list, 1, "updated name2"); 519 } 520 521 @Test public void test_rt28637() { 522 ObservableList<String> items = FXCollections.observableArrayList("String1", "String2", "String3", "String4"); 523 524 final ListView<String> listView = new ListView<String>(); 525 listView.setItems(items); 526 527 listView.getSelectionModel().select(0); 528 assertEquals("String1", listView.getSelectionModel().getSelectedItem()); 529 assertEquals("String1", listView.getSelectionModel().getSelectedItems().get(0)); 530 assertEquals(0, listView.getSelectionModel().getSelectedIndex()); 531 532 items.remove(listView.getSelectionModel().getSelectedItem()); 533 assertEquals("String2", listView.getSelectionModel().getSelectedItem()); 534 assertEquals("String2", listView.getSelectionModel().getSelectedItems().get(0)); 535 assertEquals(0, listView.getSelectionModel().getSelectedIndex()); 536 } 537 538 @Test public void test_rt28819_1() { 539 ObservableList<String> emptyModel = FXCollections.observableArrayList(); 540 541 final ListView<String> listView = new ListView<String>(); 542 listView.setItems(emptyModel); 543 VirtualFlowTestUtils.assertRowsEmpty(listView, 0, 5); 544 545 ObservableList<String> mod = FXCollections.observableArrayList(); 546 String value = System.currentTimeMillis()+""; 547 mod.add(value); 548 listView.setItems(mod); 549 VirtualFlowTestUtils.assertCellCount(listView, 1); 550 VirtualFlowTestUtils.assertCellTextEquals(listView, 0, value); 551 } 552 553 @Test public void test_rt28819_2() { 554 ObservableList<String> emptyModel = FXCollections.observableArrayList(); 555 556 final ListView<String> listView = new ListView<String>(); 557 listView.setItems(emptyModel); 558 VirtualFlowTestUtils.assertRowsEmpty(listView, 0, 5); 559 560 ObservableList<String> mod1 = FXCollections.observableArrayList(); 561 String value1 = System.currentTimeMillis()+""; 562 mod1.add(value1); 563 listView.getItems().setAll(mod1); 564 VirtualFlowTestUtils.assertCellCount(listView, 1); 565 VirtualFlowTestUtils.assertCellTextEquals(listView, 0, value1); 566 } 567 568 @Test public void test_rt29390() { 569 ObservableList<String> items = FXCollections.observableArrayList( 570 "String1", "String2", "String3", "String4", 571 "String1", "String2", "String3", "String4", 572 "String1", "String2", "String3", "String4", 573 "String1", "String2", "String3", "String4" 574 ); 575 576 final ListView<String> listView = new ListView<String>(items); 577 listView.setMaxHeight(50); 578 listView.setPrefHeight(50); 579 580 // we want the vertical scrollbar 581 VirtualScrollBar scrollBar = VirtualFlowTestUtils.getVirtualFlowVerticalScrollbar(listView); 582 583 assertNotNull(scrollBar); 584 assertTrue(scrollBar.isVisible()); 585 assertTrue(scrollBar.getVisibleAmount() > 0.0); 586 assertTrue(scrollBar.getVisibleAmount() < 1.0); 587 588 // this next test is likely to be brittle, but we'll see...If it is the 589 // cause of failure then it can be commented out 590 assertEquals(0.125, scrollBar.getVisibleAmount(), 0.0); 591 } 592 593 @Test public void test_rt30400() { 594 // create a listview that'll render cells using the check box cell factory 595 ObservableList<String> items = FXCollections.observableArrayList("String1"); 596 final ListView<String> listView = new ListView<String>(items); 597 listView.setMinHeight(100); 598 listView.setPrefHeight(100); 599 listView.setCellFactory(CheckBoxListCell.forListView(param -> new ReadOnlyBooleanWrapper(true))); 600 601 // because only the first row has data, all other rows should be 602 // empty (and not contain check boxes - we just check the first four here) 603 VirtualFlowTestUtils.assertRowsNotEmpty(listView, 0, 1); 604 VirtualFlowTestUtils.assertCellNotEmpty(VirtualFlowTestUtils.getCell(listView, 0)); 605 VirtualFlowTestUtils.assertCellEmpty(VirtualFlowTestUtils.getCell(listView, 1)); 606 VirtualFlowTestUtils.assertCellEmpty(VirtualFlowTestUtils.getCell(listView, 2)); 607 VirtualFlowTestUtils.assertCellEmpty(VirtualFlowTestUtils.getCell(listView, 3)); 608 } 609 610 @Test public void test_rt29420() { 611 final ListView<String> listView = new ListView<String>(); 612 613 VBox vbox = new VBox(listView); 614 StageLoader sl = new StageLoader(vbox); 615 616 // the initial width of a ListView should be the golden rectangle where 617 // the height is hardcoded to be 400 618 final double initialWidth = listView.prefWidth(-1); 619 assertEquals(400 * 0.618033987, initialWidth, 0.00); 620 621 // add in some items, and re-measure - seeing as the items are narrow, 622 // the width shouldn't change 623 listView.getItems().addAll("one", "two", "three", "four", "five", "six"); 624 Toolkit.getToolkit().firePulse(); 625 final double withContentWidth = listView.prefWidth(-1); 626 assertEquals(initialWidth, withContentWidth, 0.00); 627 628 // remove the items - and the width should remain the same 629 listView.getItems().clear(); 630 Toolkit.getToolkit().firePulse(); 631 final double afterEmptiedWidth = listView.prefWidth(-1); 632 assertEquals(initialWidth, afterEmptiedWidth, 0.00); 633 634 sl.dispose(); 635 } 636 637 @Test public void test_rt31165() { 638 final ObservableList names = FXCollections.observableArrayList("Adam", "Alex", "Alfred", "Albert"); 639 final ObservableList data = FXCollections.observableArrayList(); 640 for (int i = 0; i < 18; i++) { 641 data.add(""+i); 642 } 643 644 final ListView listView = new ListView(data); 645 listView.setPrefSize(200, 250); 646 listView.setEditable(true); 647 listView.setCellFactory(ComboBoxListCell.forListView(names)); 648 649 IndexedCell cell = VirtualFlowTestUtils.getCell(listView, 1); 650 assertEquals("1", cell.getText()); 651 assertFalse(cell.isEditing()); 652 653 listView.edit(1); 654 655 assertEquals(1, listView.getEditingIndex()); 656 assertTrue(cell.isEditing()); 657 658 VirtualFlowTestUtils.getVirtualFlow(listView).requestLayout(); 659 Toolkit.getToolkit().firePulse(); 660 661 assertEquals(1, listView.getEditingIndex()); 662 assertTrue(cell.isEditing()); 663 } 664 665 @Test public void test_rt31471() { 666 final ObservableList names = FXCollections.observableArrayList("Adam", "Alex", "Alfred", "Albert"); 667 final ListView listView = new ListView(names); 668 669 IndexedCell cell = VirtualFlowTestUtils.getCell(listView, 0); 670 assertEquals("Adam", cell.getItem()); 671 672 listView.setFixedCellSize(50); 673 674 VirtualFlowTestUtils.getVirtualFlow(listView).requestLayout(); 675 Toolkit.getToolkit().firePulse(); 676 677 assertEquals("Adam", cell.getItem()); 678 assertEquals(50, cell.getHeight(), 0.00); 679 } 680 681 private int rt_31200_count = 0; 682 @Test public void test_rt_31200() { 683 final ListView listView = new ListView(); 684 listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() { 685 @Override 686 public ListCell<String> call(ListView<String> param) { 687 return new ListCell<String>() { 688 ImageView view = new ImageView(); 689 { setGraphic(view); }; 690 691 @Override 692 protected void updateItem(String item, boolean empty) { 693 if (getItem() == null ? item == null : getItem().equals(item)) { 694 rt_31200_count++; 695 } 696 super.updateItem(item, empty); 697 if (item == null || empty) { 698 view.setImage(null); 699 setText(null); 700 } else { 701 setText(item); 702 } 703 } 704 }; 705 } 706 }); 707 listView.getItems().setAll("one", "two", "three", "four", "five"); 708 709 StageLoader sl = new StageLoader(listView); 710 711 assertEquals(24, rt_31200_count); 712 713 // resize the stage 714 sl.getStage().setHeight(250); 715 Toolkit.getToolkit().firePulse(); 716 sl.getStage().setHeight(50); 717 Toolkit.getToolkit().firePulse(); 718 assertEquals(24, rt_31200_count); 719 720 sl.dispose(); 721 } 722 723 @Test public void test_rt_30484() { 724 final ListView listView = new ListView(); 725 listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() { 726 @Override public ListCell<String> call(ListView<String> param) { 727 return new ListCell<String>() { 728 Rectangle graphic = new Rectangle(10, 10, Color.RED); 729 { setGraphic(graphic); }; 730 731 @Override protected void updateItem(String item, boolean empty) { 732 super.updateItem(item, empty); 733 if (item == null || empty) { 734 graphic.setVisible(false); 735 setText(null); 736 } else { 737 graphic.setVisible(true); 738 setText(item); 739 } 740 } 741 }; 742 } 743 }); 744 745 // First two rows have content, so the graphic should show. 746 // All other rows have no content, so graphic should not show. 747 listView.getItems().setAll("one", "two"); 748 749 VirtualFlowTestUtils.assertGraphicIsVisible(listView, 0); 750 VirtualFlowTestUtils.assertGraphicIsVisible(listView, 1); 751 VirtualFlowTestUtils.assertGraphicIsNotVisible(listView, 2); 752 VirtualFlowTestUtils.assertGraphicIsNotVisible(listView, 3); 753 VirtualFlowTestUtils.assertGraphicIsNotVisible(listView, 4); 754 VirtualFlowTestUtils.assertGraphicIsNotVisible(listView, 5); 755 } 756 757 private int rt_29650_start_count = 0; 758 private int rt_29650_commit_count = 0; 759 private int rt_29650_cancel_count = 0; 760 @Test public void test_rt_29650() { 761 listView.setOnEditStart(t -> { 762 rt_29650_start_count++; 763 }); 764 listView.setOnEditCommit(t -> { 765 rt_29650_commit_count++; 766 }); 767 listView.setOnEditCancel(t -> { 768 rt_29650_cancel_count++; 769 }); 770 771 listView.getItems().setAll("one", "two", "three", "four", "five"); 772 listView.setEditable(true); 773 listView.setCellFactory(TextFieldListCell.forListView()); 774 775 StageLoader sl = new StageLoader(listView); 776 777 listView.edit(0); 778 779 Toolkit.getToolkit().firePulse(); 780 781 ListCell rootCell = (ListCell) VirtualFlowTestUtils.getCell(listView, 0); 782 TextField textField = (TextField) rootCell.getGraphic(); 783 textField.setText("Testing!"); 784 KeyEventFirer keyboard = new KeyEventFirer(textField); 785 keyboard.doKeyPress(KeyCode.ENTER); 786 787 // TODO should the following assert be enabled? 788 // assertEquals("Testing!", listView.getItems().get(0)); 789 assertEquals(1, rt_29650_start_count); 790 assertEquals(1, rt_29650_commit_count); 791 assertEquals(0, rt_29650_cancel_count); 792 793 sl.dispose(); 794 } 795 796 @Test public void test_rt35039() { 797 final List<String> data = new ArrayList<>(); 798 data.add("aabbaa"); 799 data.add("bbc"); 800 801 final ListView<String> listView = new ListView<>(); 802 listView.setItems(FXCollections.observableArrayList(data)); 803 804 StageLoader sl = new StageLoader(listView); 805 806 // selection starts off on row -1 807 assertNull(listView.getSelectionModel().getSelectedItem()); 808 809 // select "bbc" and ensure everything is set to that 810 listView.getSelectionModel().select(1); 811 assertEquals("bbc", listView.getSelectionModel().getSelectedItem()); 812 813 // change the items list - but retain the same content. We expect 814 // that "bbc" remains selected as it is still in the list 815 listView.setItems(FXCollections.observableArrayList(data)); 816 assertEquals("bbc", listView.getSelectionModel().getSelectedItem()); 817 818 sl.dispose(); 819 } 820 821 @Test public void test_rt35857() { 822 ObservableList<String> fxList = FXCollections.observableArrayList("A", "B", "C"); 823 final ListView<String> listView = new ListView<String>(fxList); 824 825 listView.getSelectionModel().select(0); 826 827 ObservableList<String> selectedItems = listView.getSelectionModel().getSelectedItems(); 828 assertEquals(1, selectedItems.size()); 829 assertEquals("A", selectedItems.get(0)); 830 831 listView.getItems().removeAll(selectedItems); 832 assertEquals(2, fxList.size()); 833 assertEquals("B", fxList.get(0)); 834 assertEquals("C", fxList.get(1)); 835 } 836 837 private int rt_35889_cancel_count = 0; 838 @Test public void test_rt35889() { 839 final ListView<String> textFieldListView = new ListView<String>(); 840 textFieldListView.setItems(FXCollections.observableArrayList("A", "B", "C")); 841 textFieldListView.setEditable(true); 842 textFieldListView.setCellFactory(TextFieldListCell.forListView()); 843 textFieldListView.setOnEditCancel(t -> { 844 rt_35889_cancel_count++; 845 System.out.println("On Edit Cancel: " + t); 846 }); 847 848 ListCell cell0 = (ListCell) VirtualFlowTestUtils.getCell(textFieldListView, 0); 849 assertNull(cell0.getGraphic()); 850 assertEquals("A", cell0.getText()); 851 852 textFieldListView.edit(0); 853 TextField textField = (TextField) cell0.getGraphic(); 854 assertNotNull(textField); 855 856 assertEquals(0, rt_35889_cancel_count); 857 858 textField.setText("Z"); 859 KeyEventFirer keyboard = new KeyEventFirer(textField); 860 keyboard.doKeyPress(KeyCode.ENTER); 861 862 assertEquals(0, rt_35889_cancel_count); 863 } 864 865 @Test public void test_rt25679() { 866 Button focusBtn = new Button("Focus here"); 867 868 final ListView<String> listView = new ListView<String>(); 869 SelectionModel sm = listView.getSelectionModel(); 870 listView.setItems(FXCollections.observableArrayList("A", "B", "C")); 871 872 VBox vbox = new VBox(focusBtn, listView); 873 874 StageLoader sl = new StageLoader(vbox); 875 sl.getStage().requestFocus(); 876 focusBtn.requestFocus(); 877 Toolkit.getToolkit().firePulse(); 878 879 // test initial state 880 assertEquals(sl.getStage().getScene().getFocusOwner(), focusBtn); 881 assertTrue(focusBtn.isFocused()); 882 assertEquals(-1, sm.getSelectedIndex()); 883 assertNull(sm.getSelectedItem()); 884 885 // move focus to the listview 886 listView.requestFocus(); 887 888 // ensure that there is a selection (where previously there was not one) 889 assertEquals(sl.getStage().getScene().getFocusOwner(), listView); 890 assertTrue(listView.isFocused()); 891 assertEquals(-1, sm.getSelectedIndex()); 892 assertNull(sm.getSelectedItem()); 893 894 sl.dispose(); 895 } 896 897 private int rt_37061_index_counter = 0; 898 private int rt_37061_item_counter = 0; 899 @Test public void test_rt_37061() { 900 ListView<Integer> tv = new ListView<>(); 901 tv.getItems().add(1); 902 tv.getSelectionModel().select(0); 903 904 // note we add the listeners after the selection is made, so the counters 905 // at this point are still both at zero. 906 tv.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> { 907 rt_37061_index_counter++; 908 }); 909 910 tv.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { 911 rt_37061_item_counter++; 912 }); 913 914 // add a new item. This does not impact the selected index or selected item 915 // so the counters should remain at zero. 916 tv.getItems().add(2); 917 assertEquals(0, rt_37061_index_counter); 918 assertEquals(0, rt_37061_item_counter); 919 } 920 921 private int rt_37538_count = 0; 922 @Test public void test_rt_37538_noCNextCall() { 923 test_rt_37538(false, false); 924 } 925 926 @Test public void test_rt_37538_callCNextOnce() { 927 test_rt_37538(true, false); 928 } 929 930 @Test public void test_rt_37538_callCNextInLoop() { 931 test_rt_37538(false, true); 932 } 933 934 private void test_rt_37538(boolean callCNextOnce, boolean callCNextInLoop) { 935 ListView<Integer> list = new ListView<>(); 936 for ( int i = 1; i <= 50; i++ ) { 937 list.getItems().add(i); 938 } 939 940 list.getSelectionModel().getSelectedItems().addListener((ListChangeListener.Change<? extends Integer> c) -> { 941 if (callCNextOnce) { 942 c.next(); 943 } else if (callCNextInLoop) { 944 while (c.next()) { 945 // no-op 946 } 947 } 948 949 if (rt_37538_count >= 1) { 950 Thread.dumpStack(); 951 fail("This method should only be called once"); 952 } 953 954 rt_37538_count++; 955 }); 956 957 StageLoader sl = new StageLoader(list); 958 assertEquals(0, rt_37538_count); 959 list.getSelectionModel().select(0); 960 assertEquals(1, rt_37538_count); 961 sl.dispose(); 962 } 963 964 @Test 965 public void test_rt_35395_fixedCellSize() { 966 test_rt_35395(true); 967 } 968 969 @Test 970 public void test_rt_35395_notFixedCellSize() { 971 test_rt_35395(false); 972 } 973 974 private int rt_35395_counter; 975 976 private void test_rt_35395(boolean useFixedCellSize) { 977 rt_35395_counter = 0; 978 979 ObservableList<String> items = FXCollections.observableArrayList(); 980 for (int i = 0; i < 20; ++i) { 981 items.addAll("red", "green", "blue", "purple"); 982 } 983 984 ListView<String> listView = new ListView<>(items); 985 if (useFixedCellSize) { 986 listView.setFixedCellSize(24); 987 } 988 listView.setCellFactory(lv -> new ListCell<String>() { 989 @Override 990 protected void updateItem(String color, boolean empty) { 991 rt_35395_counter += 1; 992 super.updateItem(color, empty); 993 setText(null); 994 if (empty) { 995 setGraphic(null); 996 } else { 997 Rectangle rect = new Rectangle(16, 16); 998 rect.setStyle("-fx-fill: " + color); 999 setGraphic(rect); 1000 } 1001 } 1002 }); 1003 1004 StageLoader sl = new StageLoader(listView); 1005 1006 Platform.runLater(() -> { 1007 rt_35395_counter = 0; 1008 items.set(10, "yellow"); 1009 Platform.runLater(() -> { 1010 Toolkit.getToolkit().firePulse(); 1011 assertEquals(1, rt_35395_counter); 1012 rt_35395_counter = 0; 1013 items.set(30, "yellow"); 1014 Platform.runLater(() -> { 1015 Toolkit.getToolkit().firePulse(); 1016 assertEquals(0, rt_35395_counter); 1017 rt_35395_counter = 0; 1018 items.remove(12); 1019 Platform.runLater(() -> { 1020 Toolkit.getToolkit().firePulse(); 1021 assertEquals(useFixedCellSize ? 39 : 45, rt_35395_counter); 1022 rt_35395_counter = 0; 1023 items.add(12, "yellow"); 1024 Platform.runLater(() -> { 1025 Toolkit.getToolkit().firePulse(); 1026 assertEquals(useFixedCellSize ? 39 : 45, rt_35395_counter); 1027 rt_35395_counter = 0; 1028 listView.scrollTo(5); 1029 Platform.runLater(() -> { 1030 Toolkit.getToolkit().firePulse(); 1031 assertEquals(5, rt_35395_counter); 1032 rt_35395_counter = 0; 1033 listView.scrollTo(55); 1034 Platform.runLater(() -> { 1035 Toolkit.getToolkit().firePulse(); 1036 assertEquals(useFixedCellSize ? 17 : 53, rt_35395_counter); 1037 sl.dispose(); 1038 }); 1039 }); 1040 }); 1041 }); 1042 }); 1043 }); 1044 }); 1045 } 1046 1047 @Test public void test_rt_37632() { 1048 final ObservableList<String> listOne = FXCollections.observableArrayList("A", "B", "C"); 1049 final ObservableList<String> listTwo = FXCollections.observableArrayList("C"); 1050 1051 final ListView<String> listView = new ListView<>(); 1052 MultipleSelectionModel<String> sm = listView.getSelectionModel(); 1053 listView.setItems(listOne); 1054 listView.getSelectionModel().selectFirst(); 1055 1056 assertEquals(0, sm.getSelectedIndex()); 1057 assertEquals("A", sm.getSelectedItem()); 1058 assertEquals(1, sm.getSelectedIndices().size()); 1059 assertEquals(0, (int) sm.getSelectedIndices().get(0)); 1060 assertEquals(1, sm.getSelectedItems().size()); 1061 assertEquals("A", sm.getSelectedItems().get(0)); 1062 1063 listView.setItems(listTwo); 1064 1065 assertEquals(-1, sm.getSelectedIndex()); 1066 assertNull(sm.getSelectedItem()); 1067 assertEquals(0, sm.getSelectedIndices().size()); 1068 assertEquals(0, sm.getSelectedItems().size()); 1069 } 1070 1071 private int rt_37853_cancelCount; 1072 private int rt_37853_commitCount; 1073 @Test public void test_rt_37853() { 1074 listView.setCellFactory(TextFieldListCell.forListView()); 1075 listView.setEditable(true); 1076 1077 for (int i = 0; i < 10; i++) { 1078 listView.getItems().add("" + i); 1079 } 1080 1081 StageLoader sl = new StageLoader(listView); 1082 1083 listView.setOnEditCancel(editEvent -> rt_37853_cancelCount++); 1084 listView.setOnEditCommit(editEvent -> rt_37853_commitCount++); 1085 1086 assertEquals(0, rt_37853_cancelCount); 1087 assertEquals(0, rt_37853_commitCount); 1088 1089 listView.edit(1); 1090 assertNotNull(listView.getEditingIndex()); 1091 1092 listView.getItems().clear(); 1093 assertEquals(1, rt_37853_cancelCount); 1094 assertEquals(0, rt_37853_commitCount); 1095 1096 sl.dispose(); 1097 } 1098 1099 @Test public void test_rt_38787_remove_b() { 1100 // selection moves to "a" 1101 test_rt_38787("a", 0, "b"); 1102 } 1103 1104 @Test public void test_rt_38787_remove_b_c() { 1105 // selection moves to "a" 1106 test_rt_38787("a", 0, "b", "c"); 1107 } 1108 1109 @Test public void test_rt_38787_remove_c_d() { 1110 // selection moves to "b" 1111 test_rt_38787("b", 1, "c", "d"); 1112 } 1113 1114 @Test public void test_rt_38787_remove_a() { 1115 // selection moves to "b", now in index 0 1116 test_rt_38787("b", 0, "a"); 1117 } 1118 1119 @Test public void test_rt_38787_remove_z() { 1120 // selection shouldn't move as 'z' doesn't exist 1121 test_rt_38787("b", 1, "z"); 1122 } 1123 1124 private void test_rt_38787(String expectedItem, int expectedIndex, String... itemsToRemove) { 1125 ListView<String> stringListView = new ListView<>(); 1126 stringListView.getItems().addAll("a","b","c","d"); 1127 1128 MultipleSelectionModel<String> sm = stringListView.getSelectionModel(); 1129 sm.select("b"); 1130 1131 // test pre-conditions 1132 assertEquals(1, sm.getSelectedIndex()); 1133 assertEquals(1, (int)sm.getSelectedIndices().get(0)); 1134 assertEquals("b", sm.getSelectedItem()); 1135 assertEquals("b", sm.getSelectedItems().get(0)); 1136 assertFalse(sm.isSelected(0)); 1137 assertTrue(sm.isSelected(1)); 1138 assertFalse(sm.isSelected(2)); 1139 1140 // removing items 1141 stringListView.getItems().removeAll(itemsToRemove); 1142 1143 // testing against expectations 1144 assertEquals(expectedIndex, sm.getSelectedIndex()); 1145 assertEquals(expectedIndex, (int)sm.getSelectedIndices().get(0)); 1146 assertEquals(expectedItem, sm.getSelectedItem()); 1147 assertEquals(expectedItem, sm.getSelectedItems().get(0)); 1148 } 1149 1150 private int rt_38341_indices_count = 0; 1151 private int rt_38341_items_count = 0; 1152 @Test public void test_rt_38341() { 1153 ListView<String> stringListView = new ListView<>(); 1154 stringListView.getItems().addAll("a","b","c","d"); 1155 1156 MultipleSelectionModel<String> sm = stringListView.getSelectionModel(); 1157 sm.getSelectedIndices().addListener((ListChangeListener<Integer>) c -> rt_38341_indices_count++); 1158 sm.getSelectedItems().addListener((ListChangeListener<String>) c -> rt_38341_items_count++); 1159 1160 assertEquals(0, rt_38341_indices_count); 1161 assertEquals(0, rt_38341_items_count); 1162 1163 // expand the first child of root, and select it (note: root isn't visible) 1164 sm.select(1); 1165 assertEquals(1, sm.getSelectedIndex()); 1166 assertEquals(1, sm.getSelectedIndices().size()); 1167 assertEquals(1, (int)sm.getSelectedIndices().get(0)); 1168 assertEquals(1, sm.getSelectedItems().size()); 1169 assertEquals("b", sm.getSelectedItem()); 1170 assertEquals("b", sm.getSelectedItems().get(0)); 1171 1172 assertEquals(1, rt_38341_indices_count); 1173 assertEquals(1, rt_38341_items_count); 1174 1175 // now delete it 1176 stringListView.getItems().remove(1); 1177 1178 // selection should move to the childs parent in index 0 1179 assertEquals(0, sm.getSelectedIndex()); 1180 assertEquals(1, sm.getSelectedIndices().size()); 1181 assertEquals(0, (int)sm.getSelectedIndices().get(0)); 1182 assertEquals(1, sm.getSelectedItems().size()); 1183 assertEquals("a", sm.getSelectedItem()); 1184 assertEquals("a", sm.getSelectedItems().get(0)); 1185 1186 // we also expect there to be an event in the selection model for 1187 // selected indices and selected items 1188 assertEquals(sm.getSelectedIndices() +"", 2, rt_38341_indices_count); 1189 assertEquals(2, rt_38341_items_count); 1190 } 1191 1192 @Test public void test_rt_39132() { 1193 ObservableList items = FXCollections.observableArrayList("one", "two", "three"); 1194 ListView listView = new ListView<>(); 1195 listView.setItems(items); 1196 1197 MultipleSelectionModel sm = listView.getSelectionModel(); 1198 sm.select(0); 1199 1200 assertEquals(0, sm.getSelectedIndex()); 1201 assertEquals("one", sm.getSelectedItem()); 1202 1203 items.add(0, "new item"); 1204 assertEquals(1, sm.getSelectedIndex()); 1205 assertEquals("one", sm.getSelectedItem()); 1206 } 1207 1208 private int rt_38943_index_count = 0; 1209 private int rt_38943_item_count = 0; 1210 @Test public void test_rt_38943() { 1211 ListView<String> listView = new ListView<>(FXCollections.observableArrayList("one", "two", "three")); 1212 1213 MultipleSelectionModel sm = listView.getSelectionModel(); 1214 1215 sm.selectedIndexProperty().addListener((observable, oldValue, newValue) -> rt_38943_index_count++); 1216 sm.selectedItemProperty().addListener((observable, oldValue, newValue) -> rt_38943_item_count++); 1217 1218 assertEquals(-1, sm.getSelectedIndex()); 1219 assertNull(sm.getSelectedItem()); 1220 assertEquals(0, rt_38943_index_count); 1221 assertEquals(0, rt_38943_item_count); 1222 1223 sm.select(0); 1224 assertEquals(0, sm.getSelectedIndex()); 1225 assertEquals("one", sm.getSelectedItem()); 1226 assertEquals(1, rt_38943_index_count); 1227 assertEquals(1, rt_38943_item_count); 1228 1229 sm.clearSelection(0); 1230 assertEquals(-1, sm.getSelectedIndex()); 1231 assertNull(sm.getSelectedItem()); 1232 assertEquals(2, rt_38943_index_count); 1233 assertEquals(2, rt_38943_item_count); 1234 } 1235 1236 @Test public void test_rt_38884() { 1237 ListView<String> listView = new ListView<>(); 1238 ObservableList<String> items = listView.getItems(); 1239 1240 listView.getSelectionModel().getSelectedItems().addListener((ListChangeListener.Change<? extends String> c) -> { 1241 while (c.next()) { 1242 if (c.wasRemoved()) { 1243 assertTrue(c.getRemovedSize() > 0); 1244 1245 List<? extends String> removed = c.getRemoved(); 1246 String removedItem = null; 1247 try { 1248 removedItem = removed.get(0); 1249 } catch (Exception e) { 1250 fail(); 1251 } 1252 1253 assertEquals("foo", removedItem); 1254 } 1255 } 1256 }); 1257 1258 items.add("foo"); 1259 listView.getSelectionModel().select(0); 1260 items.clear(); 1261 } 1262 1263 private int rt_37360_add_count = 0; 1264 private int rt_37360_remove_count = 0; 1265 @Test public void test_rt_37360() { 1266 ListView<String> stringListView = new ListView<>(); 1267 stringListView.getItems().addAll("a", "b"); 1268 1269 MultipleSelectionModel<String> sm = stringListView.getSelectionModel(); 1270 sm.setSelectionMode(SelectionMode.MULTIPLE); 1271 sm.getSelectedItems().addListener((ListChangeListener<String>) c -> { 1272 while (c.next()) { 1273 if (c.wasAdded()) { 1274 rt_37360_add_count += c.getAddedSize(); 1275 } 1276 if (c.wasRemoved()) { 1277 rt_37360_remove_count += c.getRemovedSize(); 1278 } 1279 } 1280 }); 1281 1282 assertEquals(0, sm.getSelectedItems().size()); 1283 assertEquals(0, rt_37360_add_count); 1284 assertEquals(0, rt_37360_remove_count); 1285 1286 sm.select(0); 1287 assertEquals(1, sm.getSelectedItems().size()); 1288 assertEquals(1, rt_37360_add_count); 1289 assertEquals(0, rt_37360_remove_count); 1290 1291 sm.select(1); 1292 assertEquals(2, sm.getSelectedItems().size()); 1293 assertEquals(2, rt_37360_add_count); 1294 assertEquals(0, rt_37360_remove_count); 1295 1296 sm.clearAndSelect(1); 1297 assertEquals(1, sm.getSelectedItems().size()); 1298 assertEquals(2, rt_37360_add_count); 1299 assertEquals(1, rt_37360_remove_count); 1300 } 1301 1302 @Test public void test_rt_38491() { 1303 ListView<String> stringListView = new ListView<>(); 1304 stringListView.getItems().addAll("a", "b"); 1305 1306 MultipleSelectionModel<String> sm = stringListView.getSelectionModel(); 1307 sm.setSelectionMode(SelectionMode.MULTIPLE); 1308 1309 FocusModel<String> fm = stringListView.getFocusModel(); 1310 1311 // click on row 0 1312 VirtualFlowTestUtils.clickOnRow(stringListView, 0); 1313 assertTrue(sm.isSelected(0)); 1314 assertEquals("a", sm.getSelectedItem()); 1315 assertTrue(fm.isFocused(0)); 1316 assertEquals("a", fm.getFocusedItem()); 1317 assertEquals(0, fm.getFocusedIndex()); 1318 1319 int anchor = ListCellBehavior.getAnchor(stringListView, null); 1320 assertTrue(ListCellBehavior.hasNonDefaultAnchor(stringListView)); 1321 assertEquals(0, anchor); 1322 1323 // now add a new item at row 0. This has the effect of pushing down 1324 // the selected item into row 1. 1325 stringListView.getItems().add(0, "z"); 1326 1327 // The first bug was that selection and focus were not moving down to 1328 // be on row 1, so we test that now 1329 assertFalse(sm.isSelected(0)); 1330 assertFalse(fm.isFocused(0)); 1331 assertTrue(sm.isSelected(1)); 1332 assertEquals("a", sm.getSelectedItem()); 1333 assertTrue(fm.isFocused(1)); 1334 assertEquals("a", fm.getFocusedItem()); 1335 assertEquals(1, fm.getFocusedIndex()); 1336 1337 // The second bug was that the anchor was not being pushed down as well 1338 // (when it should). 1339 anchor = ListCellBehavior.getAnchor(stringListView, null); 1340 assertTrue(ListCellBehavior.hasNonDefaultAnchor(stringListView)); 1341 assertEquals(1, anchor); 1342 } 1343 1344 private final ObservableList<String> rt_39256_list = FXCollections.observableArrayList(); 1345 @Test public void test_rt_39256() { 1346 ListView<String> stringListView = new ListView<>(); 1347 stringListView.getItems().addAll("a","b", "c", "d"); 1348 1349 MultipleSelectionModel<String> sm = stringListView.getSelectionModel(); 1350 sm.setSelectionMode(SelectionMode.MULTIPLE); 1351 1352 // rt_39256_list.addListener((ListChangeListener<String>) change -> { 1353 // while (change.next()) { 1354 // System.err.println("number of selected persons (in bound list): " + change.getList().size()); 1355 // } 1356 // }); 1357 1358 Bindings.bindContent(rt_39256_list, sm.getSelectedItems()); 1359 1360 assertEquals(0, sm.getSelectedItems().size()); 1361 assertEquals(0, rt_39256_list.size()); 1362 1363 sm.selectAll(); 1364 assertEquals(4, sm.getSelectedItems().size()); 1365 assertEquals(4, rt_39256_list.size()); 1366 1367 sm.selectAll(); 1368 assertEquals(4, sm.getSelectedItems().size()); 1369 assertEquals(4, rt_39256_list.size()); 1370 1371 sm.selectAll(); 1372 assertEquals(4, sm.getSelectedItems().size()); 1373 assertEquals(4, rt_39256_list.size()); 1374 } 1375 1376 private final ObservableList<String> rt_39482_list = FXCollections.observableArrayList(); 1377 @Test public void test_rt_39482() { 1378 ListView<String> stringListView = new ListView<>(); 1379 stringListView.getItems().addAll("a", "b", "c", "d"); 1380 1381 MultipleSelectionModel<String> sm = stringListView.getSelectionModel(); 1382 sm.setSelectionMode(SelectionMode.MULTIPLE); 1383 1384 sm.getSelectedItems().addListener((ListChangeListener<String>) change -> { 1385 while (change.next()) { 1386 System.out.println("sm.getSelectedItems(): " + change.getList()); 1387 } 1388 }); 1389 1390 rt_39482_list.addListener((ListChangeListener<String>) change -> { 1391 while (change.next()) { 1392 System.out.println("rt_39482_list: " + change.getList()); 1393 } 1394 }); 1395 1396 Bindings.bindContent(rt_39482_list, sm.getSelectedItems()); 1397 1398 assertEquals(0, sm.getSelectedItems().size()); 1399 assertEquals(0, rt_39482_list.size()); 1400 1401 test_rt_39482_selectRow("a", sm, 0); 1402 test_rt_39482_selectRow("b", sm, 1); 1403 test_rt_39482_selectRow("c", sm, 2); 1404 test_rt_39482_selectRow("d", sm, 3); 1405 } 1406 1407 private void test_rt_39482_selectRow(String expectedString, 1408 MultipleSelectionModel<String> sm, 1409 int rowToSelect) { 1410 System.out.println("\nSelect row " + rowToSelect); 1411 sm.selectAll(); 1412 assertEquals(4, sm.getSelectedIndices().size()); 1413 assertEquals(4, sm.getSelectedItems().size()); 1414 assertEquals(4, rt_39482_list.size()); 1415 1416 sm.clearAndSelect(rowToSelect); 1417 assertEquals(1, sm.getSelectedIndices().size()); 1418 assertEquals(1, sm.getSelectedItems().size()); 1419 assertEquals(expectedString, sm.getSelectedItem()); 1420 assertEquals(expectedString, rt_39482_list.get(0)); 1421 assertEquals(1, rt_39482_list.size()); 1422 } 1423 1424 @Test public void test_rt_39559_useSM_selectAll() { 1425 test_rt_39559(true); 1426 } 1427 1428 @Test public void test_rt_39559_useKeyboard_selectAll() { 1429 test_rt_39559(false); 1430 } 1431 1432 private void test_rt_39559(boolean useSMSelectAll) { 1433 ListView<String> stringListView = new ListView<>(); 1434 stringListView.getItems().addAll("a", "b", "c", "d"); 1435 1436 MultipleSelectionModel<String> sm = stringListView.getSelectionModel(); 1437 sm.setSelectionMode(SelectionMode.MULTIPLE); 1438 1439 StageLoader sl = new StageLoader(stringListView); 1440 KeyEventFirer keyboard = new KeyEventFirer(stringListView); 1441 1442 assertEquals(0, sm.getSelectedItems().size()); 1443 1444 sm.clearAndSelect(0); 1445 1446 if (useSMSelectAll) { 1447 sm.selectAll(); 1448 } else { 1449 keyboard.doKeyPress(KeyCode.A, KeyModifier.getShortcutKey()); 1450 } 1451 1452 assertEquals(4, sm.getSelectedItems().size()); 1453 assertEquals(0, (int) ListCellBehavior.getAnchor(stringListView, -1)); 1454 1455 keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.SHIFT); 1456 1457 assertEquals(0, (int) ListCellBehavior.getAnchor(stringListView, -1)); 1458 assertEquals(2, sm.getSelectedItems().size()); 1459 assertEquals("a", sm.getSelectedItems().get(0)); 1460 assertEquals("b", sm.getSelectedItems().get(1)); 1461 1462 sl.dispose(); 1463 } 1464 1465 @Test public void test_rt_16068_firstElement_selectAndRemoveSameRow() { 1466 // select and then remove the 'a' item, selection and focus should both 1467 // stay at the first row, now 'b' 1468 test_rt_16068(0, 0, 0); 1469 } 1470 1471 @Test public void test_rt_16068_firstElement_selectRowAndRemoveLaterSibling() { 1472 // select row 'a', and remove row 'c', selection and focus should not change 1473 test_rt_16068(0, 2, 0); 1474 } 1475 1476 @Test public void test_rt_16068_middleElement_selectAndRemoveSameRow() { 1477 // select and then remove the 'b' item, selection and focus should both 1478 // move up one row to the 'a' item 1479 test_rt_16068(1, 1, 0); 1480 } 1481 1482 @Test public void test_rt_16068_middleElement_selectRowAndRemoveLaterSibling() { 1483 // select row 'b', and remove row 'c', selection and focus should not change 1484 test_rt_16068(1, 2, 1); 1485 } 1486 1487 @Test public void test_rt_16068_middleElement_selectRowAndRemoveEarlierSibling() { 1488 // select row 'b', and remove row 'a', selection and focus should move up 1489 // one row, remaining on 'b' 1490 test_rt_16068(1, 0, 0); 1491 } 1492 1493 @Test public void test_rt_16068_lastElement_selectAndRemoveSameRow() { 1494 // select and then remove the 'd' item, selection and focus should both 1495 // move up one row to the 'c' item 1496 test_rt_16068(3, 3, 2); 1497 } 1498 1499 @Test public void test_rt_16068_lastElement_selectRowAndRemoveEarlierSibling() { 1500 // select row 'd', and remove row 'a', selection and focus should move up 1501 // one row, remaining on 'd' 1502 test_rt_16068(3, 0, 2); 1503 } 1504 1505 private void test_rt_16068(int indexToSelect, int indexToRemove, int expectedIndex) { 1506 ListView<String> stringListView = new ListView<>(); 1507 stringListView.getItems().addAll("a", "b", "c", "d"); 1508 1509 MultipleSelectionModel<?> sm = stringListView.getSelectionModel(); 1510 FocusModel<?> fm = stringListView.getFocusModel(); 1511 1512 sm.select(indexToSelect); 1513 assertEquals(indexToSelect, sm.getSelectedIndex()); 1514 assertEquals(stringListView.getItems().get(indexToSelect), sm.getSelectedItem()); 1515 assertEquals(indexToSelect, fm.getFocusedIndex()); 1516 assertEquals(stringListView.getItems().get(indexToSelect), fm.getFocusedItem()); 1517 1518 stringListView.getItems().remove(indexToRemove); 1519 assertEquals(expectedIndex, sm.getSelectedIndex()); 1520 assertEquals(stringListView.getItems().get(expectedIndex), sm.getSelectedItem()); 1521 assertEquals(expectedIndex, fm.getFocusedIndex()); 1522 assertEquals(stringListView.getItems().get(expectedIndex), fm.getFocusedItem()); 1523 } 1524 1525 @Test public void test_rt_22599() { 1526 ObservableList<RT22599_DataType> initialData = FXCollections.observableArrayList( 1527 new RT22599_DataType(1, "row1"), 1528 new RT22599_DataType(2, "row2"), 1529 new RT22599_DataType(3, "row3") 1530 ); 1531 1532 ListView<RT22599_DataType> listView = new ListView<>(); 1533 listView.setItems(initialData); 1534 1535 StageLoader sl = new StageLoader(listView); 1536 1537 // testing initial state 1538 assertNotNull(listView.getSkin()); 1539 assertEquals("row1", VirtualFlowTestUtils.getCell(listView, 0).getText()); 1540 assertEquals("row2", VirtualFlowTestUtils.getCell(listView, 1).getText()); 1541 assertEquals("row3", VirtualFlowTestUtils.getCell(listView, 2).getText()); 1542 1543 // change row 0 (where "row1" currently resides), keeping same id. 1544 // Because 'set' is called, the control should update to the new content 1545 // without any user interaction 1546 RT22599_DataType data; 1547 initialData.set(0, data = new RT22599_DataType(0, "row1a")); 1548 Toolkit.getToolkit().firePulse(); 1549 assertEquals("row1a", VirtualFlowTestUtils.getCell(listView, 0).getText()); 1550 1551 // change the row 0 (where we currently have "row1a") value directly. 1552 // Because there is no associated property, this won't be observed, so 1553 // the control should still show "row1a" rather than "row1b" 1554 data.text = "row1b"; 1555 Toolkit.getToolkit().firePulse(); 1556 assertEquals("row1a", VirtualFlowTestUtils.getCell(listView, 0).getText()); 1557 1558 // call refresh() to force a refresh of all visible cells 1559 listView.refresh(); 1560 Toolkit.getToolkit().firePulse(); 1561 assertEquals("row1b", VirtualFlowTestUtils.getCell(listView, 0).getText()); 1562 1563 sl.dispose(); 1564 } 1565 1566 private static class RT22599_DataType { 1567 public int id = 0; 1568 public String text = ""; 1569 1570 public RT22599_DataType(int id, String text) { 1571 this.id = id; 1572 this.text = text; 1573 } 1574 1575 @Override public String toString() { 1576 return text; 1577 } 1578 1579 @Override public boolean equals(Object obj) { 1580 if (obj == null) return false; 1581 return id == ((RT22599_DataType)obj).id; 1582 } 1583 } 1584 1585 private int rt_39966_count = 0; 1586 @Test public void test_rt_39966() { 1587 ObservableList<String> list = FXCollections.observableArrayList("Hello World"); 1588 ListView<String> listView = new ListView<>(list); 1589 1590 StageLoader sl = new StageLoader(listView); 1591 1592 // initially there is no selection 1593 assertTrue(listView.getSelectionModel().isEmpty()); 1594 1595 listView.getSelectionModel().selectedItemProperty().addListener((value, s1, s2) -> { 1596 if (rt_39966_count == 0) { 1597 rt_39966_count++; 1598 assertFalse(listView.getSelectionModel().isEmpty()); 1599 } else { 1600 assertTrue(listView.getSelectionModel().isEmpty()); 1601 } 1602 }); 1603 1604 // our assertion two lines down always succeeds. What fails is our 1605 // assertion above within the listener. 1606 listView.getSelectionModel().select(0); 1607 assertFalse(listView.getSelectionModel().isEmpty()); 1608 1609 list.remove(0); 1610 assertTrue(listView.getSelectionModel().isEmpty()); 1611 1612 sl.dispose(); 1613 } 1614 1615 /** 1616 * Bullet 1: selected index must be updated 1617 * Corner case: last selected. Fails for core 1618 */ 1619 @Test public void test_rt_40012_selectedAtLastOnDisjointRemoveItemsAbove() { 1620 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1621 ListView<String> listView = new ListView<>(items); 1622 SelectionModel sm = listView.getSelectionModel(); 1623 1624 int last = items.size() - 1; 1625 1626 // selecting item "5" 1627 sm.select(last); 1628 1629 // disjoint remove of 2 elements above the last selected 1630 // Removing "1" and "3" 1631 items.removeAll(items.get(1), items.get(3)); 1632 1633 // selection should move up two places such that it remains on item "5", 1634 // but in index (last - 2). 1635 int expected = last - 2; 1636 assertEquals("5", sm.getSelectedItem()); 1637 assertEquals("selected index after disjoint removes above", expected, sm.getSelectedIndex()); 1638 } 1639 1640 /** 1641 * Variant of 1: if selectedIndex is not updated, 1642 * the old index is no longer valid 1643 * for accessing the items. 1644 */ 1645 @Test public void test_rt_40012_accessSelectedAtLastOnDisjointRemoveItemsAbove() { 1646 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1647 ListView<String> listView = new ListView<>(items); 1648 SelectionModel sm = listView.getSelectionModel(); 1649 1650 int last = items.size() - 1; 1651 1652 // selecting item "5" 1653 sm.select(last); 1654 1655 // disjoint remove of 2 elements above the last selected 1656 items.removeAll(items.get(1), items.get(3)); 1657 int selected = sm.getSelectedIndex(); 1658 if (selected > -1) { 1659 items.get(selected); 1660 } 1661 } 1662 1663 /** 1664 * Bullet 2: selectedIndex notification count 1665 * 1666 * Note that we don't use the corner case of having the last index selected 1667 * (which fails already on updating the index) 1668 */ 1669 private int rt_40012_count = 0; 1670 @Test public void test_rt_40012_selectedIndexNotificationOnDisjointRemovesAbove() { 1671 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1672 ListView<String> listView = new ListView<>(items); 1673 SelectionModel sm = listView.getSelectionModel(); 1674 1675 int last = items.size() - 2; 1676 sm.select(last); 1677 assertEquals(last, sm.getSelectedIndex()); 1678 1679 rt_40012_count = 0; 1680 sm.selectedIndexProperty().addListener(o -> rt_40012_count++); 1681 1682 // disjoint remove of 2 elements above the last selected 1683 items.removeAll(items.get(1), items.get(3)); 1684 assertEquals("sanity: selectedIndex must be shifted by -2", last - 2, sm.getSelectedIndex()); 1685 assertEquals("must fire single event on removes above", 1, rt_40012_count); 1686 } 1687 1688 /** 1689 * Bullet 3: unchanged selectedItem must not fire change 1690 */ 1691 @Test 1692 public void test_rt_40012_selectedItemNotificationOnDisjointRemovesAbove() { 1693 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1694 ListView<String> listView = new ListView<>(items); 1695 SelectionModel sm = listView.getSelectionModel(); 1696 1697 int last = items.size() - 2; 1698 Object lastItem = items.get(last); 1699 sm.select(last); 1700 assertEquals(lastItem, sm.getSelectedItem()); 1701 1702 rt_40012_count = 0; 1703 sm.selectedItemProperty().addListener(o -> rt_40012_count++); 1704 1705 // disjoint remove of 2 elements above the last selected 1706 items.removeAll(items.get(1), items.get(3)); 1707 assertEquals("sanity: selectedItem unchanged", lastItem, sm.getSelectedItem()); 1708 assertEquals("must not fire on unchanged selected item", 0, rt_40012_count); 1709 } 1710 1711 @Test public void test_rt_40185() { 1712 final ListView<String> lv = new ListView<>(); 1713 final ArrayList<Integer> expected = new ArrayList<>(); 1714 Collections.addAll(expected, 1, 2); 1715 1716 lv.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 1717 lv.getSelectionModel().getSelectedIndices().addListener((ListChangeListener<Integer>) change -> { 1718 while (change.next()) { 1719 if (change.wasRemoved()) { 1720 assertEquals(expected, change.getRemoved()); 1721 } 1722 } 1723 }); 1724 1725 lv.getItems().addAll("-0-","-1-","-2-"); 1726 lv.getSelectionModel().selectIndices(1, 2); 1727 lv.getSelectionModel().clearSelection(); 1728 } 1729 1730 /** 1731 * ClearAndSelect fires invalid change event if selectedIndex is unchanged. 1732 */ 1733 private int rt_40212_count = 0; 1734 @Test public void test_rt_40212() { 1735 final ListView<Integer> lv = new ListView<>(); 1736 for (int i = 0; i < 10; i++) { 1737 lv.getItems().add(i); 1738 } 1739 1740 MultipleSelectionModel<Integer> sm = lv.getSelectionModel(); 1741 sm.setSelectionMode(SelectionMode.MULTIPLE); 1742 1743 sm.selectRange(3, 5); 1744 int selected = sm.getSelectedIndex(); 1745 1746 sm.getSelectedIndices().addListener((ListChangeListener<Integer>) change -> { 1747 assertEquals("sanity: selectedIndex unchanged", selected, sm.getSelectedIndex()); 1748 while(change.next()) { 1749 assertEquals("single event on clearAndSelect already selected", 1, ++rt_40212_count); 1750 1751 boolean type = change.wasAdded() || change.wasRemoved() || change.wasPermutated() || change.wasUpdated(); 1752 assertTrue("at least one of the change types must be true", type); 1753 } 1754 }); 1755 1756 sm.clearAndSelect(selected); 1757 } 1758 1759 @Test public void test_rt_40280() { 1760 final ListView<String> view = new ListView<>(); 1761 StageLoader sl = new StageLoader(view); 1762 view.getFocusModel().getFocusedIndex(); 1763 sl.dispose(); 1764 } 1765 1766 /** 1767 * Test list change of selectedIndices on setIndices. Fails for core .. 1768 */ 1769 @Test public void test_rt_40263() { 1770 final ListView<Integer> lv = new ListView<>(); 1771 for (int i = 0; i < 10; i++) { 1772 lv.getItems().add(i); 1773 } 1774 1775 MultipleSelectionModel<Integer> sm = lv.getSelectionModel(); 1776 sm.setSelectionMode(SelectionMode.MULTIPLE); 1777 1778 int[] indices = new int[]{2, 5, 7}; 1779 ListChangeListener<Integer> l = c -> { 1780 // firstly, we expect only one change 1781 int subChanges = 0; 1782 while(c.next()) { 1783 subChanges++; 1784 } 1785 assertEquals(1, subChanges); 1786 1787 // secondly, we expect the added size to be three, as that is the 1788 // number of items selected 1789 c.reset(); 1790 c.next(); 1791 System.out.println("Added items: " + c.getAddedSubList()); 1792 assertEquals(indices.length, c.getAddedSize()); 1793 assertArrayEquals(indices, c.getAddedSubList().stream().mapToInt(i -> i).toArray()); 1794 }; 1795 sm.getSelectedIndices().addListener(l); 1796 sm.selectIndices(indices[0], indices); 1797 } 1798 }