1 /* 2 * Copyright (c) 2011, 2014, 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 javafx.scene.control; 27 28 import com.sun.javafx.event.EventUtil; 29 import com.sun.javafx.pgstub.StubScene; 30 31 import javafx.beans.property.BooleanProperty; 32 import javafx.beans.property.SimpleBooleanProperty; 33 import javafx.scene.Group; 34 import javafx.scene.Scene; 35 import javafx.scene.input.KeyCode; 36 import javafx.scene.input.KeyEvent; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 41 import static junit.framework.Assert.assertEquals; 42 import static junit.framework.Assert.assertNotNull; 43 import static org.junit.Assert.*; 44 45 public class ToggleGroupTest { 46 private ToggleButton b1, b2, b3, b4; 47 private ToggleGroup g1, g2; 48 49 private ToggleButton make(String s) { 50 final ToggleButton btn = new ToggleButton(s); 51 btn.setId(s); 52 return btn; 53 } 54 55 private boolean isMember(ToggleButton b, ToggleGroup g) { 56 for (Toggle t : g.getToggles()) { 57 if (t == b) return true; 58 } 59 return false; 60 } 61 62 private boolean isNotMember(ToggleButton b, ToggleGroup g) { 63 return !isMember(b, g); 64 } 65 66 @Before public void setup() { 67 b1 = make("one"); 68 b2 = make("two"); 69 b3 = make("three"); 70 b4 = make("four"); 71 g1 = new ToggleGroup(); 72 g2 = new ToggleGroup(); 73 } 74 75 // really a test of ToggleButton, not ToggleGroup 76 @Test public void testButtonInit() { 77 assertFalse(b1.isSelected()); 78 assertNull(b1.getToggleGroup()); 79 } 80 81 @Test public void testGroupInit() { 82 assertTrue(g1.getToggles().isEmpty()); 83 assertNull(g1.getSelectedToggle()); 84 } 85 86 @Test public void testGroupMembership() { 87 b1.setToggleGroup(g1); 88 b2.setToggleGroup(g2); 89 b3.setToggleGroup(g1); 90 b4.setToggleGroup(g2); 91 92 assertTrue(isMember(b1, g1)); 93 assertTrue(isMember(b2, g2)); 94 assertTrue(isMember(b3, g1)); 95 assertTrue(isMember(b4, g2)); 96 97 b3.setToggleGroup(null); 98 b4.setToggleGroup(g1); 99 100 assertTrue(isNotMember(b3, g1)); 101 assertTrue(isMember(b4, g1)); 102 assertTrue(isNotMember(b4, g2)); 103 } 104 105 @Test public void testSelectAfterAdding() { 106 b1.setToggleGroup(g1); 107 b2.setToggleGroup(g1); 108 b3.setToggleGroup(g1); 109 110 b1.setSelected(true); 111 assertTrue(b1.isSelected()); 112 assertEquals(b1, g1.getSelectedToggle()); 113 b2.setSelected(true); 114 assertFalse(b1.isSelected()); 115 assertTrue(b2.isSelected()); 116 assertEquals(b2, g1.getSelectedToggle()); 117 } 118 119 @Test public void testSelectBeforeAdding1() { 120 b2.setSelected(true); 121 b1.setToggleGroup(g1); 122 b2.setToggleGroup(g1); 123 b3.setToggleGroup(g1); 124 125 assertFalse(b1.isSelected()); 126 assertTrue(b2.isSelected()); 127 assertFalse(b3.isSelected()); 128 assertEquals(b2, g1.getSelectedToggle()); 129 } 130 131 @Test public void testSelectBeforeAdding2() { 132 b2.setSelected(true); 133 b3.setSelected(true); 134 b1.setToggleGroup(g1); 135 b2.setToggleGroup(g1); 136 b3.setToggleGroup(g1); 137 138 assertFalse(b1.isSelected()); 139 assertFalse(b2.isSelected()); 140 assertTrue(b3.isSelected()); 141 assertEquals(b3, g1.getSelectedToggle()); 142 } 143 144 @Test public void testDeselect() { 145 b2.setSelected(true); 146 b1.setToggleGroup(g1); 147 b2.setToggleGroup(g1); 148 b3.setToggleGroup(g1); 149 b2.setSelected(false); 150 151 assertFalse(b1.isSelected()); 152 assertFalse(b2.isSelected()); 153 assertFalse(b3.isSelected()); 154 assertNull(g1.getSelectedToggle()); 155 } 156 157 @Test public void testSetSelected() { 158 b1.setToggleGroup(g1); 159 b2.setToggleGroup(g1); 160 b3.setToggleGroup(g1); 161 162 g1.selectToggle(b1); 163 assertEquals(b1, g1.getSelectedToggle()); 164 assertTrue(b1.isSelected()); 165 assertFalse(b2.isSelected()); 166 assertFalse(b3.isSelected()); 167 168 g1.selectToggle(b2); 169 assertEquals(b2, g1.getSelectedToggle()); 170 assertFalse(b1.isSelected()); 171 assertTrue(b2.isSelected()); 172 assertFalse(b3.isSelected()); 173 174 g1.selectToggle(null); 175 assertNull(g1.getSelectedToggle()); 176 assertFalse(b1.isSelected()); 177 assertFalse(b2.isSelected()); 178 assertFalse(b3.isSelected()); 179 } 180 181 @Test public void testSetSelectedWrongGroup() { 182 b1.setToggleGroup(g1); 183 b2.setToggleGroup(g1); 184 b3.setToggleGroup(g2); 185 b4.setToggleGroup(g2); 186 g1.selectToggle(b1); 187 g2.selectToggle(b3); 188 189 assertTrue(b1.isSelected()); 190 assertFalse(b2.isSelected()); 191 assertTrue(b3.isSelected()); 192 assertFalse(b4.isSelected()); 193 assertEquals(b1, g1.getSelectedToggle()); 194 assertEquals(b3, g2.getSelectedToggle()); 195 196 // this is illegal, nothing should change 197 g2.selectToggle(b2); 198 199 assertTrue(b1.isSelected()); 200 assertFalse(b2.isSelected()); 201 assertTrue(b3.isSelected()); 202 assertFalse(b4.isSelected()); 203 assertEquals(b1, g1.getSelectedToggle()); 204 assertEquals(b3, g2.getSelectedToggle()); 205 } 206 207 @Test public void testSetSelectedWrongGroup2() { 208 b1.setToggleGroup(g1); 209 b2.setToggleGroup(g1); 210 b3.setToggleGroup(g2); 211 b4.setToggleGroup(g2); 212 g1.selectToggle(b1); 213 g2.selectToggle(b3); 214 215 assertTrue(b1.isSelected()); 216 assertFalse(b2.isSelected()); 217 assertTrue(b3.isSelected()); 218 assertFalse(b4.isSelected()); 219 assertEquals(b1, g1.getSelectedToggle()); 220 assertEquals(b3, g2.getSelectedToggle()); 221 222 // this is illegal, nothing should change 223 g2.selectToggle(b1); 224 225 assertTrue(b1.isSelected()); 226 assertFalse(b2.isSelected()); 227 assertTrue(b3.isSelected()); 228 assertFalse(b4.isSelected()); 229 assertEquals(b1, g1.getSelectedToggle()); 230 assertEquals(b3, g2.getSelectedToggle()); 231 } 232 233 // RT-3977 234 @Test public void testAddMultipleSelected() { 235 b1.setSelected(true); 236 b2.setSelected(true); 237 b3.setSelected(true); 238 b1.setToggleGroup(g1); 239 b2.setToggleGroup(g1); 240 b3.setToggleGroup(g1); 241 242 assertFalse(b1.isSelected()); 243 assertFalse(b2.isSelected()); 244 assertTrue(b3.isSelected()); 245 assertEquals(b3, g1.getSelectedToggle()); 246 } 247 248 // remove an unselected button 249 // remove selected button 250 @Test public void testRemoveSelected() { 251 b1.setToggleGroup(g1); 252 b2.setToggleGroup(g1); 253 b3.setToggleGroup(g1); 254 b2.setSelected(true); 255 256 b2.setToggleGroup(g2); 257 assertFalse(b1.isSelected()); 258 assertTrue(b2.isSelected()); 259 assertFalse(b3.isSelected()); 260 assertNull(g1.getSelectedToggle()); 261 assertEquals(b2, g2.getSelectedToggle()); 262 } 263 264 @Test public void testRemoveUnselected() { 265 b1.setToggleGroup(g1); 266 b2.setToggleGroup(g1); 267 b3.setToggleGroup(g1); 268 b2.setSelected(true); 269 270 b3.setToggleGroup(g2); 271 assertFalse(b1.isSelected()); 272 assertTrue(b2.isSelected()); 273 assertFalse(b3.isSelected()); 274 assertEquals(b2, g1.getSelectedToggle()); 275 } 276 277 @Test public void selectButtonInToggleGroupThenUnselectIt_ToggleGroup_getSelectedToggle_ShouldReturnNull() { 278 b1.setToggleGroup(g1); 279 b2.setToggleGroup(g1); 280 assertFalse(b1.isSelected()); 281 assertFalse(b2.isSelected()); 282 assertNull(g1.getSelectedToggle()); 283 284 b1.setSelected(true); 285 assertTrue(b1.isSelected()); 286 assertSame(b1, g1.getSelectedToggle()); 287 288 b1.setSelected(false); 289 assertFalse(b1.isSelected()); 290 assertFalse(b2.isSelected()); 291 assertNull(g1.getSelectedToggle()); 292 } 293 294 @Test public void settingSelectedToggleAndThenCreatingAModelAndReadingTheValueStillWorks() { 295 b1.setToggleGroup(g1); 296 b2.setToggleGroup(g1); 297 b3.setToggleGroup(g1); 298 g1.selectToggle(b1); 299 assertSame(b1, g1.selectedToggleProperty().get()); 300 assertTrue(b1.isSelected()); 301 } 302 303 // if (old == null || old.getToggleGroup() == ToggleGroup.this || !old.isSelected()) 304 // @Test public void foo() { 305 // // old != null 306 // // old.getToggleGroup() != this 307 // // old.isSelected (or is it, old is not selected?) 308 // b1.setToggleGroup(g1); 309 // b2.setToggleGroup(g1); 310 // b1.setSelected(true); 311 // b1.setToggleGroup(g2); 312 // assertNull(g1.getSelectedToggle()); 313 // assertTrue(b1.isSelected()); 314 // assertFalse(b2.isSelected()); 315 // } 316 317 // I just removed support for binding the "selectedToggle" property of the ToggleGroup. 318 // This was done because, as the following tests were beginning to demonstrate, the 319 // ToggleGroup simply begins to fail in its function as a mechanism for enforcing 320 // mutual exclusivity when you allow it to be bound. Likewise, the ability to 321 // bind the "selected" state of the individual Toggles is also suspect, for the same 322 // reason. Although since a Toggle (such as a RadioButton) doesn't have to be placed 323 // into a ToggleGroup, it does make sense to allow that to be bound. In which case, 324 // if two bound toggles are in the same ToggleGroup, then while both of the Toggles 325 // may claim to be selected, the ToggleGroup will only allow one of them (and it 326 // might be arbitrary as to which it is) to be bound. 327 328 // I just want to make sure, really, that there is no exception here in this case and 329 // that one of the "selected" toggles is actually selected 330 @Test public void bindingTwoTogglesSelectedBothToTrueResultsInOnlyOneBeingSelectedOnTheToggleGroup() { 331 BooleanProperty selected = new SimpleBooleanProperty(true); 332 b1.setToggleGroup(g1); 333 b2.setToggleGroup(g1); 334 b3.setToggleGroup(g1); 335 b1.selectedProperty().bind(selected); 336 b2.selectedProperty().bind(selected); 337 assertTrue(b1.isSelected()); 338 assertTrue(b2.isSelected()); 339 assertTrue(g1.getSelectedToggle() == b1 || g1.getSelectedToggle() == b2); 340 } 341 342 // Basically, if you manually bind the "selected" state of an external toggle, it doesn't really 343 // impact what the selected item is in the toggle group. It is simply, the last toggle to be set 344 // true, wins, as far as the toggle group is concerned. 345 @Test public void bindingTwoTogglesSelectedBothToTrueAndManuallySelectingAThirdResultsInTheThirdBeingSelected() { 346 BooleanProperty selected = new SimpleBooleanProperty(true); 347 b1.setToggleGroup(g1); 348 b2.setToggleGroup(g1); 349 b3.setToggleGroup(g1); 350 b1.selectedProperty().bind(selected); 351 b2.selectedProperty().bind(selected); 352 g1.selectToggle(b3); 353 assertTrue(b1.isSelected()); 354 assertTrue(b2.isSelected()); 355 assertTrue(b3.isSelected()); 356 assertSame(b3, g1.getSelectedToggle()); 357 } 358 359 @Test public void settingTheSelectedToggleAndThenBindingAnotherToTrueResultsInTheBoundToggleBeingSelected() { 360 BooleanProperty selected = new SimpleBooleanProperty(true); 361 b1.setToggleGroup(g1); 362 b2.setToggleGroup(g1); 363 b3.setToggleGroup(g1); 364 g1.selectToggle(b3); 365 b1.selectedProperty().bind(selected); 366 assertTrue(b1.isSelected()); 367 assertFalse(b3.isSelected()); 368 assertEquals(b1, g1.getSelectedToggle()); 369 } 370 371 @Test public void addingTogglesUsingToggleGroupGetToggles() { 372 g1.getToggles().add(b1); 373 g1.getToggles().add(b2); 374 assertTrue(isMember(b1, g1)); 375 assertTrue(isMember(b2, g1)); 376 } 377 378 @Test public void addingTogglesUsingToggleGroupGetTogglesAndToggleSetToggleGroup() { 379 g1.getToggles().add(b1); 380 g1.getToggles().add(b2); 381 b3.setToggleGroup(g1); 382 assertTrue(isMember(b1, g1)); 383 assertTrue(isMember(b2, g1)); 384 assertTrue(isMember(b3, g1)); 385 } 386 387 @Test public void removingTogglesUsingToggleGroupGetToggles() { 388 g1.getToggles().add(b1); 389 g1.getToggles().remove(b2); 390 assertTrue(isMember(b1, g1)); 391 assertTrue(isNotMember(b2, g1)); 392 } 393 394 @Test public void removingTogglesUsingToggleGroupGetTogglesAndToggleSetToggleGroup() { 395 g1.getToggles().add(b1); 396 g1.getToggles().remove(b2); 397 b3.setToggleGroup(g1); 398 assertTrue(isMember(b1, g1)); 399 assertTrue(isNotMember(b2, g1)); 400 assertTrue(isMember(b3, g1)); 401 } 402 403 @Test public void addingTogglesUsingToggleGroupGetTogglesSetAll() { 404 g1.getToggles().setAll(b1, b2, b3); 405 assertTrue(isMember(b1, g1)); 406 assertTrue(isMember(b2, g1)); 407 assertTrue(isMember(b3, g1)); 408 } 409 410 @Test public void addingTogglesUsingToggleGroupGetTogglesSetAllAndSet() { 411 g1.getToggles().setAll(b1, b2, b3); 412 g1.getToggles().set(0, b4); 413 assertTrue(isNotMember(b1, g1)); 414 assertTrue(isMember(b2, g1)); 415 assertTrue(isMember(b3, g1)); 416 assertTrue(isMember(b4, g1)); 417 } 418 419 @Test public void addingTogglesUsingToggleGroupGetTogglesSetAllTwice() { 420 g1.getToggles().setAll(b1, b2); 421 g1.getToggles().setAll(b3, b4); 422 assertTrue(isNotMember(b1, g1)); 423 assertTrue(isNotMember(b2, g1)); 424 assertTrue(isMember(b3, g1)); 425 assertTrue(isMember(b4, g1)); 426 } 427 428 @Test public void addingTogglesUsingToggleGroupGetTogglesSetAllAndAddAll() { 429 g1.getToggles().setAll(b1, b2); 430 g1.getToggles().addAll(b3, b4); 431 assertTrue(isMember(b1, g1)); 432 assertTrue(isMember(b2, g1)); 433 assertTrue(isMember(b3, g1)); 434 assertTrue(isMember(b4, g1)); 435 } 436 437 @Test public void addingDuplicateTogglesUsingToggleGroupGetTogglesAddAllAndSetToggleGroup() { 438 b1.setToggleGroup(g1); 439 try { 440 g1.getToggles().addAll(b1, b2); 441 fail("Duplicates are not allowed"); 442 } catch(IllegalArgumentException iae) { 443 assertNotNull(iae); 444 } 445 } 446 447 @Test public void addingDuplicateTogglesUsingToggleGroupGetTogglesSetAllTwice() { 448 g1.getToggles().setAll(b1, b2); 449 g1.getToggles().setAll(b1, b3, b4); 450 assertTrue(isMember(b1, g1)); 451 assertTrue(isNotMember(b2, g1)); 452 assertTrue(isMember(b3, g1)); 453 assertTrue(isMember(b4, g1)); 454 } 455 456 @Test public void addingFromOneTogglesUsingToggleGroupGetTogglesToAnother() { 457 g1.getToggles().setAll(b1, b2); 458 g2.getToggles().setAll(b1, b3); 459 assertTrue(isNotMember(b1, g1)); 460 assertTrue(isMember(b1, g2)); 461 assertTrue(isMember(b2, g1)); 462 assertTrue(isMember(b3, g2)); 463 } 464 465 @Test public void arrowKeysSelectTogglesTogetherWithFocus() { 466 467 Group root = new Group(); 468 469 Scene scene = new Scene(root); 470 root.getChildren().addAll(b1, b2, b3); 471 root.applyCss(); // Initilize the skin 472 473 g1.getToggles().setAll(b1, b2, b3); 474 475 g1.selectToggle(b1); 476 477 assertTrue(b1.isSelected()); 478 assertFalse(b2.isSelected()); 479 assertFalse(b3.isSelected()); 480 481 EventUtil.fireEvent(new KeyEvent(null, null, KeyEvent.KEY_PRESSED, "", "", KeyCode.RIGHT, false, false, false, false), 482 b1); 483 484 assertFalse(b1.isSelected()); 485 assertTrue(b2.isSelected()); 486 assertFalse(b3.isSelected()); 487 488 EventUtil.fireEvent(new KeyEvent(null, null, KeyEvent.KEY_PRESSED, "", "", KeyCode.DOWN, false, false, false, false), 489 b2); 490 491 assertFalse(b1.isSelected()); 492 assertFalse(b2.isSelected()); 493 assertTrue(b3.isSelected()); 494 495 EventUtil.fireEvent(new KeyEvent(null, null, KeyEvent.KEY_PRESSED, "", "", KeyCode.UP, false, false, false, false), 496 b3); 497 498 assertFalse(b1.isSelected()); 499 assertTrue(b2.isSelected()); 500 assertFalse(b3.isSelected()); 501 502 EventUtil.fireEvent(new KeyEvent(null, null, KeyEvent.KEY_PRESSED, "", "", KeyCode.LEFT, false, false, false, false), 503 b2); 504 505 assertTrue(b1.isSelected()); 506 assertFalse(b2.isSelected()); 507 assertFalse(b3.isSelected()); 508 } 509 510 @Test public void testSelectingTwiceIsNop() { 511 b1.setToggleGroup(g1); 512 b2.setToggleGroup(g1); 513 514 assertFalse(b1.isSelected()); 515 assertFalse(b2.isSelected()); 516 517 g1.selectToggle(b1); 518 assertTrue(b1.isSelected()); 519 assertFalse(b2.isSelected()); 520 assertEquals(g1.getSelectedToggle(), b1); 521 522 g1.selectToggle(b1); 523 assertTrue(b1.isSelected()); 524 assertFalse(b2.isSelected()); 525 assertEquals(g1.getSelectedToggle(), b1); 526 } 527 528 @Test public void testProperties() { 529 javafx.collections.ObservableMap<Object, Object> properties = g1.getProperties(); 530 531 /* If we ask for it, we should get it. 532 */ 533 assertNotNull(properties); 534 535 /* What we put in, we should get out. 536 */ 537 properties.put("MyKey", "MyValue"); 538 assertEquals("MyValue", properties.get("MyKey")); 539 540 /* If we ask for it again, we should get the same thing. 541 */ 542 javafx.collections.ObservableMap<Object, Object> properties2 = g1.getProperties(); 543 assertEquals(properties2, properties); 544 545 /* What we put in to the other one, we should get out of this one because 546 * they should be the same thing. 547 */ 548 assertEquals("MyValue", properties2.get("MyKey")); 549 } 550 }