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