1 /* 2 * Copyright (c) 2011, 2019, 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 test.com.sun.javafx.scene.control.infrastructure.KeyModifier; 29 import test.com.sun.javafx.scene.control.infrastructure.MouseEventFirer; 30 import com.sun.javafx.tk.Toolkit; 31 import javafx.css.PseudoClass; 32 33 import test.com.sun.javafx.scene.control.infrastructure.KeyEventFirer; 34 import test.com.sun.javafx.scene.control.infrastructure.StageLoader; 35 import javafx.scene.control.skin.ComboBoxListViewSkin; 36 37 import static test.com.sun.javafx.scene.control.infrastructure.ControlTestUtils.assertStyleClassContains; 38 import static org.junit.Assert.*; 39 import static org.junit.Assert.assertEquals; 40 41 import java.util.*; 42 import java.util.concurrent.atomic.AtomicInteger; 43 44 import javafx.beans.property.ObjectProperty; 45 import javafx.beans.property.SimpleObjectProperty; 46 import javafx.beans.property.SimpleStringProperty; 47 import javafx.beans.property.StringProperty; 48 import javafx.collections.FXCollections; 49 import javafx.collections.ObservableList; 50 import javafx.event.ActionEvent; 51 import javafx.event.EventHandler; 52 import javafx.scene.Node; 53 import javafx.scene.Scene; 54 import javafx.scene.control.Button; 55 import javafx.scene.control.ComboBox; 56 import javafx.scene.control.ComboBoxShim; 57 import javafx.scene.control.IndexedCell; 58 import javafx.scene.control.Label; 59 import javafx.scene.control.ListCell; 60 import javafx.scene.control.ListCellShim; 61 import javafx.scene.control.ListView; 62 import javafx.scene.control.SelectionModel; 63 import javafx.scene.control.SelectionModelShim; 64 import javafx.scene.control.SingleSelectionModel; 65 import javafx.scene.control.Tab; 66 import javafx.scene.control.TabPane; 67 import javafx.scene.control.TextField; 68 import javafx.scene.control.Tooltip; 69 import javafx.scene.control.skin.VirtualFlow; 70 import javafx.scene.input.KeyCode; 71 import javafx.scene.layout.BorderPane; 72 import javafx.scene.layout.FlowPane; 73 import javafx.scene.layout.VBox; 74 import javafx.scene.paint.Color; 75 import javafx.scene.shape.Circle; 76 import javafx.stage.Stage; 77 import javafx.util.Callback; 78 import javafx.util.StringConverter; 79 80 import org.junit.After; 81 import org.junit.Before; 82 import org.junit.Ignore; 83 import org.junit.Test; 84 85 public class ComboBoxTest { 86 private ComboBox<String> comboBox; 87 private SingleSelectionModel<String> sm; 88 89 /********************************************************************* 90 * * 91 * Utility methods * 92 * * 93 ********************************************************************/ 94 95 public ListView getListView() { 96 return (ListView) ((ComboBoxListViewSkin)comboBox.getSkin()).getPopupContent(); 97 } 98 99 public Node getDisplayNode() { 100 return ((ComboBoxListViewSkin)comboBox.getSkin()).getDisplayNode(); 101 } 102 103 104 105 /********************************************************************* 106 * * 107 * Setup * 108 * * 109 ********************************************************************/ 110 111 @Before public void setup() { 112 Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> { 113 if (throwable instanceof RuntimeException) { 114 throw (RuntimeException)throwable; 115 } else { 116 Thread.currentThread().getThreadGroup().uncaughtException(thread, throwable); 117 } 118 }); 119 120 comboBox = new ComboBox<String>(); 121 comboBox.setSkin(new ComboBoxListViewSkin<>(comboBox)); 122 sm = comboBox.getSelectionModel(); 123 } 124 125 @After public void cleanup() { 126 Thread.currentThread().setUncaughtExceptionHandler(null); 127 } 128 129 /********************************************************************* 130 * * 131 * Tests for the constructors * 132 * * 133 ********************************************************************/ 134 135 @Test public void noArgConstructorSetsTheStyleClass() { 136 assertStyleClassContains(comboBox, "combo-box"); 137 } 138 139 @Test public void noArgConstructorSetsNonNullSelectionModel() { 140 assertNotNull(sm); 141 } 142 143 @Test public void noArgConstructorSetsNonNullItems() { 144 assertNotNull(comboBox.getItems()); 145 } 146 147 @Test public void noArgConstructor_selectedItemIsNull() { 148 assertNull(sm.getSelectedItem()); 149 } 150 151 @Test public void noArgConstructor_selectedIndexIsNegativeOne() { 152 assertEquals(-1, sm.getSelectedIndex()); 153 } 154 155 @Test public void noArgConstructor_valueIsNull() { 156 assertNull(comboBox.getValue()); 157 } 158 159 @Test public void noArgConstructor_editableIsFalse() { 160 assertFalse(comboBox.isEditable()); 161 } 162 163 @Test public void noArgConstructor_showingIsFalse() { 164 assertFalse(comboBox.isShowing()); 165 } 166 167 @Test public void noArgConstructor_promptTextIsEmptyString() { 168 assertNull(comboBox.getPromptText()); 169 } 170 171 @Test public void noArgConstructor_placeholderIsNull() { 172 assertNull(comboBox.getPlaceholder()); 173 } 174 175 @Test public void noArgConstructor_armedIsFalse() { 176 assertFalse(comboBox.isArmed()); 177 } 178 179 @Test public void noArgConstructor_converterIsNotNull() { 180 assertNotNull(comboBox.getConverter()); 181 } 182 183 @Test public void noArgConstructor_cellFactoryIsNull() { 184 assertNull(comboBox.getCellFactory()); 185 } 186 187 @Test public void noArgConstructor_visibleRowFactoryIs10() { 188 assertEquals(10, comboBox.getVisibleRowCount()); 189 } 190 191 @Test public void singleArgConstructorSetsTheStyleClass() { 192 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 193 assertStyleClassContains(b2, "combo-box"); 194 } 195 196 @Test public void singleArgConstructorSetsNonNullSelectionModel() { 197 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 198 assertNotNull(b2.getSelectionModel()); 199 } 200 201 @Test public void singleArgConstructorAllowsNullItems() { 202 final ComboBox<String> b2 = new ComboBox<String>(null); 203 assertNull(b2.getItems()); 204 } 205 206 @Test public void singleArgConstructorTakesItems() { 207 ObservableList<String> items = FXCollections.observableArrayList("Hi"); 208 final ComboBox<String> b2 = new ComboBox<String>(items); 209 assertSame(items, b2.getItems()); 210 } 211 212 @Test public void singleArgConstructor_selectedItemIsNull() { 213 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 214 assertNull(b2.getSelectionModel().getSelectedItem()); 215 } 216 217 @Test public void singleArgConstructor_selectedIndexIsNegativeOne() { 218 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 219 assertEquals(-1, b2.getSelectionModel().getSelectedIndex()); 220 } 221 222 @Test public void singleArgConstructor_valueIsNull() { 223 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 224 assertNull(b2.getValue()); 225 } 226 227 @Test public void singleArgConstructor_editableIsFalse() { 228 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 229 assertFalse(b2.isEditable()); 230 } 231 232 @Test public void singleArgConstructor_showingIsFalse() { 233 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 234 assertFalse(b2.isShowing()); 235 } 236 237 @Test public void singleArgConstructor_promptTextIsEmptyString() { 238 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 239 assertNull(b2.getPromptText()); 240 } 241 242 @Test public void singleArgConstructor_placeholderIsNull() { 243 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 244 assertNull(b2.getPlaceholder()); 245 } 246 247 @Test public void singleArgConstructor_armedIsFalse() { 248 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 249 assertEquals(false, b2.isArmed()); 250 } 251 252 @Test public void singleArgConstructor_converterIsNotNull() { 253 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 254 assertNotNull(b2.getConverter()); 255 } 256 257 @Test public void singleArgConstructor_cellFactoryIsNull() { 258 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 259 assertNull(b2.getCellFactory()); 260 } 261 262 @Test public void singleArgConstructor_visibleRowFactoryIs10() { 263 final ComboBox<String> b2 = new ComboBox<String>(FXCollections.observableArrayList("Hi")); 264 assertEquals(10, b2.getVisibleRowCount()); 265 } 266 267 /********************************************************************* 268 * Tests for selection model * 269 ********************************************************************/ 270 271 @Test public void selectionModelCanBeNull() { 272 comboBox.setSelectionModel(null); 273 assertNull(comboBox.getSelectionModel()); 274 } 275 276 @Test public void selectionModelCanBeBound() { 277 SingleSelectionModel<String> sm = ComboBoxShim.<String>get_ComboBoxSelectionModel(comboBox); 278 ObjectProperty<SingleSelectionModel<String>> other = new SimpleObjectProperty<SingleSelectionModel<String>>(sm); 279 comboBox.selectionModelProperty().bind(other); 280 assertSame(sm, sm); 281 } 282 283 @Test public void selectionModelCanBeChanged() { 284 SingleSelectionModel<String> sm = ComboBoxShim.<String>get_ComboBoxSelectionModel(comboBox); 285 comboBox.setSelectionModel(sm); 286 assertSame(sm, sm); 287 } 288 289 @Test public void canSetSelectedItemToAnItemEvenWhenThereAreNoItems() { 290 final String randomString = new String("I AM A CRAZY RANDOM STRING"); 291 sm.select(randomString); 292 assertEquals(-1, sm.getSelectedIndex()); 293 assertSame(randomString, sm.getSelectedItem()); 294 } 295 296 @Test public void canSetSelectedItemToAnItemNotInTheDataModel() { 297 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 298 final String randomString = new String("I AM A CRAZY RANDOM STRING"); 299 sm.select(randomString); 300 assertEquals(-1, sm.getSelectedIndex()); 301 assertSame(randomString, sm.getSelectedItem()); 302 } 303 304 @Test public void settingTheSelectedItemToAnItemInItemsResultsInTheCorrectSelectedIndex() { 305 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 306 sm.select("Orange"); 307 assertEquals(1, sm.getSelectedIndex()); 308 assertSame("Orange", sm.getSelectedItem()); 309 } 310 311 @Test public void settingTheSelectedItemToANonexistantItemAndThenSettingItemsWhichContainsItResultsInCorrectSelectedIndex() { 312 sm.select("Orange"); 313 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 314 assertEquals(1, sm.getSelectedIndex()); 315 assertSame("Orange", sm.getSelectedItem()); 316 } 317 318 @Test public void ensureSelectionClearsWhenAllItemsAreRemoved_selectIndex0() { 319 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 320 sm.select(0); 321 comboBox.getItems().clear(); 322 assertEquals(-1, sm.getSelectedIndex()); 323 assertEquals(null, sm.getSelectedItem()); 324 } 325 326 @Test public void ensureSelectionClearsWhenAllItemsAreRemoved_selectIndex2() { 327 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 328 sm.select(2); 329 comboBox.getItems().clear(); 330 assertEquals(-1, sm.getSelectedIndex()); 331 assertEquals(null, sm.getSelectedItem()); 332 } 333 334 @Test public void ensureSelectedItemRemainsAccurateWhenItemsAreCleared() { 335 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 336 sm.select(2); 337 comboBox.getItems().clear(); 338 assertNull(sm.getSelectedItem()); 339 assertEquals(-1, sm.getSelectedIndex()); 340 341 comboBox.getItems().addAll("Kiwifruit", "Mandarin", "Pineapple"); 342 sm.select(2); 343 assertEquals("Pineapple", sm.getSelectedItem()); 344 } 345 346 @Test public void ensureSelectionShiftsDownWhenOneNewItemIsAdded() { 347 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 348 sm.select(1); 349 assertEquals(1, sm.getSelectedIndex()); 350 assertEquals("Orange", sm.getSelectedItem()); 351 352 comboBox.getItems().add(0, "Kiwifruit"); 353 assertEquals(2, sm.getSelectedIndex()); 354 assertEquals("Orange", sm.getSelectedItem()); 355 } 356 357 @Test public void ensureSelectionShiftsDownWhenMultipleNewItemAreAdded() { 358 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 359 sm.select(1); 360 assertEquals(1, sm.getSelectedIndex()); 361 assertEquals("Orange", sm.getSelectedItem()); 362 363 comboBox.getItems().addAll(0, Arrays.asList("Kiwifruit", "Pineapple", "Mandarin")); 364 assertEquals("Orange", sm.getSelectedItem()); 365 assertEquals(4, sm.getSelectedIndex()); 366 } 367 368 @Test public void ensureSelectionShiftsUpWhenOneItemIsRemoved() { 369 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 370 sm.select(1); 371 assertEquals(1, sm.getSelectedIndex()); 372 assertEquals("Orange", sm.getSelectedItem()); 373 374 comboBox.getItems().remove("Apple"); 375 assertEquals(0, sm.getSelectedIndex()); 376 assertEquals("Orange", sm.getSelectedItem()); 377 } 378 379 @Test public void ensureSelectionShiftsUpWheMultipleItemsAreRemoved() { 380 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 381 sm.select(2); 382 assertEquals(2, sm.getSelectedIndex()); 383 assertEquals("Banana", sm.getSelectedItem()); 384 385 comboBox.getItems().removeAll(Arrays.asList("Apple", "Orange")); 386 assertEquals(0, sm.getSelectedIndex()); 387 assertEquals("Banana", sm.getSelectedItem()); 388 } 389 390 @Test public void ensureSelectionIsCorrectWhenItemsChange() { 391 comboBox.setItems(FXCollections.observableArrayList("Item 1")); 392 sm.select(0); 393 assertEquals("Item 1", sm.getSelectedItem()); 394 395 comboBox.setItems(FXCollections.observableArrayList("Item 2")); 396 assertEquals(-1, sm.getSelectedIndex()); 397 assertEquals(null, sm.getSelectedItem()); 398 } 399 400 @Test(expected=NullPointerException.class) 401 public void selectionModelComboBoxReferenceCanNotBeNull() { 402 ComboBoxShim.<String>get_ComboBoxSelectionModel(null); 403 } 404 405 @Test public void ensureGetModelItemOutOfBoundsWorks_1() { 406 ComboBox cb = new ComboBox(null); 407 cb.getSelectionModel().select(-1); 408 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 409 } 410 411 @Test public void ensureGetModelItemOutOfBoundsWorks_2() { 412 ComboBox cb = new ComboBox(null); 413 cb.getSelectionModel().select(0); 414 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 415 } 416 417 @Test public void test_rt15793() { 418 // ComboBox selectedIndex is 0 although the items list is empty 419 final ComboBox lv = new ComboBox(); 420 final ObservableList list = FXCollections.observableArrayList(); 421 lv.setItems(list); 422 list.add("toto"); 423 lv.getSelectionModel().select(0); 424 assertEquals(0, lv.getSelectionModel().getSelectedIndex()); 425 list.remove(0); 426 assertEquals(-1, lv.getSelectionModel().getSelectedIndex()); 427 } 428 429 @Test public void ensureSelectionModelUpdatesValueProperty_withSelectIndex() { 430 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 431 assertNull(comboBox.getValue()); 432 sm.select(0); 433 assertEquals("Apple", comboBox.getValue()); 434 } 435 436 @Test public void ensureSelectionModelUpdatesValueProperty_withSelectItem() { 437 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 438 assertNull(comboBox.getValue()); 439 sm.select("Apple"); 440 assertEquals("Apple", comboBox.getValue()); 441 } 442 443 @Test public void ensureSelectionModelUpdatesValueProperty_withSelectPrevious() { 444 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 445 assertNull(comboBox.getValue()); 446 sm.select(2); 447 sm.selectPrevious(); 448 assertEquals("Orange", comboBox.getValue()); 449 } 450 451 @Test public void ensureSelectionModelUpdatesValueProperty_withSelectNext() { 452 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 453 assertNull(comboBox.getValue()); 454 sm.select("Apple"); 455 sm.selectNext(); 456 assertEquals("Orange", comboBox.getValue()); 457 } 458 459 @Test public void ensureSelectionModelUpdatesValueProperty_withSelectFirst() { 460 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 461 assertNull(comboBox.getValue()); 462 sm.selectFirst(); 463 assertEquals("Apple", comboBox.getValue()); 464 } 465 466 @Test public void ensureSelectionModelUpdatesValueProperty_withSelectLast() { 467 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 468 assertNull(comboBox.getValue()); 469 sm.selectLast(); 470 assertEquals("Banana", comboBox.getValue()); 471 } 472 473 @Test public void ensureSelectionModelClearsValueProperty() { 474 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 475 assertNull(comboBox.getValue()); 476 sm.select(0); 477 assertEquals("Apple", comboBox.getValue()); 478 479 sm.clearSelection(); 480 assertNull(comboBox.getValue()); 481 } 482 483 @Test public void ensureSelectionModelClearsValuePropertyWhenNegativeOneSelected() { 484 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 485 assertNull(comboBox.getValue()); 486 sm.select(0); 487 assertEquals("Apple", comboBox.getValue()); 488 489 sm.select(-1); 490 assertNull("Expected null, actual value: " + comboBox.getValue(), comboBox.getValue()); 491 } 492 493 @Test public void ensureValueIsCorrectWhenItemsIsAddedToWithExistingSelection() { 494 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 495 sm.select(1); 496 497 comboBox.getItems().add(0, "Kiwifruit"); 498 499 assertEquals(2, sm.getSelectedIndex()); 500 assertEquals("Orange", sm.getSelectedItem()); 501 assertEquals("Orange", comboBox.getValue()); 502 } 503 504 @Test public void ensureValueIsCorrectWhenItemsAreRemovedWithExistingSelection() { 505 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 506 sm.select(1); 507 508 comboBox.getItems().remove("Apple"); 509 510 assertEquals(0, sm.getSelectedIndex()); 511 assertEquals("Orange", sm.getSelectedItem()); 512 assertEquals("Orange", comboBox.getValue()); 513 } 514 515 @Test public void ensureValueIsUpdatedByCorrectSelectionModelWhenSelectionModelIsChanged() { 516 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 517 SingleSelectionModel sm1 = sm; 518 sm1.select(1); 519 assertEquals("Orange", comboBox.getValue()); 520 521 SingleSelectionModel sm2 = ComboBoxShim.<String>get_ComboBoxSelectionModel(comboBox); 522 comboBox.setSelectionModel(sm2); 523 524 sm1.select(2); // value should not change as we are using old SM 525 assertEquals("Orange", comboBox.getValue()); 526 527 sm2.select(0); // value should change, as we are using new SM 528 assertEquals("Apple", comboBox.getValue()); 529 } 530 531 @Test public void ensureValueDoesNotChangeWhenBoundAndNoExceptions() { 532 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 533 534 StringProperty sp = new SimpleStringProperty("empty"); 535 comboBox.valueProperty().bind(sp); 536 537 sm.select(1); 538 assertEquals("empty", comboBox.getValue()); 539 } 540 541 @Test public void ensureSelectionModelUpdatesWhenValueChanges() { 542 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 543 assertNull(sm.getSelectedItem()); 544 comboBox.setValue("Orange"); 545 assertEquals("Orange", sm.getSelectedItem()); 546 } 547 548 @Test public void ensureSelectionModelUpdatesWhenValueChangesToNull() { 549 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 550 comboBox.setValue("Kiwifruit"); 551 assertEquals("Kiwifruit", sm.getSelectedItem()); 552 assertEquals("Kiwifruit", comboBox.getValue()); 553 comboBox.setValue(null); 554 assertEquals(null, sm.getSelectedItem()); 555 assertEquals(-1, sm.getSelectedIndex()); 556 assertEquals(null, comboBox.getValue()); 557 } 558 559 @Test public void ensureValueEqualsSelectedItemWhenNotInItemsList() { 560 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 561 SelectionModelShim.setSelectedItem(sm, "pineapple"); 562 assertEquals("pineapple", sm.getSelectedItem()); 563 assertEquals("pineapple", comboBox.getValue()); 564 } 565 566 /********************************************************************* 567 * Tests for default values * 568 ********************************************************************/ 569 570 @Test public void checkPromptTextPropertyName() { 571 assertTrue(comboBox.promptTextProperty().getName().equals("promptText")); 572 } 573 574 @Test public void checkPlaceholderPropertyName() { 575 assertTrue(comboBox.placeholderProperty().getName().equals("placeholder")); 576 } 577 578 @Test public void checkValuePropertyName() { 579 assertTrue(comboBox.valueProperty().getName().equals("value")); 580 } 581 582 @Test public void checkItemsPropertyName() { 583 assertTrue(comboBox.itemsProperty().getName().equals("items")); 584 } 585 586 @Test public void checkConverterPropertyName() { 587 assertTrue(comboBox.converterProperty().getName().equals("converter")); 588 } 589 590 @Test public void checkSelectionModelPropertyName() { 591 assertTrue(comboBox.selectionModelProperty().getName().equals("selectionModel")); 592 } 593 594 @Test public void checkVisibleRowCountPropertyName() { 595 assertTrue(comboBox.visibleRowCountProperty().getName().equals("visibleRowCount")); 596 } 597 598 @Test public void checkOnActionPropertyName() { 599 assertTrue(comboBox.onActionProperty().getName().equals("onAction")); 600 } 601 602 @Test public void checkArmedPropertyName() { 603 assertTrue(comboBox.armedProperty().getName().equals("armed")); 604 } 605 606 @Test public void checkShowingPropertyName() { 607 assertTrue(comboBox.showingProperty().getName().equals("showing")); 608 } 609 610 @Test public void checkEditablePropertyName() { 611 assertTrue(comboBox.editableProperty().getName().equals("editable")); 612 } 613 614 @Test public void checkCellFactoryPropertyName() { 615 assertTrue(comboBox.cellFactoryProperty().getName().equals("cellFactory")); 616 } 617 618 @Test public void defaultActionHandlerIsNotDefined() { 619 assertNull(comboBox.getOnAction()); 620 } 621 622 @Test public void defaultConverterCanHandleStringValues() { 623 StringConverter<String> sc = comboBox.getConverter(); 624 assertEquals("input", sc.fromString("input")); 625 assertEquals("input", sc.toString("input")); 626 } 627 628 @Test public void defaultConverterCanHandleIncorrectType_1() { 629 ComboBox cb = new ComboBox(); 630 StringConverter sc = cb.getConverter(); 631 assertEquals("42", sc.toString(new Integer(42))); 632 } 633 634 @Test(expected=ClassCastException.class) 635 public void defaultConverterCanHandleIncorrectType_2() { 636 ComboBox<Integer> cb = new ComboBox<Integer>(); 637 StringConverter<Integer> sc = cb.getConverter(); 638 Integer value = sc.fromString("42"); 639 } 640 641 @Test public void defaultConverterCanHandleNullValues() { 642 StringConverter<String> sc = comboBox.getConverter(); 643 assertEquals(null, sc.fromString(null)); 644 assertEquals(null, sc.toString(null)); 645 } 646 647 @Test public void ensureImpl_getPseudoClassStateReturnsValidValue() { 648 Stage stage = new Stage(); 649 Scene scene = new Scene(comboBox); 650 stage.setScene(scene); 651 652 Set<PseudoClass> pseudoClassStates = comboBox.getPseudoClassStates(); 653 assertFalse(comboBox.isEditable()); 654 assertTrue(pseudoClassStates.size() >= 0); 655 656 comboBox.setEditable(true); 657 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("editable"))); 658 659 comboBox.setEditable(false); 660 assertFalse(pseudoClassStates.contains(PseudoClass.getPseudoClass("editable"))); 661 662 comboBox.show(); 663 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("showing"))); 664 665 comboBox.hide(); 666 assertFalse(pseudoClassStates.contains(PseudoClass.getPseudoClass("showing"))); 667 668 comboBox.arm(); 669 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("armed"))); 670 671 } 672 673 /********************************************************************* 674 * Tests for properties * 675 ********************************************************************/ 676 677 @Test public void ensureAllowsNullConverter() { 678 comboBox.setConverter(null); 679 assertNull(comboBox.getConverter()); 680 } 681 682 @Test public void ensureCanSetNonNullCellFactory() { 683 Callback<ListView<String>, ListCell<String>> cf = p -> null; 684 comboBox.setCellFactory(cf); 685 assertEquals(cf, comboBox.getCellFactory()); 686 } 687 688 @Test public void ensureEditorIsNonNullWhenComboBoxIsNotEditable() { 689 assertNotNull(comboBox.getEditor()); 690 } 691 692 @Test public void ensureEditorIsNonNullWhenComboBoxIsEditable() { 693 comboBox.setEditable(true); 694 assertNotNull(comboBox.getEditor()); 695 } 696 697 @Test public void ensureEditorDoesNotChangeWhenEditableToggles() { 698 comboBox.setEditable(true); 699 assertNotNull(comboBox.getEditor()); 700 comboBox.setEditable(false); 701 assertNotNull(comboBox.getEditor()); 702 comboBox.setEditable(true); 703 assertNotNull(comboBox.getEditor()); 704 } 705 706 @Test public void ensureCanSetValueToNonNullStringAndBackAgain() { 707 comboBox.setValue("Test 123"); 708 assertEquals("Test 123", comboBox.getValue()); 709 comboBox.setValue(null); 710 assertNull(comboBox.getValue()); 711 } 712 713 @Test public void ensureCanToggleEditable() { 714 comboBox.setEditable(true); 715 assertTrue(comboBox.isEditable()); 716 comboBox.setEditable(false); 717 assertFalse(comboBox.isEditable()); 718 } 719 720 @Test public void ensureCanToggleShowing() { 721 Stage stage = new Stage(); 722 Scene scene = new Scene(comboBox); 723 stage.setScene(scene); 724 725 comboBox.show(); 726 assertTrue(comboBox.isShowing()); 727 comboBox.hide(); 728 assertFalse(comboBox.isShowing()); 729 } 730 731 @Test public void ensureCanNotToggleShowingWhenDisabled() { 732 Stage stage = new Stage(); 733 Scene scene = new Scene(comboBox); 734 stage.setScene(scene); 735 736 comboBox.setDisable(true); 737 comboBox.show(); 738 assertFalse(comboBox.isShowing()); 739 comboBox.setDisable(false); 740 comboBox.show(); 741 assertTrue(comboBox.isShowing()); 742 } 743 744 @Test public void ensureCanSetPromptText() { 745 comboBox.setPromptText("Test 1 2 3"); 746 assertEquals("Test 1 2 3", comboBox.getPromptText()); 747 } 748 749 @Test public void ensureCanSetPromptTextToNull() { 750 comboBox.setPromptText(""); 751 assertEquals("", comboBox.getPromptText()); 752 comboBox.setPromptText(null); 753 assertEquals(null, comboBox.getPromptText()); 754 } 755 756 @Test public void ensurePromptTextStripsNewlines() { 757 comboBox.setPromptText("Test\n1\n2\n3"); 758 assertEquals("Test123", comboBox.getPromptText()); 759 } 760 761 @Test public void ensureCanSetPlaceholder() { 762 Label label = new javafx.scene.control.Label("Test 1 2 3"); 763 comboBox.setPlaceholder(label); 764 assertEquals(label, comboBox.getPlaceholder()); 765 } 766 767 @Test public void ensureCanToggleArmed() { 768 assertFalse(comboBox.isArmed()); 769 comboBox.arm(); 770 assertTrue(comboBox.isArmed()); 771 comboBox.disarm(); 772 assertFalse(comboBox.isArmed()); 773 } 774 775 @Test public void ensureCanSetVisibleRowCount() { 776 comboBox.setVisibleRowCount(13); 777 assertEquals(13, comboBox.getVisibleRowCount()); 778 } 779 780 @Test public void ensureCanSetVisibleRowCountToNegativeValues() { 781 comboBox.setVisibleRowCount(-10); 782 assertEquals(-10, comboBox.getVisibleRowCount()); 783 } 784 785 @Test public void ensureCanSetOnAction() { 786 EventHandler<ActionEvent> onAction = t -> { }; 787 comboBox.setOnAction(onAction); 788 assertEquals(onAction, comboBox.getOnAction()); 789 } 790 791 @Test public void ensureOnActionPropertyReferencesBean() { 792 assertEquals(comboBox, comboBox.onActionProperty().getBean()); 793 } 794 795 /********************************************************************* 796 * Tests for property binding * 797 ********************************************************************/ 798 @Test public void checkPromptTextPropertyBind() { 799 StringProperty strPr = new SimpleStringProperty("value"); 800 comboBox.promptTextProperty().bind(strPr); 801 assertTrue("PromptText cannot be bound", comboBox.getPromptText().equals("value")); 802 strPr.setValue("newvalue"); 803 assertTrue("PromptText cannot be bound", comboBox.getPromptText().equals("newvalue")); 804 } 805 806 @Test public void checkValuePropertyBind() { 807 StringProperty strPr = new SimpleStringProperty("value"); 808 comboBox.valueProperty().bind(strPr); 809 assertTrue("value cannot be bound", comboBox.getValue().equals("value")); 810 strPr.setValue("newvalue"); 811 assertTrue("value cannot be bound", comboBox.getValue().equals("newvalue")); 812 } 813 814 815 816 /********************************************************************* 817 * Tests for bug reports * 818 ********************************************************************/ 819 820 @Test public void test_rt18972() { 821 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 822 sm.select(1); 823 assertTrue(sm.isSelected(1)); 824 825 comboBox.setEditable(true); 826 comboBox.setValue("New Value"); 827 828 // there should be no selection in the selection model, as "New Value" 829 // isn't an item in the list, however, it is a totally valid value for 830 // the value property 831 assertFalse(sm.isSelected(1)); 832 assertEquals("New Value", sm.getSelectedItem()); 833 assertEquals("New Value", comboBox.getValue()); 834 835 comboBox.setEditable(false); 836 assertEquals(-1, sm.getSelectedIndex()); 837 assertEquals("New Value", sm.getSelectedItem()); 838 assertEquals("New Value", comboBox.getValue()); 839 } 840 841 @Test public void test_rt18941() { 842 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 843 comboBox.setValue("Orange"); 844 assertEquals("Orange", comboBox.getValue()); 845 assertEquals("Orange", comboBox.getSelectionModel().getSelectedItem()); 846 assertTrue("Selected Index: " + sm.getSelectedIndex(), sm.isSelected(1)); 847 } 848 849 @Test public void test_rt19227() { 850 comboBox.getItems().addAll("0","0","0","0","0"); 851 comboBox.getSelectionModel().select(2); 852 assertEquals("0", comboBox.getValue()); 853 assertEquals("0", comboBox.getSelectionModel().getSelectedItem()); 854 assertTrue(sm.isSelected(2)); 855 } 856 857 @Ignore("JDK-8091127 Test not working as the heights being returned are not accurate") 858 @Test public void test_rt20106() { 859 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 860 861 Stage stage = new Stage(); 862 Scene scene = new Scene(comboBox); 863 stage.setScene(scene); 864 comboBox.applyCss(); 865 comboBox.show(); 866 867 comboBox.setVisibleRowCount(5); 868 double initialHeight = getListView().getHeight(); 869 assertFalse("initialHeight: " + initialHeight, Double.compare(0.0, initialHeight) == 0); 870 871 comboBox.setVisibleRowCount(0); 872 double smallHeight = getListView().getHeight(); 873 assertTrue("smallHeight: " + smallHeight + ", initialHeight: " + initialHeight, 874 smallHeight != initialHeight && smallHeight < initialHeight); 875 876 comboBox.setVisibleRowCount(7); 877 double biggerHeight = getListView().getHeight(); 878 assertTrue(biggerHeight != smallHeight && smallHeight < biggerHeight); 879 } 880 881 private int count = 0; 882 @Test public void test_rt20103() { 883 final TextField tf = new TextField(); 884 885 comboBox.setOnAction(t -> { 886 count++; 887 }); 888 889 assertTrue(count == 0); 890 891 comboBox.valueProperty().bind(tf.textProperty()); // count++ here 892 assertTrue("count: " + count, count == 1); 893 894 tf.setText("Text1"); // count++ here 895 assertTrue("count: " + count, count == 2); 896 897 comboBox.valueProperty().unbind(); // no count++ here 898 assertTrue("count: " + count, count == 2); 899 900 comboBox.valueProperty().bindBidirectional(tf.textProperty()); // count++ here 901 tf.setText("Text2"); 902 assertTrue("count: " + count, count == 3); 903 } 904 905 @Ignore("Test not working as the skin is not being properly instantiated") 906 @Test public void test_rt20100() { 907 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 908 909 Stage stage = new Stage(); 910 Scene scene = new Scene(comboBox); 911 stage.setScene(scene); 912 comboBox.applyCss(); 913 comboBox.show(); 914 915 comboBox.setConverter(new StringConverter() { 916 int toStringCounter = 0; 917 int fromStringCounter = 0; 918 919 @Override public String toString(Object t) { 920 return "TO_STRING"; 921 } 922 923 @Override public Object fromString(String string) { 924 return "FROM_STRING"; 925 } 926 }); 927 928 comboBox.getSelectionModel().select(2); 929 assertEquals("2", comboBox.getValue()); 930 931 ListView listView = getListView(); 932 // listView.applyCss(); 933 934 assertEquals("2", listView.getSelectionModel().getSelectedItem()); 935 936 System.out.println(listView.getSkin()); 937 938 VirtualFlow flow = (VirtualFlow)listView.lookup("#virtual-flow"); 939 assertNotNull(flow); 940 941 IndexedCell cell = flow.getVisibleCell(2); 942 System.out.println("cell: " + cell); 943 assertEquals("TO_STRING", cell.getText()); 944 } 945 946 @Test public void test_rt20189() { 947 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 948 949 Stage stage = new Stage(); 950 Scene scene = new Scene(comboBox); 951 stage.setScene(scene); 952 comboBox.applyCss(); 953 comboBox.show(); 954 955 comboBox.getSelectionModel().select(2); 956 Object item = sm.getSelectedItem(); 957 assertEquals("2", item); 958 assertEquals(2, sm.getSelectedIndex()); 959 960 comboBox.setValue("test"); 961 item = sm.getSelectedItem(); 962 assertEquals("test",item); 963 assertEquals(-1, sm.getSelectedIndex()); 964 965 comboBox.getSelectionModel().select(2); 966 item = sm.getSelectedItem(); 967 assertEquals("2", item); 968 assertEquals(2, sm.getSelectedIndex()); 969 } 970 971 @Test public void test_rt27654() { 972 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 973 974 SingleSelectionModel sm = comboBox.getSelectionModel(); 975 976 Stage stage = new Stage(); 977 Scene scene = new Scene(comboBox); 978 stage.setScene(scene); 979 comboBox.applyCss(); 980 comboBox.show(); 981 ListCell<String> buttonCell = (ListCell<String>) getDisplayNode(); 982 983 sm.select(2); 984 assertEquals("2", sm.getSelectedItem()); 985 assertEquals("2", comboBox.getValue()); 986 assertEquals("2", buttonCell.getText()); 987 assertEquals(2, sm.getSelectedIndex()); 988 989 sm.clearSelection(); 990 assertNull(sm.getSelectedItem()); 991 assertNull(comboBox.getValue()); 992 assertNull(buttonCell.getText()); 993 assertEquals(-1, sm.getSelectedIndex()); 994 995 sm.select(2); 996 assertEquals("2", sm.getSelectedItem()); 997 assertEquals("2", comboBox.getValue()); 998 assertEquals("2", buttonCell.getText()); 999 assertEquals(2, sm.getSelectedIndex()); 1000 } 1001 1002 @Test public void test_rt24412() { 1003 SingleSelectionModel sm = comboBox.getSelectionModel(); 1004 1005 Stage stage = new Stage(); 1006 Scene scene = new Scene(comboBox); 1007 stage.setScene(scene); 1008 comboBox.applyCss(); 1009 comboBox.show(); 1010 ListCell<String> buttonCell = (ListCell<String>) getDisplayNode(); 1011 1012 comboBox.getItems().setAll("0","1","2","3","4","5","6","7","8","9"); 1013 1014 sm.select("2"); 1015 assertEquals("2", sm.getSelectedItem()); 1016 assertEquals("2", comboBox.getValue()); 1017 assertEquals("2", buttonCell.getText()); 1018 assertEquals(2, sm.getSelectedIndex()); 1019 1020 sm.clearSelection(); 1021 assertNull(sm.getSelectedItem()); 1022 assertNull(comboBox.getValue()); 1023 assertNull(buttonCell.getText()); 1024 assertEquals(-1, sm.getSelectedIndex()); 1025 1026 sm.select("2"); 1027 assertEquals("2", sm.getSelectedItem()); 1028 assertEquals("2", comboBox.getValue()); 1029 assertEquals("2", buttonCell.getText()); 1030 assertEquals(2, sm.getSelectedIndex()); 1031 } 1032 1033 @Test public void test_rt28245() { 1034 final ObservableList<String> strings = FXCollections.observableArrayList( 1035 "Option 1", "Option 2", "Option 3" 1036 ); 1037 1038 ComboBox<String> comboBox = new ComboBox<String>(); 1039 comboBox.setItems(strings); 1040 comboBox.setEditable(true); 1041 comboBox.valueProperty().addListener((ov, t, t1) -> { 1042 if (t == null && t1.isEmpty()) { 1043 fail("Old value is '" + t + "' and new value is '" + t1 + "'."); 1044 } 1045 }); 1046 1047 StageLoader sl = new StageLoader(comboBox); 1048 1049 assertNull(comboBox.getValue()); 1050 assertTrue(comboBox.getEditor().getText().isEmpty()); 1051 1052 comboBox.requestFocus(); 1053 1054 new KeyEventFirer(comboBox).doKeyPress(KeyCode.ENTER); 1055 1056 sl.dispose(); 1057 } 1058 1059 @Test public void test_rt31479() { 1060 ComboBox<String> comboBox = new ComboBox<String>(); 1061 1062 StageLoader sl = new StageLoader(comboBox); 1063 1064 final double widthBefore = comboBox.getWidth(); 1065 1066 // add item 1067 comboBox.getItems().add("Option 1"); 1068 1069 // open and close combobox 1070 comboBox.show(); 1071 comboBox.hide(); 1072 1073 // set a placeholder 1074 comboBox.setPlaceholder(new Circle(12, Color.RED)); 1075 1076 // remove item 1077 comboBox.getItems().clear(); 1078 1079 // fire pulse (this allows layout to cause the size to grow) 1080 Toolkit.getToolkit().firePulse(); 1081 1082 // test size 1083 assertEquals(widthBefore, comboBox.getWidth(), 0.00); 1084 1085 sl.dispose(); 1086 } 1087 1088 @Test public void test_rt32139() { 1089 final ObservableList<String> items = 1090 FXCollections.observableArrayList("Good value", "Bad value"); 1091 1092 final ComboBox<String> comboBox = new ComboBox<>(items); 1093 comboBox.getSelectionModel().select(0); 1094 1095 comboBox.getSelectionModel().selectedIndexProperty().addListener((ov, oldIdx, newIdx) -> { 1096 if (newIdx.intValue() != 0) { 1097 comboBox.getSelectionModel().select(0); 1098 } 1099 }); 1100 1101 StageLoader sl = new StageLoader(comboBox); 1102 1103 try { 1104 comboBox.getSelectionModel().select(1); 1105 } catch (StackOverflowError e) { 1106 fail("Stack overflow should not happen here"); 1107 } 1108 1109 sl.dispose(); 1110 } 1111 1112 @Test public void test_rt21186() { 1113 final ComboBox<String> comboBox = new ComboBox<>(); 1114 comboBox.setEditable(true); 1115 1116 StageLoader sl = new StageLoader(comboBox); 1117 1118 assertNull(comboBox.getTooltip()); 1119 assertNull(comboBox.getEditor().getTooltip()); 1120 1121 Tooltip tooltip = new Tooltip("Tooltip"); 1122 comboBox.setTooltip(tooltip); 1123 assertEquals(tooltip, comboBox.getTooltip()); 1124 assertEquals(tooltip, comboBox.getEditor().getTooltip()); 1125 1126 comboBox.setTooltip(null); 1127 assertNull(comboBox.getTooltip()); 1128 assertNull(comboBox.getEditor().getTooltip()); 1129 1130 sl.dispose(); 1131 } 1132 1133 @Test public void test_rt34573() { 1134 final ComboBox<String> comboBox = new ComboBox<>(); 1135 1136 final ListCell<String> customCell = new ListCellShim<String>() { 1137 @Override public void updateItem(String item, boolean empty) { 1138 super.updateItem(item, empty); 1139 setText(item); 1140 } 1141 }; 1142 comboBox.setButtonCell(customCell); 1143 1144 StageLoader sl = new StageLoader(comboBox); 1145 1146 comboBox.setItems(FXCollections.observableArrayList("A","B","C","D")); 1147 comboBox.setValue("B"); 1148 assertEquals("B", comboBox.getButtonCell().getText()); 1149 assertEquals(1, comboBox.getButtonCell().getIndex()); 1150 1151 comboBox.setItems(FXCollections.observableArrayList("1","2","3","4")); 1152 assertNull(comboBox.getButtonCell().getText()); 1153 assertEquals(-1, comboBox.getButtonCell().getIndex()); 1154 1155 sl.dispose(); 1156 } 1157 1158 @Test public void test_rt34566() { 1159 final ComboBox<String> comboBox = new ComboBox<>(); 1160 1161 final ListCell<String> customCell = new ListCellShim<String>() { 1162 @Override public void updateItem(String item, boolean empty) { 1163 super.updateItem(item, empty); 1164 setText(item); 1165 } 1166 }; 1167 comboBox.setButtonCell(customCell); 1168 1169 StageLoader sl = new StageLoader(comboBox); 1170 1171 comboBox.setItems(FXCollections.observableArrayList("A","B","C","D")); 1172 1173 PseudoClass empty = PseudoClass.getPseudoClass("empty"); 1174 1175 comboBox.setValue("B"); 1176 assertEquals("B", comboBox.getButtonCell().getText()); 1177 assertEquals(1, comboBox.getButtonCell().getIndex()); 1178 assertFalse(customCell.getPseudoClassStates().contains(empty)); 1179 1180 comboBox.setValue(null); 1181 Toolkit.getToolkit().firePulse(); 1182 assertNull(comboBox.getButtonCell().getText()); 1183 assertEquals(-1, comboBox.getButtonCell().getIndex()); 1184 assertTrue(customCell.getPseudoClassStates().contains(empty)); 1185 1186 comboBox.setValue("A"); 1187 assertEquals("A", comboBox.getButtonCell().getText()); 1188 assertEquals(0, comboBox.getButtonCell().getIndex()); 1189 assertFalse(customCell.getPseudoClassStates().contains(empty)); 1190 1191 sl.dispose(); 1192 } 1193 1194 private int test_rt34603_count = 0; 1195 @Test public void test_rt34603() { 1196 assertEquals(0, test_rt34603_count); 1197 1198 VBox hbox = new VBox(10); 1199 1200 ComboBox<String> box = new ComboBox<>(); 1201 box.getItems().add("test"); 1202 box.setEditable(true); 1203 box.getSelectionModel().selectFirst(); 1204 1205 Button defaultButton = new Button("press"); 1206 defaultButton.setOnAction(arg0 -> { 1207 test_rt34603_count++; 1208 }); 1209 defaultButton.setDefaultButton(true); 1210 1211 hbox.getChildren().addAll(box, defaultButton); 1212 1213 StageLoader sl = new StageLoader(hbox); 1214 1215 box.getEditor().requestFocus(); 1216 KeyEventFirer keyboard = new KeyEventFirer(box); 1217 keyboard.doKeyPress(KeyCode.ENTER); 1218 1219 assertEquals(1, test_rt34603_count); 1220 1221 sl.dispose(); 1222 } 1223 1224 private int test_rt35586_count = 0; 1225 @Test public void test_rt35586() { 1226 assertEquals(0, test_rt35586_count); 1227 1228 final ComboBox<String> cb = new ComboBox<String>(); 1229 cb.setEditable(true); 1230 cb.setOnAction(event -> { 1231 test_rt35586_count++; 1232 assertEquals("Test", cb.getEditor().getText()); 1233 }); 1234 1235 StageLoader sl = new StageLoader(cb); 1236 1237 cb.requestFocus(); 1238 cb.getEditor().setText("Test"); 1239 KeyEventFirer keyboard = new KeyEventFirer(cb); 1240 keyboard.doKeyPress(KeyCode.ENTER); 1241 1242 assertEquals(1, test_rt35586_count); 1243 1244 sl.dispose(); 1245 } 1246 1247 @Test public void test_rt35039() { 1248 final List<String> data = new ArrayList<>(); 1249 data.add("aabbaa"); 1250 data.add("bbc"); 1251 1252 final ComboBox<String> combo = new ComboBox<>(); 1253 combo.setEditable(true); 1254 combo.setItems(FXCollections.observableArrayList(data)); 1255 1256 StageLoader sl = new StageLoader(combo); 1257 1258 // everything should be null to start with 1259 assertNull(combo.getValue()); 1260 assertTrue(combo.getEditor().getText().isEmpty()); 1261 assertNull(combo.getSelectionModel().getSelectedItem()); 1262 1263 // select "bbc" and ensure everything is set to that 1264 combo.getSelectionModel().select(1); 1265 assertEquals("bbc", combo.getValue()); 1266 assertEquals("bbc", combo.getEditor().getText()); 1267 assertEquals("bbc", combo.getSelectionModel().getSelectedItem()); 1268 1269 // change the items list - but retain the same content. We expect 1270 // that "bbc" remains selected as it is still in the list 1271 combo.setItems(FXCollections.observableArrayList(data)); 1272 assertEquals("bbc", combo.getValue()); 1273 assertEquals("bbc", combo.getEditor().getText()); 1274 assertEquals("bbc", combo.getSelectionModel().getSelectedItem()); 1275 1276 sl.dispose(); 1277 } 1278 1279 @Test public void test_rt35840() { 1280 final ComboBox<String> cb = new ComboBox<String>(); 1281 cb.setEditable(true); 1282 StageLoader sl = new StageLoader(cb); 1283 cb.requestFocus(); 1284 1285 KeyEventFirer keyboard = new KeyEventFirer(cb); 1286 keyboard.doKeyTyped(KeyCode.T); 1287 keyboard.doKeyTyped(KeyCode.E); 1288 keyboard.doKeyTyped(KeyCode.S); 1289 keyboard.doKeyTyped(KeyCode.T); 1290 assertEquals("TEST", cb.getEditor().getText()); 1291 1292 assertNull(cb.getValue()); 1293 keyboard.doKeyPress(KeyCode.ENTER); 1294 assertEquals("TEST", cb.getValue()); 1295 1296 sl.dispose(); 1297 } 1298 1299 @Test public void test_rt36280_nonEditable_F4ShowsPopup() { 1300 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1301 StageLoader sl = new StageLoader(cb); 1302 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1303 1304 assertFalse(cb.isShowing()); 1305 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1306 assertTrue(cb.isShowing()); 1307 1308 sl.dispose(); 1309 } 1310 1311 @Test public void test_rt36280_nonEditable_altUpShowsPopup() { 1312 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1313 StageLoader sl = new StageLoader(cb); 1314 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1315 1316 assertFalse(cb.isShowing()); 1317 cbKeyboard.doKeyPress(KeyCode.UP, KeyModifier.ALT); // show the popup 1318 assertTrue(cb.isShowing()); 1319 1320 sl.dispose(); 1321 } 1322 1323 @Test public void test_rt36280_nonEditable_altDownShowsPopup() { 1324 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1325 StageLoader sl = new StageLoader(cb); 1326 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1327 1328 new StageLoader(cb); 1329 1330 assertFalse(cb.isShowing()); 1331 cbKeyboard.doKeyPress(KeyCode.DOWN, KeyModifier.ALT); // show the popup 1332 assertTrue(cb.isShowing()); 1333 1334 sl.dispose(); 1335 } 1336 1337 @Test public void test_rt36280_nonEditable_enterHidesShowingPopup() { 1338 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1339 StageLoader sl = new StageLoader(cb); 1340 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1341 1342 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1343 assertNotNull(listView); 1344 1345 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1346 1347 assertFalse(cb.isShowing()); 1348 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1349 assertTrue(cb.isShowing()); 1350 lvKeyboard.doKeyPress(KeyCode.ENTER); // hide the popup 1351 assertFalse(cb.isShowing()); 1352 1353 sl.dispose(); 1354 } 1355 1356 @Test public void test_rt36280_nonEditable_spaceHidesShowingPopup() { 1357 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1358 StageLoader sl = new StageLoader(cb); 1359 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1360 1361 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1362 assertNotNull(listView); 1363 1364 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1365 1366 assertFalse(cb.isShowing()); 1367 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1368 assertTrue(cb.isShowing()); 1369 lvKeyboard.doKeyPress(KeyCode.SPACE); // hide the popup 1370 assertFalse(cb.isShowing()); 1371 1372 sl.dispose(); 1373 } 1374 1375 @Test public void test_rt36280_nonEditable_escapeHidesShowingPopup() { 1376 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1377 StageLoader sl = new StageLoader(cb); 1378 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1379 1380 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1381 assertNotNull(listView); 1382 1383 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1384 1385 assertFalse(cb.isShowing()); 1386 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1387 assertTrue(cb.isShowing()); 1388 lvKeyboard.doKeyPress(KeyCode.ESCAPE); // hide the popup 1389 assertFalse(cb.isShowing()); 1390 1391 sl.dispose(); 1392 } 1393 1394 @Test public void test_rt36280_nonEditable_F4HidesShowingPopup() { 1395 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1396 StageLoader sl = new StageLoader(cb); 1397 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1398 1399 assertFalse(cb.isShowing()); 1400 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1401 assertTrue(cb.isShowing()); 1402 cbKeyboard.doKeyPress(KeyCode.F4); // hide the popup 1403 assertFalse(cb.isShowing()); 1404 1405 sl.dispose(); 1406 } 1407 1408 @Test public void test_rt36280_nonEditable_arrowKeysChangeSelection() { 1409 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1410 StageLoader sl = new StageLoader(cb); 1411 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1412 1413 assertFalse(cb.isShowing()); 1414 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1415 assertTrue(cb.isShowing()); 1416 1417 assertNull(cb.getSelectionModel().getSelectedItem()); 1418 1419 cbKeyboard.doDownArrowPress(); 1420 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1421 1422 cbKeyboard.doDownArrowPress(); 1423 assertEquals("b", cb.getSelectionModel().getSelectedItem()); 1424 1425 cbKeyboard.doUpArrowPress(); 1426 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1427 1428 sl.dispose(); 1429 } 1430 1431 @Test public void test_rt36280_editable_F4ShowsPopup() { 1432 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1433 cb.setEditable(true); 1434 StageLoader sl = new StageLoader(cb); 1435 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1436 1437 assertFalse(cb.isShowing()); 1438 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1439 assertTrue(cb.isShowing()); 1440 1441 sl.dispose(); 1442 } 1443 1444 @Test public void test_rt36280_editable_altUpShowsPopup() { 1445 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1446 cb.setEditable(true); 1447 StageLoader sl = new StageLoader(cb); 1448 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1449 1450 assertFalse(cb.isShowing()); 1451 cbKeyboard.doKeyPress(KeyCode.UP, KeyModifier.ALT); // show the popup 1452 assertTrue(cb.isShowing()); 1453 1454 sl.dispose(); 1455 } 1456 1457 @Test public void test_rt36280_editable_altDownShowsPopup_onComboBox() { 1458 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1459 cb.setEditable(true); 1460 StageLoader sl = new StageLoader(cb); 1461 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1462 1463 assertFalse(cb.isShowing()); 1464 assertTrue(cb.getEditor().getText().isEmpty()); 1465 cbKeyboard.doKeyPress(KeyCode.DOWN, KeyModifier.ALT); // show the popup 1466 assertTrue(cb.isShowing()); 1467 assertTrue(cb.getEditor().getText().isEmpty()); 1468 1469 sl.dispose(); 1470 } 1471 1472 @Test public void test_rt36280_editable_altDownShowsPopup_onTextField() { 1473 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1474 cb.setEditable(true); 1475 StageLoader sl = new StageLoader(cb); 1476 1477 KeyEventFirer tfKeyboard = new KeyEventFirer(cb.getEditor()); 1478 assertFalse(cb.isShowing()); 1479 assertTrue(cb.getEditor().getText().isEmpty()); 1480 tfKeyboard.doKeyPress(KeyCode.DOWN, KeyModifier.ALT); // show the popup 1481 assertTrue(cb.isShowing()); 1482 assertTrue(cb.getEditor().getText().isEmpty()); 1483 1484 sl.dispose(); 1485 } 1486 1487 @Test public void test_rt36280_editable_enterHidesShowingPopup() { 1488 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1489 cb.setEditable(true); 1490 StageLoader sl = new StageLoader(cb); 1491 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1492 1493 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1494 assertNotNull(listView); 1495 1496 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1497 1498 assertFalse(cb.isShowing()); 1499 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1500 assertTrue(cb.isShowing()); 1501 lvKeyboard.doKeyPress(KeyCode.ENTER); // hide the popup 1502 assertFalse(cb.isShowing()); 1503 1504 sl.dispose(); 1505 } 1506 1507 @Test public void test_rt36280_editable_spaceHidesShowingPopup() { 1508 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1509 cb.setEditable(true); 1510 StageLoader sl = new StageLoader(cb); 1511 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1512 1513 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1514 assertNotNull(listView); 1515 1516 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1517 1518 assertFalse(cb.isShowing()); 1519 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1520 assertTrue(cb.isShowing()); 1521 lvKeyboard.doKeyPress(KeyCode.SPACE); // hide the popup 1522 assertFalse(cb.isShowing()); 1523 1524 sl.dispose(); 1525 } 1526 1527 @Test public void test_rt36280_editable_escapeHidesShowingPopup() { 1528 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1529 cb.setEditable(true); 1530 StageLoader sl = new StageLoader(cb); 1531 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1532 1533 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1534 assertNotNull(listView); 1535 1536 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1537 1538 assertFalse(cb.isShowing()); 1539 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1540 assertTrue(cb.isShowing()); 1541 lvKeyboard.doKeyPress(KeyCode.ESCAPE); // hide the popup 1542 assertFalse(cb.isShowing()); 1543 1544 sl.dispose(); 1545 } 1546 1547 @Test public void test_rt36280_editable_F4HidesShowingPopup() { 1548 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1549 cb.setEditable(true); 1550 StageLoader sl = new StageLoader(cb); 1551 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1552 1553 assertFalse(cb.isShowing()); 1554 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1555 assertTrue(cb.isShowing()); 1556 cbKeyboard.doKeyPress(KeyCode.F4); // hide the popup 1557 assertFalse(cb.isShowing()); 1558 1559 sl.dispose(); 1560 } 1561 1562 @Test public void test_rt36280_editable_arrowKeysChangeSelection() { 1563 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1564 cb.setEditable(true); 1565 StageLoader sl = new StageLoader(cb); 1566 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1567 1568 assertFalse(cb.isShowing()); 1569 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1570 assertTrue(cb.isShowing()); 1571 1572 assertNull(cb.getSelectionModel().getSelectedItem()); 1573 1574 cbKeyboard.doDownArrowPress(); 1575 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1576 1577 cbKeyboard.doDownArrowPress(); 1578 assertEquals("b", cb.getSelectionModel().getSelectedItem()); 1579 1580 cbKeyboard.doUpArrowPress(); 1581 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1582 1583 sl.dispose(); 1584 } 1585 1586 @Test public void test_rt36651() { 1587 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1588 cb.setEditable(true); 1589 StageLoader sl = new StageLoader(cb); 1590 1591 assertNull(cb.getValue()); 1592 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1593 assertNull(cb.getSelectionModel().getSelectedItem()); 1594 1595 sl.getStage().requestFocus(); 1596 cb.show(); 1597 Toolkit.getToolkit().firePulse(); 1598 1599 // selection should not change just by showing the popup 1600 assertNull(cb.getValue()); 1601 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1602 assertNull(cb.getSelectionModel().getSelectedItem()); 1603 1604 sl.dispose(); 1605 } 1606 1607 @Test public void test_rt36717() { 1608 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1609 StageLoader sl = new StageLoader(cb); 1610 1611 // the stack overflow only occurs when a ComboBox changes from non-editable to editable 1612 cb.setEditable(false); 1613 cb.setEditable(true); 1614 assertNotNull(cb.getEditor()); 1615 KeyEventFirer tfKeyboard = new KeyEventFirer(cb.getEditor()); 1616 tfKeyboard.doKeyPress(KeyCode.ENTER); // Stack overflow here 1617 1618 sl.dispose(); 1619 } 1620 1621 @Test public void test_rt36827() { 1622 final Button btn = new Button("focus owner"); 1623 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1624 VBox vbox = new VBox(btn, cb); 1625 1626 StageLoader sl = new StageLoader(vbox); 1627 sl.getStage().requestFocus(); 1628 btn.requestFocus(); 1629 Toolkit.getToolkit().firePulse(); 1630 Scene scene = sl.getStage().getScene(); 1631 1632 assertTrue(btn.isFocused()); 1633 assertEquals(btn, scene.getFocusOwner()); 1634 1635 MouseEventFirer mouse = new MouseEventFirer(cb); 1636 mouse.fireMousePressAndRelease(); 1637 1638 assertTrue(cb.isShowing()); 1639 assertTrue(cb.isFocused()); 1640 assertEquals(cb, scene.getFocusOwner()); 1641 1642 sl.dispose(); 1643 } 1644 1645 @Test public void test_rt36902() { 1646 final ComboBox<String> cb1 = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1647 final ComboBox<String> cb2 = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1648 cb2.setEditable(true); 1649 VBox vbox = new VBox(cb1, cb2); 1650 1651 // lame - I would rather have one keyboard here but I couldn't get it to 1652 // work, so watch out for which keyboard is used below 1653 KeyEventFirer cb1Keyboard = new KeyEventFirer(cb1); 1654 KeyEventFirer cb2Keyboard = new KeyEventFirer(cb2); 1655 1656 StageLoader sl = new StageLoader(vbox); 1657 sl.getStage().requestFocus(); 1658 cb1.requestFocus(); 1659 Toolkit.getToolkit().firePulse(); 1660 Scene scene = sl.getStage().getScene(); 1661 1662 assertTrue(cb1.isFocused()); 1663 assertEquals(cb1, scene.getFocusOwner()); 1664 1665 // move focus forward to cb2 1666 cb1Keyboard.doKeyPress(KeyCode.TAB); 1667 assertTrue(cb2.isFocused()); 1668 assertEquals(cb2, scene.getFocusOwner()); 1669 1670 // move focus forward again to cb1 1671 cb2Keyboard.doKeyPress(KeyCode.TAB); 1672 assertTrue(cb1.isFocused()); 1673 assertEquals(cb1, scene.getFocusOwner()); 1674 1675 // now start going backwards with shift-tab. 1676 // The first half of the bug is here - when we shift-tab into cb2, we 1677 // actually go into the FakeFocusTextField subcomponent, so whilst the 1678 // cb2.isFocused() returns true as expected, the scene focus owner is 1679 // not the ComboBox, but the FakeFocusTextField inside it 1680 cb1Keyboard.doKeyPress(KeyCode.TAB, KeyModifier.SHIFT); 1681 assertTrue("Expect cb2 to be focused, but actual focus owner is: " + scene.getFocusOwner(), 1682 cb2.isFocused()); 1683 // Updated with fix for RT-34602: The TextField now never gets 1684 // focus (it's just faking it). 1685 // assertEquals("Expect cb2 TextField to be focused, but actual focus owner is: " + scene.getFocusOwner(), 1686 // cb2.getEditor(), scene.getFocusOwner()); 1687 assertEquals("Expect cb2 to be focused, but actual focus owner is: " + scene.getFocusOwner(), 1688 cb2, scene.getFocusOwner()); 1689 1690 // This is where the second half of the bug appears, as we are stuck in 1691 // the FakeFocusTextField of cb2, we never make it to cb1 1692 cb2Keyboard.doKeyPress(KeyCode.TAB, KeyModifier.SHIFT); 1693 assertTrue(cb1.isFocused()); 1694 assertEquals(cb1, scene.getFocusOwner()); 1695 1696 sl.dispose(); 1697 } 1698 1699 private int rt_38901_counter; 1700 @Test public void test_rt_38901_selectNull() { 1701 test_rt_38901(true); 1702 } 1703 1704 @Test public void test_rt_38901_selectNegativeOne() { 1705 test_rt_38901(false); 1706 } 1707 1708 private void test_rt_38901(boolean selectNull) { 1709 rt_38901_counter = 0; 1710 1711 final ComboBox<String> cb = new ComboBox<>(); 1712 cb.setOnShowing((e) -> { 1713 cb.getItems().setAll("DUMMY " + (rt_38901_counter++)); 1714 }); 1715 1716 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1717 assertNull(cb.getSelectionModel().getSelectedItem()); 1718 assertNull(cb.getValue()); 1719 assertEquals(0, cb.getItems().size()); 1720 1721 // round one 1722 cb.show(); 1723 assertEquals(1, cb.getItems().size()); 1724 assertEquals("DUMMY 0", cb.getItems().get(0)); 1725 cb.hide(); 1726 1727 cb.getSelectionModel().select(0); 1728 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1729 assertEquals("DUMMY 0", cb.getSelectionModel().getSelectedItem()); 1730 assertEquals("DUMMY 0", cb.getValue()); 1731 1732 if (selectNull) cb.getSelectionModel().select(null); 1733 else cb.getSelectionModel().select(-1); 1734 1735 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1736 assertNull(cb.getSelectionModel().getSelectedItem()); 1737 assertNull(cb.getValue()); 1738 1739 1740 // round two 1741 cb.show(); 1742 assertEquals(1, cb.getItems().size()); 1743 assertEquals("DUMMY 1", cb.getItems().get(0)); 1744 cb.hide(); 1745 1746 cb.getSelectionModel().select(0); 1747 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1748 assertEquals("DUMMY 1", cb.getSelectionModel().getSelectedItem()); 1749 assertEquals("DUMMY 1", cb.getValue()); 1750 1751 if (selectNull) cb.getSelectionModel().select(null); 1752 else cb.getSelectionModel().select(-1); 1753 1754 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1755 assertNull(cb.getSelectionModel().getSelectedItem()); 1756 assertNull(cb.getValue()); 1757 } 1758 1759 private int rt_22572_counter; 1760 @Test public void test_rt_22572() { 1761 rt_22572_counter = 0; 1762 1763 final ComboBox<String> cb = new ComboBox<>(); 1764 cb.setOnShowing((e) -> { 1765 cb.getItems().setAll("DUMMY " + (rt_22572_counter++)); 1766 }); 1767 1768 StageLoader sl = new StageLoader(cb); 1769 1770 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1771 assertNull(cb.getSelectionModel().getSelectedItem()); 1772 assertNull(cb.getValue()); 1773 assertEquals(0, cb.getItems().size()); 1774 1775 // round one 1776 cb.show(); 1777 assertEquals(1, cb.getItems().size()); 1778 assertEquals("DUMMY 0", cb.getItems().get(0)); 1779 cb.hide(); 1780 1781 cb.getSelectionModel().select(0); 1782 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1783 assertEquals("DUMMY 0", cb.getSelectionModel().getSelectedItem()); 1784 assertEquals("DUMMY 0", cb.getValue()); 1785 1786 1787 // round two - even though the items change, the value should still be 1788 // the old value (even though it doesn't exist in the items list any longer). 1789 // The selectedIndex and selectedItem do get reset however. 1790 cb.show(); 1791 assertEquals(1, cb.getItems().size()); 1792 assertEquals("DUMMY 1", cb.getItems().get(0)); 1793 cb.hide(); 1794 1795 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1796 assertNull(cb.getSelectionModel().getSelectedItem()); 1797 assertEquals("DUMMY 0", cb.getValue()); 1798 1799 sl.dispose(); 1800 } 1801 1802 private int rt_22937_counter; 1803 @Test public void test_rt_22937() { 1804 rt_22937_counter = 0; 1805 1806 final ComboBox<String> cb = new ComboBox<>(); 1807 cb.setOnShowing((e) -> { 1808 cb.getItems().setAll("DUMMY " + (rt_22937_counter++)); 1809 }); 1810 1811 cb.getItems().add("Toto"); 1812 cb.setEditable(true); 1813 cb.setValue("Tata"); 1814 1815 StageLoader sl = new StageLoader(cb); 1816 1817 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1818 assertEquals("Tata", cb.getSelectionModel().getSelectedItem()); 1819 assertEquals("Tata", cb.getValue()); 1820 assertEquals(1, cb.getItems().size()); 1821 1822 cb.show(); 1823 assertEquals(1, cb.getItems().size()); 1824 assertEquals("DUMMY 0", cb.getItems().get(0)); 1825 cb.hide(); 1826 1827 cb.getSelectionModel().select(0); 1828 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1829 assertEquals("DUMMY 0", cb.getSelectionModel().getSelectedItem()); 1830 assertEquals("DUMMY 0", cb.getValue()); 1831 1832 sl.dispose(); 1833 } 1834 1835 @Test public void test_rt_39809() { 1836 ComboBox<String> comboBox = new ComboBox<>(); 1837 comboBox.getItems().setAll(null, "1", "2", "3"); 1838 1839 StageLoader sl = new StageLoader(comboBox); 1840 1841 comboBox.getSelectionModel().clearAndSelect(1); 1842 assertEquals("1", comboBox.getSelectionModel().getSelectedItem()); 1843 assertEquals(1, comboBox.getSelectionModel().getSelectedIndex()); 1844 1845 comboBox.getSelectionModel().clearAndSelect(0); 1846 assertEquals(null, comboBox.getSelectionModel().getSelectedItem()); 1847 assertEquals(0, comboBox.getSelectionModel().getSelectedIndex()); 1848 1849 sl.dispose(); 1850 } 1851 1852 @Test public void test_rt_39908() { 1853 ObservableList<String> model = FXCollections.observableArrayList("0", "1", "2", "3"); 1854 ComboBox<String> comboBox = new ComboBox<>(model); 1855 1856 StageLoader sl = new StageLoader(comboBox); 1857 1858 comboBox.getSelectionModel().clearAndSelect(1); 1859 assertEquals("1", comboBox.getSelectionModel().getSelectedItem()); 1860 assertEquals(1, comboBox.getSelectionModel().getSelectedIndex()); 1861 1862 model.set(0, "a"); 1863 assertEquals("1", comboBox.getSelectionModel().getSelectedItem()); 1864 assertEquals(1, comboBox.getSelectionModel().getSelectedIndex()); 1865 1866 sl.dispose(); 1867 } 1868 1869 /** 1870 * Bullet 1: selected index must be updated 1871 * Corner case: last selected. Fails for core 1872 */ 1873 @Test public void test_rt_40012_selectedAtLastOnDisjointRemoveItemsAbove() { 1874 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1875 ComboBox<String> comboBox = new ComboBox<>(items); 1876 SelectionModel sm = comboBox.getSelectionModel(); 1877 1878 int last = items.size() - 1; 1879 1880 // selecting item "5" 1881 sm.select(last); 1882 1883 // disjoint remove of 2 elements above the last selected 1884 // Removing "1" and "3" 1885 items.removeAll(items.get(1), items.get(3)); 1886 1887 // selection should move up two places such that it remains on item "5", 1888 // but in index (last - 2). 1889 int expected = last - 2; 1890 assertEquals("5", sm.getSelectedItem()); 1891 assertEquals("selected index after disjoint removes above", expected, sm.getSelectedIndex()); 1892 } 1893 1894 /** 1895 * Variant of 1: if selectedIndex is not updated, 1896 * the old index is no longer valid 1897 * for accessing the items. 1898 */ 1899 @Test public void test_rt_40012_accessSelectedAtLastOnDisjointRemoveItemsAbove() { 1900 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1901 ComboBox<String> comboBox = new ComboBox<>(items); 1902 SelectionModel sm = comboBox.getSelectionModel(); 1903 1904 int last = items.size() - 1; 1905 1906 // selecting item "5" 1907 sm.select(last); 1908 1909 // disjoint remove of 2 elements above the last selected 1910 items.removeAll(items.get(1), items.get(3)); 1911 int selected = sm.getSelectedIndex(); 1912 if (selected > -1) { 1913 items.get(selected); 1914 } 1915 } 1916 1917 /** 1918 * Bullet 2: selectedIndex notification count 1919 * 1920 * Note that we don't use the corner case of having the last index selected 1921 * (which fails already on updating the index) 1922 */ 1923 private int rt_40012_count = 0; 1924 @Test public void test_rt_40012_selectedIndexNotificationOnDisjointRemovesAbove() { 1925 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1926 ComboBox<String> comboBox = new ComboBox<>(items); 1927 SelectionModel sm = comboBox.getSelectionModel(); 1928 1929 int last = items.size() - 2; 1930 sm.select(last); 1931 assertEquals(last, sm.getSelectedIndex()); 1932 1933 rt_40012_count = 0; 1934 sm.selectedIndexProperty().addListener(o -> rt_40012_count++); 1935 1936 // disjoint remove of 2 elements above the last selected 1937 items.removeAll(items.get(1), items.get(3)); 1938 assertEquals("sanity: selectedIndex must be shifted by -2", last - 2, sm.getSelectedIndex()); 1939 assertEquals("must fire single event on removes above", 1, rt_40012_count); 1940 } 1941 1942 /** 1943 * Bullet 3: unchanged selectedItem must not fire change 1944 */ 1945 @Test 1946 public void test_rt_40012_selectedItemNotificationOnDisjointRemovesAbove() { 1947 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1948 ComboBox<String> comboBox = new ComboBox<>(items); 1949 SelectionModel sm = comboBox.getSelectionModel(); 1950 1951 int last = items.size() - 2; 1952 Object lastItem = items.get(last); 1953 sm.select(last); 1954 assertEquals(lastItem, sm.getSelectedItem()); 1955 1956 rt_40012_count = 0; 1957 sm.selectedItemProperty().addListener(o -> rt_40012_count++); 1958 1959 // disjoint remove of 2 elements above the last selected 1960 items.removeAll(items.get(1), items.get(3)); 1961 assertEquals("sanity: selectedItem unchanged", lastItem, sm.getSelectedItem()); 1962 assertEquals("must not fire on unchanged selected item", 0, rt_40012_count); 1963 } 1964 1965 @Test public void test_jdk_8150946_testCommit_valid() { 1966 ComboBox<String> comboBox = new ComboBox<>(); 1967 comboBox.setEditable(true); 1968 assertEquals(null, comboBox.getValue()); 1969 comboBox.getEditor().setText("ABC"); 1970 comboBox.commitValue(); 1971 assertEquals("ABC", comboBox.getValue()); 1972 } 1973 1974 @Test public void test_jdk_8150946_testCancel_toNull() { 1975 ComboBox<String> comboBox = new ComboBox<>(); 1976 comboBox.setEditable(true); 1977 assertNull(comboBox.getValue()); 1978 assertEquals("", comboBox.getEditor().getText()); 1979 comboBox.getEditor().setText("ABC"); 1980 assertNull(comboBox.getValue()); 1981 comboBox.cancelEdit(); 1982 assertNull(comboBox.getValue()); 1983 assertNull(comboBox.getEditor().getText()); 1984 } 1985 1986 @Test public void test_jdk_8150946_testCancel_toNonNull() { 1987 ComboBox<String> comboBox = new ComboBox<>(); 1988 comboBox.setEditable(true); 1989 comboBox.getEditor().setText("ABC"); 1990 comboBox.commitValue(); 1991 assertEquals("ABC", comboBox.getValue()); 1992 assertEquals("ABC", comboBox.getEditor().getText()); 1993 comboBox.getEditor().setText("DEF"); 1994 assertEquals("DEF", comboBox.getEditor().getText()); 1995 assertEquals("ABC", comboBox.getValue()); 1996 comboBox.cancelEdit(); 1997 assertEquals("ABC", comboBox.getValue()); 1998 assertEquals("ABC", comboBox.getEditor().getText()); 1999 } 2000 2001 @Test public void test_jdk_8160493() { 2002 AtomicInteger count = new AtomicInteger(); 2003 comboBox.valueProperty().addListener(o -> count.incrementAndGet()); 2004 assertEquals(0, count.get()); 2005 2006 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 2007 sm.select(1); 2008 assertTrue(sm.isSelected(1)); 2009 assertEquals(1, count.get()); 2010 assertEquals("Orange", comboBox.getValue()); 2011 2012 comboBox.setValue("New Value"); 2013 assertEquals(2, count.get()); 2014 assertEquals("New Value", comboBox.getValue()); 2015 } 2016 2017 private int skinChangedCount = 0; 2018 @Test public void test_JDK_8185854() { 2019 final FlowPane comboPane = new FlowPane(10, 10); 2020 ComboBox combo = new ComboBox<String>(); 2021 2022 combo.skinProperty().addListener((o, oldSkin, newSkin) -> { 2023 skinChangedCount++; 2024 }); 2025 2026 combo.setDisable(false); 2027 combo.setEditable(false); 2028 2029 comboPane.getChildren().add(combo); 2030 2031 TabPane tabPane = new TabPane(); 2032 Tab tab = new Tab(); 2033 tab.setText("ComboBox"); 2034 tab.setContent(comboPane); 2035 tabPane.getTabs().add(tab); 2036 2037 BorderPane p = new BorderPane(); 2038 p.setCenter(tabPane); 2039 2040 Scene scene = new Scene(p); 2041 scene.getStylesheets().add(ComboBoxTest.class.getResource("JDK_8185854.css").toExternalForm()); 2042 2043 Toolkit tk = Toolkit.getToolkit(); 2044 2045 Stage stage = new Stage(); 2046 stage.setScene(scene); 2047 stage.setWidth(500); 2048 stage.setHeight(400); 2049 2050 stage.show(); 2051 2052 tk.firePulse(); 2053 2054 assertEquals("ComboBox skinProperty changed more than once, which is not expected.", 1, skinChangedCount); 2055 } 2056 }