1 /* 2 * Copyright (c) 2010, 2016, 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 static test.com.sun.javafx.scene.control.infrastructure.ControlTestUtils.assertStyleClassContains; 29 import static javafx.scene.control.TableColumn.SortType.ASCENDING; 30 import static javafx.scene.control.TableColumn.SortType.DESCENDING; 31 import static org.junit.Assert.*; 32 33 import java.util.*; 34 import java.util.concurrent.atomic.AtomicLong; 35 import java.util.function.Supplier; 36 37 import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList; 38 import com.sun.javafx.scene.control.SelectedCellsMap; 39 import com.sun.javafx.scene.control.behavior.TableCellBehavior; 40 import javafx.beans.InvalidationListener; 41 import test.com.sun.javafx.scene.control.infrastructure.ControlTestUtils; 42 import test.com.sun.javafx.scene.control.infrastructure.KeyEventFirer; 43 import test.com.sun.javafx.scene.control.infrastructure.KeyModifier; 44 import test.com.sun.javafx.scene.control.infrastructure.MouseEventFirer; 45 import test.com.sun.javafx.scene.control.infrastructure.StageLoader; 46 import javafx.application.Platform; 47 import javafx.beans.binding.Bindings; 48 import javafx.beans.binding.ObjectBinding; 49 import javafx.beans.property.*; 50 import javafx.collections.FXCollections; 51 import javafx.collections.ListChangeListener; 52 import javafx.collections.ObservableList; 53 import javafx.collections.transformation.SortedList; 54 import javafx.event.EventHandler; 55 import javafx.geometry.Orientation; 56 import javafx.scene.Group; 57 import javafx.scene.Scene; 58 import javafx.scene.control.cell.*; 59 import javafx.scene.control.skin.TableCellSkin; 60 import javafx.scene.control.skin.TableColumnHeader; 61 import javafx.scene.control.skin.TableColumnHeaderShim; 62 import javafx.scene.control.skin.TableHeaderRow; 63 import javafx.scene.control.skin.VirtualFlow; 64 import com.sun.javafx.scene.control.VirtualScrollBar; 65 import javafx.scene.image.ImageView; 66 import javafx.scene.input.KeyCode; 67 import javafx.scene.layout.StackPane; 68 import javafx.scene.layout.VBox; 69 import javafx.scene.paint.Color; 70 import javafx.scene.shape.Rectangle; 71 import javafx.util.Callback; 72 73 import com.sun.javafx.tk.Toolkit; 74 import org.junit.Before; 75 import org.junit.Ignore; 76 import org.junit.Test; 77 78 import com.sun.javafx.scene.control.TableColumnComparatorBase.TableColumnComparator; 79 import javafx.scene.control.Button; 80 import javafx.scene.control.Cell; 81 import javafx.scene.control.CheckBox; 82 import javafx.scene.control.ControlShim; 83 import javafx.scene.control.FocusModel; 84 import javafx.scene.control.IndexedCell; 85 import javafx.scene.control.MultipleSelectionModel; 86 import javafx.scene.control.MultipleSelectionModelBaseShim; 87 import javafx.scene.control.ScrollBar; 88 import javafx.scene.control.SelectionMode; 89 import javafx.scene.control.SplitPane; 90 import javafx.scene.control.TableCell; 91 import javafx.scene.control.TableCellShim; 92 import javafx.scene.control.TableColumn; 93 import javafx.scene.control.TablePosition; 94 import javafx.scene.control.TableRow; 95 import javafx.scene.control.TableRowShim; 96 import javafx.scene.control.TableSelectionModel; 97 import javafx.scene.control.TableView; 98 import javafx.scene.control.TableViewShim; 99 import javafx.scene.control.TextField; 100 import javafx.scene.control.TreeTableColumn; 101 import javafx.scene.control.TreeTableView; 102 import test.com.sun.javafx.scene.control.infrastructure.VirtualFlowTestUtils; 103 import test.com.sun.javafx.scene.control.test.Person; 104 import test.com.sun.javafx.scene.control.test.RT_22463_Person; 105 106 import javafx.scene.control.skin.TableHeaderRowShim; 107 import static org.junit.Assert.assertEquals; 108 import test.com.sun.javafx.scene.control.infrastructure.TableColumnHeaderUtil; 109 110 public class TableViewTest { 111 private TableView<String> table; 112 private TableView.TableViewSelectionModel sm; 113 private TableView.TableViewFocusModel<String> fm; 114 115 private ObservableList<Person> personTestData; 116 117 @Before public void setup() { 118 table = new TableView<>(); 119 sm = table.getSelectionModel(); 120 fm = table.getFocusModel(); 121 122 personTestData = FXCollections.observableArrayList( 123 new Person("Jacob", "Smith", "jacob.smith@example.com"), 124 new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 125 new Person("Ethan", "Williams", "ethan.williams@example.com"), 126 new Person("Emma", "Jones", "emma.jones@example.com"), 127 new Person("Michael", "Brown", "michael.brown@example.com")); 128 } 129 130 131 /********************************************************************* 132 * Tests for the constructors * 133 ********************************************************************/ 134 135 @Test public void noArgConstructorSetsTheStyleClass() { 136 assertStyleClassContains(table, "table-view"); 137 } 138 139 @Test public void noArgConstructorSetsNonNullSelectionModel() { 140 assertNotNull(sm); 141 } 142 143 @Test public void noArgConstructorSetsNonNullItems() { 144 assertNotNull(table.getItems()); 145 } 146 147 @Test public void noArgConstructorSetsNonNullSortPolicy() { 148 assertNotNull(table.getSortPolicy()); 149 } 150 151 @Test public void noArgConstructorSetsNullComparator() { 152 assertNull(table.getComparator()); 153 } 154 155 @Test public void noArgConstructorSetsNullOnSort() { 156 assertNull(table.getOnSort()); 157 } 158 159 @Test public void noArgConstructor_selectedItemIsNull() { 160 assertNull(sm.getSelectedItem()); 161 } 162 163 @Test public void noArgConstructor_selectedIndexIsNegativeOne() { 164 assertEquals(-1, sm.getSelectedIndex()); 165 } 166 167 @Test public void singleArgConstructorSetsTheStyleClass() { 168 final TableView<String> b2 = new TableView<>(FXCollections.observableArrayList("Hi")); 169 assertStyleClassContains(b2, "table-view"); 170 } 171 172 @Test public void singleArgConstructorSetsNonNullSelectionModel() { 173 final TableView<String> b2 = new TableView<>(FXCollections.observableArrayList("Hi")); 174 assertNotNull(b2.getSelectionModel()); 175 } 176 177 @Test public void singleArgConstructorAllowsNullItems() { 178 final TableView<String> b2 = new TableView<>(null); 179 assertNull(b2.getItems()); 180 } 181 182 @Test public void singleArgConstructorTakesItems() { 183 ObservableList<String> items = FXCollections.observableArrayList("Hi"); 184 final TableView<String> b2 = new TableView<>(items); 185 assertSame(items, b2.getItems()); 186 } 187 188 @Test public void singleArgConstructor_selectedItemIsNull() { 189 final TableView<String> b2 = new TableView<>(FXCollections.observableArrayList("Hi")); 190 assertNull(b2.getSelectionModel().getSelectedItem()); 191 } 192 193 @Test public void singleArgConstructor_selectedIndexIsNegativeOne() { 194 final TableView<String> b2 = new TableView<>(FXCollections.observableArrayList("Hi")); 195 assertEquals(-1, b2.getSelectionModel().getSelectedIndex()); 196 } 197 198 /********************************************************************* 199 * Tests for selection model * 200 ********************************************************************/ 201 202 @Test public void selectionModelCanBeNull() { 203 table.setSelectionModel(null); 204 assertNull(table.getSelectionModel()); 205 } 206 207 @Test public void selectionModelCanBeBound() { 208 TableView.TableViewSelectionModel<String> sm = TableViewShim.<String>get_TableViewArrayListSelectionModel(table); 209 ObjectProperty<TableView.TableViewSelectionModel<String>> other = new SimpleObjectProperty<TableView.TableViewSelectionModel<String>>(sm); 210 table.selectionModelProperty().bind(other); 211 assertSame(sm, sm); 212 } 213 214 @Test public void selectionModelCanBeChanged() { 215 TableView.TableViewSelectionModel<String> sm = TableViewShim.<String>get_TableViewArrayListSelectionModel(table); 216 table.setSelectionModel(sm); 217 assertSame(sm, sm); 218 } 219 220 @Test public void canSetSelectedItemToAnItemEvenWhenThereAreNoItems() { 221 final String randomString = new String("I AM A CRAZY RANDOM STRING"); 222 sm.select(randomString); 223 assertEquals(-1, sm.getSelectedIndex()); 224 assertSame(randomString, sm.getSelectedItem()); 225 } 226 227 @Test public void canSetSelectedItemToAnItemNotInTheDataModel() { 228 table.getItems().addAll("Apple", "Orange", "Banana"); 229 final String randomString = new String("I AM A CRAZY RANDOM STRING"); 230 sm.select(randomString); 231 assertSame(randomString, sm.getSelectedItem()); 232 assertEquals(-1, sm.getSelectedIndex()); 233 } 234 235 @Test public void settingTheSelectedItemToAnItemInItemsResultsInTheCorrectSelectedIndex() { 236 table.getItems().addAll("Apple", "Orange", "Banana"); 237 sm.select("Orange"); 238 assertEquals(1, sm.getSelectedIndex()); 239 assertSame("Orange", sm.getSelectedItem()); 240 } 241 242 @Test public void settingTheSelectedItemToANonexistantItemAndThenSettingItemsWhichContainsItResultsInCorrectSelectedIndex() { 243 sm.select("Orange"); 244 table.getItems().addAll("Apple", "Orange", "Banana"); 245 assertEquals(1, sm.getSelectedIndex()); 246 assertSame("Orange", sm.getSelectedItem()); 247 } 248 249 @Test public void ensureSelectionClearsWhenAllItemsAreRemoved_selectIndex0() { 250 table.getItems().addAll("Apple", "Orange", "Banana"); 251 sm.select(0); 252 table.getItems().clear(); 253 assertEquals(-1, sm.getSelectedIndex()); 254 } 255 256 @Test public void ensureSelectionClearsWhenAllItemsAreRemoved_selectIndex2() { 257 table.getItems().addAll("Apple", "Orange", "Banana"); 258 sm.select(2); 259 table.getItems().clear(); 260 assertEquals(-1, sm.getSelectedIndex()); 261 } 262 263 @Test public void ensureSelectedItemRemainsAccurateWhenItemsAreCleared() { 264 table.getItems().addAll("Apple", "Orange", "Banana"); 265 sm.select(2); 266 table.getItems().clear(); 267 assertNull("Selected Item: " + sm.getSelectedItem(), sm.getSelectedItem()); 268 assertEquals(-1, sm.getSelectedIndex()); 269 270 table.getItems().addAll("Kiwifruit", "Mandarin", "Pineapple"); 271 sm.select(2); 272 assertEquals("Pineapple", sm.getSelectedItem()); 273 } 274 275 @Ignore("Not fixed yet") 276 @Test public void ensureSelectionShiftsDownWhenOneNewItemIsAdded() { 277 table.getItems().addAll("Apple", "Orange", "Banana"); 278 sm.select(1); 279 assertEquals(1, sm.getSelectedIndex()); 280 assertEquals("Orange", sm.getSelectedItem()); 281 282 table.getItems().add(0, "Kiwifruit"); 283 assertEquals(2, sm.getSelectedIndex()); 284 assertEquals("Orange", sm.getSelectedItem()); 285 } 286 287 @Ignore("Not fixed yet") 288 @Test public void ensureSelectionShiftsDownWhenMultipleNewItemAreAdded() { 289 table.getItems().addAll("Apple", "Orange", "Banana"); 290 sm.select(1); 291 assertEquals(1, sm.getSelectedIndex()); 292 assertEquals("Orange", sm.getSelectedItem()); 293 294 table.getItems().addAll(0, Arrays.asList("Kiwifruit", "Pineapple", "Mandarin")); 295 assertEquals("Orange", sm.getSelectedItem()); 296 assertEquals(4, sm.getSelectedIndex()); 297 } 298 299 @Ignore("Not fixed yet") 300 @Test public void ensureSelectionShiftsDownWhenOneItemIsRemoved() { 301 table.getItems().addAll("Apple", "Orange", "Banana"); 302 sm.select(1); 303 assertEquals(1, sm.getSelectedIndex()); 304 assertEquals("Orange", sm.getSelectedItem()); 305 306 table.getItems().remove("Apple"); 307 assertEquals(0, sm.getSelectedIndex()); 308 assertEquals("Orange", sm.getSelectedItem()); 309 } 310 311 @Ignore("Not fixed yet") 312 @Test public void ensureSelectionShiftsDownWheMultipleItemsAreRemoved() { 313 table.getItems().addAll("Apple", "Orange", "Banana"); 314 sm.select(2); 315 assertEquals(2, sm.getSelectedIndex()); 316 assertEquals("Banana", sm.getSelectedItem()); 317 318 table.getItems().removeAll(Arrays.asList("Apple", "Orange")); 319 assertEquals(0, sm.getSelectedIndex()); 320 assertEquals("Banana", sm.getSelectedItem()); 321 } 322 323 @Test public void ensureSelectionIsCorrectWhenItemsChange() { 324 table.setItems(FXCollections.observableArrayList("Item 1")); 325 sm.select(0); 326 assertEquals("Item 1", sm.getSelectedItem()); 327 328 table.setItems(FXCollections.observableArrayList("Item 2")); 329 assertEquals(-1, sm.getSelectedIndex()); 330 assertNull(sm.getSelectedItem()); 331 assertEquals(0, fm.getFocusedIndex()); 332 assertEquals("Item 2", fm.getFocusedItem()); 333 } 334 335 /********************************************************************* 336 * Tests for columns * 337 ********************************************************************/ 338 339 @Test public void testColumns() { 340 TableColumn col1 = new TableColumn(); 341 342 assertNotNull(table.getColumns()); 343 assertEquals(0, table.getColumns().size()); 344 345 table.getColumns().add(col1); 346 assertEquals(1, table.getColumns().size()); 347 348 table.getColumns().remove(col1); 349 assertEquals(0, table.getColumns().size()); 350 } 351 352 @Test public void testVisibleLeafColumns() { 353 TableColumn col1 = new TableColumn(); 354 355 assertNotNull(table.getColumns()); 356 assertEquals(0, table.getColumns().size()); 357 358 table.getColumns().add(col1); 359 assertEquals(1, table.getVisibleLeafColumns().size()); 360 361 table.getColumns().remove(col1); 362 assertEquals(0, table.getVisibleLeafColumns().size()); 363 } 364 365 @Test public void testSortOrderCleanup() { 366 // ObservableList<ObservablePerson> persons = ObservablePerson.createFXPersonList(); 367 TableView table = new TableView(); 368 TableColumn<String,String> first = new TableColumn<String,String>("first"); 369 first.setCellValueFactory(new PropertyValueFactory("firstName")); 370 TableColumn<String,String> second = new TableColumn<String,String>("second"); 371 second.setCellValueFactory(new PropertyValueFactory("lastName")); 372 table.getColumns().addAll(first, second); 373 table.getSortOrder().setAll(first, second); 374 table.getColumns().remove(first); 375 assertFalse(table.getSortOrder().contains(first)); 376 } 377 378 379 /********************************************************************* 380 * Tests for new sorting API in JavaFX 8.0 * 381 ********************************************************************/ 382 383 // TODO test for sort policies returning null 384 // TODO test for changing column sortType out of order 385 // TODO test comparator returns to original when sort fails / is consumed 386 387 private static final Callback<TableView<String>, Boolean> NO_SORT_FAILED_SORT_POLICY = 388 tableView -> false; 389 390 private static final Callback<TableView<String>, Boolean> SORT_SUCCESS_ASCENDING_SORT_POLICY = 391 tableView -> { 392 if (tableView.getSortOrder().isEmpty()) return true; 393 FXCollections.sort(tableView.getItems(), new Comparator<String>() { 394 @Override public int compare(String o1, String o2) { 395 return o1.compareTo(o2); 396 } 397 }); 398 return true; 399 }; 400 401 private TableColumn<String, String> initSortTestStructure() { 402 TableColumn<String, String> col = new TableColumn<String, String>("column"); 403 col.setSortType(ASCENDING); 404 col.setCellValueFactory(param -> new ReadOnlyObjectWrapper<String>(param.getValue())); 405 table.getColumns().add(col); 406 table.getItems().addAll("Apple", "Orange", "Banana"); 407 return col; 408 } 409 410 @Ignore("This test is only valid if sort event consumption should revert changes") 411 @Test public void testSortEventCanBeConsumedToStopSortOccurring_changeSortOrderList() { 412 TableColumn<String, String> col = initSortTestStructure(); 413 table.setOnSort(event -> { 414 event.consume(); 415 }); 416 417 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 418 table.getSortOrder().add(col); 419 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 420 421 // the sort order list should be returned back to its original state 422 assertTrue(table.getSortOrder().isEmpty()); 423 } 424 425 @Test public void testSortEventCanBeNotConsumedToAllowSortToOccur_changeSortOrderList() { 426 TableColumn<String, String> col = initSortTestStructure(); 427 table.setOnSort(event -> { 428 // do not consume here - this allows the sort to happen 429 }); 430 431 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 432 table.getSortOrder().add(col); 433 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 434 435 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 436 } 437 438 @Ignore("This test is only valid if sort event consumption should revert changes") 439 @Test public void testSortEventCanBeConsumedToStopSortOccurring_changeColumnSortType_AscendingToDescending() { 440 TableColumn<String, String> col = initSortTestStructure(); 441 assertEquals(ASCENDING, col.getSortType()); 442 table.getSortOrder().add(col); 443 table.setOnSort(event -> { 444 event.consume(); 445 }); 446 447 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 448 449 // when we change from ASCENDING to DESCENDING we don't expect the sort 450 // to actually change (and in fact we expect the sort type to resort 451 // back to being ASCENDING) 452 col.setSortType(DESCENDING); 453 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 454 assertEquals(ASCENDING, col.getSortType()); 455 456 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 457 } 458 459 @Test public void testSortEventCanBeNotConsumedToAllowSortToOccur_changeColumnSortType_AscendingToDescending() { 460 TableColumn<String, String> col = initSortTestStructure(); 461 assertEquals(ASCENDING, col.getSortType()); 462 table.getSortOrder().add(col); 463 table.setOnSort(event -> { 464 // do not consume here - this allows the sort to happen 465 }); 466 467 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 468 469 col.setSortType(DESCENDING); 470 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 471 assertEquals(DESCENDING, col.getSortType()); 472 473 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 474 } 475 476 @Ignore("This test is only valid if sort event consumption should revert changes") 477 @Test public void testSortEventCanBeConsumedToStopSortOccurring_changeColumnSortType_DescendingToNull() { 478 TableColumn<String, String> col = initSortTestStructure(); 479 col.setSortType(DESCENDING); 480 assertEquals(DESCENDING, col.getSortType()); 481 table.getSortOrder().add(col); 482 table.setOnSort(event -> { 483 event.consume(); 484 }); 485 486 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 487 488 col.setSortType(null); 489 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 490 assertEquals(DESCENDING, col.getSortType()); 491 492 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 493 } 494 495 @Test public void testSortEventCanBeNotConsumedToAllowSortToOccur_changeColumnSortType_DescendingToNull() { 496 TableColumn<String, String> col = initSortTestStructure(); 497 col.setSortType(DESCENDING); 498 assertEquals(DESCENDING, col.getSortType()); 499 table.getSortOrder().add(col); 500 table.setOnSort(event -> { 501 // do not consume here - this allows the sort to happen 502 }); 503 504 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 505 506 col.setSortType(null); 507 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 508 assertNull(col.getSortType()); 509 510 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 511 } 512 513 @Ignore("This test is only valid if sort event consumption should revert changes") 514 @Test public void testSortEventCanBeConsumedToStopSortOccurring_changeColumnSortType_NullToAscending() { 515 TableColumn<String, String> col = initSortTestStructure(); 516 col.setSortType(null); 517 assertNull(col.getSortType()); 518 table.getSortOrder().add(col); 519 table.setOnSort(event -> { 520 event.consume(); 521 }); 522 523 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 524 525 col.setSortType(ASCENDING); 526 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 527 assertNull(col.getSortType()); 528 529 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 530 } 531 532 @Test public void testSortEventCanBeNotConsumedToAllowSortToOccur_changeColumnSortType_NullToAscending() { 533 TableColumn<String, String> col = initSortTestStructure(); 534 col.setSortType(null); 535 assertNull(col.getSortType()); 536 table.getSortOrder().add(col); 537 table.setOnSort(event -> { 538 // do not consume here - this allows the sort to happen 539 }); 540 541 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 542 543 col.setSortType(ASCENDING); 544 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 545 assertEquals(ASCENDING, col.getSortType()); 546 547 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 548 } 549 550 @Test public void testSortMethodWithNullSortPolicy() { 551 TableColumn<String, String> col = initSortTestStructure(); 552 table.setSortPolicy(null); 553 assertNull(table.getSortPolicy()); 554 table.sort(); 555 } 556 557 @Test public void testChangingSortPolicyUpdatesItemsList() { 558 TableColumn<String, String> col = initSortTestStructure(); 559 col.setSortType(DESCENDING); 560 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 561 table.getSortOrder().add(col); 562 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 563 table.setSortPolicy(SORT_SUCCESS_ASCENDING_SORT_POLICY); 564 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 565 } 566 567 @Test public void testChangingSortPolicyDoesNotUpdateItemsListWhenTheSortOrderListIsEmpty() { 568 TableColumn<String, String> col = initSortTestStructure(); 569 col.setSortType(DESCENDING); 570 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 571 572 table.setSortPolicy(SORT_SUCCESS_ASCENDING_SORT_POLICY); 573 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 574 } 575 576 @Test public void testFailedSortPolicyBacksOutLastChange_sortOrderAddition() { 577 TableColumn<String, String> col = initSortTestStructure(); 578 col.setSortType(DESCENDING); 579 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 580 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 581 582 table.getSortOrder().add(col); 583 584 // no sort should be run (as we have a custom sort policy), and the 585 // sortOrder list should be empty as the sortPolicy failed 586 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 587 assertTrue(table.getSortOrder().isEmpty()); 588 } 589 590 @Test public void testFailedSortPolicyBacksOutLastChange_sortOrderRemoval() { 591 TableColumn<String, String> col = initSortTestStructure(); 592 col.setSortType(DESCENDING); 593 table.getSortOrder().add(col); 594 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 595 596 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 597 598 // even though we remove the column from the sort order here, because the 599 // sort policy fails the items list should remain unchanged and the sort 600 // order list should continue to have the column in it. 601 table.getSortOrder().remove(col); 602 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 603 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getSortOrder(), col); 604 } 605 606 @Test public void testFailedSortPolicyBacksOutLastChange_sortTypeChange_ascendingToDescending() { 607 TableColumn<String, String> col = initSortTestStructure(); 608 col.setSortType(ASCENDING); 609 table.getSortOrder().add(col); 610 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 611 612 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 613 614 col.setSortType(DESCENDING); 615 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Banana", "Orange"); 616 assertEquals(ASCENDING, col.getSortType()); 617 } 618 619 @Test public void testFailedSortPolicyBacksOutLastChange_sortTypeChange_descendingToNull() { 620 TableColumn<String, String> col = initSortTestStructure(); 621 col.setSortType(DESCENDING); 622 table.getSortOrder().add(col); 623 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 624 625 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 626 627 col.setSortType(null); 628 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 629 assertEquals(DESCENDING, col.getSortType()); 630 } 631 632 @Test public void testFailedSortPolicyBacksOutLastChange_sortTypeChange_nullToAscending() { 633 TableColumn<String, String> col = initSortTestStructure(); 634 col.setSortType(null); 635 table.getSortOrder().add(col); 636 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 637 638 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 639 640 col.setSortType(ASCENDING); 641 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 642 assertNull(col.getSortType()); 643 } 644 645 @Test public void testComparatorChangesInSyncWithSortOrder_1() { 646 TableColumn<String, String> col = initSortTestStructure(); 647 assertNull(table.getComparator()); 648 assertTrue(table.getSortOrder().isEmpty()); 649 650 table.getSortOrder().add(col); 651 TableColumnComparator c = (TableColumnComparator)table.getComparator(); 652 assertNotNull(c); 653 VirtualFlowTestUtils.assertListContainsItemsInOrder(c.getColumns(), col); 654 } 655 656 @Ignore 657 @Test public void testComparatorChangesInSyncWithSortOrder_2() { 658 // same as test above 659 TableColumn<String, String> col = initSortTestStructure(); 660 assertNull(table.getComparator()); 661 assertTrue(table.getSortOrder().isEmpty()); 662 663 table.getSortOrder().add(col); 664 TableColumnComparator c = (TableColumnComparator)table.getComparator(); 665 assertNotNull(c); 666 VirtualFlowTestUtils.assertListContainsItemsInOrder(c.getColumns(), col); 667 668 // now remove column from sort order, and the comparator should go to 669 // being null 670 table.getSortOrder().remove(col); 671 assertNull(table.getComparator()); 672 } 673 674 @Test public void testFailedSortPolicyBacksOutComparatorChange_sortOrderAddition() { 675 TableColumn<String, String> col = initSortTestStructure(); 676 final TableColumnComparator oldComparator = (TableColumnComparator)table.getComparator(); 677 678 col.setSortType(DESCENDING); 679 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Apple", "Orange", "Banana"); 680 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 681 682 table.getSortOrder().add(col); 683 684 assertEquals(oldComparator, table.getComparator()); 685 } 686 687 @Test public void testFailedSortPolicyBacksOutComparatorChange_sortOrderRemoval() { 688 TableColumn<String, String> col = initSortTestStructure(); 689 TableColumnComparator oldComparator = (TableColumnComparator)table.getComparator(); 690 assertNull(oldComparator); 691 692 col.setSortType(DESCENDING); 693 table.getSortOrder().add(col); 694 VirtualFlowTestUtils.assertListContainsItemsInOrder(table.getItems(), "Orange", "Banana", "Apple"); 695 oldComparator = (TableColumnComparator)table.getComparator(); 696 VirtualFlowTestUtils.assertListContainsItemsInOrder(oldComparator.getColumns(), col); 697 698 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 699 table.getSortOrder().remove(col); 700 701 assertTrue(table.getSortOrder().contains(col)); 702 VirtualFlowTestUtils.assertListContainsItemsInOrder(oldComparator.getColumns(), col); 703 } 704 705 @Test public void testFailedSortPolicyBacksOutComparatorChange_sortTypeChange() { 706 TableColumn<String, String> col = initSortTestStructure(); 707 final TableColumnComparator oldComparator = (TableColumnComparator)table.getComparator(); 708 assertNull(oldComparator); 709 710 table.setSortPolicy(NO_SORT_FAILED_SORT_POLICY); 711 table.getSortOrder().add(col); 712 col.setSortType(ASCENDING); 713 714 assertTrue(table.getSortOrder().isEmpty()); 715 assertNull(oldComparator); 716 } 717 718 @Test public void testComparatorIsNullWhenSortOrderListIsEmpty() { 719 TableColumn<String, String> col = initSortTestStructure(); 720 721 assertNull(table.getComparator()); 722 723 table.getSortOrder().add(col); 724 assertFalse(table.getSortOrder().isEmpty()); 725 assertNotNull(table.getComparator()); 726 727 table.getSortOrder().clear(); 728 assertTrue(table.getSortOrder().isEmpty()); 729 assertNull(table.getComparator()); 730 } 731 732 733 734 /********************************************************************* 735 * Tests for specific bugs * 736 ********************************************************************/ 737 @Test public void test_rt16019() { 738 // RT-16019: NodeMemory TableView tests fail with 739 // IndexOutOfBoundsException (ObservableListWrapper.java:336) 740 TableView table = new TableView(); 741 for (int i = 0; i < 1000; i++) { 742 table.getItems().add("data " + i); 743 } 744 } 745 746 @Test public void test_rt15793() { 747 // ListView/TableView selectedIndex is 0 although the items list is empty 748 final TableView tv = new TableView(); 749 final ObservableList list = FXCollections.observableArrayList(); 750 tv.setItems(list); 751 list.add("toto"); 752 tv.getSelectionModel().select(0); 753 assertEquals(0, tv.getSelectionModel().getSelectedIndex()); 754 list.remove(0); 755 assertEquals(-1, tv.getSelectionModel().getSelectedIndex()); 756 } 757 758 @Ignore("Started failing recently, but manual tests seem to indicate the functionality is intact") 759 @Test public void test_rt17522_focusShouldMoveWhenItemAddedAtFocusIndex() { 760 final TableView lv = new TableView(); 761 StageLoader sl = new StageLoader(lv); 762 FocusModel fm = lv.getFocusModel(); 763 lv.getItems().add("row1"); 764 assertTrue(fm.isFocused(0)); 765 766 lv.getItems().add(0, "row0"); 767 assertTrue("Focus is on " + fm.getFocusedIndex(), fm.isFocused(1)); 768 assertFalse(fm.isFocused(0)); 769 770 sl.dispose(); 771 } 772 773 @Test public void test_rt17522_focusShouldMoveWhenItemAddedBeforeFocusIndex() { 774 final TableView lv = new TableView(); 775 FocusModel fm = lv.getFocusModel(); 776 lv.getItems().addAll("row1", "row2"); 777 fm.focus(1); 778 assertTrue(fm.isFocused(1)); 779 assertEquals("row2", fm.getFocusedItem()); 780 781 lv.getItems().add(1, "row0"); 782 assertTrue(fm.isFocused(2)); 783 assertEquals("row2", fm.getFocusedItem()); 784 assertFalse(fm.isFocused(1)); 785 } 786 787 @Test public void test_rt17522_focusShouldNotMoveWhenItemAddedAfterFocusIndex() { 788 final TableView lv = new TableView(); 789 FocusModel fm = lv.getFocusModel(); 790 lv.getItems().addAll("row1"); 791 fm.focus(0); 792 assertTrue(fm.isFocused(0)); 793 assertEquals("row1", fm.getFocusedItem()); 794 795 lv.getItems().add(1, "row2"); 796 assertTrue(fm.isFocused(0)); 797 assertEquals("row1", fm.getFocusedItem()); 798 assertFalse(fm.isFocused(1)); 799 } 800 801 @Test public void test_rt17522_focusShouldBeResetWhenFocusedItemIsRemoved() { 802 final TableView lv = new TableView(); 803 FocusModel fm = lv.getFocusModel(); 804 lv.getItems().add("row1"); 805 assertTrue(fm.isFocused(0)); 806 807 lv.getItems().remove("row1"); 808 assertTrue(fm.getFocusedIndex() == -1); 809 assertNull(fm.getFocusedItem()); 810 } 811 812 @Test public void test_rt17522_focusShouldMoveWhenItemRemovedBeforeFocusIndex() { 813 final TableView lv = new TableView(); 814 FocusModel fm = lv.getFocusModel(); 815 lv.getItems().addAll("row1", "row2"); 816 assertTrue(fm.isFocused(0)); 817 818 fm.focus(1); 819 assertTrue(fm.isFocused(1)); 820 assertEquals("row2", fm.getFocusedItem()); 821 822 lv.getItems().remove("row1"); 823 assertTrue(fm.isFocused(0)); 824 assertEquals("row2", fm.getFocusedItem()); 825 } 826 827 @Test public void test_rt17522_focusShouldNotMoveWhenItemRemovedAfterFocusIndex() { 828 final TableView lv = new TableView(); 829 FocusModel fm = lv.getFocusModel(); 830 lv.getItems().addAll("row1", "row2"); 831 fm.focus(0); 832 assertTrue(fm.isFocused(0)); 833 assertEquals("row1", fm.getFocusedItem()); 834 835 lv.getItems().remove("row2"); 836 assertTrue(fm.isFocused(0)); 837 assertEquals("row1", fm.getFocusedItem()); 838 } 839 840 @Test public void test_rt18385() { 841 table.getItems().addAll("row1", "row2", "row3"); 842 sm.select(1); 843 table.getItems().add("Another Row"); 844 assertEquals(1, sm.getSelectedIndices().size()); 845 assertEquals(1, sm.getSelectedItems().size()); 846 assertEquals(1, sm.getSelectedCells().size()); 847 } 848 849 @Test public void test_rt18339_onlyEditWhenTableViewIsEditable_tableEditableIsFalse_columnEditableIsFalse() { 850 TableColumn<String,String> first = new TableColumn<String,String>("first"); 851 first.setEditable(false); 852 table.getColumns().add(first); 853 table.setEditable(false); 854 table.edit(1, first); 855 assertEquals(null, table.getEditingCell()); 856 } 857 858 @Test public void test_rt18339_onlyEditWhenTableViewIsEditable_tableEditableIsFalse_columnEditableIsTrue() { 859 TableColumn<String,String> first = new TableColumn<String,String>("first"); 860 first.setEditable(true); 861 table.getColumns().add(first); 862 table.setEditable(false); 863 table.edit(1, first); 864 assertEquals(null, table.getEditingCell()); 865 } 866 867 @Test public void test_rt18339_onlyEditWhenTableViewIsEditable_tableEditableIsTrue_columnEditableIsFalse() { 868 TableColumn<String,String> first = new TableColumn<String,String>("first"); 869 first.setEditable(false); 870 table.getColumns().add(first); 871 table.setEditable(true); 872 table.edit(1, first); 873 assertEquals(null, table.getEditingCell()); 874 } 875 876 @Test public void test_rt18339_onlyEditWhenTableViewIsEditable_tableEditableIsTrue_columnEditableIsTrue() { 877 TableColumn<String,String> first = new TableColumn<String,String>("first"); 878 first.setEditable(true); 879 table.getColumns().add(first); 880 table.setEditable(true); 881 table.edit(1, first); 882 assertEquals(new TablePosition(table, 1, first), table.getEditingCell()); 883 } 884 885 @Test public void test_rt14451() { 886 table.getItems().addAll("Apple", "Orange", "Banana"); 887 sm.setSelectionMode(SelectionMode.MULTIPLE); 888 sm.selectRange(0, 2); // select from 0 (inclusive) to 2 (exclusive) 889 assertEquals(2, sm.getSelectedIndices().size()); 890 } 891 892 @Test public void test_rt21586() { 893 table.getItems().setAll("Apple", "Orange", "Banana"); 894 table.getSelectionModel().select(1); 895 assertEquals(1, table.getSelectionModel().getSelectedIndex()); 896 assertEquals("Orange", table.getSelectionModel().getSelectedItem()); 897 898 table.getItems().setAll("Kiwifruit", "Pineapple", "Grape"); 899 assertEquals(-1, table.getSelectionModel().getSelectedIndex()); 900 assertNull(table.getSelectionModel().getSelectedItem()); 901 assertEquals(0, table.getFocusModel().getFocusedIndex()); 902 assertEquals("Kiwifruit", table.getFocusModel().getFocusedItem()); 903 } 904 905 @Test public void test_rt27820_1() { 906 table.getItems().setAll("Apple", "Orange"); 907 table.getSelectionModel().select(0); 908 assertEquals(1, table.getSelectionModel().getSelectedItems().size()); 909 assertEquals("Apple", table.getSelectionModel().getSelectedItem()); 910 911 table.getItems().clear(); 912 assertEquals(0, table.getSelectionModel().getSelectedItems().size()); 913 assertNull(table.getSelectionModel().getSelectedItem()); 914 } 915 916 @Test public void test_rt27820_2() { 917 table.getItems().setAll("Apple", "Orange"); 918 table.getSelectionModel().select(1); 919 assertEquals(1, table.getSelectionModel().getSelectedItems().size()); 920 assertEquals("Orange", table.getSelectionModel().getSelectedItem()); 921 922 table.getItems().clear(); 923 assertEquals(0, table.getSelectionModel().getSelectedItems().size()); 924 assertNull(table.getSelectionModel().getSelectedItem()); 925 } 926 927 @Test public void test_rt28534() { 928 TableView<Person> table = new TableView<Person>(); 929 table.setItems(personTestData); 930 931 TableColumn firstNameCol = new TableColumn("First Name"); 932 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 933 934 TableColumn lastNameCol = new TableColumn("Last Name"); 935 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 936 937 TableColumn emailCol = new TableColumn("Email"); 938 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 939 940 table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 941 942 VirtualFlowTestUtils.assertRowsNotEmpty(table, 0, 5); // rows 0 - 5 should be filled 943 VirtualFlowTestUtils.assertRowsEmpty(table, 5, -1); // rows 5+ should be empty 944 945 // now we replace the data and expect the cells that have no data 946 // to be empty 947 table.setItems(FXCollections.observableArrayList( 948 new Person("*_*Emma", "Jones", "emma.jones@example.com"), 949 new Person("_Michael", "Brown", "michael.brown@example.com"))); 950 951 VirtualFlowTestUtils.assertRowsNotEmpty(table, 0, 2); // rows 0 - 2 should be filled 952 VirtualFlowTestUtils.assertRowsEmpty(table, 2, -1); // rows 2+ should be empty 953 } 954 955 @Test public void test_rt22463() { 956 final TableView<RT_22463_Person> table = new TableView<RT_22463_Person>(); 957 table.setTableMenuButtonVisible(true); 958 TableColumn c1 = new TableColumn("Id"); 959 TableColumn c2 = new TableColumn("Name"); 960 c1.setCellValueFactory(new PropertyValueFactory<Person, Long>("id")); 961 c2.setCellValueFactory(new PropertyValueFactory<Person, String>("name")); 962 table.getColumns().addAll(c1, c2); 963 964 // before the change things display fine 965 RT_22463_Person p1 = new RT_22463_Person(); 966 p1.setId(1l); 967 p1.setName("name1"); 968 RT_22463_Person p2 = new RT_22463_Person(); 969 p2.setId(2l); 970 p2.setName("name2"); 971 table.setItems(FXCollections.observableArrayList(p1, p2)); 972 VirtualFlowTestUtils.assertCellTextEquals(table, 0, "1", "name1"); 973 VirtualFlowTestUtils.assertCellTextEquals(table, 1, "2", "name2"); 974 975 // now we change the persons but they are still equal as the ID's don't 976 // change - but the items list is cleared so the cells should update 977 RT_22463_Person new_p1 = new RT_22463_Person(); 978 new_p1.setId(1l); 979 new_p1.setName("updated name1"); 980 RT_22463_Person new_p2 = new RT_22463_Person(); 981 new_p2.setId(2l); 982 new_p2.setName("updated name2"); 983 table.getItems().clear(); 984 table.setItems(FXCollections.observableArrayList(new_p1, new_p2)); 985 VirtualFlowTestUtils.assertCellTextEquals(table, 0, "1", "updated name1"); 986 VirtualFlowTestUtils.assertCellTextEquals(table, 1, "2", "updated name2"); 987 } 988 989 @Test public void test_rt28637() { 990 ObservableList<String> items = FXCollections.observableArrayList("String1", "String2", "String3", "String4"); 991 992 final TableView<String> tableView = new TableView<String>(); 993 final MultipleSelectionModel sm = tableView.getSelectionModel(); 994 tableView.setItems(items); 995 996 tableView.getSelectionModel().select(0); 997 assertEquals("String1", sm.getSelectedItem()); 998 assertEquals(1, sm.getSelectedItems().size()); 999 assertEquals("String1", sm.getSelectedItems().get(0)); 1000 assertEquals(0, sm.getSelectedIndex()); 1001 1002 items.remove(sm.getSelectedItem()); 1003 assertEquals("String2", sm.getSelectedItem()); 1004 assertEquals(1, sm.getSelectedItems().size()); 1005 assertEquals("String2", sm.getSelectedItems().get(0)); 1006 assertEquals(0, sm.getSelectedIndex()); 1007 } 1008 1009 @Test public void test_rt24844() { 1010 // p1 == lowest first name 1011 Person p0, p1, p2, p3, p4; 1012 1013 TableView<Person> table = new TableView<Person>(); 1014 table.setItems(FXCollections.observableArrayList( 1015 p3 = new Person("Jacob", "Smith", "jacob.smith@example.com"), 1016 p2 = new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 1017 p1 = new Person("Ethan", "Williams", "ethan.williams@example.com"), 1018 p0 = new Person("Emma", "Jones", "emma.jones@example.com"), 1019 p4 = new Person("Michael", "Brown", "michael.brown@example.com"))); 1020 1021 TableColumn firstNameCol = new TableColumn("First Name"); 1022 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1023 1024 // set dummy comparator to lock items in place until new comparator is set 1025 firstNameCol.setComparator((t, t1) -> 0); 1026 1027 table.getColumns().addAll(firstNameCol); 1028 table.getSortOrder().add(firstNameCol); 1029 1030 // ensure the existing order is as expected 1031 assertEquals(p3, table.getItems().get(0)); 1032 assertEquals(p2, table.getItems().get(1)); 1033 assertEquals(p1, table.getItems().get(2)); 1034 assertEquals(p0, table.getItems().get(3)); 1035 assertEquals(p4, table.getItems().get(4)); 1036 1037 // set a new comparator 1038 firstNameCol.setComparator(new Comparator() { 1039 Random r = new Random(); 1040 @Override public int compare(Object t, Object t1) { 1041 return t.toString().compareTo(t1.toString()); 1042 } 1043 }); 1044 1045 // ensure the new order is as expected 1046 assertEquals(p0, table.getItems().get(0)); 1047 assertEquals(p1, table.getItems().get(1)); 1048 assertEquals(p2, table.getItems().get(2)); 1049 assertEquals(p3, table.getItems().get(3)); 1050 assertEquals(p4, table.getItems().get(4)); 1051 } 1052 1053 @Test public void test_rt29331() { 1054 TableView<Person> table = new TableView<Person>(); 1055 1056 TableColumn firstNameCol = new TableColumn("First Name"); 1057 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1058 1059 TableColumn lastNameCol = new TableColumn("Last Name"); 1060 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 1061 1062 TableColumn emailCol = new TableColumn("Email"); 1063 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 1064 1065 TableColumn parentColumn = new TableColumn<>("Parent"); 1066 parentColumn.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 1067 1068 table.getColumns().addAll(parentColumn); 1069 1070 // table is setup, now hide the 'last name' column 1071 emailCol.setVisible(false); 1072 assertFalse(emailCol.isVisible()); 1073 1074 // reorder columns inside the parent column 1075 parentColumn.getColumns().setAll(emailCol, firstNameCol, lastNameCol); 1076 1077 // the email column should not become visible after this, but it does 1078 assertFalse(emailCol.isVisible()); 1079 } 1080 1081 private int rt29330_count = 0; 1082 @Test public void test_rt29330_1() { 1083 TableView<Person> table = new TableView<>(personTestData); 1084 1085 TableColumn parentColumn = new TableColumn<>("Parent"); 1086 table.getColumns().addAll(parentColumn); 1087 1088 TableColumn firstNameCol = new TableColumn("First Name"); 1089 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1090 1091 TableColumn lastNameCol = new TableColumn("Last Name"); 1092 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 1093 1094 parentColumn.getColumns().addAll(firstNameCol, lastNameCol); 1095 1096 table.setOnSort(event -> { 1097 rt29330_count++; 1098 }); 1099 1100 // test preconditions 1101 assertEquals(ASCENDING, lastNameCol.getSortType()); 1102 assertEquals(0, rt29330_count); 1103 1104 table.getSortOrder().add(lastNameCol); 1105 assertEquals(1, rt29330_count); 1106 1107 lastNameCol.setSortType(DESCENDING); 1108 assertEquals(2, rt29330_count); 1109 1110 lastNameCol.setSortType(null); 1111 assertEquals(3, rt29330_count); 1112 1113 lastNameCol.setSortType(ASCENDING); 1114 assertEquals(4, rt29330_count); 1115 } 1116 1117 @Test public void test_rt29330_2() { 1118 TableView<Person> table = new TableView<>(personTestData); 1119 1120 TableColumn firstNameCol = new TableColumn("First Name"); 1121 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1122 1123 TableColumn lastNameCol = new TableColumn("Last Name"); 1124 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 1125 1126 // this test differs from the previous one by installing the parent column 1127 // into the tableview after it has the children added into it 1128 TableColumn parentColumn = new TableColumn<>("Parent"); 1129 parentColumn.getColumns().addAll(firstNameCol, lastNameCol); 1130 table.getColumns().addAll(parentColumn); 1131 1132 table.setOnSort(event -> { 1133 rt29330_count++; 1134 }); 1135 1136 // test preconditions 1137 assertEquals(ASCENDING, lastNameCol.getSortType()); 1138 assertEquals(0, rt29330_count); 1139 1140 table.getSortOrder().add(lastNameCol); 1141 assertEquals(1, rt29330_count); 1142 1143 lastNameCol.setSortType(DESCENDING); 1144 assertEquals(2, rt29330_count); 1145 1146 lastNameCol.setSortType(null); 1147 assertEquals(3, rt29330_count); 1148 1149 lastNameCol.setSortType(ASCENDING); 1150 assertEquals(4, rt29330_count); 1151 } 1152 1153 @Test public void test_rt29313_selectedIndices() { 1154 TableView<Person> table = new TableView<>(personTestData); 1155 1156 TableSelectionModel sm = table.getSelectionModel(); 1157 1158 TableColumn firstNameCol = new TableColumn("First Name"); 1159 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1160 1161 TableColumn lastNameCol = new TableColumn("Last Name"); 1162 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 1163 1164 TableColumn emailCol = new TableColumn("Email"); 1165 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 1166 1167 table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 1168 sm.setCellSelectionEnabled(true); 1169 sm.setSelectionMode(SelectionMode.MULTIPLE); 1170 1171 assertEquals(0, sm.getSelectedIndices().size()); 1172 1173 // only (0,0) should be selected, so selected indices should be [0] 1174 sm.select(0, firstNameCol); 1175 assertEquals(1, sm.getSelectedIndices().size()); 1176 1177 // now (0,0) and (1,0) should be selected, so selected indices should be [0, 1] 1178 sm.select(1, firstNameCol); 1179 assertEquals(2, sm.getSelectedIndices().size()); 1180 1181 // now (0,0), (1,0) and (1,1) should be selected, but selected indices 1182 // should remain as [0, 1], as we don't want selected indices to become 1183 // [0,1,1] (which is what RT-29313 is about) 1184 sm.select(1, lastNameCol); 1185 assertEquals(2, sm.getSelectedIndices().size()); 1186 assertEquals(0, sm.getSelectedIndices().get(0)); 1187 assertEquals(1, sm.getSelectedIndices().get(1)); 1188 } 1189 1190 @Test public void test_rt29313_selectedItems() { 1191 Person p0, p1; 1192 TableView<Person> table = new TableView<>(); 1193 table.setItems(FXCollections.observableArrayList( 1194 p0 = new Person("Jacob", "Smith", "jacob.smith@example.com"), 1195 p1 = new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 1196 new Person("Ethan", "Williams", "ethan.williams@example.com"), 1197 new Person("Emma", "Jones", "emma.jones@example.com"), 1198 new Person("Michael", "Brown", "michael.brown@example.com"))); 1199 1200 TableSelectionModel sm = table.getSelectionModel(); 1201 1202 TableColumn firstNameCol = new TableColumn("First Name"); 1203 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1204 1205 TableColumn lastNameCol = new TableColumn("Last Name"); 1206 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 1207 1208 TableColumn emailCol = new TableColumn("Email"); 1209 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 1210 1211 table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 1212 sm.setCellSelectionEnabled(true); 1213 sm.setSelectionMode(SelectionMode.MULTIPLE); 1214 1215 assertEquals(0, sm.getSelectedIndices().size()); 1216 1217 // only (0,0) should be selected, so selected items should be [p0] 1218 sm.select(0, firstNameCol); 1219 assertEquals(1, sm.getSelectedItems().size()); 1220 1221 // now (0,0) and (1,0) should be selected, so selected items should be [p0, p1] 1222 sm.select(1, firstNameCol); 1223 assertEquals(2, sm.getSelectedItems().size()); 1224 1225 // now (0,0), (1,0) and (1,1) should be selected, but selected items 1226 // should remain as [p0, p1], as we don't want selected items to become 1227 // [p0,p1,p1] (which is what RT-29313 is about) 1228 sm.select(1, lastNameCol); 1229 assertEquals(2, sm.getSelectedItems().size()); 1230 assertEquals(p0, sm.getSelectedItems().get(0)); 1231 assertEquals(p1, sm.getSelectedItems().get(1)); 1232 } 1233 1234 @Test public void test_rt29566() { 1235 TableView<Person> table = new TableView<>(personTestData); 1236 1237 TableSelectionModel sm = table.getSelectionModel(); 1238 1239 TableColumn firstNameCol = new TableColumn("First Name"); 1240 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1241 1242 TableColumn lastNameCol = new TableColumn("Last Name"); 1243 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 1244 1245 TableColumn emailCol = new TableColumn("Email"); 1246 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 1247 1248 table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 1249 1250 // test the state before we hide and re-add a column 1251 VirtualFlowTestUtils.assertCellTextEquals(table, 0, "Jacob", "Smith", "jacob.smith@example.com"); 1252 VirtualFlowTestUtils.assertCellTextEquals(table, 1, "Isabella", "Johnson", "isabella.johnson@example.com"); 1253 VirtualFlowTestUtils.assertCellTextEquals(table, 2, "Ethan", "Williams", "ethan.williams@example.com"); 1254 VirtualFlowTestUtils.assertCellTextEquals(table, 3, "Emma", "Jones", "emma.jones@example.com"); 1255 VirtualFlowTestUtils.assertCellTextEquals(table, 4, "Michael", "Brown", "michael.brown@example.com"); 1256 1257 // hide the last name column, and test cells again 1258 table.getColumns().remove(lastNameCol); 1259 VirtualFlowTestUtils.assertCellTextEquals(table, 0, "Jacob", "jacob.smith@example.com"); 1260 VirtualFlowTestUtils.assertCellTextEquals(table, 1, "Isabella", "isabella.johnson@example.com"); 1261 VirtualFlowTestUtils.assertCellTextEquals(table, 2, "Ethan", "ethan.williams@example.com"); 1262 VirtualFlowTestUtils.assertCellTextEquals(table, 3, "Emma", "emma.jones@example.com"); 1263 VirtualFlowTestUtils.assertCellTextEquals(table, 4, "Michael", "michael.brown@example.com"); 1264 1265 // re-add the last name column - we should go back to the original state. 1266 // However, what appears to be happening is that, for some reason, some 1267 // of the cells from the removed column do not reappear - meaning in this case 1268 // some of the last name values will not be where we expect them to be. 1269 // This is clearly not ideal! 1270 table.getColumns().add(1, lastNameCol); 1271 VirtualFlowTestUtils.assertCellTextEquals(table, 0, "Jacob", "Smith", "jacob.smith@example.com"); 1272 VirtualFlowTestUtils.assertCellTextEquals(table, 1, "Isabella", "Johnson", "isabella.johnson@example.com"); 1273 VirtualFlowTestUtils.assertCellTextEquals(table, 2, "Ethan", "Williams", "ethan.williams@example.com"); 1274 VirtualFlowTestUtils.assertCellTextEquals(table, 3, "Emma", "Jones", "emma.jones@example.com"); 1275 VirtualFlowTestUtils.assertCellTextEquals(table, 4, "Michael", "Brown", "michael.brown@example.com"); 1276 } 1277 1278 @Test public void test_rt29390() { 1279 final TableView<Person> tableView = new TableView<Person>(); 1280 tableView.setMaxHeight(50); 1281 tableView.setPrefHeight(50); 1282 tableView.setItems(FXCollections.observableArrayList( 1283 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1284 new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 1285 new Person("Ethan", "Williams", "ethan.williams@example.com"), 1286 new Person("Emma", "Jones", "emma.jones@example.com"), 1287 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1288 new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 1289 new Person("Ethan", "Williams", "ethan.williams@example.com"), 1290 new Person("Emma", "Jones", "emma.jones@example.com"), 1291 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1292 new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 1293 new Person("Ethan", "Williams", "ethan.williams@example.com"), 1294 new Person("Emma", "Jones", "emma.jones@example.com"), 1295 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1296 new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 1297 new Person("Ethan", "Williams", "ethan.williams@example.com"), 1298 new Person("Emma", "Jones", "emma.jones@example.com") 1299 )); 1300 1301 TableColumn firstNameCol = new TableColumn("First Name"); 1302 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1303 1304 tableView.getColumns().add(firstNameCol); 1305 1306 // we want the vertical scrollbar 1307 VirtualScrollBar scrollBar = VirtualFlowTestUtils.getVirtualFlowVerticalScrollbar(tableView); 1308 1309 assertNotNull(scrollBar); 1310 assertTrue(scrollBar.isVisible()); 1311 assertTrue(scrollBar.getVisibleAmount() > 0.0); 1312 assertTrue(scrollBar.getVisibleAmount() < 1.0); 1313 1314 // this next test is likely to be brittle, but we'll see...If it is the 1315 // cause of failure then it can be commented out 1316 assertEquals(0.0625, scrollBar.getVisibleAmount(), 0.0); 1317 } 1318 1319 @Test public void test_rt30400() { 1320 // create a listview that'll render cells using the check box cell factory 1321 final TableView<Person> tableView = new TableView<Person>(); 1322 tableView.setMinHeight(100); 1323 tableView.setPrefHeight(100); 1324 tableView.setItems(FXCollections.observableArrayList( 1325 new Person("Jacob", "Smith", "jacob.smith@example.com") 1326 )); 1327 1328 TableColumn firstNameCol = new TableColumn("First Name"); 1329 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1330 firstNameCol.setCellFactory(CheckBoxTableCell.forTableColumn(param -> new ReadOnlyBooleanWrapper(true))); 1331 tableView.getColumns().add(firstNameCol); 1332 1333 // because only the first row has data, all other rows should be 1334 // empty (and not contain check boxes - we just check the first four here) 1335 VirtualFlowTestUtils.assertRowsNotEmpty(tableView, 0, 1); 1336 VirtualFlowTestUtils.assertCellNotEmpty(VirtualFlowTestUtils.getCell(tableView, 0)); 1337 VirtualFlowTestUtils.assertCellEmpty(VirtualFlowTestUtils.getCell(tableView, 1)); 1338 VirtualFlowTestUtils.assertCellEmpty(VirtualFlowTestUtils.getCell(tableView, 2)); 1339 VirtualFlowTestUtils.assertCellEmpty(VirtualFlowTestUtils.getCell(tableView, 3)); 1340 } 1341 1342 @Test public void test_rt31165() { 1343 final ObservableList names = FXCollections.observableArrayList("Adam", "Alex", "Alfred", "Albert"); 1344 1345 final TableView<Person> tableView = new TableView<Person>(); 1346 tableView.setEditable(true); 1347 tableView.setItems(FXCollections.observableArrayList( 1348 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1349 new Person("Jim", "Bob", "jim.bob@example.com") 1350 )); 1351 1352 TableColumn firstNameCol = new TableColumn("First Name"); 1353 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1354 firstNameCol.setCellFactory(ChoiceBoxTableCell.forTableColumn(names)); 1355 firstNameCol.setEditable(true); 1356 1357 tableView.getColumns().add(firstNameCol); 1358 1359 IndexedCell cell = VirtualFlowTestUtils.getCell(tableView, 1, 0); 1360 assertEquals("Jim", cell.getText()); 1361 assertFalse(cell.isEditing()); 1362 1363 tableView.edit(1, firstNameCol); 1364 1365 TablePosition editingCell = tableView.getEditingCell(); 1366 assertEquals(1, editingCell.getRow()); 1367 assertEquals(firstNameCol, editingCell.getTableColumn()); 1368 assertTrue(cell.isEditing()); 1369 1370 VirtualFlowTestUtils.getVirtualFlow(tableView).requestLayout(); 1371 Toolkit.getToolkit().firePulse(); 1372 1373 editingCell = tableView.getEditingCell(); 1374 assertEquals(1, editingCell.getRow()); 1375 assertEquals(firstNameCol, editingCell.getTableColumn()); 1376 assertTrue(cell.isEditing()); 1377 } 1378 1379 @Test public void test_rt31471() { 1380 Person jacobSmith; 1381 final TableView<Person> tableView = new TableView<Person>(); 1382 tableView.setItems(FXCollections.observableArrayList( 1383 jacobSmith = new Person("Jacob", "Smith", "jacob.smith@example.com"), 1384 new Person("Jim", "Bob", "jim.bob@example.com") 1385 )); 1386 1387 TableColumn firstNameCol = new TableColumn("First Name"); 1388 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1389 tableView.getColumns().add(firstNameCol); 1390 1391 IndexedCell cell = VirtualFlowTestUtils.getCell(tableView, 0); 1392 assertEquals(jacobSmith, cell.getItem()); 1393 1394 tableView.setFixedCellSize(50); 1395 1396 VirtualFlowTestUtils.getVirtualFlow(tableView).requestLayout(); 1397 Toolkit.getToolkit().firePulse(); 1398 1399 assertEquals(jacobSmith, cell.getItem()); 1400 assertEquals(50, cell.getHeight(), 0.00); 1401 } 1402 1403 private int rt_31200_count = 0; 1404 @Test public void test_rt_31200_tableCell() { 1405 rt_31200_count = 0; 1406 final TableView<Person> tableView = new TableView<Person>(); 1407 tableView.setItems(FXCollections.observableArrayList( 1408 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1409 new Person("Jim", "Bob", "jim.bob@example.com") 1410 )); 1411 1412 TableColumn<Person,String> firstNameCol = new TableColumn("First Name"); 1413 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1414 tableView.getColumns().add(firstNameCol); 1415 1416 firstNameCol.setCellFactory(new Callback<TableColumn<Person,String>, TableCell<Person, String>>() { 1417 @Override 1418 public TableCell<Person, String> call(TableColumn<Person,String> param) { 1419 return new TableCellShim<Person, String>() { 1420 ImageView view = new ImageView(); 1421 { setGraphic(view); }; 1422 1423 @Override 1424 public void updateItem(String item, boolean empty) { 1425 if (getItem() == null ? item == null : getItem().equals(item)) { 1426 rt_31200_count++; 1427 } 1428 super.updateItem(item, empty); 1429 if (item == null || empty) { 1430 view.setImage(null); 1431 setText(null); 1432 } else { 1433 setText(item); 1434 } 1435 } 1436 }; 1437 } 1438 }); 1439 1440 StageLoader sl = new StageLoader(tableView); 1441 1442 assertEquals(14, rt_31200_count); 1443 1444 // resize the stage 1445 sl.getStage().setHeight(250); 1446 Toolkit.getToolkit().firePulse(); 1447 sl.getStage().setHeight(50); 1448 Toolkit.getToolkit().firePulse(); 1449 assertEquals(14, rt_31200_count); 1450 1451 sl.dispose(); 1452 } 1453 1454 @Test public void test_rt_31200_tableRow() { 1455 rt_31200_count = 0; 1456 final TableView<Person> tableView = new TableView<Person>(); 1457 tableView.setItems(FXCollections.observableArrayList( 1458 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1459 new Person("Jim", "Bob", "jim.bob@example.com") 1460 )); 1461 1462 TableColumn<Person,String> firstNameCol = new TableColumn("First Name"); 1463 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 1464 tableView.getColumns().add(firstNameCol); 1465 1466 tableView.setRowFactory(new Callback<TableView<Person>, TableRow<Person>>() { 1467 @Override 1468 public TableRow<Person> call(TableView<Person> param) { 1469 return new TableRowShim<Person>() { 1470 ImageView view = new ImageView(); 1471 { setGraphic(view); }; 1472 1473 @Override 1474 public void updateItem(Person item, boolean empty) { 1475 if (getItem() == null ? item == null : getItem().equals(item)) { 1476 rt_31200_count++; 1477 } 1478 super.updateItem(item, empty); 1479 if (item == null || empty) { 1480 view.setImage(null); 1481 setText(null); 1482 } else { 1483 setText(item.toString()); 1484 } 1485 } 1486 }; 1487 } 1488 }); 1489 1490 StageLoader sl = new StageLoader(tableView); 1491 1492 assertEquals(14, rt_31200_count); 1493 1494 // resize the stage 1495 sl.getStage().setHeight(250); 1496 Toolkit.getToolkit().firePulse(); 1497 sl.getStage().setHeight(50); 1498 Toolkit.getToolkit().firePulse(); 1499 assertEquals(14, rt_31200_count); 1500 1501 sl.dispose(); 1502 } 1503 1504 @Test public void test_rt_31727() { 1505 TableView table = new TableView(); 1506 TableColumn<String,String> first = new TableColumn<String,String>("first"); 1507 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1508 TableColumn<String,String> second = new TableColumn<String,String>("second"); 1509 second.setCellValueFactory(new PropertyValueFactory("lastName")); 1510 table.getColumns().addAll(first, second); 1511 1512 table.setItems(FXCollections.observableArrayList( 1513 new Person("Jacob", "Smith", "jacob.smith@example.com"), 1514 new Person("Jim", "Bob", "jim.bob@example.com") 1515 )); 1516 1517 table.setEditable(true); 1518 first.setEditable(true); 1519 1520 // do a normal edit 1521 table.edit(0, first); 1522 TablePosition editingCell = table.getEditingCell(); 1523 assertNotNull(editingCell); 1524 assertEquals(0, editingCell.getRow()); 1525 assertEquals(0, editingCell.getColumn()); 1526 assertEquals(first, editingCell.getTableColumn()); 1527 assertEquals(table, editingCell.getTableView()); 1528 1529 // cancel editing 1530 table.edit(-1, null); 1531 editingCell = table.getEditingCell(); 1532 assertNull(editingCell); 1533 } 1534 1535 @Test public void test_rt_21517() { 1536 TableView table = new TableView(); 1537 TableColumn<String,String> first = new TableColumn<String,String>("first"); 1538 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1539 TableColumn<String,String> second = new TableColumn<String,String>("second"); 1540 second.setCellValueFactory(new PropertyValueFactory("lastName")); 1541 table.getColumns().addAll(first, second); 1542 1543 Person aaa,bbb,ccc; 1544 table.setItems(FXCollections.observableArrayList( 1545 aaa = new Person("AAA", "Smith", "jacob.smith@example.com"), 1546 bbb = new Person("BBB", "Bob", "jim.bob@example.com"), 1547 ccc = new Person("CCC", "Giles", "jim.bob@example.com") 1548 )); 1549 1550 final TableView.TableViewSelectionModel sm = table.getSelectionModel(); 1551 1552 // test pre-conditions 1553 assertEquals(0, sm.getSelectedCells().size()); 1554 assertEquals(0, sm.getSelectedItems().size()); 1555 assertEquals(0, sm.getSelectedIndices().size()); 1556 1557 // select the 3rd row (that is, CCC) 1558 sm.select(2); 1559 assertTrue(sm.isSelected(2)); 1560 assertEquals(2, sm.getSelectedIndex()); 1561 assertEquals(1, sm.getSelectedIndices().size()); 1562 assertTrue(sm.getSelectedIndices().contains(2)); 1563 assertEquals(ccc, sm.getSelectedItem()); 1564 assertEquals(1, sm.getSelectedItems().size()); 1565 assertTrue(sm.getSelectedItems().contains(ccc)); 1566 1567 // we also want to test visually 1568 TableRow aaaRow = (TableRow) VirtualFlowTestUtils.getCell(table, 0); 1569 assertFalse(aaaRow.isSelected()); 1570 TableRow cccRow = (TableRow) VirtualFlowTestUtils.getCell(table, 2); 1571 assertTrue(cccRow.isSelected()); 1572 1573 // sort tableview by firstname column in ascending (default) order 1574 // (so aaa continues to come first) 1575 table.getSortOrder().add(first); 1576 1577 // nothing should have changed 1578 assertTrue(sm.isSelected(2)); 1579 assertEquals(2, sm.getSelectedIndex()); 1580 assertEquals(1, sm.getSelectedIndices().size()); 1581 assertTrue(sm.getSelectedIndices().contains(2)); 1582 assertEquals(ccc, sm.getSelectedItem()); 1583 assertEquals(1, sm.getSelectedItems().size()); 1584 assertTrue(sm.getSelectedItems().contains(ccc)); 1585 aaaRow = (TableRow) VirtualFlowTestUtils.getCell(table, 0); 1586 assertFalse(aaaRow.isSelected()); 1587 cccRow = (TableRow) VirtualFlowTestUtils.getCell(table, 2); 1588 assertTrue(cccRow.isSelected()); 1589 1590 // continue to sort tableview by firstname column, but now in descending 1591 // order, (so ccc to come first) 1592 first.setSortType(TableColumn.SortType.DESCENDING); 1593 1594 // now test to ensure that CCC is still the only selected item, but now 1595 // located in index 0 1596 assertTrue(sm.isSelected(0)); 1597 assertEquals(0, sm.getSelectedIndex()); 1598 assertEquals(1, sm.getSelectedIndices().size()); 1599 assertTrue(sm.getSelectedIndices().contains(0)); 1600 assertEquals(ccc, sm.getSelectedItem()); 1601 assertEquals(1, sm.getSelectedItems().size()); 1602 assertTrue(sm.getSelectedItems().contains(ccc)); 1603 1604 // we also want to test visually 1605 aaaRow = (TableRow) VirtualFlowTestUtils.getCell(table, 1); 1606 assertFalse(aaaRow.isSelected()); 1607 cccRow = (TableRow) VirtualFlowTestUtils.getCell(table, 0); 1608 assertTrue(cccRow.isSelected()); 1609 } 1610 1611 @Test public void test_rt_30484_tableCell() { 1612 TableView<Person> table = new TableView<>(); 1613 TableColumn<Person,String> first = new TableColumn<>("first"); 1614 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1615 table.getColumns().addAll(first); 1616 1617 table.setItems(FXCollections.observableArrayList( 1618 new Person("AAA", "Smith", "jacob.smith@example.com"), 1619 new Person("BBB", "Bob", "jim.bob@example.com") 1620 )); 1621 1622 first.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() { 1623 @Override 1624 public TableCell<Person, String> call(TableColumn<Person, String> param) { 1625 return new TableCellShim<Person, String>() { 1626 Rectangle graphic = new Rectangle(10, 10, Color.RED); 1627 { setGraphic(graphic); }; 1628 1629 @Override public void updateItem(String item, boolean empty) { 1630 super.updateItem(item, empty); 1631 if (item == null || empty) { 1632 graphic.setVisible(false); 1633 setText(null); 1634 } else { 1635 graphic.setVisible(true); 1636 setText(item); 1637 } 1638 } 1639 }; 1640 } 1641 }); 1642 1643 // First two rows have content, so the graphic should show. 1644 // All other rows have no content, so graphic should not show. 1645 1646 VirtualFlowTestUtils.assertGraphicIsVisible(table, 0, 0); 1647 VirtualFlowTestUtils.assertGraphicIsVisible(table, 1, 0); 1648 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 2, 0); 1649 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 3, 0); 1650 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 4, 0); 1651 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 5, 0); 1652 } 1653 1654 @Test public void test_rt_30484_tableRow() { 1655 TableView<Person> table = new TableView<>(); 1656 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1657 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1658 table.getColumns().addAll(first); 1659 1660 table.setItems(FXCollections.observableArrayList( 1661 new Person("AAA", "Smith", "jacob.smith@example.com"), 1662 new Person("BBB", "Bob", "jim.bob@example.com") 1663 )); 1664 1665 table.setRowFactory(new Callback<TableView<Person>, TableRow<Person>>() { 1666 @Override public TableRow<Person> call(TableView<Person> param) { 1667 return new TableRowShim<Person>() { 1668 Rectangle graphic = new Rectangle(10, 10, Color.RED); 1669 { setGraphic(graphic); }; 1670 1671 @Override public void updateItem(Person item, boolean empty) { 1672 super.updateItem(item, empty); 1673 if (item == null || empty) { 1674 graphic.setVisible(false); 1675 setText(null); 1676 } else { 1677 graphic.setVisible(true); 1678 setText(item.toString()); 1679 } 1680 } 1681 }; 1682 } 1683 }); 1684 1685 // First two rows have content, so the graphic should show. 1686 // All other rows have no content, so graphic should not show. 1687 1688 VirtualFlowTestUtils.assertGraphicIsVisible(table, 0); 1689 VirtualFlowTestUtils.assertGraphicIsVisible(table, 1); 1690 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 2); 1691 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 3); 1692 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 4); 1693 VirtualFlowTestUtils.assertGraphicIsNotVisible(table, 5); 1694 } 1695 1696 @Test public void test_rt_32201() { 1697 final int numRows = 150; 1698 final int numColumns = 30; 1699 1700 // create data 1701 final ObservableList<List<Object>> bigData = FXCollections.observableArrayList(); 1702 for (int row = bigData.size(); row < numRows; row++) { 1703 List<Object> line = new ArrayList<>(); 1704 for (int col = 0; col <= numColumns; col++) { 1705 double value = (col == 0) ? (double)row : Math.random() * 1000; 1706 line.add(value); 1707 } 1708 bigData.add(line); 1709 } 1710 1711 TableView<List<Object>> table = new TableView<>(bigData); 1712 1713 // create columns 1714 for (int i = 0; i <= numColumns; i++) { 1715 TableColumn<List<Object>,Object> col = new TableColumn<>("Col" + i); 1716 final int coli = i; 1717 col.setCellValueFactory(p -> new ReadOnlyObjectWrapper(p.getValue().get(coli))); 1718 1719 table.getColumns().add(col); 1720 } 1721 1722 // start test 1723 assertNull(table.getComparator()); 1724 assertTrue(table.getSortOrder().isEmpty()); 1725 1726 table.getSortOrder().add(table.getColumns().get(0)); 1727 assertNotNull(table.getComparator()); 1728 assertTrue(table.getSortOrder().contains(table.getColumns().get(0))); 1729 assertEquals(1, table.getSortOrder().size()); 1730 1731 // remove column again 1732 try { 1733 table.getSortOrder().clear(); 1734 } catch (ClassCastException e) { 1735 fail("Comparator should be null as the sort order list is empty."); 1736 } 1737 assertNull(table.getComparator()); 1738 assertTrue(table.getSortOrder().isEmpty()); 1739 } 1740 1741 private int rt_31015_count = 0; 1742 @Test public void test_rt_31015() { 1743 TableView<Person> table = new TableView<>(); 1744 table.setEditable(true); 1745 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1746 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1747 table.getColumns().addAll(first); 1748 1749 table.setItems(FXCollections.observableArrayList( 1750 new Person("John", "Smith", "jacob.smith@example.com") 1751 )); 1752 1753 //Set cell factory for cells that allow editing 1754 Callback<TableColumn<Person,String>, TableCell<Person, String>> cellFactory = new Callback<TableColumn<Person,String>, TableCell<Person, String>>() { 1755 public TableCell<Person, String> call(TableColumn<Person, String> p) { 1756 return new TableCell<Person, String>() { 1757 @Override public void cancelEdit() { 1758 super.cancelEdit(); 1759 rt_31015_count++; 1760 } 1761 }; 1762 } 1763 }; 1764 first.setCellFactory(cellFactory); 1765 1766 StageLoader sl = new StageLoader(table); 1767 1768 assertEquals(0, rt_31015_count); 1769 1770 table.edit(0, first); 1771 assertEquals(0, rt_31015_count); 1772 1773 table.edit(-1, null); 1774 assertEquals(1, rt_31015_count); 1775 1776 sl.dispose(); 1777 } 1778 1779 @Test public void test_rt_31653() { 1780 TableView<Person> table = new TableView<>(); 1781 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1782 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1783 table.getColumns().addAll(first); 1784 1785 table.setItems(FXCollections.observableArrayList( 1786 new Person("John", "Smith", "jacob.smith@example.com") 1787 )); 1788 1789 TableRow<Person> rowCell = (TableRow<Person>)VirtualFlowTestUtils.getCell(table, 0); 1790 final double initialWidth = ControlShim.computePrefWidth(rowCell, -1); 1791 1792 first.setPrefWidth(200); 1793 1794 final double newWidth = ControlShim.computePrefWidth(rowCell, -1); 1795 assertEquals(200, newWidth, 0.0); 1796 assertTrue(initialWidth != newWidth); 1797 } 1798 1799 private int rt_29650_start_count = 0; 1800 private int rt_29650_commit_count = 0; 1801 private int rt_29650_cancel_count = 0; 1802 @Test public void test_rt_29650() { 1803 TableView<Person> table = new TableView<>(); 1804 table.setEditable(true); 1805 table.setItems(FXCollections.observableArrayList( 1806 new Person("John", "Smith", "jacob.smith@example.com") 1807 )); 1808 1809 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1810 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1811 Callback<TableColumn<Person, String>, TableCell<Person, String>> factory = TextFieldTableCell.forTableColumn(); 1812 first.setCellFactory(factory); 1813 table.getColumns().addAll(first); 1814 first.setOnEditStart(t -> { 1815 rt_29650_start_count++; 1816 }); 1817 first.setOnEditCommit(t -> { 1818 rt_29650_commit_count++; 1819 }); 1820 first.setOnEditCancel(t -> { 1821 rt_29650_cancel_count++; 1822 }); 1823 1824 StageLoader sl = new StageLoader(table); 1825 1826 table.edit(0, first); 1827 1828 Toolkit.getToolkit().firePulse(); 1829 1830 TableCell rootCell = (TableCell) VirtualFlowTestUtils.getCell(table, 0, 0); 1831 TextField textField = (TextField) rootCell.getGraphic(); 1832 textField.setText("Testing!"); 1833 KeyEventFirer keyboard = new KeyEventFirer(textField); 1834 keyboard.doKeyPress(KeyCode.ENTER); 1835 1836 // TODO should the following assert be enabled? 1837 // assertEquals("Testing!", listView.getItems().get(0)); 1838 assertEquals(1, rt_29650_start_count); 1839 assertEquals(1, rt_29650_commit_count); 1840 assertEquals(0, rt_29650_cancel_count); 1841 1842 sl.dispose(); 1843 } 1844 1845 private int rt_29849_start_count = 0; 1846 @Test public void test_rt_29849() { 1847 TableView<Person> table = new TableView<>(); 1848 table.setEditable(true); 1849 table.setItems(FXCollections.observableArrayList( 1850 new Person("John", "Smith", "jacob.smith@example.com") 1851 )); 1852 1853 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1854 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1855 Callback<TableColumn<Person, String>, TableCell<Person, String>> factory = TextFieldTableCell.forTableColumn(); 1856 first.setCellFactory(factory); 1857 table.getColumns().addAll(first); 1858 first.setOnEditStart(t -> { 1859 rt_29849_start_count++; 1860 }); 1861 1862 // load the table so the default cells are created 1863 StageLoader sl = new StageLoader(table); 1864 1865 // now replace the cell factory 1866 first.setCellFactory(TextFieldTableCell.<Person>forTableColumn()); 1867 1868 Toolkit.getToolkit().firePulse(); 1869 1870 // now start an edit and count the start edit events - it should be just 1 1871 table.edit(0, first); 1872 assertEquals(1, rt_29849_start_count); 1873 1874 sl.dispose(); 1875 } 1876 1877 @Test public void test_rt_32708_removeFromColumnsList() { 1878 TableView<Person> table = new TableView<>(); 1879 table.setEditable(true); 1880 table.setItems(FXCollections.observableArrayList( 1881 new Person("John", "Smith", "jacob.smith@example.com") 1882 )); 1883 1884 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1885 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1886 TableColumn<Person,String> last = new TableColumn<Person,String>("last"); 1887 first.setCellValueFactory(new PropertyValueFactory("lastName")); 1888 TableColumn<Person,String> email = new TableColumn<Person,String>("email"); 1889 first.setCellValueFactory(new PropertyValueFactory("email")); 1890 table.getColumns().addAll(first, last, email); 1891 1892 // load the table so the default cells are created 1893 StageLoader sl = new StageLoader(table); 1894 1895 // test pre-conditions - last column should be visible 1896 VirtualFlowTestUtils.assertTableHeaderColumnExists(table, last, true); 1897 1898 // remove last column from tableview 1899 table.getColumns().remove(last); 1900 Toolkit.getToolkit().firePulse(); 1901 1902 // test post conditions - last column should not be visible 1903 VirtualFlowTestUtils.assertTableHeaderColumnExists(table, last, false); 1904 1905 sl.dispose(); 1906 } 1907 1908 @Test public void test_rt_32708_toggleVisible() { 1909 TableView<Person> table = new TableView<>(); 1910 table.setEditable(true); 1911 table.setItems(FXCollections.observableArrayList( 1912 new Person("John", "Smith", "jacob.smith@example.com") 1913 )); 1914 1915 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1916 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1917 TableColumn<Person,String> last = new TableColumn<Person,String>("last"); 1918 first.setCellValueFactory(new PropertyValueFactory("lastName")); 1919 TableColumn<Person,String> email = new TableColumn<Person,String>("email"); 1920 first.setCellValueFactory(new PropertyValueFactory("email")); 1921 table.getColumns().addAll(first, last, email); 1922 1923 // load the table so the default cells are created 1924 StageLoader sl = new StageLoader(table); 1925 1926 // test pre-conditions - last column should be visible 1927 VirtualFlowTestUtils.assertTableHeaderColumnExists(table, last, true); 1928 1929 // hide the last column from tableview 1930 last.setVisible(false); 1931 Toolkit.getToolkit().firePulse(); 1932 1933 // test post conditions - last column should not be visible 1934 VirtualFlowTestUtils.assertTableHeaderColumnExists(table, last, false); 1935 1936 sl.dispose(); 1937 } 1938 1939 // @Ignore("Test started intermittently failing, most probably due to RT-36855 changeset") 1940 @Test public void test_rt_34493() { 1941 TableView<Person> table = new TableView<>(); 1942 table.setItems(FXCollections.observableArrayList( 1943 new Person("John", "Smith", "jacob.smith@example.com") 1944 )); 1945 1946 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 1947 first.setCellValueFactory(new PropertyValueFactory("firstName")); 1948 TableColumn<Person,String> last = new TableColumn<Person,String>("last"); 1949 first.setCellValueFactory(new PropertyValueFactory("lastName")); 1950 TableColumn<Person,String> email = new TableColumn<Person,String>("email"); 1951 first.setCellValueFactory(new PropertyValueFactory("email")); 1952 table.getColumns().addAll(first, last, email); 1953 1954 // load the table 1955 StageLoader sl = new StageLoader(table); 1956 1957 // resize the last column 1958 last.impl_setWidth(400); 1959 assertEquals(400, last.getWidth(), 0.0); 1960 1961 // hide the first column 1962 table.getColumns().remove(first); 1963 Toolkit.getToolkit().firePulse(); 1964 1965 // the last column should still be 400px, not the default width or any 1966 // other value (based on the width of the content in that column) 1967 assertEquals(400, last.getWidth(), 0.0); 1968 1969 sl.dispose(); 1970 } 1971 1972 @Test public void test_rt_34685_directEditCall_cellSelectionMode() { 1973 test_rt_34685_commitCount = 0; 1974 test_rt_34685(false, true); 1975 } 1976 1977 @Test public void test_rt_34685_directEditCall_rowSelectionMode() { 1978 test_rt_34685_commitCount = 0; 1979 test_rt_34685(false, false); 1980 } 1981 1982 @Test public void test_rt_34685_mouseDoubleClick_cellSelectionMode() { 1983 test_rt_34685_commitCount = 0; 1984 test_rt_34685(true, true); 1985 } 1986 1987 @Test public void test_rt_34685_mouseDoubleClick_rowSelectionMode() { 1988 test_rt_34685_commitCount = 0; 1989 test_rt_34685(true, false); 1990 } 1991 1992 private int test_rt_34685_commitCount = 0; 1993 private void test_rt_34685(boolean useMouseToInitiateEdit, boolean cellSelectionModeEnabled) { 1994 assertEquals(0, test_rt_34685_commitCount); 1995 1996 TableView<Person> table = new TableView<>(); 1997 table.getSelectionModel().setCellSelectionEnabled(cellSelectionModeEnabled); 1998 table.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); 1999 table.setEditable(true); 2000 2001 Person person1; 2002 table.setItems(FXCollections.observableArrayList( 2003 person1 = new Person("John", "Smith", "john.smith@example.com"), 2004 new Person("Jacob", "Michaels", "jacob.michaels@example.com"), 2005 new Person("Jim", "Bob", "jim.bob@example.com") 2006 )); 2007 2008 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 2009 first.setCellValueFactory(new PropertyValueFactory("firstName")); 2010 Callback<TableColumn<Person, String>, TableCell<Person, String>> factory = TextFieldTableCell.forTableColumn(); 2011 first.setCellFactory(factory); // note that only the first name col is editable 2012 2013 EventHandler<TableColumn.CellEditEvent<Person, String>> onEditCommit = first.getOnEditCommit(); 2014 first.setOnEditCommit(event -> { 2015 test_rt_34685_commitCount++; 2016 onEditCommit.handle(event); 2017 }); 2018 2019 table.getColumns().addAll(first); 2020 2021 // get the cell at (0,0) 2022 VirtualFlowTestUtils.BLOCK_STAGE_LOADER_DISPOSE = true; 2023 TableCell cell = (TableCell) VirtualFlowTestUtils.getCell(table, 0, 0); 2024 VirtualFlowTestUtils.BLOCK_STAGE_LOADER_DISPOSE = false; 2025 assertTrue(cell.getSkin() instanceof TableCellSkin); 2026 assertNull(cell.getGraphic()); 2027 assertEquals("John", cell.getText()); 2028 assertEquals("John", person1.getFirstName()); 2029 2030 // set the table to be editing the first cell at 0,0 2031 if (useMouseToInitiateEdit) { 2032 MouseEventFirer mouse = new MouseEventFirer(cell); 2033 mouse.fireMousePressAndRelease(2, 10, 10); // click 10 pixels in and 10 pixels down 2034 mouse.dispose(); 2035 } else { 2036 table.edit(0,first); 2037 } 2038 2039 Toolkit.getToolkit().firePulse(); 2040 assertNotNull(cell.getGraphic()); 2041 assertTrue(cell.getGraphic() instanceof TextField); 2042 2043 TextField textField = (TextField) cell.getGraphic(); 2044 assertEquals("John", textField.getText()); 2045 2046 textField.setText("Andrew"); 2047 textField.requestFocus(); 2048 Toolkit.getToolkit().firePulse(); 2049 2050 KeyEventFirer keyboard = new KeyEventFirer(textField); 2051 keyboard.doKeyPress(KeyCode.ENTER); 2052 2053 VirtualFlowTestUtils.getVirtualFlow(table).requestLayout(); 2054 Toolkit.getToolkit().firePulse(); 2055 2056 VirtualFlowTestUtils.assertTableCellTextEquals(table, 0, 0, "Andrew"); 2057 assertEquals("Andrew", cell.getText()); 2058 assertEquals("Andrew", person1.getFirstName()); 2059 assertEquals(1, test_rt_34685_commitCount); 2060 } 2061 2062 @Test public void test_rt_35224() { 2063 TableView table = new TableView(); 2064 TableColumn col1 = new TableColumn(); 2065 TableColumn col2 = new TableColumn(); 2066 table.getColumns().setAll(col1, col2); 2067 2068 StageLoader sl = new StageLoader(table); 2069 2070 Toolkit.getToolkit().firePulse(); 2071 col1.getColumns().setAll(new TableColumn(), new TableColumn()); 2072 Toolkit.getToolkit().firePulse(); 2073 col2.getColumns().setAll(new TableColumn(), new TableColumn()); 2074 Toolkit.getToolkit().firePulse(); 2075 2076 sl.dispose(); 2077 } 2078 2079 @Test public void test_rt_35141_simple_switch_two_columns_move_col1_forward_1_place() { 2080 TableView table = new TableView(); 2081 TableColumn col1 = new TableColumn(); 2082 TableColumn col2 = new TableColumn(); 2083 table.getColumns().setAll(col1, col2); 2084 2085 StageLoader sl = new StageLoader(table); 2086 2087 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2088 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2089 2090 TableColumnHeaderUtil.moveColumn(col1, 1); 2091 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2092 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col2)); 2093 2094 sl.dispose(); 2095 } 2096 2097 @Test public void test_rt_35141_simple_switch_two_columns_move_col2_backward_1_place() { 2098 TableView table = new TableView(); 2099 TableColumn col1 = new TableColumn(); 2100 TableColumn col2 = new TableColumn(); 2101 table.getColumns().setAll(col1, col2); 2102 2103 StageLoader sl = new StageLoader(table); 2104 2105 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2106 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2107 2108 TableColumnHeaderUtil.moveColumn(col2, 0); 2109 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2110 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col2)); 2111 2112 sl.dispose(); 2113 } 2114 2115 @Test public void test_rt_35141_simple_switch_three_columns_move_col1_forward_1_place() { 2116 TableView table = new TableView(); 2117 TableColumn col1 = new TableColumn(); 2118 TableColumn col2 = new TableColumn(); 2119 TableColumn col3 = new TableColumn(); 2120 table.getColumns().setAll(col1, col2, col3); 2121 2122 StageLoader sl = new StageLoader(table); 2123 2124 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2125 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2126 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2127 2128 TableColumnHeaderUtil.moveColumn(col1, 1); 2129 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2130 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col2)); 2131 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2132 2133 sl.dispose(); 2134 } 2135 2136 @Test public void test_rt_35141_simple_switch_three_columns_move_col2_backward_1_place() { 2137 TableView table = new TableView(); 2138 TableColumn col1 = new TableColumn(); 2139 TableColumn col2 = new TableColumn(); 2140 TableColumn col3 = new TableColumn(); 2141 table.getColumns().setAll(col1, col2, col3); 2142 2143 StageLoader sl = new StageLoader(table); 2144 2145 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2146 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2147 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2148 2149 TableColumnHeaderUtil.moveColumn(col2, 0); 2150 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2151 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col2)); 2152 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2153 2154 sl.dispose(); 2155 } 2156 2157 @Test public void test_rt_35141_simple_switch_three_columns_move_col2_forward_1_place() { 2158 TableView table = new TableView(); 2159 TableColumn col1 = new TableColumn(); 2160 TableColumn col2 = new TableColumn(); 2161 TableColumn col3 = new TableColumn(); 2162 table.getColumns().setAll(col1, col2, col3); 2163 2164 StageLoader sl = new StageLoader(table); 2165 2166 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2167 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2168 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2169 2170 TableColumnHeaderUtil.moveColumn(col2, 2); 2171 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2172 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col2)); 2173 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2174 2175 sl.dispose(); 2176 } 2177 2178 @Test public void test_rt_35141_simple_switch_three_columns_move_col3_backward_1_place() { 2179 TableView table = new TableView(); 2180 TableColumn col1 = new TableColumn(); 2181 TableColumn col2 = new TableColumn(); 2182 TableColumn col3 = new TableColumn(); 2183 table.getColumns().setAll(col1, col2, col3); 2184 2185 StageLoader sl = new StageLoader(table); 2186 2187 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2188 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2189 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2190 2191 TableColumnHeaderUtil.moveColumn(col3, 1); 2192 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2193 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col2)); 2194 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2195 2196 sl.dispose(); 2197 } 2198 2199 @Test public void test_rt_35141_simple_switch_three_columns_move_col0_forward_2_places() { 2200 TableView table = new TableView(); 2201 TableColumn col1 = new TableColumn(); 2202 TableColumn col2 = new TableColumn(); 2203 TableColumn col3 = new TableColumn(); 2204 table.getColumns().setAll(col1, col2, col3); 2205 2206 StageLoader sl = new StageLoader(table); 2207 2208 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2209 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2210 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2211 2212 TableColumnHeaderUtil.moveColumn(col1, 2); 2213 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col1)); 2214 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col2)); 2215 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2216 2217 sl.dispose(); 2218 } 2219 2220 @Test public void test_rt_35141_simple_switch_three_columns_move_col3_backward_2_places() { 2221 TableView table = new TableView(); 2222 TableColumn col1 = new TableColumn(); 2223 TableColumn col2 = new TableColumn(); 2224 TableColumn col3 = new TableColumn(); 2225 table.getColumns().setAll(col1, col2, col3); 2226 2227 StageLoader sl = new StageLoader(table); 2228 2229 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2230 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col2)); 2231 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2232 2233 TableColumnHeaderUtil.moveColumn(col3, 0); 2234 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2235 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col2)); 2236 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col3)); 2237 2238 sl.dispose(); 2239 } 2240 2241 @Test public void test_rt_35141_hidden_column_move_col1_forward_1_place() { 2242 TableView table = new TableView(); 2243 TableColumn col1 = new TableColumn(); 2244 TableColumn col2 = new TableColumn(); 2245 TableColumn col3 = new TableColumn(); 2246 table.getColumns().setAll(col1, col2, col3); 2247 2248 StageLoader sl = new StageLoader(table); 2249 2250 col2.setVisible(false); 2251 2252 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2253 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2254 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2255 2256 TableColumnHeaderUtil.moveColumn(col1, 1); 2257 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2258 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2259 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col3)); 2260 2261 sl.dispose(); 2262 } 2263 2264 @Test public void test_rt_35141_hidden_column_move_col1_forward_100_places() { 2265 TableView table = new TableView(); 2266 TableColumn col1 = new TableColumn(); 2267 TableColumn col2 = new TableColumn(); 2268 TableColumn col3 = new TableColumn(); 2269 table.getColumns().setAll(col1, col2, col3); 2270 2271 StageLoader sl = new StageLoader(table); 2272 2273 col2.setVisible(false); 2274 2275 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2276 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2277 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2278 2279 TableColumnHeaderUtil.moveColumn(col1, 100); 2280 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2281 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2282 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col3)); 2283 2284 sl.dispose(); 2285 } 2286 2287 @Test public void test_rt_35141_hidden_column_move_col3_backward_1_place() { 2288 TableView table = new TableView(); 2289 TableColumn col1 = new TableColumn(); 2290 TableColumn col2 = new TableColumn(); 2291 TableColumn col3 = new TableColumn(); 2292 table.getColumns().setAll(col1, col2, col3); 2293 2294 StageLoader sl = new StageLoader(table); 2295 2296 col2.setVisible(false); 2297 2298 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2299 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2300 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2301 2302 TableColumnHeaderUtil.moveColumn(col3, 0); 2303 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2304 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2305 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col3)); 2306 2307 sl.dispose(); 2308 } 2309 2310 @Test public void test_rt_35141_multiple_hidden_columns_move_col1_to_middle() { 2311 TableView table = new TableView(); 2312 TableColumn col1 = new TableColumn(); 2313 TableColumn col2 = new TableColumn(); 2314 TableColumn col3 = new TableColumn(); 2315 TableColumn col4 = new TableColumn(); 2316 TableColumn col5 = new TableColumn(); 2317 TableColumn col6 = new TableColumn(); 2318 table.getColumns().setAll(col1, col2, col3, col4, col5, col6); 2319 2320 StageLoader sl = new StageLoader(table); 2321 2322 col2.setVisible(false); 2323 col4.setVisible(false); 2324 2325 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2326 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2327 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2328 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2329 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2330 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2331 2332 TableColumnHeaderUtil.moveColumn(col1, 1); // 1 should represent the spot between col2 and col4 2333 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2334 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2335 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col3)); 2336 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2337 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2338 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2339 2340 sl.dispose(); 2341 } 2342 2343 @Test public void test_rt_35141_multiple_hidden_columns_move_col1_to_end() { 2344 TableView table = new TableView(); 2345 TableColumn col1 = new TableColumn(); 2346 TableColumn col2 = new TableColumn(); 2347 TableColumn col3 = new TableColumn(); 2348 TableColumn col4 = new TableColumn(); 2349 TableColumn col5 = new TableColumn(); 2350 TableColumn col6 = new TableColumn(); 2351 table.getColumns().setAll(col1, col2, col3, col4, col5, col6); 2352 2353 StageLoader sl = new StageLoader(table); 2354 2355 col2.setVisible(false); 2356 col4.setVisible(false); 2357 2358 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2359 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2360 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2361 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2362 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2363 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2364 2365 TableColumnHeaderUtil.moveColumn(col1, 3); // 3 should represent the end place 2366 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col1)); 2367 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2368 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col3)); 2369 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2370 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col5)); 2371 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col6)); 2372 2373 sl.dispose(); 2374 } 2375 2376 @Test public void test_rt_35141_multiple_hidden_columns_move_col3_to_start() { 2377 TableView table = new TableView(); 2378 TableColumn col1 = new TableColumn(); 2379 TableColumn col2 = new TableColumn(); 2380 TableColumn col3 = new TableColumn(); 2381 TableColumn col4 = new TableColumn(); 2382 TableColumn col5 = new TableColumn(); 2383 TableColumn col6 = new TableColumn(); 2384 table.getColumns().setAll(col1, col2, col3, col4, col5, col6); 2385 2386 StageLoader sl = new StageLoader(table); 2387 2388 col2.setVisible(false); 2389 col4.setVisible(false); 2390 2391 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2392 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2393 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2394 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2395 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2396 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2397 2398 TableColumnHeaderUtil.moveColumn(col3, 0); 2399 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2400 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2401 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col3)); 2402 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2403 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2404 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2405 2406 sl.dispose(); 2407 } 2408 2409 @Test public void test_rt_35141_multiple_hidden_columns_move_col3_to_end() { 2410 TableView table = new TableView(); 2411 TableColumn col1 = new TableColumn(); 2412 TableColumn col2 = new TableColumn(); 2413 TableColumn col3 = new TableColumn(); 2414 TableColumn col4 = new TableColumn(); 2415 TableColumn col5 = new TableColumn(); 2416 TableColumn col6 = new TableColumn(); 2417 table.getColumns().setAll(col1, col2, col3, col4, col5, col6); 2418 2419 StageLoader sl = new StageLoader(table); 2420 2421 col2.setVisible(false); 2422 col4.setVisible(false); 2423 2424 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2425 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2426 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2427 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2428 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2429 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2430 2431 TableColumnHeaderUtil.moveColumn(col3, 3); // 3 should represent the end place 2432 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2433 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2434 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col3)); 2435 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2436 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col5)); 2437 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col6)); 2438 2439 sl.dispose(); 2440 } 2441 2442 @Test public void test_rt_35141_multiple_hidden_columns_move_col6_to_start() { 2443 TableView table = new TableView(); 2444 TableColumn col1 = new TableColumn(); 2445 TableColumn col2 = new TableColumn(); 2446 TableColumn col3 = new TableColumn(); 2447 TableColumn col4 = new TableColumn(); 2448 TableColumn col5 = new TableColumn(); 2449 TableColumn col6 = new TableColumn(); 2450 table.getColumns().setAll(col1, col2, col3, col4, col5, col6); 2451 2452 StageLoader sl = new StageLoader(table); 2453 2454 col2.setVisible(false); 2455 col4.setVisible(false); 2456 2457 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2458 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2459 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2460 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2461 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2462 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2463 2464 TableColumnHeaderUtil.moveColumn(col6, 0); 2465 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col1)); 2466 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2467 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2468 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2469 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col5)); 2470 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col6)); 2471 2472 sl.dispose(); 2473 } 2474 2475 @Test public void test_rt_35141_multiple_hidden_columns_move_col6_to_middle() { 2476 TableView table = new TableView(); 2477 TableColumn col1 = new TableColumn(); 2478 TableColumn col2 = new TableColumn(); 2479 TableColumn col3 = new TableColumn(); 2480 TableColumn col4 = new TableColumn(); 2481 TableColumn col5 = new TableColumn(); 2482 TableColumn col6 = new TableColumn(); 2483 table.getColumns().setAll(col1, col2, col3, col4, col5, col6); 2484 2485 StageLoader sl = new StageLoader(table); 2486 2487 col2.setVisible(false); 2488 col4.setVisible(false); 2489 2490 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2491 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2492 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col3)); 2493 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2494 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col5)); 2495 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col6)); 2496 2497 TableColumnHeaderUtil.moveColumn(col6, 1); 2498 assertEquals(0, TableColumnHeaderUtil.getColumnIndex(col1)); 2499 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col2)); 2500 assertEquals(2, TableColumnHeaderUtil.getColumnIndex(col3)); 2501 assertEquals(-1, TableColumnHeaderUtil.getColumnIndex(col4)); 2502 assertEquals(3, TableColumnHeaderUtil.getColumnIndex(col5)); 2503 assertEquals(1, TableColumnHeaderUtil.getColumnIndex(col6)); 2504 2505 sl.dispose(); 2506 } 2507 2508 @Test public void test_rt_34042() { 2509 Scene scene = new Scene(new Group()); 2510 SplitPane splitPane = new SplitPane(); 2511 splitPane.setOrientation(Orientation.VERTICAL); 2512 2513 //TREETABLECOLUMN 2514 TreeTableView<Person> treeTableView = new TreeTableView<>(); 2515 TreeTableColumn temp = new TreeTableColumn("First Name"); 2516 temp.setMinWidth(100); 2517 temp.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 2518 2519 TreeTableColumn temp2 = new TreeTableColumn("Last Name"); 2520 temp2.setMinWidth(100); 2521 temp2.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 2522 2523 TreeTableColumn temp3 = new TreeTableColumn("Email"); 2524 temp3.setMinWidth(200); 2525 temp3.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 2526 2527 treeTableView.getColumns().addAll(temp, temp2, temp3); 2528 2529 //TABLE 2530 TableView<Person> table = new TableView<Person>(); 2531 table.setEditable(true); 2532 table.getSelectionModel().setCellSelectionEnabled(true); 2533 TableColumn firstNameCol = new TableColumn("First Name"); 2534 firstNameCol.setMinWidth(100); 2535 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 2536 2537 TableColumn lastNameCol = new TableColumn("Last Name"); 2538 lastNameCol.setMinWidth(100); 2539 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 2540 2541 TableColumn emailCol = new TableColumn("Email"); 2542 emailCol.setMinWidth(200); 2543 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 2544 2545 table.setItems(personTestData); 2546 table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 2547 2548 splitPane.getItems().add(treeTableView); 2549 splitPane.getItems().add(table); 2550 2551 ((Group) scene.getRoot()).getChildren().addAll(splitPane); 2552 2553 new StageLoader(scene); 2554 2555 TableView.TableViewSelectionModel sm = table.getSelectionModel(); 2556 sm.select(2, lastNameCol); 2557 assertFalse(sm.isSelected(2, firstNameCol)); 2558 assertTrue(sm.isSelected(2, lastNameCol)); 2559 assertFalse(sm.isSelected(2, emailCol)); 2560 2561 KeyEventFirer keyboard = new KeyEventFirer(table); 2562 keyboard.doKeyPress(KeyCode.LEFT); 2563 assertTrue(sm.isSelected(2, firstNameCol)); 2564 assertFalse(sm.isSelected(2, lastNameCol)); 2565 assertFalse(sm.isSelected(2, emailCol)); 2566 2567 keyboard.doKeyPress(KeyCode.RIGHT); 2568 assertFalse(sm.isSelected(2, firstNameCol)); 2569 assertTrue(sm.isSelected(2, lastNameCol)); 2570 assertFalse(sm.isSelected(2, emailCol)); 2571 2572 keyboard.doKeyPress(KeyCode.RIGHT); 2573 assertFalse(sm.isSelected(2, firstNameCol)); 2574 assertFalse(sm.isSelected(2, lastNameCol)); 2575 assertTrue(sm.isSelected(2, emailCol)); 2576 } 2577 2578 @Test public void test_rt35039() { 2579 final List<String> data = new ArrayList<>(); 2580 data.add("aabbaa"); 2581 data.add("bbc"); 2582 2583 final TableView<String> tableView = new TableView<>(); 2584 tableView.setItems(FXCollections.observableArrayList(data)); 2585 2586 StageLoader sl = new StageLoader(tableView); 2587 2588 // selection starts off at row -1 2589 assertNull(tableView.getSelectionModel().getSelectedItem()); 2590 2591 // select "bbc" and ensure everything is set to that 2592 tableView.getSelectionModel().select(1); 2593 assertEquals("bbc", tableView.getSelectionModel().getSelectedItem()); 2594 2595 // change the items list - but retain the same content. We expect 2596 // that "bbc" remains selected as it is still in the list 2597 tableView.setItems(FXCollections.observableArrayList(data)); 2598 assertEquals("bbc", tableView.getSelectionModel().getSelectedItem()); 2599 2600 sl.dispose(); 2601 } 2602 2603 @Test public void test_rt35763_observableList() { 2604 TableView<Person> table = new TableView(); 2605 2606 TableColumn firstNameCol = new TableColumn("First Name"); 2607 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 2608 table.getColumns().add(firstNameCol); 2609 2610 Person jacob, isabella, ethan, emma, michael; 2611 table.setItems(FXCollections.observableArrayList( 2612 jacob = new Person("Jacob", "Smith", "jacob.smith@example.com"), 2613 isabella = new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 2614 ethan = new Person("Ethan", "Williams", "ethan.williams@example.com"), 2615 emma = new Person("Emma", "Jones", "emma.jones@example.com"), 2616 michael = new Person("Michael", "Brown", "michael.brown@example.com"))); 2617 2618 assertEquals(jacob, table.getItems().get(0)); 2619 assertEquals(isabella, table.getItems().get(1)); 2620 assertEquals(ethan, table.getItems().get(2)); 2621 assertEquals(emma, table.getItems().get(3)); 2622 assertEquals(michael, table.getItems().get(4)); 2623 2624 // change sort order - expect items to be sorted 2625 table.getSortOrder().setAll(firstNameCol); 2626 2627 assertEquals(jacob, table.getItems().get(3)); 2628 assertEquals(isabella, table.getItems().get(2)); 2629 assertEquals(ethan, table.getItems().get(1)); 2630 assertEquals(emma, table.getItems().get(0)); 2631 assertEquals(michael, table.getItems().get(4)); 2632 2633 // set new items into items list - expect sortOrder list to be reset 2634 // and the items list to remain unsorted 2635 table.setItems(FXCollections.observableArrayList( 2636 jacob = new Person("Jacob", "Smith", "jacob.smith@example.com"), 2637 isabella = new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 2638 ethan = new Person("Ethan", "Williams", "ethan.williams@example.com"), 2639 emma = new Person("Emma", "Jones", "emma.jones@example.com"), 2640 michael = new Person("Michael", "Brown", "michael.brown@example.com"))); 2641 2642 assertEquals(jacob, table.getItems().get(0)); 2643 assertEquals(isabella, table.getItems().get(1)); 2644 assertEquals(ethan, table.getItems().get(2)); 2645 assertEquals(emma, table.getItems().get(3)); 2646 assertEquals(michael, table.getItems().get(4)); 2647 2648 assertTrue(table.getSortOrder().isEmpty()); 2649 } 2650 2651 @Test public void test_rt35763_sortedList() { 2652 TableView<Person> table = new TableView(); 2653 2654 TableColumn firstNameCol = new TableColumn("First Name"); 2655 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 2656 table.getColumns().add(firstNameCol); 2657 2658 Person jacob, isabella, ethan, emma, michael; 2659 SortedList<Person> sortedList = new SortedList<>(FXCollections.observableArrayList( 2660 jacob = new Person("Jacob", "Smith", "jacob.smith@example.com"), 2661 isabella = new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 2662 ethan = new Person("Ethan", "Williams", "ethan.williams@example.com"), 2663 emma = new Person("Emma", "Jones", "emma.jones@example.com"), 2664 michael = new Person("Michael", "Brown", "michael.brown@example.com"))); 2665 sortedList.comparatorProperty().bind(table.comparatorProperty()); 2666 table.setItems(sortedList); 2667 2668 assertEquals(jacob, table.getItems().get(0)); 2669 assertEquals(isabella, table.getItems().get(1)); 2670 assertEquals(ethan, table.getItems().get(2)); 2671 assertEquals(emma, table.getItems().get(3)); 2672 assertEquals(michael, table.getItems().get(4)); 2673 2674 // change sort order - expect items to be sorted 2675 table.getSortOrder().setAll(firstNameCol); 2676 2677 assertEquals(jacob, table.getItems().get(3)); 2678 assertEquals(isabella, table.getItems().get(2)); 2679 assertEquals(ethan, table.getItems().get(1)); 2680 assertEquals(emma, table.getItems().get(0)); 2681 assertEquals(michael, table.getItems().get(4)); 2682 2683 // set new items into items list - expect sortOrder list to be retained 2684 // as we're inserting a SortedList 2685 SortedList<Person> sortedList2 = new SortedList<>(FXCollections.observableArrayList( 2686 jacob = new Person("Jacob", "Smith", "jacob.smith@example.com"), 2687 isabella = new Person("Isabella", "Johnson", "isabella.johnson@example.com"), 2688 ethan = new Person("Ethan", "Williams", "ethan.williams@example.com"), 2689 emma = new Person("Emma", "Jones", "emma.jones@example.com"), 2690 michael = new Person("Michael", "Brown", "michael.brown@example.com"))); 2691 sortedList2.comparatorProperty().bind(table.comparatorProperty()); 2692 table.setItems(sortedList2); 2693 2694 assertEquals(jacob, table.getItems().get(3)); 2695 assertEquals(isabella, table.getItems().get(2)); 2696 assertEquals(ethan, table.getItems().get(1)); 2697 assertEquals(emma, table.getItems().get(0)); 2698 assertEquals(michael, table.getItems().get(4)); 2699 2700 assertEquals(1, table.getSortOrder().size()); 2701 assertEquals(firstNameCol, table.getSortOrder().get(0)); 2702 } 2703 2704 @Test(expected = IndexOutOfBoundsException.class) 2705 public void test_rt35768_negativeFrom() { 2706 readOnlyUnbackedObservableListSubListTest(-1, 0); 2707 } 2708 2709 @Test(expected = IndexOutOfBoundsException.class) 2710 public void test_rt35768_bigTo() { 2711 readOnlyUnbackedObservableListSubListTest(0, 10); 2712 } 2713 2714 @Test(expected = IndexOutOfBoundsException.class) 2715 public void test_rt35768_fromEqualsTo() { 2716 readOnlyUnbackedObservableListSubListTest(1, 1); 2717 } 2718 2719 private void readOnlyUnbackedObservableListSubListTest(int from, int to) { 2720 final SelectedCellsMap<TablePosition> selectedCellsMap = new SelectedCellsMap<TablePosition>(c -> { /* Do nothing */}) { 2721 @Override public boolean isCellSelectionEnabled() { 2722 return false; 2723 } 2724 }; 2725 ReadOnlyUnbackedObservableList<TablePosition<Object, ?>> selectedCellsSeq = new ReadOnlyUnbackedObservableList<TablePosition<Object, ?>>() { 2726 @Override public TablePosition<Object, ?> get(int i) { 2727 return selectedCellsMap.get(i); 2728 } 2729 2730 @Override public int size() { 2731 return selectedCellsMap.size(); 2732 } 2733 }; 2734 2735 // This should result in an IOOBE, but didn't until this bug was fixed 2736 selectedCellsSeq.subList(from, to); 2737 } 2738 2739 @Test public void test_rt35857() { 2740 ObservableList<String> fxList = FXCollections.observableArrayList("A", "B", "C"); 2741 final TableView<String> tableView = new TableView<String>(fxList); 2742 2743 tableView.getSelectionModel().select(0); 2744 2745 ObservableList<String> selectedItems = tableView.getSelectionModel().getSelectedItems(); 2746 assertEquals(1, selectedItems.size()); 2747 assertEquals("A", selectedItems.get(0)); 2748 2749 tableView.getItems().removeAll(selectedItems); 2750 assertEquals(2, fxList.size()); 2751 assertEquals("B", fxList.get(0)); 2752 assertEquals("C", fxList.get(1)); 2753 } 2754 2755 @Test public void test_getColumnHeaderForColumn() { 2756 TableView<Person> table = new TableView<>(); 2757 table.setItems(FXCollections.observableArrayList( 2758 new Person("John", "Smith", "jacob.smith@example.com") 2759 )); 2760 2761 TableColumn<Person,String> first = new TableColumn<Person,String>("first"); 2762 first.setCellValueFactory(new PropertyValueFactory("firstName")); 2763 TableColumn<Person,String> last = new TableColumn<Person,String>("last"); 2764 first.setCellValueFactory(new PropertyValueFactory("lastName")); 2765 2766 TableColumn name = new TableColumn("Name"); 2767 name.getColumns().addAll(first, last); 2768 2769 table.getColumns().setAll(name); 2770 2771 StageLoader sl = new StageLoader(table); 2772 2773 TableHeaderRow headerRow = VirtualFlowTestUtils.getTableHeaderRow(table); 2774 2775 TableColumnHeader nameHeader = TableHeaderRowShim.getColumnHeaderFor(headerRow, name); 2776 TableColumnHeader firstHeader = TableHeaderRowShim.getColumnHeaderFor(headerRow, first); 2777 TableColumnHeader lastHeader = TableHeaderRowShim.getColumnHeaderFor(headerRow, last); 2778 assertNotNull(nameHeader); 2779 assertEquals(name, nameHeader.getTableColumn()); 2780 assertNotNull(firstHeader); 2781 assertEquals(first, firstHeader.getTableColumn()); 2782 assertNotNull(lastHeader); 2783 assertEquals(last, lastHeader.getTableColumn()); 2784 2785 sl.dispose(); 2786 } 2787 2788 @Test public void test_rt36220() { 2789 ObservableList<AtomicLong> tableItems = FXCollections.observableArrayList(); 2790 tableItems.add(new AtomicLong(0L)); 2791 2792 TableView<AtomicLong> tableView = new TableView<>(); 2793 tableView.getItems().setAll(tableItems); 2794 2795 TableColumn<AtomicLong, String> col = new TableColumn<>(); 2796 col.setCellValueFactory(obj -> new SimpleStringProperty(String.valueOf(obj.getValue().longValue()))); 2797 col.setPrefWidth(180); 2798 tableView.getColumns().add(col); 2799 2800 new StageLoader(tableView); 2801 2802 VirtualFlowTestUtils.assertTableCellTextEquals(tableView, 0, 0, "0"); 2803 2804 // 1) using this trick will prevent the first update 2805 col.setMinWidth(col.getPrefWidth() + 1); 2806 2807 long expected = System.currentTimeMillis(); 2808 tableItems.get(0).set(expected); 2809 tableView.getItems().setAll(tableItems); 2810 2811 Toolkit.getToolkit().firePulse(); 2812 2813 VirtualFlowTestUtils.assertTableCellTextEquals(tableView, 0, 0, ""+expected); 2814 } 2815 2816 @Test public void test_rt36425() { 2817 TableView<String> tableView = new TableView<>(); 2818 2819 TableColumn<String, String> tableColumn = new TableColumn<>(); 2820 tableColumn.setCellValueFactory(data -> new SimpleStringProperty(data.getValue())); 2821 tableColumn.setText("Test"); 2822 tableView.getColumns().add(tableColumn); 2823 2824 SimpleListProperty<String> data = new SimpleListProperty<>(FXCollections.observableArrayList()); 2825 tableView.itemsProperty().bind(data); 2826 data.addAll("AAA", "BBB"); 2827 2828 assertEquals("AAA", data.get(0)); 2829 assertEquals("BBB", data.get(1)); 2830 2831 tableView.getSortOrder().add(tableColumn); 2832 2833 assertTrue(tableView.getSortOrder().contains(tableColumn)); 2834 assertEquals("AAA", data.get(0)); 2835 assertEquals("BBB", data.get(1)); 2836 2837 tableColumn.setSortType(TableColumn.SortType.DESCENDING); 2838 assertEquals("AAA", data.get(1)); 2839 assertEquals("BBB", data.get(0)); 2840 } 2841 2842 private int test_rt_36353_selectedItemCount = 0; 2843 private int test_rt_36353_selectedIndexCount = 0; 2844 @Test public void test_rt36353() { 2845 ObservableList<String> data = FXCollections.observableArrayList(); 2846 data.addAll("2", "1", "3"); 2847 SortedList<String> sortedList = new SortedList<>(data); 2848 2849 TableView<String> tableView = new TableView<>(sortedList); 2850 sortedList.comparatorProperty().bind(tableView.comparatorProperty()); 2851 2852 TableColumn<String, String> tableColumn = new TableColumn<>(); 2853 tableColumn.setCellValueFactory(rowValue -> new SimpleStringProperty(rowValue.getValue())); 2854 tableColumn.setText("Test"); 2855 tableView.getColumns().add(tableColumn); 2856 2857 tableView.getSelectionModel().selectedItemProperty().addListener((e, oldSelection, newSelection) -> { 2858 test_rt_36353_selectedItemCount++; 2859 }); 2860 tableView.getSelectionModel().selectedIndexProperty().addListener((e, oldIndex, newIndex) -> { 2861 test_rt_36353_selectedIndexCount++; 2862 }); 2863 2864 assertEquals(0, test_rt_36353_selectedItemCount); 2865 assertEquals(0, test_rt_36353_selectedIndexCount); 2866 2867 tableView.getSelectionModel().select(1); 2868 assertEquals(1, test_rt_36353_selectedItemCount); 2869 assertEquals(1, test_rt_36353_selectedIndexCount); 2870 assertEquals("2", sortedList.get(0)); 2871 assertEquals("1", sortedList.get(1)); 2872 assertEquals("3", sortedList.get(2)); 2873 2874 tableView.getSortOrder().add(tableColumn); 2875 assertEquals(1, test_rt_36353_selectedItemCount); 2876 assertEquals(2, test_rt_36353_selectedIndexCount); 2877 assertEquals("1", sortedList.get(0)); 2878 assertEquals("2", sortedList.get(1)); 2879 assertEquals("3", sortedList.get(2)); 2880 2881 tableColumn.setSortType(TableColumn.SortType.DESCENDING); 2882 assertEquals(1, test_rt_36353_selectedItemCount); 2883 assertEquals(3, test_rt_36353_selectedIndexCount); 2884 assertEquals("3", sortedList.get(0)); 2885 assertEquals("2", sortedList.get(1)); 2886 assertEquals("1", sortedList.get(2)); 2887 2888 tableView.getSortOrder().remove(tableColumn); 2889 assertEquals(1, test_rt_36353_selectedItemCount); 2890 assertEquals(4, test_rt_36353_selectedIndexCount); 2891 assertEquals("2", sortedList.get(0)); 2892 assertEquals("1", sortedList.get(1)); 2893 assertEquals("3", sortedList.get(2)); 2894 } 2895 2896 // This test ensures that we reuse column headers when the columns still 2897 // exist after a change to the columns list - rather than recreating new 2898 // column headers. The issue in RT-36290 was that we were creating new column 2899 // headers that were then in their initial states, allowing them to call 2900 // TableColumnHeader#updateScene(), which would resize the column based on the 2901 // data within it. 2902 @Test public void test_rt36290() { 2903 TableView<String> tableView = new TableView<>(); 2904 2905 TableColumn<String, String> tableColumn1 = new TableColumn<>(); 2906 tableColumn1.setCellValueFactory(data -> new SimpleStringProperty(data.getValue())); 2907 tableColumn1.setText("Test1"); 2908 2909 TableColumn<String, String> tableColumn2 = new TableColumn<>(); 2910 tableColumn2.setCellValueFactory(data -> new SimpleStringProperty(data.getValue())); 2911 tableColumn2.setText("Test2"); 2912 2913 tableView.getColumns().setAll(tableColumn1, tableColumn2); 2914 2915 StageLoader sl = new StageLoader(tableView); 2916 2917 final TableColumnHeader header1 = VirtualFlowTestUtils.getTableColumnHeader(tableView, tableColumn1); 2918 final TableColumnHeader header2 = VirtualFlowTestUtils.getTableColumnHeader(tableView, tableColumn2); 2919 2920 tableView.getColumns().setAll(tableColumn2, tableColumn1); 2921 Toolkit.getToolkit().firePulse(); 2922 2923 final TableColumnHeader header1_after = VirtualFlowTestUtils.getTableColumnHeader(tableView, tableColumn1); 2924 final TableColumnHeader header2_after = VirtualFlowTestUtils.getTableColumnHeader(tableView, tableColumn2); 2925 2926 assertEquals(header1, header1_after); 2927 assertEquals(header2, header2_after); 2928 2929 sl.dispose(); 2930 } 2931 2932 @Test public void test_rt25679_rowSelection() { 2933 test_rt25679(true); 2934 } 2935 2936 @Test public void test_rt25679_cellSelection() { 2937 test_rt25679(false); 2938 } 2939 2940 private void test_rt25679(boolean rowSelection) { 2941 Button focusBtn = new Button("Focus here"); 2942 2943 TableView<String> tableView = new TableView<>(FXCollections.observableArrayList("A", "B", "C")); 2944 2945 TableColumn<String, String> tableColumn = new TableColumn<>(); 2946 tableColumn.setCellValueFactory(rowValue -> new SimpleStringProperty(rowValue.getValue())); 2947 tableView.getColumns().add(tableColumn); 2948 TableView.TableViewSelectionModel<String> sm = tableView.getSelectionModel(); 2949 sm.setCellSelectionEnabled(! rowSelection); 2950 2951 VBox vbox = new VBox(focusBtn, tableView); 2952 2953 StageLoader sl = new StageLoader(vbox); 2954 sl.getStage().requestFocus(); 2955 focusBtn.requestFocus(); 2956 Toolkit.getToolkit().firePulse(); 2957 2958 // test initial state 2959 assertEquals(sl.getStage().getScene().getFocusOwner(), focusBtn); 2960 assertTrue(focusBtn.isFocused()); 2961 assertEquals(-1, sm.getSelectedIndex()); 2962 assertNull(sm.getSelectedItem()); 2963 2964 // move focus to the tableView 2965 tableView.requestFocus(); 2966 2967 // ensure that there is a selection (where previously there was not one) 2968 assertEquals(sl.getStage().getScene().getFocusOwner(), tableView); 2969 assertTrue(tableView.isFocused()); 2970 2971 if (rowSelection) { 2972 assertEquals(0, sm.getSelectedIndices().size()); 2973 assertNull(sm.getSelectedItem()); 2974 assertFalse(sm.isSelected(0)); 2975 assertEquals(0, sm.getSelectedCells().size()); 2976 } else { 2977 assertFalse(sm.isSelected(0, tableColumn)); 2978 assertEquals(0, sm.getSelectedCells().size()); 2979 } 2980 2981 sl.dispose(); 2982 } 2983 2984 private int rt36556_instanceCount; 2985 @Test public void test_rt36556_scrollTo() { 2986 rt36556_instanceCount = 0; 2987 2988 TableView<String> tableView = new TableView<>(); 2989 tableView.setRowFactory(new Callback<TableView<String>, TableRow<String>>() { 2990 @Override public TableRow<String> call(TableView<String> param) { 2991 rt36556_instanceCount++; 2992 return new TableRow<>(); 2993 } 2994 }); 2995 2996 TableColumn<String, String> tableColumn = new TableColumn<>(); 2997 tableColumn.setCellValueFactory(rowValue -> new SimpleStringProperty(rowValue.getValue())); 2998 2999 tableView.getColumns().add(tableColumn); 3000 3001 for (int i = 0; i < 1000; i++) { 3002 tableView.getItems().add("Row " + i); 3003 } 3004 3005 StackPane root = new StackPane(); 3006 root.getChildren().add(tableView); 3007 3008 StageLoader sl = new StageLoader(root); 3009 3010 final int cellCountAtStart = rt36556_instanceCount; 3011 3012 // start scrolling 3013 for (int i = 0; i < 1000; i++) { 3014 tableView.scrollTo(i); 3015 // Toolkit.getToolkit().firePulse(); 3016 } 3017 3018 assertEquals(cellCountAtStart, rt36556_instanceCount); 3019 sl.dispose(); 3020 } 3021 3022 @Test public void test_rt36556_mouseWheel() { 3023 rt36556_instanceCount = 0; 3024 3025 TableView<String> tableView = new TableView<>(); 3026 tableView.setRowFactory(new Callback<TableView<String>, TableRow<String>>() { 3027 @Override public TableRow<String> call(TableView<String> param) { 3028 rt36556_instanceCount++; 3029 return new TableRow<String>(); 3030 } 3031 }); 3032 3033 TableColumn<String, String> tableColumn = new TableColumn<>(); 3034 tableColumn.setCellValueFactory(rowValue -> new SimpleStringProperty(rowValue.getValue())); 3035 tableView.getColumns().add(tableColumn); 3036 3037 for (int i = 0; i < 1000; i++) { 3038 tableView.getItems().add("Row " + i); 3039 } 3040 3041 StackPane root = new StackPane(); 3042 root.getChildren().add(tableView); 3043 3044 StageLoader sl = new StageLoader(root); 3045 3046 final int cellCountAtStart = rt36556_instanceCount; 3047 3048 // start scrolling - we call VirtualFlow.adjustPixels, which is what 3049 // is called when the mouse wheel is scrolled 3050 VirtualFlow flow = VirtualFlowTestUtils.getVirtualFlow(tableView); 3051 flow.scrollPixels(1000 * 24); 3052 3053 assertEquals(cellCountAtStart, rt36556_instanceCount); 3054 3055 sl.dispose(); 3056 } 3057 3058 @Test public void test_rt_36656_removeFromSortOrder() { 3059 test_rt_36656(true, false, false); 3060 } 3061 3062 @Test public void test_rt_36656_removeFromColumns() { 3063 test_rt_36656(false, true, false); 3064 } 3065 3066 @Test public void test_rt_36656_setInvisible() { 3067 test_rt_36656(false, false, true); 3068 } 3069 3070 private void test_rt_36656(boolean removeFromSortOrder, boolean removeFromColumns, boolean setInvisible) { 3071 TableView<Person> table = new TableView<Person>(); 3072 table.setItems(personTestData); 3073 3074 TableColumn firstNameCol = new TableColumn("First Name"); 3075 firstNameCol.setMinWidth(100); 3076 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 3077 3078 TableColumn lastNameCol = new TableColumn("Last Name"); 3079 lastNameCol.setMinWidth(100); 3080 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 3081 3082 TableColumn emailCol = new TableColumn("Email"); 3083 emailCol.setMinWidth(200); 3084 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 3085 3086 table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 3087 3088 new StageLoader(table); 3089 3090 TableColumnHeader firstNameColHeader = VirtualFlowTestUtils.getTableColumnHeader(table, firstNameCol); 3091 TableColumnHeader lastNameColHeader = VirtualFlowTestUtils.getTableColumnHeader(table, lastNameCol); 3092 TableColumnHeader emailColHeader = VirtualFlowTestUtils.getTableColumnHeader(table, emailCol); 3093 3094 // test initial state 3095 assertEquals(-1, TableColumnHeaderShim.getSortPos(firstNameColHeader)); 3096 assertEquals(-1, TableColumnHeaderShim.getSortPos(lastNameColHeader)); 3097 assertEquals(-1, TableColumnHeaderShim.getSortPos(emailColHeader)); 3098 3099 // set an order including all columns 3100 table.getSortOrder().addAll(firstNameCol, lastNameCol, emailCol); 3101 assertEquals(0, TableColumnHeaderShim.getSortPos(firstNameColHeader)); 3102 assertEquals(1, TableColumnHeaderShim.getSortPos(lastNameColHeader)); 3103 assertEquals(2, TableColumnHeaderShim.getSortPos(emailColHeader)); 3104 3105 if (removeFromSortOrder) { 3106 // Remove lastNameCol from the table sortOrder list, so this column 3107 // is no longer part of the sort comparator 3108 table.getSortOrder().remove(lastNameCol); 3109 } else if (removeFromColumns) { 3110 // Remove lastNameCol from the table entirely. 3111 table.getColumns().remove(lastNameCol); 3112 } else if (setInvisible) { 3113 // Hide the lastNameColumn. 3114 lastNameCol.setVisible(false); 3115 } 3116 3117 // Regardless of action taken above, expect lastNameCol sortPos to be -1 3118 // and emailCol sortPos to shift from 2 to 1. 3119 assertEquals(0, TableColumnHeaderShim.getSortPos(firstNameColHeader)); 3120 assertEquals(-1, TableColumnHeaderShim.getSortPos(lastNameColHeader)); 3121 assertEquals(1, TableColumnHeaderShim.getSortPos(emailColHeader)); 3122 } 3123 3124 @Test public void test_rt_36670() { 3125 final ObservableList<Person> data = FXCollections.observableArrayList( 3126 new Person("Jacob", "Smith", "jacob.smith@example.com", true), 3127 new Person("Isabella", "Johnson", "isabella.johnson@example.com", false), 3128 new Person("Ethan", "Williams", "ethan.williams@example.com", true), 3129 new Person("Emma", "Jones", "emma.jones@example.com", true), 3130 new Person("Michael", "Brown", "michael.brown@example.com", false)); 3131 3132 TableColumn invitedCol = new TableColumn<>(); 3133 invitedCol.setText("Invited"); 3134 invitedCol.setMinWidth(70); 3135 invitedCol.setCellValueFactory(new PropertyValueFactory("invited")); 3136 invitedCol.setCellFactory(CheckBoxTableCell.forTableColumn(invitedCol)); 3137 3138 TableColumn firstNameCol = new TableColumn(); 3139 firstNameCol.setText("First"); 3140 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 3141 3142 TableView tableView = new TableView(data); 3143 tableView.getColumns().addAll(invitedCol, firstNameCol); 3144 3145 StageLoader sl = new StageLoader(tableView); 3146 3147 // get the checkboxes 3148 CheckBox row0CheckBox = (CheckBox) VirtualFlowTestUtils.getCell(tableView, 0, 0).getGraphic(); 3149 CheckBox row1CheckBox = (CheckBox) VirtualFlowTestUtils.getCell(tableView, 1, 0).getGraphic(); 3150 CheckBox row2CheckBox = (CheckBox) VirtualFlowTestUtils.getCell(tableView, 2, 0).getGraphic(); 3151 CheckBox row3CheckBox = (CheckBox) VirtualFlowTestUtils.getCell(tableView, 3, 0).getGraphic(); 3152 CheckBox row4CheckBox = (CheckBox) VirtualFlowTestUtils.getCell(tableView, 4, 0).getGraphic(); 3153 3154 // check initial state of all checkboxes 3155 assertTrue(row0CheckBox.isSelected()); 3156 assertFalse(row1CheckBox.isSelected()); 3157 assertTrue(row2CheckBox.isSelected()); 3158 assertTrue(row3CheckBox.isSelected()); 3159 assertFalse(row4CheckBox.isSelected()); 3160 3161 // sort the table based on the invited column 3162 tableView.getSortOrder().add(invitedCol); 3163 Toolkit.getToolkit().firePulse(); 3164 3165 // The sort order has changed, with unselected items at the top and 3166 // selected items beneath them. 3167 assertFalse(row0CheckBox.isSelected()); 3168 assertFalse(row1CheckBox.isSelected()); 3169 assertTrue(row2CheckBox.isSelected()); 3170 assertTrue(row3CheckBox.isSelected()); 3171 assertTrue(row4CheckBox.isSelected()); 3172 3173 // now, select the 'Michael' row, which is row 1 3174 row1CheckBox.setSelected(true); 3175 Toolkit.getToolkit().firePulse(); 3176 3177 // only the Michael row should have changed state - but the bug 3178 // identified in RT-36670 shows that row 0 is also selected 3179 assertFalse(row0CheckBox.isSelected()); 3180 assertTrue(row1CheckBox.isSelected()); 3181 assertTrue(row2CheckBox.isSelected()); 3182 assertTrue(row3CheckBox.isSelected()); 3183 assertTrue(row4CheckBox.isSelected()); 3184 3185 sl.dispose(); 3186 } 3187 3188 @Test public void test_rt_36669() { 3189 TableView<Person> table = new TableView<>(personTestData); 3190 3191 TableColumn firstNameCol = new TableColumn("First Name"); 3192 firstNameCol.setMinWidth(100); 3193 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 3194 3195 TableColumn lastNameCol = new TableColumn("Last Name"); 3196 lastNameCol.setMinWidth(100); 3197 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 3198 3199 TableColumn emailCol = new TableColumn("Email"); 3200 emailCol.setMinWidth(200); 3201 emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 3202 3203 table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 3204 table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 3205 3206 StageLoader sl = new StageLoader(table); 3207 3208 ScrollBar vbar = VirtualFlowTestUtils.getVirtualFlowVerticalScrollbar(table); 3209 ScrollBar hbar = VirtualFlowTestUtils.getVirtualFlowHorizontalScrollbar(table); 3210 3211 // firstly test case where the TableView is tall enough to not need a vbar 3212 assertFalse(vbar.isVisible()); 3213 assertFalse(hbar.isVisible()); 3214 3215 // now make the table quite narrow and ensure that even if a vbar appears 3216 // that the hbar does not appear 3217 table.setMaxHeight(30); 3218 Toolkit.getToolkit().firePulse(); 3219 assertTrue(vbar.isVisible()); 3220 assertFalse(hbar.isVisible()); 3221 3222 sl.dispose(); 3223 } 3224 3225 private int rt_37061_index_counter = 0; 3226 private int rt_37061_item_counter = 0; 3227 @Test public void test_rt_37061() { 3228 TableView<Integer> tv = new TableView<>(); 3229 tv.getItems().add(1); 3230 tv.getSelectionModel().select(0); 3231 3232 // note we add the listeners after the selection is made, so the counters 3233 // at this point are still both at zero. 3234 tv.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> { 3235 rt_37061_index_counter++; 3236 }); 3237 3238 tv.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { 3239 rt_37061_item_counter++; 3240 }); 3241 3242 // add a new item. This does not impact the selected index or selected item 3243 // so the counters should remain at zero. 3244 tv.getItems().add(2); 3245 assertEquals(0, rt_37061_index_counter); 3246 assertEquals(0, rt_37061_item_counter); 3247 } 3248 3249 @Test public void test_rt_37058_noContent() { 3250 test_rt_37058(false); 3251 } 3252 3253 @Test public void test_rt_37058_withContent() { 3254 test_rt_37058(true); 3255 } 3256 3257 private void test_rt_37058(boolean hasContent) { 3258 // create table with a bunch of column and no rows... 3259 TableView<Integer> table = new TableView<>(); 3260 TableColumn<Integer, Integer> column = new TableColumn<>("Column"); 3261 table.getColumns().add(column); 3262 column.setPrefWidth(150); 3263 3264 if (hasContent) { 3265 table.getItems().add(1); 3266 } 3267 3268 StageLoader sl = new StageLoader(table); 3269 Toolkit.getToolkit().firePulse(); 3270 3271 assertEquals(150, column.getWidth(), 0.0); 3272 3273 sl.dispose(); 3274 } 3275 3276 @Test public void test_rt_37057_test1_MoveColumn() { 3277 // create table with a bunch of column and no rows... 3278 TableView<Integer> table = new TableView<>(); 3279 for ( int i = 1; i <= 10; i++ ) { 3280 TableColumn<Integer, Integer> column = new TableColumn<>("" + i); 3281 table.getColumns().add( column ); 3282 3283 // sneak some hidden columns in there 3284 column = new TableColumn<>("h" + i); 3285 column.setVisible( false ); 3286 table.getColumns().add( column ); 3287 } 3288 3289 StageLoader sl = new StageLoader(table); 3290 3291 TableColumn column1 = table.getVisibleLeafColumn(0); 3292 TableColumn column2 = table.getVisibleLeafColumn(1); 3293 3294 // get the headers of a few columns 3295 TableColumnHeader header1 = VirtualFlowTestUtils.getTableColumnHeader(table, column1); 3296 TableColumnHeader header2 = VirtualFlowTestUtils.getTableColumnHeader(table, column2); 3297 3298 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3299 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3300 3301 // move as per first instructions in RT-37057. Note that the moveColumn 3302 // positions seem counter-intuitive. I got these numbers by printing 3303 // the positions when in a manual test run (using the test script in 3304 // RT-37057). 3305 3306 // Drag column 1 to slot 1. As expected, the column position doesn't change. 3307 TableColumnHeaderUtil.moveColumn(column1, 0); 3308 assertEquals(column1, table.getVisibleLeafColumn(0)); 3309 assertEquals(column2, table.getVisibleLeafColumn(1)); 3310 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3311 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3312 3313 // Drag column 1 to slot 2. As expected, the column 1 and 2 swap positions. 3314 TableColumnHeaderUtil.moveColumn(column1, 1); 3315 assertEquals(column2, table.getVisibleLeafColumn(0)); 3316 assertEquals(column1, table.getVisibleLeafColumn(1)); 3317 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header1)); 3318 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header2)); 3319 3320 // Drag column 1 to slot 0. As expected, the column 1 and 2 swap positions. 3321 TableColumnHeaderUtil.moveColumn(column1, 0); 3322 assertEquals(column1, table.getVisibleLeafColumn(0)); 3323 assertEquals(column2, table.getVisibleLeafColumn(1)); 3324 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3325 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3326 3327 // Drag column 1 to slot 1 again. What? Why did they swap positions this time? 3328 TableColumnHeaderUtil.moveColumn(column1, 0); 3329 assertEquals(column1, table.getVisibleLeafColumn(0)); 3330 assertEquals(column2, table.getVisibleLeafColumn(1)); 3331 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3332 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3333 3334 sl.dispose(); 3335 } 3336 3337 @Test public void test_rt_37057_test1_MouseEvents() { 3338 // create table with a bunch of column and no rows... 3339 TableView<Integer> table = new TableView<>(); 3340 for ( int i = 1; i <= 10; i++ ) { 3341 TableColumn<Integer, Integer> column = new TableColumn<>("" + i); 3342 table.getColumns().add( column ); 3343 3344 // sneak some hidden columns in there 3345 column = new TableColumn<>("h" + i); 3346 column.setVisible( false ); 3347 column.impl_setWidth(50); 3348 column.setResizable(false); 3349 table.getColumns().add( column ); 3350 } 3351 3352 StageLoader sl = new StageLoader(table); 3353 3354 TableColumn column1 = table.getVisibleLeafColumn(0); 3355 TableColumn column2 = table.getVisibleLeafColumn(1); 3356 3357 // get the headers of a few columns 3358 TableColumnHeader header1 = VirtualFlowTestUtils.getTableColumnHeader(table, column1); 3359 TableColumnHeader header2 = VirtualFlowTestUtils.getTableColumnHeader(table, column2); 3360 3361 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3362 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3363 3364 // move as per first instructions in RT-37057. The dragOffset and sceneX 3365 // values passed into moveColumn have been derived from a manual run of 3366 // the test application attached to RT-37057 with debug output printed 3367 // in TableColumnHeader 3368 3369 // Drag column 1 to slot 1. As expected, the column position doesn't change. 3370 TableColumnHeaderUtil.moveColumn(column1, 9, 61); 3371 assertEquals(column1, table.getVisibleLeafColumn(0)); 3372 assertEquals(column2, table.getVisibleLeafColumn(1)); 3373 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3374 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3375 3376 // Drag column 1 to slot 2. As expected, the column 1 and 2 swap positions. 3377 TableColumnHeaderUtil.moveColumn(column1, 12, 139); 3378 assertEquals(column2, table.getVisibleLeafColumn(0)); 3379 assertEquals(column1, table.getVisibleLeafColumn(1)); 3380 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header1)); 3381 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header2)); 3382 3383 // Drag column 1 to slot 0. As expected, the column 1 and 2 swap positions. 3384 TableColumnHeaderUtil.moveColumn(column1, 45, 21); 3385 assertEquals(column1, table.getVisibleLeafColumn(0)); 3386 assertEquals(column2, table.getVisibleLeafColumn(1)); 3387 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3388 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3389 3390 // Drag column 1 to slot 1 again. What? Why did they swap positions this time? 3391 TableColumnHeaderUtil.moveColumn(column1, 19, 63); 3392 assertEquals(column1, table.getVisibleLeafColumn(0)); 3393 assertEquals(column2, table.getVisibleLeafColumn(1)); 3394 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3395 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3396 3397 sl.dispose(); 3398 } 3399 3400 @Test public void test_rt_37057_test2_MoveColumn() { 3401 // create table with a bunch of column and no rows... 3402 TableView<Integer> table = new TableView<>(); 3403 for ( int i = 1; i <= 10; i++ ) { 3404 TableColumn<Integer, Integer> column = new TableColumn<>("" + i); 3405 table.getColumns().add( column ); 3406 3407 // sneak some hidden columns in there 3408 column = new TableColumn<>("h" + i); 3409 column.setVisible( false ); 3410 table.getColumns().add( column ); 3411 } 3412 3413 StageLoader sl = new StageLoader(table); 3414 3415 TableColumn column1 = table.getVisibleLeafColumn(0); 3416 TableColumn column2 = table.getVisibleLeafColumn(1); 3417 TableColumn column4 = table.getVisibleLeafColumn(3); 3418 3419 // get the headers of a few columns 3420 TableColumnHeader header1 = VirtualFlowTestUtils.getTableColumnHeader(table, column1); 3421 TableColumnHeader header2 = VirtualFlowTestUtils.getTableColumnHeader(table, column2); 3422 TableColumnHeader header4 = VirtualFlowTestUtils.getTableColumnHeader(table, column4); 3423 3424 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3425 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3426 3427 // move as per second instructions in RT-37057. Note that the moveColumn 3428 // positions seem counter-intuitive. I got these numbers by printing 3429 // the positions when in a manual test run (using the test script in 3430 // RT-37057). 3431 3432 // Drag column 1 to slot 2. As expected, the column 1 and 2 swap positions 3433 TableColumnHeaderUtil.moveColumn(column1, 1); 3434 assertEquals(column2, table.getVisibleLeafColumn(0)); 3435 assertEquals(column1, table.getVisibleLeafColumn(1)); 3436 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header1)); 3437 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header2)); 3438 3439 // Drag column 1 to slot 0. As expected, the column 1 and 2 swap positions. 3440 TableColumnHeaderUtil.moveColumn(column1, 0); 3441 assertEquals(column1, table.getVisibleLeafColumn(0)); 3442 assertEquals(column2, table.getVisibleLeafColumn(1)); 3443 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3444 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3445 3446 // Drag column 4 to slot 1. What? It behaves like it was dragged to slot 0?! 3447 TableColumnHeaderUtil.moveColumn(column4, 1); 3448 assertEquals(column1, table.getVisibleLeafColumn(0)); 3449 assertEquals(column4, table.getVisibleLeafColumn(1)); 3450 assertEquals(column2, table.getVisibleLeafColumn(2)); 3451 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3452 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header4)); 3453 assertEquals(2, TableColumnHeaderShim.getColumnIndex(header2)); 3454 3455 sl.dispose(); 3456 } 3457 3458 @Test public void test_rt_37057_test2_MouseEvents() { 3459 // create table with a bunch of column and no rows... 3460 TableView<Integer> table = new TableView<>(); 3461 for ( int i = 1; i <= 10; i++ ) { 3462 TableColumn<Integer, Integer> column = new TableColumn<>("" + i); 3463 table.getColumns().add( column ); 3464 3465 // sneak some hidden columns in there 3466 column = new TableColumn<>("h" + i); 3467 column.setVisible( false ); 3468 column.impl_setWidth(50); 3469 column.setResizable(false); 3470 table.getColumns().add( column ); 3471 } 3472 3473 StageLoader sl = new StageLoader(table); 3474 3475 TableColumn column1 = table.getVisibleLeafColumn(0); 3476 TableColumn column2 = table.getVisibleLeafColumn(1); 3477 TableColumn column4 = table.getVisibleLeafColumn(3); 3478 3479 // get the headers of a few columns 3480 TableColumnHeader header1 = VirtualFlowTestUtils.getTableColumnHeader(table, column1); 3481 TableColumnHeader header2 = VirtualFlowTestUtils.getTableColumnHeader(table, column2); 3482 TableColumnHeader header4 = VirtualFlowTestUtils.getTableColumnHeader(table, column4); 3483 3484 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3485 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3486 3487 // move as per second instructions in RT-37057. The dragOffset and sceneX 3488 // values passed into moveColumn have been derived from a manual run of 3489 // the test application attached to RT-37057 with debug output printed 3490 // in TableColumnHeader 3491 3492 // Drag column 1 to slot 2. As expected, the column 1 and 2 swap positions 3493 TableColumnHeaderUtil.moveColumn(column1, 25, 136); 3494 assertEquals(column2, table.getVisibleLeafColumn(0)); 3495 assertEquals(column1, table.getVisibleLeafColumn(1)); 3496 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header1)); 3497 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header2)); 3498 3499 // Drag column 1 to slot 0. As expected, the column 1 and 2 swap positions. 3500 TableColumnHeaderUtil.moveColumn(column1, 51, 23); 3501 assertEquals(column1, table.getVisibleLeafColumn(0)); 3502 assertEquals(column2, table.getVisibleLeafColumn(1)); 3503 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3504 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header2)); 3505 3506 // Drag column 4 to slot 1. What? It behaves like it was dragged to slot 0?! 3507 TableColumnHeaderUtil.moveColumn(column4, 56, 103); 3508 assertEquals(column1, table.getVisibleLeafColumn(0)); 3509 assertEquals(column4, table.getVisibleLeafColumn(1)); 3510 assertEquals(column2, table.getVisibleLeafColumn(2)); 3511 assertEquals(0, TableColumnHeaderShim.getColumnIndex(header1)); 3512 assertEquals(1, TableColumnHeaderShim.getColumnIndex(header4)); 3513 assertEquals(2, TableColumnHeaderShim.getColumnIndex(header2)); 3514 3515 sl.dispose(); 3516 } 3517 3518 @Test public void test_rt_37054_noScroll() { 3519 test_rt_37054(false); 3520 } 3521 3522 @Test public void test_rt_37054_scroll() { 3523 test_rt_37054(true); 3524 } 3525 3526 private void test_rt_37054(boolean scroll) { 3527 ObjectProperty<Integer> offset = new SimpleObjectProperty<Integer>(0); 3528 3529 // create table with a bunch of rows and 1 column... 3530 TableView<Integer> table = new TableView<>(); 3531 for ( int i = 1; i <= 50; i++ ) { 3532 table.getItems().add(i); 3533 } 3534 final TableColumn<Integer, Integer> column = new TableColumn<>("Column"); 3535 table.getColumns().add( column ); 3536 column.setPrefWidth( 150 ); 3537 3538 // each cell displays x, where x = "cell row number + offset" 3539 column.setCellValueFactory( cdf -> new ObjectBinding<Integer>() { 3540 { super.bind( offset ); } 3541 3542 @Override protected Integer computeValue() { 3543 return cdf.getValue() + offset.get(); 3544 } 3545 }); 3546 3547 StackPane root = new StackPane(); 3548 root.getChildren().add( table ); 3549 3550 StageLoader sl = new StageLoader(root); 3551 3552 int index = scroll ? 0 : 25; 3553 3554 if (scroll) { 3555 // we scroll to force the table cells to update the objects they observe 3556 table.scrollTo(index); 3557 Toolkit.getToolkit().firePulse(); 3558 } 3559 3560 TableCell cell = (TableCell) VirtualFlowTestUtils.getCell(table, index + 3, 0); 3561 final int initialValue = (Integer) cell.getItem(); 3562 3563 // increment the offset value 3564 offset.setValue(offset.get() + 1); 3565 Toolkit.getToolkit().firePulse(); 3566 3567 final int incrementedValue = (Integer) cell.getItem(); 3568 assertEquals(initialValue + 1, incrementedValue); 3569 3570 sl.dispose(); 3571 } 3572 3573 @Test public void test_rt_37429() { 3574 // get the current exception handler before replacing with our own, 3575 // as ListListenerHelp intercepts the exception otherwise 3576 final Thread.UncaughtExceptionHandler exceptionHandler = Thread.currentThread().getUncaughtExceptionHandler(); 3577 Thread.currentThread().setUncaughtExceptionHandler((t, e) -> fail("We don't expect any exceptions in this test!")); 3578 3579 // table columns - 1 column; name 3580 TableColumn<String, String> nameColumn = new TableColumn<>("name"); 3581 nameColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper(param.getValue())); 3582 nameColumn.setPrefWidth(200); 3583 3584 // table 3585 TableView<String> table = new TableView<>(); 3586 table.setItems(FXCollections.observableArrayList("one", "two", "three", "four", "five")); 3587 table.getColumns().addAll(nameColumn); 3588 3589 table.getSelectionModel().getSelectedItems().addListener((ListChangeListener<String>) c -> { 3590 while (c.next()) { 3591 if(c.wasRemoved()) { 3592 // The removed list of items must be iterated or the AIOOBE will 3593 // not be thrown when getAddedSubList is called. 3594 c.getRemoved().forEach(item -> {}); 3595 } 3596 3597 if (c.wasAdded()) { 3598 c.getAddedSubList(); 3599 } 3600 } 3601 }); 3602 3603 StageLoader sl = new StageLoader(table); 3604 3605 table.getSelectionModel().select(0); 3606 table.getSortOrder().add(nameColumn); 3607 3608 sl.dispose(); 3609 3610 // reset the exception handler 3611 Thread.currentThread().setUncaughtExceptionHandler(exceptionHandler); 3612 } 3613 3614 private int rt_37429_items_change_count = 0; 3615 private int rt_37429_cells_change_count = 0; 3616 @Test public void test_rt_37429_sortEventsShouldNotFireExtraChangeEvents() { 3617 // table columns - 1 column; name 3618 TableColumn<String, String> nameColumn = new TableColumn<>("name"); 3619 nameColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper(param.getValue())); 3620 nameColumn.setPrefWidth(200); 3621 3622 // table 3623 TableView<String> table = new TableView<>(); 3624 table.setItems(FXCollections.observableArrayList("a", "c", "b")); 3625 table.getColumns().addAll(nameColumn); 3626 3627 table.getSelectionModel().getSelectedItems().addListener((ListChangeListener<String>) c -> { 3628 while (c.next()) { 3629 rt_37429_items_change_count++; 3630 } 3631 }); 3632 table.getSelectionModel().getSelectedCells().addListener((ListChangeListener<TablePosition>) c -> { 3633 while (c.next()) { 3634 rt_37429_cells_change_count++; 3635 } 3636 }); 3637 3638 StageLoader sl = new StageLoader(table); 3639 3640 assertEquals(0, rt_37429_items_change_count); 3641 assertEquals(0, rt_37429_cells_change_count); 3642 3643 table.getSelectionModel().select(0); 3644 assertEquals(1, rt_37429_items_change_count); 3645 assertEquals(1, rt_37429_cells_change_count); 3646 3647 table.getSortOrder().add(nameColumn); 3648 assertEquals(1, rt_37429_items_change_count); 3649 assertEquals(1, rt_37429_cells_change_count); 3650 3651 nameColumn.setSortType(TableColumn.SortType.DESCENDING); 3652 assertEquals(1, rt_37429_items_change_count); 3653 assertEquals(2, rt_37429_cells_change_count); 3654 3655 nameColumn.setSortType(TableColumn.SortType.ASCENDING); 3656 assertEquals(1, rt_37429_items_change_count); 3657 assertEquals(3, rt_37429_cells_change_count); 3658 3659 sl.dispose(); 3660 } 3661 3662 private int rt_37538_count = 0; 3663 @Test public void test_rt_37538_noCNextCall() { 3664 test_rt_37538(false, false); 3665 } 3666 3667 @Test public void test_rt_37538_callCNextOnce() { 3668 test_rt_37538(true, false); 3669 } 3670 3671 @Test public void test_rt_37538_callCNextInLoop() { 3672 test_rt_37538(false, true); 3673 } 3674 3675 private void test_rt_37538(boolean callCNextOnce, boolean callCNextInLoop) { 3676 TableView<Integer> table = new TableView<>(); 3677 for ( int i = 1; i <= 50; i++ ) { 3678 table.getItems().add(i); 3679 } 3680 final TableColumn<Integer, Integer> column = new TableColumn<>("Column"); 3681 table.getColumns().add(column); 3682 column.setCellValueFactory( cdf -> new ReadOnlyObjectWrapper<Integer>(cdf.getValue())); 3683 3684 table.getSelectionModel().getSelectedItems().addListener((ListChangeListener.Change<? extends Integer> c) -> { 3685 if (callCNextOnce) { 3686 c.next(); 3687 } else if (callCNextInLoop) { 3688 while (c.next()) { 3689 // no-op 3690 } 3691 } 3692 3693 if (rt_37538_count >= 1) { 3694 Thread.dumpStack(); 3695 fail("This method should only be called once"); 3696 } 3697 3698 rt_37538_count++; 3699 }); 3700 3701 StageLoader sl = new StageLoader(table); 3702 assertEquals(0, rt_37538_count); 3703 table.getSelectionModel().select(0); 3704 assertEquals(1, rt_37538_count); 3705 sl.dispose(); 3706 } 3707 3708 @Ignore("Fix not yet developed for TableView") 3709 @Test public void test_rt_35395_testCell_fixedCellSize() { 3710 test_rt_35395(true, true); 3711 } 3712 3713 @Ignore("Fix not yet developed for TableView") 3714 @Test public void test_rt_35395_testCell_notFixedCellSize() { 3715 test_rt_35395(true, false); 3716 } 3717 3718 @Ignore("Fix not yet developed for TableView") 3719 @Test public void test_rt_35395_testRow_fixedCellSize() { 3720 test_rt_35395(false, true); 3721 } 3722 3723 @Ignore("Fix not yet developed for TableView") 3724 @Test public void test_rt_35395_testRow_notFixedCellSize() { 3725 test_rt_35395(false, false); 3726 } 3727 3728 private int rt_35395_counter; 3729 private void test_rt_35395(boolean testCell, boolean useFixedCellSize) { 3730 rt_35395_counter = 0; 3731 3732 ObservableList<String> items = FXCollections.observableArrayList(); 3733 for (int i = 0; i < 20; ++i) { 3734 items.addAll("red", "green", "blue", "purple"); 3735 } 3736 3737 TableView<String> tableView = new TableView<>(items); 3738 if (useFixedCellSize) { 3739 tableView.setFixedCellSize(24); 3740 } 3741 tableView.setRowFactory(tv -> new TableRowShim<String>() { 3742 @Override public void updateItem(String color, boolean empty) { 3743 rt_35395_counter += testCell ? 0 : 1; 3744 super.updateItem(color, empty); 3745 } 3746 }); 3747 3748 TableColumn<String,String> column = new TableColumn<>("Column"); 3749 column.setCellValueFactory(param -> new ReadOnlyStringWrapper(param.getValue())); 3750 column.setCellFactory(tv -> new TableCellShim<String,String>() { 3751 @Override public void updateItem(String color, boolean empty) { 3752 rt_35395_counter += testCell ? 1 : 0; 3753 super.updateItem(color, empty); 3754 setText(null); 3755 if (empty) { 3756 setGraphic(null); 3757 } else { 3758 Rectangle rect = new Rectangle(16, 16); 3759 rect.setStyle("-fx-fill: " + color); 3760 setGraphic(rect); 3761 } 3762 } 3763 }); 3764 tableView.getColumns().addAll(column); 3765 3766 StageLoader sl = new StageLoader(tableView); 3767 3768 Platform.runLater(() -> { 3769 rt_35395_counter = 0; 3770 items.set(10, "yellow"); 3771 Platform.runLater(() -> { 3772 Toolkit.getToolkit().firePulse(); 3773 assertEquals(1, rt_35395_counter); 3774 rt_35395_counter = 0; 3775 items.set(30, "yellow"); 3776 Platform.runLater(() -> { 3777 Toolkit.getToolkit().firePulse(); 3778 assertEquals(0, rt_35395_counter); 3779 rt_35395_counter = 0; 3780 tableView.scrollTo(5); 3781 Platform.runLater(() -> { 3782 Toolkit.getToolkit().firePulse(); 3783 assertEquals(5, rt_35395_counter); 3784 rt_35395_counter = 0; 3785 tableView.scrollTo(55); 3786 Platform.runLater(() -> { 3787 Toolkit.getToolkit().firePulse(); 3788 3789 int expected = useFixedCellSize ? 17 : 53; 3790 assertEquals(expected, rt_35395_counter); 3791 sl.dispose(); 3792 }); 3793 }); 3794 }); 3795 }); 3796 }); 3797 } 3798 3799 @Test public void test_rt_37632() { 3800 final ObservableList<String> listOne = FXCollections.observableArrayList("A", "B", "C"); 3801 final ObservableList<String> listTwo = FXCollections.observableArrayList("C"); 3802 3803 TableColumn<String,String> tableColumn = new TableColumn("column"); 3804 tableColumn.setCellValueFactory(c -> new ReadOnlyStringWrapper(c.getValue())); 3805 3806 final TableView<String> tableView = new TableView<>(); 3807 tableView.getColumns().add(tableColumn); 3808 MultipleSelectionModel<String> sm = tableView.getSelectionModel(); 3809 tableView.setItems(listOne); 3810 tableView.getSelectionModel().selectFirst(); 3811 3812 assertEquals(0, sm.getSelectedIndex()); 3813 assertEquals("A", sm.getSelectedItem()); 3814 assertEquals(1, sm.getSelectedIndices().size()); 3815 assertEquals(0, (int) sm.getSelectedIndices().get(0)); 3816 assertEquals(1, sm.getSelectedItems().size()); 3817 assertEquals("A", sm.getSelectedItems().get(0)); 3818 3819 tableView.setItems(listTwo); 3820 3821 assertEquals(-1, sm.getSelectedIndex()); 3822 assertNull(sm.getSelectedItem()); 3823 assertEquals(0, sm.getSelectedIndices().size()); 3824 assertEquals(0, sm.getSelectedItems().size()); 3825 } 3826 3827 @Test public void test_rt_38464_rowSelection_selectFirstRowOnly() { 3828 TableColumn firstNameCol = new TableColumn("First"); 3829 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 3830 3831 TableColumn lastNameCol = new TableColumn("Last"); 3832 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 3833 3834 TableView tableView = new TableView(personTestData); 3835 tableView.getColumns().addAll(firstNameCol, lastNameCol); 3836 3837 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 3838 sm.setCellSelectionEnabled(false); 3839 sm.setSelectionMode(SelectionMode.MULTIPLE); 3840 3841 sm.select(0); 3842 3843 assertTrue(sm.isSelected(0)); 3844 assertTrue(sm.isSelected(0, firstNameCol)); 3845 assertTrue(sm.isSelected(0, lastNameCol)); 3846 3847 assertEquals(1, sm.getSelectedIndices().size()); 3848 assertEquals(1, sm.getSelectedItems().size()); 3849 assertEquals(1, sm.getSelectedCells().size()); 3850 } 3851 3852 @Test public void test_rt_38464_rowSelection_selectFirstRowAndThenCallNoOpMethods() { 3853 TableColumn firstNameCol = new TableColumn("First"); 3854 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 3855 3856 TableColumn lastNameCol = new TableColumn("Last"); 3857 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 3858 3859 TableView tableView = new TableView(personTestData); 3860 tableView.getColumns().addAll(firstNameCol, lastNameCol); 3861 3862 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 3863 sm.setCellSelectionEnabled(false); 3864 sm.setSelectionMode(SelectionMode.MULTIPLE); 3865 3866 sm.select(0); // select first row 3867 sm.select(0); // this should be a no-op 3868 sm.select(0, firstNameCol); // so should this, as we are in row selection mode 3869 sm.select(0, lastNameCol); // and same here 3870 3871 assertTrue(sm.isSelected(0)); 3872 assertTrue(sm.isSelected(0, firstNameCol)); 3873 assertTrue(sm.isSelected(0, lastNameCol)); 3874 3875 assertEquals(1, sm.getSelectedIndices().size()); 3876 assertEquals(1, sm.getSelectedItems().size()); 3877 assertEquals(1, sm.getSelectedCells().size()); 3878 } 3879 3880 3881 @Test public void test_rt_38464_cellSelection_selectFirstRowOnly() { 3882 TableColumn firstNameCol = new TableColumn("First"); 3883 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 3884 3885 TableColumn lastNameCol = new TableColumn("Last"); 3886 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 3887 3888 TableView tableView = new TableView(personTestData); 3889 tableView.getColumns().addAll(firstNameCol, lastNameCol); 3890 3891 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 3892 sm.setCellSelectionEnabled(true); 3893 sm.setSelectionMode(SelectionMode.MULTIPLE); 3894 3895 // select first row. This should be translated into selection of all 3896 // cells in this row, and (as of JDK 9) _does_ result in the row itself being 3897 // considered selected. 3898 sm.select(0); 3899 3900 assertTrue(sm.isSelected(0)); 3901 assertTrue(sm.isSelected(0, firstNameCol)); 3902 assertTrue(sm.isSelected(0, lastNameCol)); 3903 3904 assertEquals(1, sm.getSelectedIndices().size()); 3905 assertEquals(1, sm.getSelectedItems().size()); 3906 assertEquals(2, sm.getSelectedCells().size()); 3907 } 3908 3909 @Test public void test_rt_38464_cellSelection_selectFirstRowAndThenCallNoOpMethods() { 3910 TableColumn firstNameCol = new TableColumn("First"); 3911 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 3912 3913 TableColumn lastNameCol = new TableColumn("Last"); 3914 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 3915 3916 TableView tableView = new TableView(personTestData); 3917 tableView.getColumns().addAll(firstNameCol, lastNameCol); 3918 3919 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 3920 sm.setCellSelectionEnabled(true); 3921 sm.setSelectionMode(SelectionMode.MULTIPLE); 3922 3923 // select first row. This should be translated into selection of all 3924 // cells in this row, and (as of JDK 9) _does_ result in the row itself being 3925 // considered selected. 3926 sm.select(0); // select first row 3927 sm.select(0, firstNameCol); // This line and the next should be no-ops 3928 sm.select(0, lastNameCol); 3929 3930 assertTrue(sm.isSelected(0)); 3931 assertTrue(sm.isSelected(0, firstNameCol)); 3932 assertTrue(sm.isSelected(0, lastNameCol)); 3933 3934 assertEquals(1, sm.getSelectedIndices().size()); 3935 assertEquals(1, sm.getSelectedItems().size()); 3936 assertEquals(2, sm.getSelectedCells().size()); 3937 } 3938 3939 @Test public void test_rt38464_selectCellMultipleTimes() { 3940 TableColumn firstNameCol = new TableColumn("First"); 3941 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 3942 3943 TableColumn lastNameCol = new TableColumn("Last"); 3944 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 3945 3946 TableView tableView = new TableView(personTestData); 3947 tableView.getColumns().addAll(firstNameCol, lastNameCol); 3948 3949 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 3950 sm.setCellSelectionEnabled(true); 3951 sm.setSelectionMode(SelectionMode.MULTIPLE); 3952 3953 // default selection when in cell selection mode 3954 assertEquals(0, sm.getSelectedCells().size()); 3955 assertEquals(0, sm.getSelectedItems().size()); 3956 assertEquals(0, sm.getSelectedIndices().size()); 3957 3958 // select the first cell 3959 sm.select(0, firstNameCol); 3960 assertEquals(1, sm.getSelectedCells().size()); 3961 assertEquals(1, sm.getSelectedItems().size()); 3962 assertEquals(1, sm.getSelectedIndices().size()); 3963 3964 // select the first cell....again 3965 sm.select(0, firstNameCol); 3966 assertEquals(1, sm.getSelectedCells().size()); 3967 assertEquals(1, sm.getSelectedItems().size()); 3968 assertEquals(1, sm.getSelectedIndices().size()); 3969 } 3970 3971 @Test public void test_rt38464_selectCellThenRow() { 3972 TableColumn firstNameCol = new TableColumn("First"); 3973 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 3974 3975 TableColumn lastNameCol = new TableColumn("Last"); 3976 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 3977 3978 TableView tableView = new TableView(personTestData); 3979 tableView.getColumns().addAll(firstNameCol, lastNameCol); 3980 3981 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 3982 sm.setCellSelectionEnabled(true); 3983 sm.setSelectionMode(SelectionMode.MULTIPLE); 3984 3985 // default selection when in cell selection mode 3986 assertEquals(0, sm.getSelectedCells().size()); 3987 assertEquals(0, sm.getSelectedItems().size()); 3988 assertEquals(0, sm.getSelectedIndices().size()); 3989 3990 // select the first cell 3991 sm.select(0, firstNameCol); 3992 assertEquals(1, sm.getSelectedCells().size()); 3993 assertEquals(1, sm.getSelectedItems().size()); 3994 assertEquals(1, sm.getSelectedIndices().size()); 3995 3996 // select the first row 3997 sm.select(0); 3998 3999 // we go to 2 here as all cells in the row become selected. What we do 4000 // not expect is to go to 3, as that would mean duplication 4001 assertEquals(2, sm.getSelectedCells().size()); 4002 assertEquals(1, sm.getSelectedItems().size()); 4003 assertEquals(1, sm.getSelectedIndices().size()); 4004 } 4005 4006 @Test public void test_rt38464_selectRowThenCell() { 4007 TableColumn firstNameCol = new TableColumn("First"); 4008 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 4009 4010 TableColumn lastNameCol = new TableColumn("Last"); 4011 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 4012 4013 TableView tableView = new TableView(personTestData); 4014 tableView.getColumns().addAll(firstNameCol, lastNameCol); 4015 4016 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 4017 sm.setCellSelectionEnabled(true); 4018 sm.setSelectionMode(SelectionMode.MULTIPLE); 4019 4020 // default selection when in cell selection mode 4021 assertEquals(0, sm.getSelectedCells().size()); 4022 assertEquals(0, sm.getSelectedItems().size()); 4023 assertEquals(0, sm.getSelectedIndices().size()); 4024 4025 // select the first row 4026 sm.select(0); 4027 4028 // we go to 2 here as all cells in the row become selected. 4029 assertEquals(2, sm.getSelectedCells().size()); 4030 assertEquals(1, sm.getSelectedItems().size()); 4031 assertEquals(1, sm.getSelectedIndices().size()); 4032 4033 // select the first cell - no change is expected 4034 sm.select(0, firstNameCol); 4035 assertEquals(2, sm.getSelectedCells().size()); 4036 assertEquals(1, sm.getSelectedItems().size()); 4037 assertEquals(1, sm.getSelectedIndices().size()); 4038 } 4039 4040 @Test public void test_rt38464_selectTests_cellSelection_singleSelection_selectsOneRow() { 4041 test_rt38464_selectTests(true, true, true); 4042 } 4043 4044 @Test public void test_rt38464_selectTests_cellSelection_singleSelection_selectsTwoRows() { 4045 test_rt38464_selectTests(true, true, false); 4046 } 4047 4048 @Test public void test_rt38464_selectTests_cellSelection_multipleSelection_selectsOneRow() { 4049 test_rt38464_selectTests(true, false, true); 4050 } 4051 4052 @Test public void test_rt38464_selectTests_cellSelection_multipleSelection_selectsTwoRows() { 4053 test_rt38464_selectTests(true, false, false); 4054 } 4055 4056 @Test public void test_rt38464_selectTests_rowSelection_singleSelection_selectsOneRow() { 4057 test_rt38464_selectTests(false, true, true); 4058 } 4059 4060 @Test public void test_rt38464_selectTests_rowSelection_singleSelection_selectsTwoRows() { 4061 test_rt38464_selectTests(false, true, false); 4062 } 4063 4064 @Test public void test_rt38464_selectTests_rowSelection_multipleSelection_selectsOneRow() { 4065 test_rt38464_selectTests(false, false, true); 4066 } 4067 4068 @Test public void test_rt38464_selectTests_rowSelection_multipleSelection_selectsTwoRows() { 4069 test_rt38464_selectTests(false, false, false); 4070 } 4071 4072 private void test_rt38464_selectTests(boolean cellSelection, boolean singleSelection, boolean selectsOneRow) { 4073 TableColumn firstNameCol = new TableColumn("First"); 4074 firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 4075 4076 TableColumn lastNameCol = new TableColumn("Last"); 4077 lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); 4078 4079 TableView tableView = new TableView(personTestData); 4080 tableView.getColumns().addAll(firstNameCol, lastNameCol); 4081 4082 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 4083 sm.setCellSelectionEnabled(cellSelection); 4084 sm.setSelectionMode(singleSelection ? SelectionMode.SINGLE : SelectionMode.MULTIPLE); 4085 4086 // default selection when in cell selection mode 4087 assertEquals(0, sm.getSelectedCells().size()); 4088 assertEquals(0, sm.getSelectedItems().size()); 4089 assertEquals(0, sm.getSelectedIndices().size()); 4090 4091 if (selectsOneRow) { 4092 sm.select(0); 4093 } else { 4094 // select the first two rows 4095 sm.selectIndices(0, 1); 4096 } 4097 4098 final int expectedCells = singleSelection ? 1 : 4099 selectsOneRow && cellSelection ? 2 : 4100 selectsOneRow && !cellSelection ? 1 : 4101 !selectsOneRow && cellSelection ? 4 : 4102 /* !selectsOneRow && !cellSelection */ 2; 4103 4104 final int expectedItems = singleSelection ? 1 : 4105 selectsOneRow ? 1 : 2; 4106 4107 assertEquals(expectedCells, sm.getSelectedCells().size()); 4108 assertEquals(expectedItems, sm.getSelectedItems().size()); 4109 assertEquals(expectedItems, sm.getSelectedIndices().size()); 4110 4111 // we expect the table column of all selected cells, in this instance, 4112 // to be null as we have not explicitly stated a column, nor have we clicked 4113 // on a column. The only alternative is to use the first column. 4114 for (TablePosition<?,?> tp : sm.getSelectedCells()) { 4115 if (cellSelection) { 4116 assertNotNull(tp.getTableColumn()); 4117 } else { 4118 assertNull(tp.getTableColumn()); 4119 } 4120 } 4121 } 4122 4123 private int rt_37853_cancelCount; 4124 private int rt_37853_commitCount; 4125 @Test public void test_rt_37853() { 4126 TableColumn<String,String> first = new TableColumn<>("first"); 4127 first.setEditable(true); 4128 first.setCellFactory(TextFieldTableCell.forTableColumn()); 4129 table.getColumns().add(first); 4130 table.setEditable(true); 4131 4132 for (int i = 0; i < 10; i++) { 4133 table.getItems().add("" + i); 4134 } 4135 4136 StageLoader sl = new StageLoader(table); 4137 4138 first.setOnEditCancel(editEvent -> rt_37853_cancelCount++); 4139 first.setOnEditCommit(editEvent -> rt_37853_commitCount++); 4140 4141 assertEquals(0, rt_37853_cancelCount); 4142 assertEquals(0, rt_37853_commitCount); 4143 4144 table.edit(1, first); 4145 assertNotNull(table.getEditingCell()); 4146 4147 table.getItems().clear(); 4148 assertEquals(1, rt_37853_cancelCount); 4149 assertEquals(0, rt_37853_commitCount); 4150 4151 sl.dispose(); 4152 } 4153 4154 4155 /************************************************************************** 4156 * 4157 * Tests (and related code) for RT-38892 4158 * 4159 *************************************************************************/ 4160 4161 private final Supplier<TableColumn<Person,String>> columnCallable = () -> { 4162 TableColumn<Person,String> column = new TableColumn<>("Last Name"); 4163 column.setCellValueFactory(new PropertyValueFactory<Person,String>("lastName")); 4164 return column; 4165 }; 4166 4167 private TableColumn<Person, String> test_rt_38892_firstNameCol; 4168 private TableColumn<Person, String> test_rt_38892_lastNameCol; 4169 4170 private TableView<Person> init_test_rt_38892() { 4171 ObservableList<Person> data = FXCollections.observableArrayList( 4172 new Person("Jacob", "Smith", ""), 4173 new Person("Isabella", "Johnson", ""), 4174 new Person("Ethan", "Williams", ""), 4175 new Person("Emma", "Jones", ""), 4176 new Person("Michael", "Brown", "") 4177 ); 4178 4179 TableView<Person> table = new TableView<>(); 4180 table.getSelectionModel().setCellSelectionEnabled(true); 4181 table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 4182 table.setItems(data); 4183 4184 test_rt_38892_firstNameCol = new TableColumn<>("First Name"); 4185 test_rt_38892_firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName")); 4186 test_rt_38892_lastNameCol = columnCallable.get(); 4187 table.getColumns().addAll(test_rt_38892_firstNameCol, test_rt_38892_lastNameCol); 4188 4189 return table; 4190 } 4191 4192 @Test public void test_rt_38892_focusMovesToLeftWhenPossible() { 4193 TableView<Person> table = init_test_rt_38892(); 4194 4195 TableView.TableViewFocusModel<Person> fm = table.getFocusModel(); 4196 fm.focus(0, test_rt_38892_lastNameCol); 4197 4198 // assert pre-conditions 4199 assertEquals(0, fm.getFocusedIndex()); 4200 assertEquals(0, fm.getFocusedCell().getRow()); 4201 assertEquals(test_rt_38892_lastNameCol, fm.getFocusedCell().getTableColumn()); 4202 assertEquals(1, fm.getFocusedCell().getColumn()); 4203 4204 // now remove column where focus is and replace it with a new column. 4205 // We expect focus to move to the left one cell. 4206 table.getColumns().remove(1); 4207 table.getColumns().add(columnCallable.get()); 4208 4209 assertEquals(0, fm.getFocusedIndex()); 4210 assertEquals(0, fm.getFocusedCell().getRow()); 4211 assertEquals(test_rt_38892_firstNameCol, fm.getFocusedCell().getTableColumn()); 4212 assertEquals(0, fm.getFocusedCell().getColumn()); 4213 } 4214 4215 @Test public void test_rt_38892_removeLeftMostColumn() { 4216 TableView<Person> table = init_test_rt_38892(); 4217 4218 TableView.TableViewFocusModel<Person> fm = table.getFocusModel(); 4219 fm.focus(0, test_rt_38892_firstNameCol); 4220 4221 // assert pre-conditions 4222 assertEquals(0, fm.getFocusedIndex()); 4223 assertEquals(0, fm.getFocusedCell().getRow()); 4224 assertEquals(test_rt_38892_firstNameCol, fm.getFocusedCell().getTableColumn()); 4225 assertEquals(0, fm.getFocusedCell().getColumn()); 4226 4227 // now remove column where focus is and replace it with a new column. 4228 // In the current (non-specified) behavior, this results in focus being 4229 // shifted to a cell in the remaining column, even when we add a new column 4230 // as we index based on the column, not on its index. 4231 table.getColumns().remove(0); 4232 TableColumn<Person,String> newColumn = columnCallable.get(); 4233 table.getColumns().add(0, newColumn); 4234 4235 assertEquals(0, fm.getFocusedIndex()); 4236 assertEquals(0, fm.getFocusedCell().getRow()); 4237 assertEquals(test_rt_38892_lastNameCol, fm.getFocusedCell().getTableColumn()); 4238 assertEquals(0, fm.getFocusedCell().getColumn()); 4239 } 4240 4241 @Test public void test_rt_38892_removeSelectionFromCellsInRemovedColumn() { 4242 TableView<Person> table = init_test_rt_38892(); 4243 4244 TableView.TableViewSelectionModel sm = table.getSelectionModel(); 4245 sm.select(0, test_rt_38892_firstNameCol); 4246 sm.select(1, test_rt_38892_lastNameCol); // this should go 4247 sm.select(2, test_rt_38892_firstNameCol); 4248 sm.select(3, test_rt_38892_lastNameCol); // so should this 4249 sm.select(4, test_rt_38892_firstNameCol); 4250 4251 assertEquals(5, sm.getSelectedCells().size()); 4252 4253 table.getColumns().remove(1); 4254 4255 assertEquals(3, sm.getSelectedCells().size()); 4256 assertTrue(sm.isSelected(0, test_rt_38892_firstNameCol)); 4257 assertFalse(sm.isSelected(1, test_rt_38892_lastNameCol)); 4258 assertTrue(sm.isSelected(2, test_rt_38892_firstNameCol)); 4259 assertFalse(sm.isSelected(3, test_rt_38892_lastNameCol)); 4260 assertTrue(sm.isSelected(4, test_rt_38892_firstNameCol)); 4261 } 4262 4263 @Test public void test_rt_38787_remove_b() { 4264 // selection moves to "a" 4265 test_rt_38787("a", 0, "b"); 4266 } 4267 4268 @Test public void test_rt_38787_remove_b_c() { 4269 // selection moves to "a" 4270 test_rt_38787("a", 0, "b", "c"); 4271 } 4272 4273 @Test public void test_rt_38787_remove_c_d() { 4274 // selection stays on "b" 4275 test_rt_38787("b", 1, "c", "d"); 4276 } 4277 4278 @Test public void test_rt_38787_remove_a() { 4279 // selection moves to "b", now in index 0 4280 test_rt_38787("b", 0, "a"); 4281 } 4282 4283 @Test public void test_rt_38787_remove_z() { 4284 // selection shouldn't move as 'z' doesn't exist 4285 test_rt_38787("b", 1, "z"); 4286 } 4287 4288 private void test_rt_38787(String expectedItem, int expectedIndex, String... itemsToRemove) { 4289 TableView<String> stringTableView = new TableView<>(); 4290 stringTableView.getItems().addAll("a","b","c","d"); 4291 4292 TableColumn<String,String> column = new TableColumn<>("Column"); 4293 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4294 stringTableView.getColumns().add(column); 4295 4296 MultipleSelectionModel<String> sm = stringTableView.getSelectionModel(); 4297 sm.select("b"); 4298 4299 // test pre-conditions 4300 assertEquals(1, sm.getSelectedIndex()); 4301 assertEquals(1, (int)sm.getSelectedIndices().get(0)); 4302 assertEquals("b", sm.getSelectedItem()); 4303 assertEquals("b", sm.getSelectedItems().get(0)); 4304 assertFalse(sm.isSelected(0)); 4305 assertTrue(sm.isSelected(1)); 4306 assertFalse(sm.isSelected(2)); 4307 4308 // removing items 4309 stringTableView.getItems().removeAll(itemsToRemove); 4310 4311 // testing against expectations 4312 assertEquals(expectedIndex, sm.getSelectedIndex()); 4313 assertEquals(expectedIndex, (int)sm.getSelectedIndices().get(0)); 4314 assertEquals(expectedItem, sm.getSelectedItem()); 4315 assertEquals(expectedItem, sm.getSelectedItems().get(0)); 4316 } 4317 4318 private int rt_38341_indices_count = 0; 4319 private int rt_38341_items_count = 0; 4320 @Test public void test_rt_38341() { 4321 TableView<String> stringTableView = new TableView<>(); 4322 stringTableView.getItems().addAll("a","b","c","d"); 4323 4324 TableColumn<String,String> column = new TableColumn<>("Column"); 4325 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4326 stringTableView.getColumns().add(column); 4327 4328 MultipleSelectionModel<String> sm = stringTableView.getSelectionModel(); 4329 sm.getSelectedIndices().addListener((ListChangeListener<Integer>) c -> { 4330 rt_38341_indices_count++; 4331 }); 4332 sm.getSelectedItems().addListener((ListChangeListener<String>) c -> rt_38341_items_count++); 4333 4334 assertEquals(0, rt_38341_indices_count); 4335 assertEquals(0, rt_38341_items_count); 4336 4337 // expand the first child of root, and select it (note: root isn't visible) 4338 sm.select(1); 4339 assertEquals(1, sm.getSelectedIndex()); 4340 assertEquals(1, sm.getSelectedIndices().size()); 4341 assertEquals(1, (int)sm.getSelectedIndices().get(0)); 4342 assertEquals(1, sm.getSelectedItems().size()); 4343 assertEquals("b", sm.getSelectedItem()); 4344 assertEquals("b", sm.getSelectedItems().get(0)); 4345 4346 assertEquals(1, rt_38341_indices_count); 4347 assertEquals(1, rt_38341_items_count); 4348 4349 // now delete it 4350 stringTableView.getItems().remove(1); 4351 4352 // selection should move to the childs parent in index 0 4353 assertEquals(0, sm.getSelectedIndex()); 4354 assertEquals(1, sm.getSelectedIndices().size()); 4355 assertEquals(0, (int)sm.getSelectedIndices().get(0)); 4356 assertEquals(1, sm.getSelectedItems().size()); 4357 assertEquals("a", sm.getSelectedItem()); 4358 assertEquals("a", sm.getSelectedItems().get(0)); 4359 4360 // we also expect there to be an event in the selection model for 4361 // selected indices and selected items 4362 assertEquals(2, rt_38341_indices_count); 4363 assertEquals(2, rt_38341_items_count); 4364 } 4365 4366 @Test public void test_rt_39132() { 4367 TableView<String> tableView = new TableView<>(); 4368 4369 ObservableList items = FXCollections.observableArrayList("one", "two", "three"); 4370 tableView.setItems(items); 4371 4372 TableColumn<String,String> column = new TableColumn<>("Column"); 4373 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4374 tableView.getColumns().add(column); 4375 4376 MultipleSelectionModel sm = tableView.getSelectionModel(); 4377 sm.select(0); 4378 4379 assertEquals(0, sm.getSelectedIndex()); 4380 assertEquals("one", sm.getSelectedItem()); 4381 4382 items.add(0, "new item"); 4383 assertEquals(1, sm.getSelectedIndex()); 4384 assertEquals("one", sm.getSelectedItem()); 4385 } 4386 4387 private int rt_38943_index_count = 0; 4388 private int rt_38943_item_count = 0; 4389 @Test public void test_rt_38943() { 4390 TableView<String> tableView = new TableView<>(FXCollections.observableArrayList("one", "two", "three")); 4391 4392 TableColumn<String,String> column = new TableColumn<>("Column"); 4393 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4394 tableView.getColumns().add(column); 4395 4396 MultipleSelectionModel sm = tableView.getSelectionModel(); 4397 4398 sm.selectedIndexProperty().addListener((observable, oldValue, newValue) -> rt_38943_index_count++); 4399 sm.selectedItemProperty().addListener((observable, oldValue, newValue) -> rt_38943_item_count++); 4400 4401 assertEquals(-1, sm.getSelectedIndex()); 4402 assertNull(sm.getSelectedItem()); 4403 assertEquals(0, rt_38943_index_count); 4404 assertEquals(0, rt_38943_item_count); 4405 4406 sm.select(0); 4407 assertEquals(0, sm.getSelectedIndex()); 4408 assertEquals("one", sm.getSelectedItem()); 4409 assertEquals(1, rt_38943_index_count); 4410 assertEquals(1, rt_38943_item_count); 4411 4412 sm.clearSelection(0); 4413 assertEquals(-1, sm.getSelectedIndex()); 4414 assertNull(sm.getSelectedItem()); 4415 assertEquals(2, rt_38943_index_count); 4416 assertEquals(2, rt_38943_item_count); 4417 } 4418 4419 @Test public void test_rt_38884() { 4420 TableView<String> table = new TableView<>(); 4421 ObservableList<String> items = table.getItems(); 4422 4423 table.getSelectionModel().getSelectedItems().addListener((ListChangeListener.Change<? extends String> c) -> { 4424 while (c.next()) { 4425 if (c.wasRemoved()) { 4426 assertTrue(c.getRemovedSize() > 0); 4427 4428 List<? extends String> removed = c.getRemoved(); 4429 String removedItem = null; 4430 try { 4431 removedItem = removed.get(0); 4432 } catch (Exception e) { 4433 fail(); 4434 } 4435 4436 assertEquals("foo", removedItem); 4437 } 4438 } 4439 }); 4440 4441 items.add("foo"); 4442 table.getSelectionModel().select(0); 4443 items.clear(); 4444 } 4445 4446 private int rt_37360_add_count = 0; 4447 private int rt_37360_remove_count = 0; 4448 @Test public void test_rt_37360() { 4449 TableView<String> stringTableView = new TableView<>(); 4450 stringTableView.getItems().addAll("a","b"); 4451 4452 TableColumn<String,String> column = new TableColumn<>("Column"); 4453 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4454 stringTableView.getColumns().add(column); 4455 4456 MultipleSelectionModel<String> sm = stringTableView.getSelectionModel(); 4457 sm.setSelectionMode(SelectionMode.MULTIPLE); 4458 sm.getSelectedItems().addListener((ListChangeListener<String>) c -> { 4459 while (c.next()) { 4460 if (c.wasAdded()) { 4461 rt_37360_add_count += c.getAddedSize(); 4462 } 4463 if (c.wasRemoved()) { 4464 rt_37360_remove_count += c.getRemovedSize(); 4465 } 4466 } 4467 }); 4468 4469 assertEquals(0, sm.getSelectedItems().size()); 4470 assertEquals(0, rt_37360_add_count); 4471 assertEquals(0, rt_37360_remove_count); 4472 4473 sm.select(0); 4474 assertEquals(1, sm.getSelectedItems().size()); 4475 assertEquals(1, rt_37360_add_count); 4476 assertEquals(0, rt_37360_remove_count); 4477 4478 sm.select(1); 4479 assertEquals(2, sm.getSelectedItems().size()); 4480 assertEquals(2, rt_37360_add_count); 4481 assertEquals(0, rt_37360_remove_count); 4482 4483 sm.clearAndSelect(1); 4484 assertEquals(1, sm.getSelectedItems().size()); 4485 assertEquals(2, rt_37360_add_count); 4486 assertEquals(1, rt_37360_remove_count); 4487 } 4488 4489 @Test public void test_rt_38491() { 4490 TableView<String> stringTableView = new TableView<>(); 4491 stringTableView.getItems().addAll("a","b", "c", "d"); 4492 4493 TableColumn<String,String> column = new TableColumn<>("Column"); 4494 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4495 stringTableView.getColumns().add(column); 4496 4497 TableSelectionModel<String> sm = stringTableView.getSelectionModel(); 4498 sm.setSelectionMode(SelectionMode.MULTIPLE); 4499 4500 TableView.TableViewFocusModel fm = stringTableView.getFocusModel(); 4501 4502 StageLoader sl = new StageLoader(stringTableView); 4503 4504 // click on row 0 4505 sm.select(0, column); 4506 assertTrue(sm.isSelected(0)); 4507 assertEquals("a", sm.getSelectedItem()); 4508 assertTrue(fm.isFocused(0)); 4509 assertEquals("a", fm.getFocusedItem()); 4510 assertEquals(0, fm.getFocusedCell().getRow()); 4511 assertEquals(column, fm.getFocusedCell().getTableColumn()); 4512 4513 TablePosition anchor = TableCellBehavior.getAnchor(stringTableView, null); 4514 assertTrue(TableCellBehavior.hasNonDefaultAnchor(stringTableView)); 4515 assertEquals(0, anchor.getRow()); 4516 assertEquals(column, anchor.getTableColumn()); 4517 4518 // now add a new item at row 0. This has the effect of pushing down 4519 // the selected item into row 1. 4520 stringTableView.getItems().add(0, "z"); 4521 4522 Toolkit.getToolkit().firePulse(); 4523 4524 // The first bug was that selection and focus were not moving down to 4525 // be on row 1, so we test that now 4526 assertFalse(sm.isSelected(0)); 4527 assertFalse(fm.isFocused(0)); 4528 assertTrue(sm.isSelected(1)); 4529 assertEquals("a", sm.getSelectedItem()); 4530 assertTrue(fm.isFocused(1)); 4531 assertEquals("a", fm.getFocusedItem()); 4532 assertEquals(1, fm.getFocusedCell().getRow()); 4533 assertEquals(column, fm.getFocusedCell().getTableColumn()); 4534 4535 // The second bug was that the anchor was not being pushed down as well 4536 // (when it should). 4537 anchor = TableCellBehavior.getAnchor(stringTableView, null); 4538 assertTrue(TableCellBehavior.hasNonDefaultAnchor(stringTableView)); 4539 assertEquals(1, anchor.getRow()); 4540 assertEquals(column, anchor.getTableColumn()); 4541 4542 sl.dispose(); 4543 } 4544 4545 private final ObservableList<String> rt_39256_list = FXCollections.observableArrayList(); 4546 @Test public void test_rt_39256() { 4547 TableView<String> stringTableView = new TableView<>(); 4548 stringTableView.getItems().addAll("a","b", "c", "d"); 4549 4550 TableColumn<String,String> column = new TableColumn<>("Column"); 4551 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4552 stringTableView.getColumns().add(column); 4553 4554 TableSelectionModel<String> sm = stringTableView.getSelectionModel(); 4555 sm.setSelectionMode(SelectionMode.MULTIPLE); 4556 4557 // rt_39256_list.addListener((ListChangeListener<String>) change -> { 4558 // while (change.next()) { 4559 // System.err.println("number of selected persons (in bound list): " + change.getList().size()); 4560 // } 4561 // }); 4562 4563 Bindings.bindContent(rt_39256_list, sm.getSelectedItems()); 4564 4565 assertEquals(0, sm.getSelectedItems().size()); 4566 assertEquals(0, rt_39256_list.size()); 4567 4568 sm.selectAll(); 4569 assertEquals(4, sm.getSelectedItems().size()); 4570 assertEquals(4, rt_39256_list.size()); 4571 4572 sm.selectAll(); 4573 assertEquals(4, sm.getSelectedItems().size()); 4574 assertEquals(4, rt_39256_list.size()); 4575 4576 sm.selectAll(); 4577 assertEquals(4, sm.getSelectedItems().size()); 4578 assertEquals(4, rt_39256_list.size()); 4579 } 4580 4581 @Test public void test_rt_39256_noTableView() { 4582 ObservableList<String> listOne = FXCollections.observableArrayList(); 4583 ObservableList<String> listTwo = FXCollections.observableArrayList(); 4584 4585 // listOne.addListener((ListChangeListener<String>) change -> { 4586 // while (change.next()) { 4587 // System.out.println("number of strings in bound list - listOne: " + change.getList().size() + ", change: " + change); 4588 // } 4589 // }); 4590 // 4591 // listTwo.addListener((ListChangeListener<String>) change -> { 4592 // while (change.next()) { 4593 // System.out.println("number of strings in unbound list - listTwo: " + change.getList().size() + ", change: " + change); 4594 // } 4595 // }); 4596 4597 Bindings.bindContent(listOne, listTwo); 4598 4599 assertEquals(0, listOne.size()); 4600 assertEquals(0, listTwo.size()); 4601 4602 System.out.println("Test One:"); 4603 listTwo.setAll("a", "b", "c", "d"); 4604 assertEquals(4, listOne.size()); 4605 assertEquals(4, listTwo.size()); 4606 4607 System.out.println("\nTest Two:"); 4608 listTwo.setAll("e", "f", "g", "h"); 4609 assertEquals(4, listOne.size()); 4610 assertEquals(4, listTwo.size()); 4611 4612 System.out.println("\nTest Three:"); 4613 listTwo.setAll("i", "j", "k", "l"); 4614 assertEquals(4, listOne.size()); 4615 assertEquals(4, listTwo.size()); 4616 } 4617 4618 private final ObservableList<String> rt_39482_list = FXCollections.observableArrayList(); 4619 @Test public void test_rt_39482() { 4620 TableView<String> stringTableView = new TableView<>(); 4621 stringTableView.getItems().addAll("a","b", "c", "d"); 4622 4623 TableColumn<String,String> column = new TableColumn<>("Column"); 4624 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4625 stringTableView.getColumns().add(column); 4626 4627 TableView.TableViewSelectionModel<String> sm = stringTableView.getSelectionModel(); 4628 sm.setSelectionMode(SelectionMode.MULTIPLE); 4629 4630 sm.getSelectedItems().addListener((ListChangeListener<String>) change -> { 4631 while (change.next()) { 4632 System.out.println("sm.getSelectedItems(): " + change.getList()); 4633 } 4634 }); 4635 4636 rt_39482_list.addListener((ListChangeListener<String>) change -> { 4637 while (change.next()) { 4638 System.out.println("rt_39482_list: " + change.getList()); 4639 } 4640 }); 4641 4642 Bindings.bindContent(rt_39482_list, sm.getSelectedItems()); 4643 4644 assertEquals(0, sm.getSelectedItems().size()); 4645 assertEquals(0, rt_39482_list.size()); 4646 4647 test_rt_39482_selectRow("a", sm, 0, column); 4648 test_rt_39482_selectRow("b", sm, 1, column); 4649 test_rt_39482_selectRow("c", sm, 2, column); 4650 test_rt_39482_selectRow("d", sm, 3, column); 4651 } 4652 4653 private void test_rt_39482_selectRow(String expectedString, 4654 TableView.TableViewSelectionModel<String> sm, 4655 int rowToSelect, 4656 TableColumn<String,String> columnToSelect) { 4657 System.out.println("\nSelect row " + rowToSelect); 4658 sm.selectAll(); 4659 assertEquals(4, sm.getSelectedCells().size()); 4660 assertEquals(4, sm.getSelectedIndices().size()); 4661 assertEquals(4, sm.getSelectedItems().size()); 4662 assertEquals(4, rt_39482_list.size()); 4663 4664 sm.clearAndSelect(rowToSelect, columnToSelect); 4665 assertEquals(1, sm.getSelectedCells().size()); 4666 assertEquals(1, sm.getSelectedIndices().size()); 4667 assertEquals(1, sm.getSelectedItems().size()); 4668 assertEquals(expectedString, sm.getSelectedItem()); 4669 assertEquals(expectedString, rt_39482_list.get(0)); 4670 assertEquals(1, rt_39482_list.size()); 4671 } 4672 4673 @Test public void test_rt_39559_useSM_selectAll() { 4674 test_rt_39559(true); 4675 } 4676 4677 @Test public void test_rt_39559_useKeyboard_selectAll() { 4678 test_rt_39559(false); 4679 } 4680 4681 private void test_rt_39559(boolean useSMSelectAll) { 4682 TableView<String> stringTableView = new TableView<>(); 4683 stringTableView.getItems().addAll("a","b", "c", "d"); 4684 4685 TableColumn<String,String> column = new TableColumn<>("Column"); 4686 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4687 stringTableView.getColumns().add(column); 4688 4689 TableView.TableViewSelectionModel<String> sm = stringTableView.getSelectionModel(); 4690 sm.setSelectionMode(SelectionMode.MULTIPLE); 4691 4692 StageLoader sl = new StageLoader(stringTableView); 4693 KeyEventFirer keyboard = new KeyEventFirer(stringTableView); 4694 4695 assertEquals(0, sm.getSelectedItems().size()); 4696 4697 sm.clearAndSelect(0); 4698 4699 if (useSMSelectAll) { 4700 sm.selectAll(); 4701 } else { 4702 keyboard.doKeyPress(KeyCode.A, KeyModifier.getShortcutKey()); 4703 } 4704 4705 assertEquals(4, sm.getSelectedItems().size()); 4706 assertEquals(0, ((TablePosition) TableCellBehavior.getAnchor(stringTableView, null)).getRow()); 4707 4708 keyboard.doKeyPress(KeyCode.DOWN, KeyModifier.SHIFT); 4709 4710 assertEquals(0, ((TablePosition) TableCellBehavior.getAnchor(stringTableView, null)).getRow()); 4711 assertEquals(2, sm.getSelectedItems().size()); 4712 assertEquals("a", sm.getSelectedItems().get(0)); 4713 assertEquals("b", sm.getSelectedItems().get(1)); 4714 4715 sl.dispose(); 4716 } 4717 4718 @Test public void test_rt_16068_firstElement_selectAndRemoveSameRow() { 4719 // select and then remove the 'a' item, selection and focus should both 4720 // stay at the first row, now 'b' 4721 test_rt_16068(0, 0, 0); 4722 } 4723 4724 @Test public void test_rt_16068_firstElement_selectRowAndRemoveLaterSibling() { 4725 // select row 'a', and remove row 'c', selection and focus should not change 4726 test_rt_16068(0, 2, 0); 4727 } 4728 4729 @Test public void test_rt_16068_middleElement_selectAndRemoveSameRow() { 4730 // select and then remove the 'b' item, selection and focus should both 4731 // move up one row to the 'a' item 4732 test_rt_16068(1, 1, 0); 4733 } 4734 4735 @Test public void test_rt_16068_middleElement_selectRowAndRemoveLaterSibling() { 4736 // select row 'b', and remove row 'c', selection and focus should not change 4737 test_rt_16068(1, 2, 1); 4738 } 4739 4740 @Test public void test_rt_16068_middleElement_selectRowAndRemoveEarlierSibling() { 4741 // select row 'b', and remove row 'a', selection and focus should move up 4742 // one row, remaining on 'b' 4743 test_rt_16068(1, 0, 0); 4744 } 4745 4746 @Test public void test_rt_16068_lastElement_selectAndRemoveSameRow() { 4747 // select and then remove the 'd' item, selection and focus should both 4748 // move up one row to the 'c' item 4749 test_rt_16068(3, 3, 2); 4750 } 4751 4752 @Test public void test_rt_16068_lastElement_selectRowAndRemoveEarlierSibling() { 4753 // select row 'd', and remove row 'a', selection and focus should move up 4754 // one row, remaining on 'd' 4755 test_rt_16068(3, 0, 2); 4756 } 4757 4758 private void test_rt_16068(int indexToSelect, int indexToRemove, int expectedIndex) { 4759 TableView<String> stringTableView = new TableView<>(); 4760 stringTableView.getItems().addAll("a","b", "c", "d"); 4761 4762 TableColumn<String,String> column = new TableColumn<>("Column"); 4763 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4764 stringTableView.getColumns().add(column); 4765 4766 TableView.TableViewSelectionModel<?> sm = stringTableView.getSelectionModel(); 4767 FocusModel<?> fm = stringTableView.getFocusModel(); 4768 4769 sm.select(indexToSelect); 4770 assertEquals(indexToSelect, sm.getSelectedIndex()); 4771 assertEquals(stringTableView.getItems().get(indexToSelect), sm.getSelectedItem()); 4772 assertEquals(indexToSelect, fm.getFocusedIndex()); 4773 assertEquals(stringTableView.getItems().get(indexToSelect), fm.getFocusedItem()); 4774 4775 stringTableView.getItems().remove(indexToRemove); 4776 assertEquals(expectedIndex, sm.getSelectedIndex()); 4777 assertEquals(stringTableView.getItems().get(expectedIndex), sm.getSelectedItem()); 4778 assertEquals(expectedIndex, fm.getFocusedIndex()); 4779 assertEquals(stringTableView.getItems().get(expectedIndex), fm.getFocusedItem()); 4780 } 4781 4782 private int test_rt_39822_count = 0; 4783 @Test public void test_rt_39822() { 4784 // get the current exception handler before replacing with our own, 4785 // as ListListenerHelp intercepts the exception otherwise 4786 final Thread.UncaughtExceptionHandler exceptionHandler = Thread.currentThread().getUncaughtExceptionHandler(); 4787 Thread.currentThread().setUncaughtExceptionHandler((t, e) -> { 4788 e.printStackTrace(); 4789 4790 if (test_rt_39822_count == 0) { 4791 test_rt_39822_count++; 4792 if (! (e instanceof IllegalStateException)) { 4793 fail("Incorrect exception type - expecting IllegalStateException"); 4794 } 4795 } else { 4796 // don't care 4797 test_rt_39822_count++; 4798 } 4799 }); 4800 4801 TableView<String> table = new TableView<>(); 4802 TableColumn<String, String> col1 = new TableColumn<>("Foo"); 4803 table.getColumns().addAll(col1, col1); // add column twice 4804 4805 StageLoader sl = null; 4806 try { 4807 sl = new StageLoader(table); 4808 } finally { 4809 if (sl != null) { 4810 sl.dispose(); 4811 } 4812 4813 // reset the exception handler 4814 Thread.currentThread().setUncaughtExceptionHandler(exceptionHandler); 4815 } 4816 } 4817 4818 private int test_rt_39842_count = 0; 4819 @Test public void test_rt_39842_selectLeftDown() { 4820 test_rt_39842(true, false); 4821 } 4822 4823 @Test public void test_rt_39842_selectLeftUp() { 4824 test_rt_39842(true, true); 4825 } 4826 4827 @Test public void test_rt_39842_selectRightDown() { 4828 test_rt_39842(false, false); 4829 } 4830 4831 @Test public void test_rt_39842_selectRightUp() { 4832 test_rt_39842(false, true); 4833 } 4834 4835 private void test_rt_39842(boolean selectToLeft, boolean selectUpwards) { 4836 test_rt_39842_count = 0; 4837 4838 TableColumn firstNameCol = new TableColumn("First Name"); 4839 firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 4840 4841 TableColumn lastNameCol = new TableColumn("Last Name"); 4842 lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 4843 4844 TableView<Person> table = new TableView<>(); 4845 table.setItems(personTestData); 4846 table.getColumns().addAll(firstNameCol, lastNameCol); 4847 4848 sm = table.getSelectionModel(); 4849 sm.setCellSelectionEnabled(true); 4850 sm.setSelectionMode(SelectionMode.MULTIPLE); 4851 sm.getSelectedCells().addListener((ListChangeListener) c -> test_rt_39842_count++); 4852 4853 StageLoader sl = new StageLoader(table); 4854 4855 assertEquals(0, test_rt_39842_count); 4856 4857 if (selectToLeft) { 4858 if (selectUpwards) { 4859 sm.selectRange(3, lastNameCol, 0, firstNameCol); 4860 } else { 4861 sm.selectRange(0, lastNameCol, 3, firstNameCol); 4862 } 4863 } else { 4864 if (selectUpwards) { 4865 sm.selectRange(3, firstNameCol, 0, lastNameCol); 4866 } else { 4867 sm.selectRange(0, firstNameCol, 3, lastNameCol); 4868 } 4869 } 4870 4871 // test model state 4872 assertEquals(8, sm.getSelectedCells().size()); 4873 assertEquals(1, test_rt_39842_count); 4874 4875 // test visual state 4876 for (int row = 0; row <= 3; row++) { 4877 for (int column = 0; column <= 1; column++) { 4878 IndexedCell cell = VirtualFlowTestUtils.getCell(table, row, column); 4879 assertTrue(cell.isSelected()); 4880 } 4881 } 4882 4883 sl.dispose(); 4884 } 4885 4886 @Test public void test_rt_22599() { 4887 ObservableList<RT22599_DataType> initialData = FXCollections.observableArrayList( 4888 new RT22599_DataType(1, "row1"), 4889 new RT22599_DataType(2, "row2"), 4890 new RT22599_DataType(3, "row3") 4891 ); 4892 4893 TableColumn<RT22599_DataType, String> col = new TableColumn<>("Header"); 4894 col.setCellValueFactory(param -> new ReadOnlyStringWrapper(param.getValue().text)); 4895 4896 TableView<RT22599_DataType> table = new TableView<>(); 4897 table.setItems(initialData); 4898 table.getColumns().addAll(col); 4899 4900 StageLoader sl = new StageLoader(table); 4901 4902 // testing initial state 4903 assertNotNull(table.getSkin()); 4904 assertEquals("row1", VirtualFlowTestUtils.getCell(table, 0, 0).getText()); 4905 assertEquals("row2", VirtualFlowTestUtils.getCell(table, 1, 0).getText()); 4906 assertEquals("row3", VirtualFlowTestUtils.getCell(table, 2, 0).getText()); 4907 4908 // change row 0 (where "row1" currently resides), keeping same id. 4909 // Because 'set' is called, the control should update to the new content 4910 // without any user interaction 4911 RT22599_DataType data; 4912 initialData.set(0, data = new RT22599_DataType(0, "row1a")); 4913 Toolkit.getToolkit().firePulse(); 4914 assertEquals("row1a", VirtualFlowTestUtils.getCell(table, 0, 0).getText()); 4915 4916 // change the row 0 (where we currently have "row1a") value directly. 4917 // Because there is no associated property, this won't be observed, so 4918 // the control should still show "row1a" rather than "row1b" 4919 data.text = "row1b"; 4920 Toolkit.getToolkit().firePulse(); 4921 assertEquals("row1a", VirtualFlowTestUtils.getCell(table, 0, 0).getText()); 4922 4923 // call refresh() to force a refresh of all visible cells 4924 table.refresh(); 4925 Toolkit.getToolkit().firePulse(); 4926 assertEquals("row1b", VirtualFlowTestUtils.getCell(table, 0, 0).getText()); 4927 4928 sl.dispose(); 4929 } 4930 4931 private static class RT22599_DataType { 4932 public int id = 0; 4933 public String text = ""; 4934 4935 public RT22599_DataType(int id, String text) { 4936 this.id = id; 4937 this.text = text; 4938 } 4939 4940 @Override public boolean equals(Object obj) { 4941 if (obj == null) return false; 4942 return id == ((RT22599_DataType)obj).id; 4943 } 4944 } 4945 4946 private int rt_39966_count = 0; 4947 @Test public void test_rt_39966() { 4948 ObservableList<String> initialData = FXCollections.observableArrayList("Hello World"); 4949 4950 TableColumn<String, String> col = new TableColumn<>("Header"); 4951 col.setCellValueFactory(param -> new ReadOnlyStringWrapper(param.getValue())); 4952 4953 TableView<String> table = new TableView<>(initialData); 4954 table.getColumns().addAll(col); 4955 4956 StageLoader sl = new StageLoader(table); 4957 4958 // initially there is no selection 4959 assertTrue(table.getSelectionModel().isEmpty()); 4960 4961 table.getSelectionModel().selectedItemProperty().addListener((value, s1, s2) -> { 4962 if (rt_39966_count == 0) { 4963 rt_39966_count++; 4964 assertFalse(table.getSelectionModel().isEmpty()); 4965 } else { 4966 assertTrue(table.getSelectionModel().isEmpty()); 4967 } 4968 }); 4969 4970 // our assertion two lines down always succeeds. What fails is our 4971 // assertion above within the listener. 4972 table.getSelectionModel().select(0); 4973 assertFalse(table.getSelectionModel().isEmpty()); 4974 4975 initialData.remove(0); 4976 assertTrue(table.getSelectionModel().isEmpty()); 4977 4978 sl.dispose(); 4979 } 4980 4981 /** 4982 * Bullet 1: selected index must be updated 4983 * Corner case: last selected. Fails for core 4984 */ 4985 @Test public void test_rt_40012_selectedAtLastOnDisjointRemoveItemsAbove() { 4986 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 4987 TableView<String> stringTableView = new TableView<>(items); 4988 TableView.TableViewSelectionModel<?> sm = stringTableView.getSelectionModel(); 4989 4990 TableColumn<String,String> column = new TableColumn<>("Column"); 4991 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 4992 stringTableView.getColumns().add(column); 4993 4994 int last = items.size() - 1; 4995 4996 // selecting item "5" 4997 sm.select(last); 4998 4999 // disjoint remove of 2 elements above the last selected 5000 // Removing "1" and "3" 5001 items.removeAll(items.get(1), items.get(3)); 5002 5003 // selection should move up two places such that it remains on item "5", 5004 // but in index (last - 2). 5005 int expected = last - 2; 5006 assertEquals("5", sm.getSelectedItem()); 5007 assertEquals("selected index after disjoint removes above", expected, sm.getSelectedIndex()); 5008 } 5009 5010 /** 5011 * Variant of 1: if selectedIndex is not updated, 5012 * the old index is no longer valid 5013 * for accessing the items. 5014 */ 5015 @Test public void test_rt_40012_accessSelectedAtLastOnDisjointRemoveItemsAbove() { 5016 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 5017 TableView<String> stringTableView = new TableView<>(items); 5018 TableView.TableViewSelectionModel<?> sm = stringTableView.getSelectionModel(); 5019 5020 TableColumn<String,String> column = new TableColumn<>("Column"); 5021 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 5022 stringTableView.getColumns().add(column); 5023 5024 int last = items.size() - 1; 5025 5026 // selecting item "5" 5027 sm.select(last); 5028 5029 // disjoint remove of 2 elements above the last selected 5030 items.removeAll(items.get(1), items.get(3)); 5031 int selected = sm.getSelectedIndex(); 5032 if (selected > -1) { 5033 items.get(selected); 5034 } 5035 } 5036 5037 /** 5038 * Bullet 2: selectedIndex notification count 5039 * 5040 * Note that we don't use the corner case of having the last index selected 5041 * (which fails already on updating the index) 5042 */ 5043 private int rt_40012_count = 0; 5044 @Test public void test_rt_40012_selectedIndexNotificationOnDisjointRemovesAbove() { 5045 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 5046 TableView<String> stringTableView = new TableView<>(items); 5047 TableView.TableViewSelectionModel<?> sm = stringTableView.getSelectionModel(); 5048 5049 TableColumn<String,String> column = new TableColumn<>("Column"); 5050 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 5051 stringTableView.getColumns().add(column); 5052 5053 int last = items.size() - 2; 5054 sm.select(last); 5055 assertEquals(last, sm.getSelectedIndex()); 5056 5057 rt_40012_count = 0; 5058 sm.selectedIndexProperty().addListener(o -> rt_40012_count++); 5059 5060 // disjoint remove of 2 elements above the last selected 5061 items.removeAll(items.get(1), items.get(3)); 5062 assertEquals("sanity: selectedIndex must be shifted by -2", last - 2, sm.getSelectedIndex()); 5063 assertEquals("must fire single event on removes above", 1, rt_40012_count); 5064 } 5065 5066 /** 5067 * Bullet 3: unchanged selectedItem must not fire change 5068 */ 5069 @Test 5070 public void test_rt_40012_selectedItemNotificationOnDisjointRemovesAbove() { 5071 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 5072 TableView<String> stringTableView = new TableView<>(items); 5073 TableView.TableViewSelectionModel<?> sm = stringTableView.getSelectionModel(); 5074 5075 TableColumn<String,String> column = new TableColumn<>("Column"); 5076 column.setCellValueFactory(cdf -> new ReadOnlyStringWrapper(cdf.getValue())); 5077 stringTableView.getColumns().add(column); 5078 5079 int last = items.size() - 2; 5080 Object lastItem = items.get(last); 5081 sm.select(last); 5082 assertEquals(lastItem, sm.getSelectedItem()); 5083 5084 rt_40012_count = 0; 5085 sm.selectedItemProperty().addListener(o -> rt_40012_count++); 5086 5087 // disjoint remove of 2 elements above the last selected 5088 items.removeAll(items.get(1), items.get(3)); 5089 assertEquals("sanity: selectedItem unchanged", lastItem, sm.getSelectedItem()); 5090 assertEquals("must not fire on unchanged selected item", 0, rt_40012_count); 5091 } 5092 5093 /** 5094 * ClearAndSelect fires invalid change event if selectedIndex is unchanged. 5095 */ 5096 private int rt_40212_count = 0; 5097 @Test public void test_rt_40212() { 5098 final TableView<Number> table = new TableView<>(); 5099 for (int i = 0; i < 10; i++) { 5100 table.getItems().add(i); 5101 } 5102 5103 TableColumn<Number,Number> column = new TableColumn<>("Column"); 5104 column.setCellValueFactory(cdf -> new ReadOnlyIntegerWrapper((int) cdf.getValue())); 5105 table.getColumns().add(column); 5106 5107 MultipleSelectionModel<Number> sm = table.getSelectionModel(); 5108 sm.setSelectionMode(SelectionMode.MULTIPLE); 5109 5110 sm.selectRange(3, 5); 5111 int selected = sm.getSelectedIndex(); 5112 5113 sm.getSelectedIndices().addListener((ListChangeListener<Integer>) change -> { 5114 assertEquals("sanity: selectedIndex unchanged", selected, sm.getSelectedIndex()); 5115 while(change.next()) { 5116 assertEquals("single event on clearAndSelect already selected", 1, ++rt_40212_count); 5117 5118 boolean type = change.wasAdded() || change.wasRemoved() || change.wasPermutated() || change.wasUpdated(); 5119 assertTrue("at least one of the change types must be true", type); 5120 } 5121 }); 5122 5123 sm.clearAndSelect(selected); 5124 } 5125 5126 @Test public void test_rt_40280() { 5127 final TableView<String> view = new TableView<>(); 5128 StageLoader sl = new StageLoader(view); 5129 MultipleSelectionModelBaseShim.getFocusedIndex(view.getSelectionModel()); 5130 view.getFocusModel().getFocusedIndex(); 5131 sl.dispose(); 5132 } 5133 5134 /** 5135 * Test list change of selectedIndices on setIndices. Fails for core .. 5136 */ 5137 @Test public void test_rt_40263() { 5138 final TableView<Integer> view = new TableView<>(); 5139 for (int i = 0; i < 10; i++) { 5140 view.getItems().add(i); 5141 } 5142 5143 MultipleSelectionModel<Integer> sm = view.getSelectionModel(); 5144 sm.setSelectionMode(SelectionMode.MULTIPLE); 5145 5146 int[] indices = new int[]{2, 5, 7}; 5147 ListChangeListener<Integer> l = c -> { 5148 // firstly, we expect only one change 5149 int subChanges = 0; 5150 while(c.next()) { 5151 subChanges++; 5152 } 5153 assertEquals(1, subChanges); 5154 5155 // secondly, we expect the added size to be three, as that is the 5156 // number of items selected 5157 c.reset(); 5158 c.next(); 5159 System.out.println("Added items: " + c.getAddedSubList()); 5160 assertEquals(indices.length, c.getAddedSize()); 5161 assertArrayEquals(indices, c.getAddedSubList().stream().mapToInt(i -> i).toArray()); 5162 }; 5163 sm.getSelectedIndices().addListener(l); 5164 sm.selectIndices(indices[0], indices); 5165 } 5166 5167 @Test public void test_rt_40319_toRight_toBottom() { test_rt_40319(true, true, false); } 5168 @Test public void test_rt_40319_toRight_toTop() { test_rt_40319(true, false, false); } 5169 @Test public void test_rt_40319_toLeft_toBottom() { test_rt_40319(false, true, false); } 5170 @Test public void test_rt_40319_toLeft_toTop() { test_rt_40319(false, false, false); } 5171 @Test public void test_rt_40319_toRight_toBottom_useMouse() { test_rt_40319(true, true, true); } 5172 @Test public void test_rt_40319_toRight_toTop_useMouse() { test_rt_40319(true, false, true); } 5173 @Test public void test_rt_40319_toLeft_toBottom_useMouse() { test_rt_40319(false, true, true); } 5174 @Test public void test_rt_40319_toLeft_toTop_useMouse() { test_rt_40319(false, false, true); } 5175 5176 private void test_rt_40319(boolean toRight, boolean toBottom, boolean useMouse) { 5177 ObservableList<Person> p = FXCollections.observableArrayList(); 5178 p.add(new Person("FirstName1", "LastName1", "")); 5179 p.add(new Person("FirstName2", "LastName2", "")); 5180 p.add(new Person("FirstName3", "LastName3", "")); 5181 5182 TableView<Person> t = new TableView<>(p); 5183 sm = t.getSelectionModel(); 5184 sm.setSelectionMode(SelectionMode.MULTIPLE); 5185 5186 TableColumn<Person, String> c1 = new TableColumn<>("First Name"); 5187 c1.setCellValueFactory(new PropertyValueFactory<>("firstname")); 5188 TableColumn<Person, String> c2 = new TableColumn<>("Last Name"); 5189 c2.setCellValueFactory(new PropertyValueFactory<>("lastname")); 5190 t.getColumns().addAll(c1, c2); 5191 5192 final int startIndex = toRight ? 0 : 2; 5193 final int endIndex = toRight ? 2 : 0; 5194 final TableColumn<Person,String> startColumn = toBottom ? c1 : c2; 5195 final TableColumn<Person,String> endColumn = toBottom ? c2 : c1; 5196 5197 sm.select(startIndex, startColumn); 5198 5199 if (useMouse) { 5200 Cell endCell = VirtualFlowTestUtils.getCell(t, endIndex, toRight ? 1 : 0); 5201 MouseEventFirer mouse = new MouseEventFirer(endCell); 5202 mouse.fireMousePressAndRelease(KeyModifier.SHIFT); 5203 } else { 5204 t.getSelectionModel().selectRange(startIndex, startColumn, endIndex, endColumn); 5205 } 5206 5207 assertEquals(3, sm.getSelectedItems().size()); 5208 assertEquals(3, sm.getSelectedIndices().size()); 5209 assertEquals(3, sm.getSelectedCells().size()); 5210 } 5211 5212 private int rt_40546_count = 0; 5213 @Test public void test_rt_40546() { 5214 ObservableList<Person> p = FXCollections.observableArrayList(); 5215 5216 TableView<Person> t = new TableView<>(p); 5217 sm = t.getSelectionModel(); 5218 sm.setSelectionMode(SelectionMode.MULTIPLE); 5219 5220 TableColumn<Person, String> c1 = new TableColumn<>("First Name"); 5221 c1.setCellValueFactory(new PropertyValueFactory<>("firstname")); 5222 TableColumn<Person, String> c2 = new TableColumn<>("Last Name"); 5223 c2.setCellValueFactory(new PropertyValueFactory<>("lastname")); 5224 t.getColumns().addAll(c1, c2); 5225 5226 p.add(new Person("FirstName1", "LastName1", "")); 5227 p.add(new Person("FirstName2", "LastName2", "")); 5228 p.add(new Person("FirstName3", "LastName3", "")); 5229 5230 // add a listener - although we don't expect to hear anything 5231 sm.getSelectedItems().addListener((ListChangeListener) c -> { 5232 while (c.next()) { 5233 rt_40546_count++; 5234 } 5235 }); 5236 5237 assertEquals(0, rt_40546_count); 5238 5239 t.getSelectionModel().clearSelection(); 5240 assertEquals(0, rt_40546_count); 5241 5242 p.clear(); 5243 assertEquals(0, rt_40546_count); 5244 5245 p.add(new Person("FirstName1", "LastName1", "")); 5246 assertEquals(0, rt_40546_count); 5247 p.add(new Person("FirstName2", "LastName2", "")); 5248 assertEquals(0, rt_40546_count); 5249 p.add(new Person("FirstName3", "LastName3", "")); 5250 assertEquals(0, rt_40546_count); 5251 } 5252 5253 @Test public void test_jdk_8144681_removeColumn() { 5254 TableView<Book> table = new TableView<>(); 5255 Book books[] = { 5256 new Book("Book 1", "Author 1", "Remark 1") 5257 , new Book("Book 2", "Author 2", "Remark 2") 5258 , new Book("Book 3", "Author 3", "Remark 3") 5259 , new Book("Book 4", "Author 4", "Remark 4") 5260 }; 5261 table.setItems(FXCollections.observableArrayList()); 5262 table.getItems().addAll(books); 5263 5264 String[] columns = { "title", "author", "remark" }; 5265 for (String prop : columns) { 5266 TableColumn<Book, String> col = new TableColumn<>(prop); 5267 col.setCellValueFactory(new PropertyValueFactory<>(prop)); 5268 table.getColumns().add(col); 5269 } 5270 table.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY); 5271 table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 5272 table.getSelectionModel().setCellSelectionEnabled(true); 5273 5274 table.getSelectionModel().selectAll(); 5275 5276 ControlTestUtils.runWithExceptionHandler(() -> table.getColumns().remove(2)); 5277 } 5278 5279 @Test public void test_jdk_8144681_moveColumn() { 5280 TableView<Book> table = new TableView<>(); 5281 Book books[] = { 5282 new Book("Book 1", "Author 1", "Remark 1") 5283 , new Book("Book 2", "Author 2", "Remark 2") 5284 , new Book("Book 3", "Author 3", "Remark 3") 5285 , new Book("Book 4", "Author 4", "Remark 4") 5286 }; 5287 table.setItems(FXCollections.observableArrayList()); 5288 table.getItems().addAll(books); 5289 5290 String[] columns = { "title", "author", "remark" }; 5291 for (String prop : columns) { 5292 TableColumn<Book, String> col = new TableColumn<>(prop); 5293 col.setCellValueFactory(new PropertyValueFactory<>(prop)); 5294 table.getColumns().add(col); 5295 } 5296 table.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY); 5297 table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 5298 table.getSelectionModel().setCellSelectionEnabled(true); 5299 5300 table.getSelectionModel().selectAll(); 5301 5302 ControlTestUtils.runWithExceptionHandler(() -> { 5303 table.getColumns().setAll(table.getColumns().get(0), table.getColumns().get(2), table.getColumns().get(1)); 5304 }); 5305 } 5306 5307 public static class Book { 5308 private SimpleStringProperty title = new SimpleStringProperty(); 5309 private SimpleStringProperty author = new SimpleStringProperty(); 5310 private SimpleStringProperty remark = new SimpleStringProperty(); 5311 5312 public Book(String title, String author, String remark) { 5313 super(); 5314 setTitle(title); 5315 setAuthor(author); 5316 setRemark(remark); 5317 } 5318 5319 public SimpleStringProperty titleProperty() { 5320 return this.title; 5321 } 5322 5323 public java.lang.String getTitle() { 5324 return this.titleProperty().get(); 5325 } 5326 5327 public void setTitle(final java.lang.String title) { 5328 this.titleProperty().set(title); 5329 } 5330 5331 public SimpleStringProperty authorProperty() { 5332 return this.author; 5333 } 5334 5335 public java.lang.String getAuthor() { 5336 return this.authorProperty().get(); 5337 } 5338 5339 public void setAuthor(final java.lang.String author) { 5340 this.authorProperty().set(author); 5341 } 5342 5343 public SimpleStringProperty remarkProperty() { 5344 return this.remark; 5345 } 5346 5347 public java.lang.String getRemark() { 5348 return this.remarkProperty().get(); 5349 } 5350 5351 public void setRemark(final java.lang.String remark) { 5352 this.remarkProperty().set(remark); 5353 } 5354 5355 @Override 5356 public String toString() { 5357 return String.format("%s(%s) - %s", getTitle(), getAuthor(), getRemark()); 5358 } 5359 } 5360 }