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