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 pseudoClassStates = comboBox.getPseudoClassStates(); 658 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("editable"))); 659 660 comboBox.setEditable(false); 661 pseudoClassStates = comboBox.getPseudoClassStates(); 662 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("editable")) == false); 663 664 comboBox.show(); 665 pseudoClassStates = comboBox.getPseudoClassStates(); 666 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("showing"))); 667 668 comboBox.hide(); 669 pseudoClassStates = comboBox.getPseudoClassStates(); 670 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("showing")) == false); 671 672 comboBox.arm(); 673 pseudoClassStates = comboBox.getPseudoClassStates(); 674 assertTrue(pseudoClassStates.contains(PseudoClass.getPseudoClass("armed"))); 675 676 } 677 678 /********************************************************************* 679 * Tests for properties * 680 ********************************************************************/ 681 682 @Test public void ensureAllowsNullConverter() { 683 comboBox.setConverter(null); 684 assertNull(comboBox.getConverter()); 685 } 686 687 @Test public void ensureCanSetNonNullCellFactory() { 688 Callback<ListView<String>, ListCell<String>> cf = p -> null; 689 comboBox.setCellFactory(cf); 690 assertEquals(cf, comboBox.getCellFactory()); 691 } 692 693 @Test public void ensureEditorIsNonNullWhenComboBoxIsNotEditable() { 694 assertNotNull(comboBox.getEditor()); 695 } 696 697 @Test public void ensureEditorIsNonNullWhenComboBoxIsEditable() { 698 comboBox.setEditable(true); 699 assertNotNull(comboBox.getEditor()); 700 } 701 702 @Test public void ensureEditorDoesNotChangeWhenEditableToggles() { 703 comboBox.setEditable(true); 704 assertNotNull(comboBox.getEditor()); 705 comboBox.setEditable(false); 706 assertNotNull(comboBox.getEditor()); 707 comboBox.setEditable(true); 708 assertNotNull(comboBox.getEditor()); 709 } 710 711 @Test public void ensureCanSetValueToNonNullStringAndBackAgain() { 712 comboBox.setValue("Test 123"); 713 assertEquals("Test 123", comboBox.getValue()); 714 comboBox.setValue(null); 715 assertNull(comboBox.getValue()); 716 } 717 718 @Test public void ensureCanToggleEditable() { 719 comboBox.setEditable(true); 720 assertTrue(comboBox.isEditable()); 721 comboBox.setEditable(false); 722 assertFalse(comboBox.isEditable()); 723 } 724 725 @Test public void ensureCanToggleShowing() { 726 Stage stage = new Stage(); 727 Scene scene = new Scene(comboBox); 728 stage.setScene(scene); 729 730 comboBox.show(); 731 assertTrue(comboBox.isShowing()); 732 comboBox.hide(); 733 assertFalse(comboBox.isShowing()); 734 } 735 736 @Test public void ensureCanNotToggleShowingWhenDisabled() { 737 Stage stage = new Stage(); 738 Scene scene = new Scene(comboBox); 739 stage.setScene(scene); 740 741 comboBox.setDisable(true); 742 comboBox.show(); 743 assertFalse(comboBox.isShowing()); 744 comboBox.setDisable(false); 745 comboBox.show(); 746 assertTrue(comboBox.isShowing()); 747 } 748 749 @Test public void ensureCanSetPromptText() { 750 comboBox.setPromptText("Test 1 2 3"); 751 assertEquals("Test 1 2 3", comboBox.getPromptText()); 752 } 753 754 @Test public void ensureCanSetPromptTextToNull() { 755 comboBox.setPromptText(""); 756 assertEquals("", comboBox.getPromptText()); 757 comboBox.setPromptText(null); 758 assertEquals(null, comboBox.getPromptText()); 759 } 760 761 @Test public void ensurePromptTextStripsNewlines() { 762 comboBox.setPromptText("Test\n1\n2\n3"); 763 assertEquals("Test123", comboBox.getPromptText()); 764 } 765 766 @Test public void ensureCanSetPlaceholder() { 767 Label label = new javafx.scene.control.Label("Test 1 2 3"); 768 comboBox.setPlaceholder(label); 769 assertEquals(label, comboBox.getPlaceholder()); 770 } 771 772 @Test public void ensureCanToggleArmed() { 773 assertFalse(comboBox.isArmed()); 774 comboBox.arm(); 775 assertTrue(comboBox.isArmed()); 776 comboBox.disarm(); 777 assertFalse(comboBox.isArmed()); 778 } 779 780 @Test public void ensureCanSetVisibleRowCount() { 781 comboBox.setVisibleRowCount(13); 782 assertEquals(13, comboBox.getVisibleRowCount()); 783 } 784 785 @Test public void ensureCanSetVisibleRowCountToNegativeValues() { 786 comboBox.setVisibleRowCount(-10); 787 assertEquals(-10, comboBox.getVisibleRowCount()); 788 } 789 790 @Test public void ensureCanSetOnAction() { 791 EventHandler<ActionEvent> onAction = t -> { }; 792 comboBox.setOnAction(onAction); 793 assertEquals(onAction, comboBox.getOnAction()); 794 } 795 796 @Test public void ensureOnActionPropertyReferencesBean() { 797 assertEquals(comboBox, comboBox.onActionProperty().getBean()); 798 } 799 800 /********************************************************************* 801 * Tests for property binding * 802 ********************************************************************/ 803 @Test public void checkPromptTextPropertyBind() { 804 StringProperty strPr = new SimpleStringProperty("value"); 805 comboBox.promptTextProperty().bind(strPr); 806 assertTrue("PromptText cannot be bound", comboBox.getPromptText().equals("value")); 807 strPr.setValue("newvalue"); 808 assertTrue("PromptText cannot be bound", comboBox.getPromptText().equals("newvalue")); 809 } 810 811 @Test public void checkValuePropertyBind() { 812 StringProperty strPr = new SimpleStringProperty("value"); 813 comboBox.valueProperty().bind(strPr); 814 assertTrue("value cannot be bound", comboBox.getValue().equals("value")); 815 strPr.setValue("newvalue"); 816 assertTrue("value cannot be bound", comboBox.getValue().equals("newvalue")); 817 } 818 819 820 821 /********************************************************************* 822 * Tests for bug reports * 823 ********************************************************************/ 824 825 @Test public void test_rt18972() { 826 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 827 sm.select(1); 828 assertTrue(sm.isSelected(1)); 829 830 comboBox.setEditable(true); 831 comboBox.setValue("New Value"); 832 833 // there should be no selection in the selection model, as "New Value" 834 // isn't an item in the list, however, it is a totally valid value for 835 // the value property 836 assertFalse(sm.isSelected(1)); 837 assertEquals("New Value", sm.getSelectedItem()); 838 assertEquals("New Value", comboBox.getValue()); 839 840 comboBox.setEditable(false); 841 assertEquals(-1, sm.getSelectedIndex()); 842 assertEquals("New Value", sm.getSelectedItem()); 843 assertEquals("New Value", comboBox.getValue()); 844 } 845 846 @Test public void test_rt18941() { 847 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 848 comboBox.setValue("Orange"); 849 assertEquals("Orange", comboBox.getValue()); 850 assertEquals("Orange", comboBox.getSelectionModel().getSelectedItem()); 851 assertTrue("Selected Index: " + sm.getSelectedIndex(), sm.isSelected(1)); 852 } 853 854 @Test public void test_rt19227() { 855 comboBox.getItems().addAll("0","0","0","0","0"); 856 comboBox.getSelectionModel().select(2); 857 assertEquals("0", comboBox.getValue()); 858 assertEquals("0", comboBox.getSelectionModel().getSelectedItem()); 859 assertTrue(sm.isSelected(2)); 860 } 861 862 @Ignore("JDK-8091127 Test not working as the heights being returned are not accurate") 863 @Test public void test_rt20106() { 864 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 865 866 Stage stage = new Stage(); 867 Scene scene = new Scene(comboBox); 868 stage.setScene(scene); 869 comboBox.applyCss(); 870 comboBox.show(); 871 872 comboBox.setVisibleRowCount(5); 873 double initialHeight = getListView().getHeight(); 874 assertFalse("initialHeight: " + initialHeight, Double.compare(0.0, initialHeight) == 0); 875 876 comboBox.setVisibleRowCount(0); 877 double smallHeight = getListView().getHeight(); 878 assertTrue("smallHeight: " + smallHeight + ", initialHeight: " + initialHeight, 879 smallHeight != initialHeight && smallHeight < initialHeight); 880 881 comboBox.setVisibleRowCount(7); 882 double biggerHeight = getListView().getHeight(); 883 assertTrue(biggerHeight != smallHeight && smallHeight < biggerHeight); 884 } 885 886 private int count = 0; 887 @Test public void test_rt20103() { 888 final TextField tf = new TextField(); 889 890 comboBox.setOnAction(t -> { 891 count++; 892 }); 893 894 assertTrue(count == 0); 895 896 comboBox.valueProperty().bind(tf.textProperty()); // count++ here 897 assertTrue("count: " + count, count == 1); 898 899 tf.setText("Text1"); // count++ here 900 assertTrue("count: " + count, count == 2); 901 902 comboBox.valueProperty().unbind(); // no count++ here 903 assertTrue("count: " + count, count == 2); 904 905 comboBox.valueProperty().bindBidirectional(tf.textProperty()); // count++ here 906 tf.setText("Text2"); 907 assertTrue("count: " + count, count == 3); 908 } 909 910 @Ignore("Test not working as the skin is not being properly instantiated") 911 @Test public void test_rt20100() { 912 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 913 914 Stage stage = new Stage(); 915 Scene scene = new Scene(comboBox); 916 stage.setScene(scene); 917 comboBox.applyCss(); 918 comboBox.show(); 919 920 comboBox.setConverter(new StringConverter() { 921 int toStringCounter = 0; 922 int fromStringCounter = 0; 923 924 @Override public String toString(Object t) { 925 return "TO_STRING"; 926 } 927 928 @Override public Object fromString(String string) { 929 return "FROM_STRING"; 930 } 931 }); 932 933 comboBox.getSelectionModel().select(2); 934 assertEquals("2", comboBox.getValue()); 935 936 ListView listView = getListView(); 937 // listView.applyCss(); 938 939 assertEquals("2", listView.getSelectionModel().getSelectedItem()); 940 941 System.out.println(listView.getSkin()); 942 943 VirtualFlow flow = (VirtualFlow)listView.lookup("#virtual-flow"); 944 assertNotNull(flow); 945 946 IndexedCell cell = flow.getVisibleCell(2); 947 System.out.println("cell: " + cell); 948 assertEquals("TO_STRING", cell.getText()); 949 } 950 951 @Test public void test_rt20189() { 952 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 953 954 Stage stage = new Stage(); 955 Scene scene = new Scene(comboBox); 956 stage.setScene(scene); 957 comboBox.applyCss(); 958 comboBox.show(); 959 960 comboBox.getSelectionModel().select(2); 961 Object item = sm.getSelectedItem(); 962 assertEquals("2", item); 963 assertEquals(2, sm.getSelectedIndex()); 964 965 comboBox.setValue("test"); 966 item = sm.getSelectedItem(); 967 assertEquals("test",item); 968 assertEquals(-1, sm.getSelectedIndex()); 969 970 comboBox.getSelectionModel().select(2); 971 item = sm.getSelectedItem(); 972 assertEquals("2", item); 973 assertEquals(2, sm.getSelectedIndex()); 974 } 975 976 @Test public void test_rt27654() { 977 comboBox.getItems().addAll("0","1","2","3","4","5","6","7","8","9"); 978 979 SingleSelectionModel sm = comboBox.getSelectionModel(); 980 981 Stage stage = new Stage(); 982 Scene scene = new Scene(comboBox); 983 stage.setScene(scene); 984 comboBox.applyCss(); 985 comboBox.show(); 986 ListCell<String> buttonCell = (ListCell<String>) getDisplayNode(); 987 988 sm.select(2); 989 assertEquals("2", sm.getSelectedItem()); 990 assertEquals("2", comboBox.getValue()); 991 assertEquals("2", buttonCell.getText()); 992 assertEquals(2, sm.getSelectedIndex()); 993 994 sm.clearSelection(); 995 assertNull(sm.getSelectedItem()); 996 assertNull(comboBox.getValue()); 997 assertNull(buttonCell.getText()); 998 assertEquals(-1, sm.getSelectedIndex()); 999 1000 sm.select(2); 1001 assertEquals("2", sm.getSelectedItem()); 1002 assertEquals("2", comboBox.getValue()); 1003 assertEquals("2", buttonCell.getText()); 1004 assertEquals(2, sm.getSelectedIndex()); 1005 } 1006 1007 @Test public void test_rt24412() { 1008 SingleSelectionModel sm = comboBox.getSelectionModel(); 1009 1010 Stage stage = new Stage(); 1011 Scene scene = new Scene(comboBox); 1012 stage.setScene(scene); 1013 comboBox.applyCss(); 1014 comboBox.show(); 1015 ListCell<String> buttonCell = (ListCell<String>) getDisplayNode(); 1016 1017 comboBox.getItems().setAll("0","1","2","3","4","5","6","7","8","9"); 1018 1019 sm.select("2"); 1020 assertEquals("2", sm.getSelectedItem()); 1021 assertEquals("2", comboBox.getValue()); 1022 assertEquals("2", buttonCell.getText()); 1023 assertEquals(2, sm.getSelectedIndex()); 1024 1025 sm.clearSelection(); 1026 assertNull(sm.getSelectedItem()); 1027 assertNull(comboBox.getValue()); 1028 assertNull(buttonCell.getText()); 1029 assertEquals(-1, sm.getSelectedIndex()); 1030 1031 sm.select("2"); 1032 assertEquals("2", sm.getSelectedItem()); 1033 assertEquals("2", comboBox.getValue()); 1034 assertEquals("2", buttonCell.getText()); 1035 assertEquals(2, sm.getSelectedIndex()); 1036 } 1037 1038 @Test public void test_rt28245() { 1039 final ObservableList<String> strings = FXCollections.observableArrayList( 1040 "Option 1", "Option 2", "Option 3" 1041 ); 1042 1043 ComboBox<String> comboBox = new ComboBox<String>(); 1044 comboBox.setItems(strings); 1045 comboBox.setEditable(true); 1046 comboBox.valueProperty().addListener((ov, t, t1) -> { 1047 if (t == null && t1.isEmpty()) { 1048 fail("Old value is '" + t + "' and new value is '" + t1 + "'."); 1049 } 1050 }); 1051 1052 StageLoader sl = new StageLoader(comboBox); 1053 1054 assertNull(comboBox.getValue()); 1055 assertTrue(comboBox.getEditor().getText().isEmpty()); 1056 1057 comboBox.requestFocus(); 1058 1059 new KeyEventFirer(comboBox).doKeyPress(KeyCode.ENTER); 1060 1061 sl.dispose(); 1062 } 1063 1064 @Test public void test_rt31479() { 1065 ComboBox<String> comboBox = new ComboBox<String>(); 1066 1067 StageLoader sl = new StageLoader(comboBox); 1068 1069 final double widthBefore = comboBox.getWidth(); 1070 1071 // add item 1072 comboBox.getItems().add("Option 1"); 1073 1074 // open and close combobox 1075 comboBox.show(); 1076 comboBox.hide(); 1077 1078 // set a placeholder 1079 comboBox.setPlaceholder(new Circle(12, Color.RED)); 1080 1081 // remove item 1082 comboBox.getItems().clear(); 1083 1084 // fire pulse (this allows layout to cause the size to grow) 1085 Toolkit.getToolkit().firePulse(); 1086 1087 // test size 1088 assertEquals(widthBefore, comboBox.getWidth(), 0.00); 1089 1090 sl.dispose(); 1091 } 1092 1093 @Test public void test_rt32139() { 1094 final ObservableList<String> items = 1095 FXCollections.observableArrayList("Good value", "Bad value"); 1096 1097 final ComboBox<String> comboBox = new ComboBox<>(items); 1098 comboBox.getSelectionModel().select(0); 1099 1100 comboBox.getSelectionModel().selectedIndexProperty().addListener((ov, oldIdx, newIdx) -> { 1101 if (newIdx.intValue() != 0) { 1102 comboBox.getSelectionModel().select(0); 1103 } 1104 }); 1105 1106 StageLoader sl = new StageLoader(comboBox); 1107 1108 try { 1109 comboBox.getSelectionModel().select(1); 1110 } catch (StackOverflowError e) { 1111 fail("Stack overflow should not happen here"); 1112 } 1113 1114 sl.dispose(); 1115 } 1116 1117 @Test public void test_rt21186() { 1118 final ComboBox<String> comboBox = new ComboBox<>(); 1119 comboBox.setEditable(true); 1120 1121 StageLoader sl = new StageLoader(comboBox); 1122 1123 assertNull(comboBox.getTooltip()); 1124 assertNull(comboBox.getEditor().getTooltip()); 1125 1126 Tooltip tooltip = new Tooltip("Tooltip"); 1127 comboBox.setTooltip(tooltip); 1128 assertEquals(tooltip, comboBox.getTooltip()); 1129 assertEquals(tooltip, comboBox.getEditor().getTooltip()); 1130 1131 comboBox.setTooltip(null); 1132 assertNull(comboBox.getTooltip()); 1133 assertNull(comboBox.getEditor().getTooltip()); 1134 1135 sl.dispose(); 1136 } 1137 1138 @Test public void test_rt34573() { 1139 final ComboBox<String> comboBox = new ComboBox<>(); 1140 1141 final ListCell<String> customCell = new ListCellShim<String>() { 1142 @Override public void updateItem(String item, boolean empty) { 1143 super.updateItem(item, empty); 1144 setText(item); 1145 } 1146 }; 1147 comboBox.setButtonCell(customCell); 1148 1149 StageLoader sl = new StageLoader(comboBox); 1150 1151 comboBox.setItems(FXCollections.observableArrayList("A","B","C","D")); 1152 comboBox.setValue("B"); 1153 assertEquals("B", comboBox.getButtonCell().getText()); 1154 assertEquals(1, comboBox.getButtonCell().getIndex()); 1155 1156 comboBox.setItems(FXCollections.observableArrayList("1","2","3","4")); 1157 assertNull(comboBox.getButtonCell().getText()); 1158 assertEquals(-1, comboBox.getButtonCell().getIndex()); 1159 1160 sl.dispose(); 1161 } 1162 1163 @Test public void test_rt34566() { 1164 final ComboBox<String> comboBox = new ComboBox<>(); 1165 1166 final ListCell<String> customCell = new ListCellShim<String>() { 1167 @Override public void updateItem(String item, boolean empty) { 1168 super.updateItem(item, empty); 1169 setText(item); 1170 } 1171 }; 1172 comboBox.setButtonCell(customCell); 1173 1174 StageLoader sl = new StageLoader(comboBox); 1175 1176 comboBox.setItems(FXCollections.observableArrayList("A","B","C","D")); 1177 1178 PseudoClass empty = PseudoClass.getPseudoClass("empty"); 1179 1180 comboBox.setValue("B"); 1181 assertEquals("B", comboBox.getButtonCell().getText()); 1182 assertEquals(1, comboBox.getButtonCell().getIndex()); 1183 assertFalse(customCell.getPseudoClassStates().contains(empty)); 1184 1185 comboBox.setValue(null); 1186 Toolkit.getToolkit().firePulse(); 1187 assertNull(comboBox.getButtonCell().getText()); 1188 assertEquals(-1, comboBox.getButtonCell().getIndex()); 1189 assertTrue(customCell.getPseudoClassStates().contains(empty)); 1190 1191 comboBox.setValue("A"); 1192 assertEquals("A", comboBox.getButtonCell().getText()); 1193 assertEquals(0, comboBox.getButtonCell().getIndex()); 1194 assertFalse(customCell.getPseudoClassStates().contains(empty)); 1195 1196 sl.dispose(); 1197 } 1198 1199 private int test_rt34603_count = 0; 1200 @Test public void test_rt34603() { 1201 assertEquals(0, test_rt34603_count); 1202 1203 VBox hbox = new VBox(10); 1204 1205 ComboBox<String> box = new ComboBox<>(); 1206 box.getItems().add("test"); 1207 box.setEditable(true); 1208 box.getSelectionModel().selectFirst(); 1209 1210 Button defaultButton = new Button("press"); 1211 defaultButton.setOnAction(arg0 -> { 1212 test_rt34603_count++; 1213 }); 1214 defaultButton.setDefaultButton(true); 1215 1216 hbox.getChildren().addAll(box, defaultButton); 1217 1218 StageLoader sl = new StageLoader(hbox); 1219 1220 box.getEditor().requestFocus(); 1221 KeyEventFirer keyboard = new KeyEventFirer(box); 1222 keyboard.doKeyPress(KeyCode.ENTER); 1223 1224 assertEquals(1, test_rt34603_count); 1225 1226 sl.dispose(); 1227 } 1228 1229 private int test_rt35586_count = 0; 1230 @Test public void test_rt35586() { 1231 assertEquals(0, test_rt35586_count); 1232 1233 final ComboBox<String> cb = new ComboBox<String>(); 1234 cb.setEditable(true); 1235 cb.setOnAction(event -> { 1236 test_rt35586_count++; 1237 assertEquals("Test", cb.getEditor().getText()); 1238 }); 1239 1240 StageLoader sl = new StageLoader(cb); 1241 1242 cb.requestFocus(); 1243 cb.getEditor().setText("Test"); 1244 KeyEventFirer keyboard = new KeyEventFirer(cb); 1245 keyboard.doKeyPress(KeyCode.ENTER); 1246 1247 assertEquals(1, test_rt35586_count); 1248 1249 sl.dispose(); 1250 } 1251 1252 @Test public void test_rt35039() { 1253 final List<String> data = new ArrayList<>(); 1254 data.add("aabbaa"); 1255 data.add("bbc"); 1256 1257 final ComboBox<String> combo = new ComboBox<>(); 1258 combo.setEditable(true); 1259 combo.setItems(FXCollections.observableArrayList(data)); 1260 1261 StageLoader sl = new StageLoader(combo); 1262 1263 // everything should be null to start with 1264 assertNull(combo.getValue()); 1265 assertTrue(combo.getEditor().getText().isEmpty()); 1266 assertNull(combo.getSelectionModel().getSelectedItem()); 1267 1268 // select "bbc" and ensure everything is set to that 1269 combo.getSelectionModel().select(1); 1270 assertEquals("bbc", combo.getValue()); 1271 assertEquals("bbc", combo.getEditor().getText()); 1272 assertEquals("bbc", combo.getSelectionModel().getSelectedItem()); 1273 1274 // change the items list - but retain the same content. We expect 1275 // that "bbc" remains selected as it is still in the list 1276 combo.setItems(FXCollections.observableArrayList(data)); 1277 assertEquals("bbc", combo.getValue()); 1278 assertEquals("bbc", combo.getEditor().getText()); 1279 assertEquals("bbc", combo.getSelectionModel().getSelectedItem()); 1280 1281 sl.dispose(); 1282 } 1283 1284 @Test public void test_rt35840() { 1285 final ComboBox<String> cb = new ComboBox<String>(); 1286 cb.setEditable(true); 1287 StageLoader sl = new StageLoader(cb); 1288 cb.requestFocus(); 1289 1290 KeyEventFirer keyboard = new KeyEventFirer(cb); 1291 keyboard.doKeyTyped(KeyCode.T); 1292 keyboard.doKeyTyped(KeyCode.E); 1293 keyboard.doKeyTyped(KeyCode.S); 1294 keyboard.doKeyTyped(KeyCode.T); 1295 assertEquals("TEST", cb.getEditor().getText()); 1296 1297 assertNull(cb.getValue()); 1298 keyboard.doKeyPress(KeyCode.ENTER); 1299 assertEquals("TEST", cb.getValue()); 1300 1301 sl.dispose(); 1302 } 1303 1304 @Test public void test_rt36280_nonEditable_F4ShowsPopup() { 1305 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1306 StageLoader sl = new StageLoader(cb); 1307 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1308 1309 assertFalse(cb.isShowing()); 1310 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1311 assertTrue(cb.isShowing()); 1312 1313 sl.dispose(); 1314 } 1315 1316 @Test public void test_rt36280_nonEditable_altUpShowsPopup() { 1317 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1318 StageLoader sl = new StageLoader(cb); 1319 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1320 1321 assertFalse(cb.isShowing()); 1322 cbKeyboard.doKeyPress(KeyCode.UP, KeyModifier.ALT); // show the popup 1323 assertTrue(cb.isShowing()); 1324 1325 sl.dispose(); 1326 } 1327 1328 @Test public void test_rt36280_nonEditable_altDownShowsPopup() { 1329 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1330 StageLoader sl = new StageLoader(cb); 1331 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1332 1333 new StageLoader(cb); 1334 1335 assertFalse(cb.isShowing()); 1336 cbKeyboard.doKeyPress(KeyCode.DOWN, KeyModifier.ALT); // show the popup 1337 assertTrue(cb.isShowing()); 1338 1339 sl.dispose(); 1340 } 1341 1342 @Test public void test_rt36280_nonEditable_enterHidesShowingPopup() { 1343 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1344 StageLoader sl = new StageLoader(cb); 1345 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1346 1347 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1348 assertNotNull(listView); 1349 1350 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1351 1352 assertFalse(cb.isShowing()); 1353 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1354 assertTrue(cb.isShowing()); 1355 lvKeyboard.doKeyPress(KeyCode.ENTER); // hide the popup 1356 assertFalse(cb.isShowing()); 1357 1358 sl.dispose(); 1359 } 1360 1361 @Test public void test_rt36280_nonEditable_spaceHidesShowingPopup() { 1362 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1363 StageLoader sl = new StageLoader(cb); 1364 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1365 1366 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1367 assertNotNull(listView); 1368 1369 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1370 1371 assertFalse(cb.isShowing()); 1372 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1373 assertTrue(cb.isShowing()); 1374 lvKeyboard.doKeyPress(KeyCode.SPACE); // hide the popup 1375 assertFalse(cb.isShowing()); 1376 1377 sl.dispose(); 1378 } 1379 1380 @Test public void test_rt36280_nonEditable_escapeHidesShowingPopup() { 1381 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1382 StageLoader sl = new StageLoader(cb); 1383 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1384 1385 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1386 assertNotNull(listView); 1387 1388 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1389 1390 assertFalse(cb.isShowing()); 1391 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1392 assertTrue(cb.isShowing()); 1393 lvKeyboard.doKeyPress(KeyCode.ESCAPE); // hide the popup 1394 assertFalse(cb.isShowing()); 1395 1396 sl.dispose(); 1397 } 1398 1399 @Test public void test_rt36280_nonEditable_F4HidesShowingPopup() { 1400 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1401 StageLoader sl = new StageLoader(cb); 1402 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1403 1404 assertFalse(cb.isShowing()); 1405 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1406 assertTrue(cb.isShowing()); 1407 cbKeyboard.doKeyPress(KeyCode.F4); // hide the popup 1408 assertFalse(cb.isShowing()); 1409 1410 sl.dispose(); 1411 } 1412 1413 @Test public void test_rt36280_nonEditable_arrowKeysChangeSelection() { 1414 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1415 StageLoader sl = new StageLoader(cb); 1416 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1417 1418 assertFalse(cb.isShowing()); 1419 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1420 assertTrue(cb.isShowing()); 1421 1422 assertNull(cb.getSelectionModel().getSelectedItem()); 1423 1424 cbKeyboard.doDownArrowPress(); 1425 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1426 1427 cbKeyboard.doDownArrowPress(); 1428 assertEquals("b", cb.getSelectionModel().getSelectedItem()); 1429 1430 cbKeyboard.doUpArrowPress(); 1431 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1432 1433 sl.dispose(); 1434 } 1435 1436 @Test public void test_rt36280_editable_F4ShowsPopup() { 1437 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1438 cb.setEditable(true); 1439 StageLoader sl = new StageLoader(cb); 1440 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1441 1442 assertFalse(cb.isShowing()); 1443 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1444 assertTrue(cb.isShowing()); 1445 1446 sl.dispose(); 1447 } 1448 1449 @Test public void test_rt36280_editable_altUpShowsPopup() { 1450 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1451 cb.setEditable(true); 1452 StageLoader sl = new StageLoader(cb); 1453 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1454 1455 assertFalse(cb.isShowing()); 1456 cbKeyboard.doKeyPress(KeyCode.UP, KeyModifier.ALT); // show the popup 1457 assertTrue(cb.isShowing()); 1458 1459 sl.dispose(); 1460 } 1461 1462 @Test public void test_rt36280_editable_altDownShowsPopup_onComboBox() { 1463 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1464 cb.setEditable(true); 1465 StageLoader sl = new StageLoader(cb); 1466 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1467 1468 assertFalse(cb.isShowing()); 1469 assertTrue(cb.getEditor().getText().isEmpty()); 1470 cbKeyboard.doKeyPress(KeyCode.DOWN, KeyModifier.ALT); // show the popup 1471 assertTrue(cb.isShowing()); 1472 assertTrue(cb.getEditor().getText().isEmpty()); 1473 1474 sl.dispose(); 1475 } 1476 1477 @Test public void test_rt36280_editable_altDownShowsPopup_onTextField() { 1478 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1479 cb.setEditable(true); 1480 StageLoader sl = new StageLoader(cb); 1481 1482 KeyEventFirer tfKeyboard = new KeyEventFirer(cb.getEditor()); 1483 assertFalse(cb.isShowing()); 1484 assertTrue(cb.getEditor().getText().isEmpty()); 1485 tfKeyboard.doKeyPress(KeyCode.DOWN, KeyModifier.ALT); // show the popup 1486 assertTrue(cb.isShowing()); 1487 assertTrue(cb.getEditor().getText().isEmpty()); 1488 1489 sl.dispose(); 1490 } 1491 1492 @Test public void test_rt36280_editable_enterHidesShowingPopup() { 1493 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1494 cb.setEditable(true); 1495 StageLoader sl = new StageLoader(cb); 1496 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1497 1498 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1499 assertNotNull(listView); 1500 1501 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1502 1503 assertFalse(cb.isShowing()); 1504 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1505 assertTrue(cb.isShowing()); 1506 lvKeyboard.doKeyPress(KeyCode.ENTER); // hide the popup 1507 assertFalse(cb.isShowing()); 1508 1509 sl.dispose(); 1510 } 1511 1512 @Test public void test_rt36280_editable_spaceHidesShowingPopup() { 1513 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1514 cb.setEditable(true); 1515 StageLoader sl = new StageLoader(cb); 1516 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1517 1518 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1519 assertNotNull(listView); 1520 1521 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1522 1523 assertFalse(cb.isShowing()); 1524 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1525 assertTrue(cb.isShowing()); 1526 lvKeyboard.doKeyPress(KeyCode.SPACE); // hide the popup 1527 assertFalse(cb.isShowing()); 1528 1529 sl.dispose(); 1530 } 1531 1532 @Test public void test_rt36280_editable_escapeHidesShowingPopup() { 1533 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1534 cb.setEditable(true); 1535 StageLoader sl = new StageLoader(cb); 1536 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1537 1538 ListView listView = (ListView) ((ComboBoxListViewSkin)cb.getSkin()).getPopupContent(); 1539 assertNotNull(listView); 1540 1541 KeyEventFirer lvKeyboard = new KeyEventFirer(listView); 1542 1543 assertFalse(cb.isShowing()); 1544 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1545 assertTrue(cb.isShowing()); 1546 lvKeyboard.doKeyPress(KeyCode.ESCAPE); // hide the popup 1547 assertFalse(cb.isShowing()); 1548 1549 sl.dispose(); 1550 } 1551 1552 @Test public void test_rt36280_editable_F4HidesShowingPopup() { 1553 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1554 cb.setEditable(true); 1555 StageLoader sl = new StageLoader(cb); 1556 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1557 1558 assertFalse(cb.isShowing()); 1559 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1560 assertTrue(cb.isShowing()); 1561 cbKeyboard.doKeyPress(KeyCode.F4); // hide the popup 1562 assertFalse(cb.isShowing()); 1563 1564 sl.dispose(); 1565 } 1566 1567 @Test public void test_rt36280_editable_arrowKeysChangeSelection() { 1568 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1569 cb.setEditable(true); 1570 StageLoader sl = new StageLoader(cb); 1571 KeyEventFirer cbKeyboard = new KeyEventFirer(cb); 1572 1573 assertFalse(cb.isShowing()); 1574 cbKeyboard.doKeyPress(KeyCode.F4); // show the popup 1575 assertTrue(cb.isShowing()); 1576 1577 assertNull(cb.getSelectionModel().getSelectedItem()); 1578 1579 cbKeyboard.doDownArrowPress(); 1580 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1581 1582 cbKeyboard.doDownArrowPress(); 1583 assertEquals("b", cb.getSelectionModel().getSelectedItem()); 1584 1585 cbKeyboard.doUpArrowPress(); 1586 assertEquals("a", cb.getSelectionModel().getSelectedItem()); 1587 1588 sl.dispose(); 1589 } 1590 1591 @Test public void test_rt36651() { 1592 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1593 cb.setEditable(true); 1594 StageLoader sl = new StageLoader(cb); 1595 1596 assertNull(cb.getValue()); 1597 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1598 assertNull(cb.getSelectionModel().getSelectedItem()); 1599 1600 sl.getStage().requestFocus(); 1601 cb.show(); 1602 Toolkit.getToolkit().firePulse(); 1603 1604 // selection should not change just by showing the popup 1605 assertNull(cb.getValue()); 1606 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1607 assertNull(cb.getSelectionModel().getSelectedItem()); 1608 1609 sl.dispose(); 1610 } 1611 1612 @Test public void test_rt36717() { 1613 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1614 StageLoader sl = new StageLoader(cb); 1615 1616 // the stack overflow only occurs when a ComboBox changes from non-editable to editable 1617 cb.setEditable(false); 1618 cb.setEditable(true); 1619 assertNotNull(cb.getEditor()); 1620 KeyEventFirer tfKeyboard = new KeyEventFirer(cb.getEditor()); 1621 tfKeyboard.doKeyPress(KeyCode.ENTER); // Stack overflow here 1622 1623 sl.dispose(); 1624 } 1625 1626 @Test public void test_rt36827() { 1627 final Button btn = new Button("focus owner"); 1628 final ComboBox<String> cb = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1629 VBox vbox = new VBox(btn, cb); 1630 1631 StageLoader sl = new StageLoader(vbox); 1632 sl.getStage().requestFocus(); 1633 btn.requestFocus(); 1634 Toolkit.getToolkit().firePulse(); 1635 Scene scene = sl.getStage().getScene(); 1636 1637 assertTrue(btn.isFocused()); 1638 assertEquals(btn, scene.getFocusOwner()); 1639 1640 MouseEventFirer mouse = new MouseEventFirer(cb); 1641 mouse.fireMousePressAndRelease(); 1642 1643 assertTrue(cb.isShowing()); 1644 assertTrue(cb.isFocused()); 1645 assertEquals(cb, scene.getFocusOwner()); 1646 1647 sl.dispose(); 1648 } 1649 1650 @Test public void test_rt36902() { 1651 final ComboBox<String> cb1 = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1652 final ComboBox<String> cb2 = new ComboBox<>(FXCollections.observableArrayList("a", "b", "c")); 1653 cb2.setEditable(true); 1654 VBox vbox = new VBox(cb1, cb2); 1655 1656 // lame - I would rather have one keyboard here but I couldn't get it to 1657 // work, so watch out for which keyboard is used below 1658 KeyEventFirer cb1Keyboard = new KeyEventFirer(cb1); 1659 KeyEventFirer cb2Keyboard = new KeyEventFirer(cb2); 1660 1661 StageLoader sl = new StageLoader(vbox); 1662 sl.getStage().requestFocus(); 1663 cb1.requestFocus(); 1664 Toolkit.getToolkit().firePulse(); 1665 Scene scene = sl.getStage().getScene(); 1666 1667 assertTrue(cb1.isFocused()); 1668 assertEquals(cb1, scene.getFocusOwner()); 1669 1670 // move focus forward to cb2 1671 cb1Keyboard.doKeyPress(KeyCode.TAB); 1672 assertTrue(cb2.isFocused()); 1673 assertEquals(cb2, scene.getFocusOwner()); 1674 1675 // move focus forward again to cb1 1676 cb2Keyboard.doKeyPress(KeyCode.TAB); 1677 assertTrue(cb1.isFocused()); 1678 assertEquals(cb1, scene.getFocusOwner()); 1679 1680 // now start going backwards with shift-tab. 1681 // The first half of the bug is here - when we shift-tab into cb2, we 1682 // actually go into the FakeFocusTextField subcomponent, so whilst the 1683 // cb2.isFocused() returns true as expected, the scene focus owner is 1684 // not the ComboBox, but the FakeFocusTextField inside it 1685 cb1Keyboard.doKeyPress(KeyCode.TAB, KeyModifier.SHIFT); 1686 assertTrue("Expect cb2 to be focused, but actual focus owner is: " + scene.getFocusOwner(), 1687 cb2.isFocused()); 1688 // Updated with fix for RT-34602: The TextField now never gets 1689 // focus (it's just faking it). 1690 // assertEquals("Expect cb2 TextField to be focused, but actual focus owner is: " + scene.getFocusOwner(), 1691 // cb2.getEditor(), scene.getFocusOwner()); 1692 assertEquals("Expect cb2 to be focused, but actual focus owner is: " + scene.getFocusOwner(), 1693 cb2, scene.getFocusOwner()); 1694 1695 // This is where the second half of the bug appears, as we are stuck in 1696 // the FakeFocusTextField of cb2, we never make it to cb1 1697 cb2Keyboard.doKeyPress(KeyCode.TAB, KeyModifier.SHIFT); 1698 assertTrue(cb1.isFocused()); 1699 assertEquals(cb1, scene.getFocusOwner()); 1700 1701 sl.dispose(); 1702 } 1703 1704 private int rt_38901_counter; 1705 @Test public void test_rt_38901_selectNull() { 1706 test_rt_38901(true); 1707 } 1708 1709 @Test public void test_rt_38901_selectNegativeOne() { 1710 test_rt_38901(false); 1711 } 1712 1713 private void test_rt_38901(boolean selectNull) { 1714 rt_38901_counter = 0; 1715 1716 final ComboBox<String> cb = new ComboBox<>(); 1717 cb.setOnShowing((e) -> { 1718 cb.getItems().setAll("DUMMY " + (rt_38901_counter++)); 1719 }); 1720 1721 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1722 assertNull(cb.getSelectionModel().getSelectedItem()); 1723 assertNull(cb.getValue()); 1724 assertEquals(0, cb.getItems().size()); 1725 1726 // round one 1727 cb.show(); 1728 assertEquals(1, cb.getItems().size()); 1729 assertEquals("DUMMY 0", cb.getItems().get(0)); 1730 cb.hide(); 1731 1732 cb.getSelectionModel().select(0); 1733 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1734 assertEquals("DUMMY 0", cb.getSelectionModel().getSelectedItem()); 1735 assertEquals("DUMMY 0", cb.getValue()); 1736 1737 if (selectNull) cb.getSelectionModel().select(null); 1738 else cb.getSelectionModel().select(-1); 1739 1740 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1741 assertNull(cb.getSelectionModel().getSelectedItem()); 1742 assertNull(cb.getValue()); 1743 1744 1745 // round two 1746 cb.show(); 1747 assertEquals(1, cb.getItems().size()); 1748 assertEquals("DUMMY 1", cb.getItems().get(0)); 1749 cb.hide(); 1750 1751 cb.getSelectionModel().select(0); 1752 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1753 assertEquals("DUMMY 1", cb.getSelectionModel().getSelectedItem()); 1754 assertEquals("DUMMY 1", cb.getValue()); 1755 1756 if (selectNull) cb.getSelectionModel().select(null); 1757 else cb.getSelectionModel().select(-1); 1758 1759 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1760 assertNull(cb.getSelectionModel().getSelectedItem()); 1761 assertNull(cb.getValue()); 1762 } 1763 1764 private int rt_22572_counter; 1765 @Test public void test_rt_22572() { 1766 rt_22572_counter = 0; 1767 1768 final ComboBox<String> cb = new ComboBox<>(); 1769 cb.setOnShowing((e) -> { 1770 cb.getItems().setAll("DUMMY " + (rt_22572_counter++)); 1771 }); 1772 1773 StageLoader sl = new StageLoader(cb); 1774 1775 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1776 assertNull(cb.getSelectionModel().getSelectedItem()); 1777 assertNull(cb.getValue()); 1778 assertEquals(0, cb.getItems().size()); 1779 1780 // round one 1781 cb.show(); 1782 assertEquals(1, cb.getItems().size()); 1783 assertEquals("DUMMY 0", cb.getItems().get(0)); 1784 cb.hide(); 1785 1786 cb.getSelectionModel().select(0); 1787 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1788 assertEquals("DUMMY 0", cb.getSelectionModel().getSelectedItem()); 1789 assertEquals("DUMMY 0", cb.getValue()); 1790 1791 1792 // round two - even though the items change, the value should still be 1793 // the old value (even though it doesn't exist in the items list any longer). 1794 // The selectedIndex and selectedItem do get reset however. 1795 cb.show(); 1796 assertEquals(1, cb.getItems().size()); 1797 assertEquals("DUMMY 1", cb.getItems().get(0)); 1798 cb.hide(); 1799 1800 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1801 assertNull(cb.getSelectionModel().getSelectedItem()); 1802 assertEquals("DUMMY 0", cb.getValue()); 1803 1804 sl.dispose(); 1805 } 1806 1807 private int rt_22937_counter; 1808 @Test public void test_rt_22937() { 1809 rt_22937_counter = 0; 1810 1811 final ComboBox<String> cb = new ComboBox<>(); 1812 cb.setOnShowing((e) -> { 1813 cb.getItems().setAll("DUMMY " + (rt_22937_counter++)); 1814 }); 1815 1816 cb.getItems().add("Toto"); 1817 cb.setEditable(true); 1818 cb.setValue("Tata"); 1819 1820 StageLoader sl = new StageLoader(cb); 1821 1822 assertEquals(-1, cb.getSelectionModel().getSelectedIndex()); 1823 assertEquals("Tata", cb.getSelectionModel().getSelectedItem()); 1824 assertEquals("Tata", cb.getValue()); 1825 assertEquals(1, cb.getItems().size()); 1826 1827 cb.show(); 1828 assertEquals(1, cb.getItems().size()); 1829 assertEquals("DUMMY 0", cb.getItems().get(0)); 1830 cb.hide(); 1831 1832 cb.getSelectionModel().select(0); 1833 assertEquals(0, cb.getSelectionModel().getSelectedIndex()); 1834 assertEquals("DUMMY 0", cb.getSelectionModel().getSelectedItem()); 1835 assertEquals("DUMMY 0", cb.getValue()); 1836 1837 sl.dispose(); 1838 } 1839 1840 @Test public void test_rt_39809() { 1841 ComboBox<String> comboBox = new ComboBox<>(); 1842 comboBox.getItems().setAll(null, "1", "2", "3"); 1843 1844 StageLoader sl = new StageLoader(comboBox); 1845 1846 comboBox.getSelectionModel().clearAndSelect(1); 1847 assertEquals("1", comboBox.getSelectionModel().getSelectedItem()); 1848 assertEquals(1, comboBox.getSelectionModel().getSelectedIndex()); 1849 1850 comboBox.getSelectionModel().clearAndSelect(0); 1851 assertEquals(null, comboBox.getSelectionModel().getSelectedItem()); 1852 assertEquals(0, comboBox.getSelectionModel().getSelectedIndex()); 1853 1854 sl.dispose(); 1855 } 1856 1857 @Test public void test_rt_39908() { 1858 ObservableList<String> model = FXCollections.observableArrayList("0", "1", "2", "3"); 1859 ComboBox<String> comboBox = new ComboBox<>(model); 1860 1861 StageLoader sl = new StageLoader(comboBox); 1862 1863 comboBox.getSelectionModel().clearAndSelect(1); 1864 assertEquals("1", comboBox.getSelectionModel().getSelectedItem()); 1865 assertEquals(1, comboBox.getSelectionModel().getSelectedIndex()); 1866 1867 model.set(0, "a"); 1868 assertEquals("1", comboBox.getSelectionModel().getSelectedItem()); 1869 assertEquals(1, comboBox.getSelectionModel().getSelectedIndex()); 1870 1871 sl.dispose(); 1872 } 1873 1874 /** 1875 * Bullet 1: selected index must be updated 1876 * Corner case: last selected. Fails for core 1877 */ 1878 @Test public void test_rt_40012_selectedAtLastOnDisjointRemoveItemsAbove() { 1879 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1880 ComboBox<String> comboBox = new ComboBox<>(items); 1881 SelectionModel sm = comboBox.getSelectionModel(); 1882 1883 int last = items.size() - 1; 1884 1885 // selecting item "5" 1886 sm.select(last); 1887 1888 // disjoint remove of 2 elements above the last selected 1889 // Removing "1" and "3" 1890 items.removeAll(items.get(1), items.get(3)); 1891 1892 // selection should move up two places such that it remains on item "5", 1893 // but in index (last - 2). 1894 int expected = last - 2; 1895 assertEquals("5", sm.getSelectedItem()); 1896 assertEquals("selected index after disjoint removes above", expected, sm.getSelectedIndex()); 1897 } 1898 1899 /** 1900 * Variant of 1: if selectedIndex is not updated, 1901 * the old index is no longer valid 1902 * for accessing the items. 1903 */ 1904 @Test public void test_rt_40012_accessSelectedAtLastOnDisjointRemoveItemsAbove() { 1905 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1906 ComboBox<String> comboBox = new ComboBox<>(items); 1907 SelectionModel sm = comboBox.getSelectionModel(); 1908 1909 int last = items.size() - 1; 1910 1911 // selecting item "5" 1912 sm.select(last); 1913 1914 // disjoint remove of 2 elements above the last selected 1915 items.removeAll(items.get(1), items.get(3)); 1916 int selected = sm.getSelectedIndex(); 1917 if (selected > -1) { 1918 items.get(selected); 1919 } 1920 } 1921 1922 /** 1923 * Bullet 2: selectedIndex notification count 1924 * 1925 * Note that we don't use the corner case of having the last index selected 1926 * (which fails already on updating the index) 1927 */ 1928 private int rt_40012_count = 0; 1929 @Test public void test_rt_40012_selectedIndexNotificationOnDisjointRemovesAbove() { 1930 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1931 ComboBox<String> comboBox = new ComboBox<>(items); 1932 SelectionModel sm = comboBox.getSelectionModel(); 1933 1934 int last = items.size() - 2; 1935 sm.select(last); 1936 assertEquals(last, sm.getSelectedIndex()); 1937 1938 rt_40012_count = 0; 1939 sm.selectedIndexProperty().addListener(o -> rt_40012_count++); 1940 1941 // disjoint remove of 2 elements above the last selected 1942 items.removeAll(items.get(1), items.get(3)); 1943 assertEquals("sanity: selectedIndex must be shifted by -2", last - 2, sm.getSelectedIndex()); 1944 assertEquals("must fire single event on removes above", 1, rt_40012_count); 1945 } 1946 1947 /** 1948 * Bullet 3: unchanged selectedItem must not fire change 1949 */ 1950 @Test 1951 public void test_rt_40012_selectedItemNotificationOnDisjointRemovesAbove() { 1952 ObservableList<String> items = FXCollections.observableArrayList("0", "1", "2", "3", "4", "5"); 1953 ComboBox<String> comboBox = new ComboBox<>(items); 1954 SelectionModel sm = comboBox.getSelectionModel(); 1955 1956 int last = items.size() - 2; 1957 Object lastItem = items.get(last); 1958 sm.select(last); 1959 assertEquals(lastItem, sm.getSelectedItem()); 1960 1961 rt_40012_count = 0; 1962 sm.selectedItemProperty().addListener(o -> rt_40012_count++); 1963 1964 // disjoint remove of 2 elements above the last selected 1965 items.removeAll(items.get(1), items.get(3)); 1966 assertEquals("sanity: selectedItem unchanged", lastItem, sm.getSelectedItem()); 1967 assertEquals("must not fire on unchanged selected item", 0, rt_40012_count); 1968 } 1969 1970 @Test public void test_jdk_8150946_testCommit_valid() { 1971 ComboBox<String> comboBox = new ComboBox<>(); 1972 comboBox.setEditable(true); 1973 assertEquals(null, comboBox.getValue()); 1974 comboBox.getEditor().setText("ABC"); 1975 comboBox.commitValue(); 1976 assertEquals("ABC", comboBox.getValue()); 1977 } 1978 1979 @Test public void test_jdk_8150946_testCancel_toNull() { 1980 ComboBox<String> comboBox = new ComboBox<>(); 1981 comboBox.setEditable(true); 1982 assertNull(comboBox.getValue()); 1983 assertEquals("", comboBox.getEditor().getText()); 1984 comboBox.getEditor().setText("ABC"); 1985 assertNull(comboBox.getValue()); 1986 comboBox.cancelEdit(); 1987 assertNull(comboBox.getValue()); 1988 assertNull(comboBox.getEditor().getText()); 1989 } 1990 1991 @Test public void test_jdk_8150946_testCancel_toNonNull() { 1992 ComboBox<String> comboBox = new ComboBox<>(); 1993 comboBox.setEditable(true); 1994 comboBox.getEditor().setText("ABC"); 1995 comboBox.commitValue(); 1996 assertEquals("ABC", comboBox.getValue()); 1997 assertEquals("ABC", comboBox.getEditor().getText()); 1998 comboBox.getEditor().setText("DEF"); 1999 assertEquals("DEF", comboBox.getEditor().getText()); 2000 assertEquals("ABC", comboBox.getValue()); 2001 comboBox.cancelEdit(); 2002 assertEquals("ABC", comboBox.getValue()); 2003 assertEquals("ABC", comboBox.getEditor().getText()); 2004 } 2005 2006 @Test public void test_jdk_8160493() { 2007 AtomicInteger count = new AtomicInteger(); 2008 comboBox.valueProperty().addListener(o -> count.incrementAndGet()); 2009 assertEquals(0, count.get()); 2010 2011 comboBox.getItems().addAll("Apple", "Orange", "Banana"); 2012 sm.select(1); 2013 assertTrue(sm.isSelected(1)); 2014 assertEquals(1, count.get()); 2015 assertEquals("Orange", comboBox.getValue()); 2016 2017 comboBox.setValue("New Value"); 2018 assertEquals(2, count.get()); 2019 assertEquals("New Value", comboBox.getValue()); 2020 } 2021 2022 private int skinChangedCount = 0; 2023 @Test public void test_JDK_8185854() { 2024 final FlowPane comboPane = new FlowPane(10, 10); 2025 ComboBox combo = new ComboBox<String>(); 2026 2027 combo.skinProperty().addListener((o, oldSkin, newSkin) -> { 2028 skinChangedCount++; 2029 }); 2030 2031 combo.setDisable(false); 2032 combo.setEditable(false); 2033 2034 comboPane.getChildren().add(combo); 2035 2036 TabPane tabPane = new TabPane(); 2037 Tab tab = new Tab(); 2038 tab.setText("ComboBox"); 2039 tab.setContent(comboPane); 2040 tabPane.getTabs().add(tab); 2041 2042 BorderPane p = new BorderPane(); 2043 p.setCenter(tabPane); 2044 2045 Scene scene = new Scene(p); 2046 scene.getStylesheets().add(ComboBoxTest.class.getResource("JDK_8185854.css").toExternalForm()); 2047 2048 Toolkit tk = Toolkit.getToolkit(); 2049 2050 Stage stage = new Stage(); 2051 stage.setScene(scene); 2052 stage.setWidth(500); 2053 stage.setHeight(400); 2054 2055 stage.show(); 2056 2057 tk.firePulse(); 2058 2059 assertEquals("ComboBox skinProperty changed more than once, which is not expected.", 1, skinChangedCount); 2060 } 2061 }