1 /* 2 * Copyright (c) 2011, 2013, 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; 27 28 import static org.junit.Assert.assertEquals; 29 30 import java.util.Arrays; 31 import java.util.Collection; 32 33 import javafx.event.Event; 34 import javafx.event.EventHandler; 35 import javafx.event.EventType; 36 import javafx.scene.input.KeyCode; 37 import javafx.scene.input.KeyEvent; 38 import javafx.scene.input.MouseButton; 39 import javafx.scene.input.MouseEvent; 40 import javafx.scene.shape.Rectangle; 41 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.junit.runners.Parameterized; 45 import org.junit.runners.Parameterized.Parameters; 46 47 import com.sun.javafx.test.PropertyReference; 48 import com.sun.javafx.test.MouseEventGenerator; 49 import javafx.scene.input.ContextMenuEvent; 50 import javafx.scene.input.SwipeEvent; 51 52 @RunWith(Parameterized.class) 53 public final class Scenegraph_eventHandlers_Test { 54 private final EventType<?> eventType; 55 private final PropertyReference sceneOnHandlerPropRef; 56 private final PropertyReference nodeOnHandlerPropRef; 57 private final Event triggeringEvent; 58 59 @Parameters 60 public static Collection data() { 61 final MouseEventGenerator mouseEventGenerator = 62 new MouseEventGenerator(); 63 return Arrays.asList(new Object[][] { 64 { 65 KeyEvent.KEY_PRESSED, 66 "onKeyPressed", 67 createTestKeyEvent(KeyEvent.KEY_PRESSED) 68 }, { 69 KeyEvent.KEY_RELEASED, 70 "onKeyReleased", 71 createTestKeyEvent(KeyEvent.KEY_RELEASED) 72 }, { 73 KeyEvent.KEY_TYPED, 74 "onKeyTyped", 75 createTestKeyEvent(KeyEvent.KEY_TYPED) 76 }, { 77 MouseEvent.MOUSE_PRESSED, 78 "onMousePressed", 79 mouseEventGenerator.generateMouseEvent( 80 MouseEvent.MOUSE_PRESSED, 0, 0) 81 }, { 82 MouseEvent.MOUSE_RELEASED, 83 "onMouseReleased", 84 mouseEventGenerator.generateMouseEvent( 85 MouseEvent.MOUSE_RELEASED, 0, 0) 86 }, { 87 MouseEvent.MOUSE_CLICKED, 88 "onMouseClicked", 89 mouseEventGenerator.generateMouseEvent( 90 MouseEvent.MOUSE_CLICKED, 0, 0) 91 }, { 92 MouseEvent.MOUSE_ENTERED, 93 "onMouseEntered", 94 mouseEventGenerator.generateMouseEvent( 95 MouseEvent.MOUSE_ENTERED, 0, 0) 96 }, { 97 MouseEvent.MOUSE_EXITED, 98 "onMouseExited", 99 mouseEventGenerator.generateMouseEvent( 100 MouseEvent.MOUSE_EXITED, 0, 0) 101 }, { 102 MouseEvent.MOUSE_MOVED, 103 "onMouseMoved", 104 mouseEventGenerator.generateMouseEvent( 105 MouseEvent.MOUSE_MOVED, 0, 0) 106 }, { 107 MouseEvent.MOUSE_DRAGGED, 108 "onMouseDragged", 109 mouseEventGenerator.generateMouseEvent( 110 MouseEvent.MOUSE_DRAGGED, 0, 0) 111 }, { 112 SwipeEvent.SWIPE_LEFT, 113 "onSwipeLeft", 114 createSwipeEvent(SwipeEvent.SWIPE_LEFT) 115 }, { 116 SwipeEvent.SWIPE_RIGHT, 117 "onSwipeRight", 118 createSwipeEvent(SwipeEvent.SWIPE_RIGHT) 119 }, { 120 SwipeEvent.SWIPE_UP, 121 "onSwipeUp", 122 createSwipeEvent(SwipeEvent.SWIPE_UP) 123 }, { 124 SwipeEvent.SWIPE_DOWN, 125 "onSwipeDown", 126 createSwipeEvent(SwipeEvent.SWIPE_DOWN) 127 }, { 128 ContextMenuEvent.CONTEXT_MENU_REQUESTED, 129 "onContextMenuRequested", 130 createContextMenuEvent() 131 } 132 }); 133 } 134 135 public Scenegraph_eventHandlers_Test( 136 final EventType<?> eventType, 137 final String onHandlerName, 138 final Event triggeringEvent) { 139 this.eventType = eventType; 140 this.sceneOnHandlerPropRef = 141 PropertyReference.createForBean(Scene.class, onHandlerName); 142 this.nodeOnHandlerPropRef = 143 PropertyReference.createForBean(Node.class, onHandlerName); 144 this.triggeringEvent = triggeringEvent; 145 } 146 147 @Test 148 public void shouldCallRegisteredHandlers() { 149 final EventCountingHandler sceneHandler = new EventCountingHandler(); 150 final EventCountingHandler lNodeHandler = new EventCountingHandler(); 151 final EventCountingHandler rNodeHandler = new EventCountingHandler(); 152 final EventCountingHandler rlNodeHandler = new EventCountingHandler(); 153 154 setEventHandler(TEST_SCENE, sceneOnHandlerPropRef, sceneHandler); 155 setEventHandler(TEST_L_NODE, nodeOnHandlerPropRef, lNodeHandler); 156 TEST_R_NODE.addEventHandler(eventType, rNodeHandler); 157 setEventHandler(TEST_RL_NODE, nodeOnHandlerPropRef, rlNodeHandler); 158 159 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 160 assertEquals(1, sceneHandler.getCounter()); 161 assertEquals(0, lNodeHandler.getCounter()); 162 assertEquals(1, rNodeHandler.getCounter()); 163 assertEquals(1, rlNodeHandler.getCounter()); 164 165 Event.fireEvent(TEST_RR_NODE, triggeringEvent); 166 assertEquals(2, sceneHandler.getCounter()); 167 assertEquals(0, lNodeHandler.getCounter()); 168 assertEquals(2, rNodeHandler.getCounter()); 169 assertEquals(1, rlNodeHandler.getCounter()); 170 171 Event.fireEvent(TEST_R_NODE, triggeringEvent); 172 assertEquals(3, sceneHandler.getCounter()); 173 assertEquals(0, lNodeHandler.getCounter()); 174 assertEquals(3, rNodeHandler.getCounter()); 175 assertEquals(1, rlNodeHandler.getCounter()); 176 177 Event.fireEvent(TEST_L_NODE, triggeringEvent); 178 assertEquals(4, sceneHandler.getCounter()); 179 assertEquals(1, lNodeHandler.getCounter()); 180 assertEquals(3, rNodeHandler.getCounter()); 181 assertEquals(1, rlNodeHandler.getCounter()); 182 183 Event.fireEvent(TEST_SCENE, triggeringEvent); 184 assertEquals(5, sceneHandler.getCounter()); 185 assertEquals(1, lNodeHandler.getCounter()); 186 assertEquals(3, rNodeHandler.getCounter()); 187 assertEquals(1, rlNodeHandler.getCounter()); 188 189 Event.fireEvent(TEST_RL_NODE, TEST_EVENT); 190 assertEquals(5, sceneHandler.getCounter()); 191 assertEquals(1, lNodeHandler.getCounter()); 192 assertEquals(3, rNodeHandler.getCounter()); 193 assertEquals(1, rlNodeHandler.getCounter()); 194 195 setEventHandler(TEST_SCENE, sceneOnHandlerPropRef, null); 196 setEventHandler(TEST_L_NODE, nodeOnHandlerPropRef, null); 197 TEST_R_NODE.removeEventHandler(eventType, rNodeHandler); 198 setEventHandler(TEST_RL_NODE, nodeOnHandlerPropRef, null); 199 200 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 201 assertEquals(5, sceneHandler.getCounter()); 202 assertEquals(1, lNodeHandler.getCounter()); 203 assertEquals(3, rNodeHandler.getCounter()); 204 assertEquals(1, rlNodeHandler.getCounter()); 205 } 206 207 @Test 208 public void shouldNotCallHandlersWithoutDispatcher() { 209 final EventCountingHandler sceneHandler = new EventCountingHandler(); 210 final EventCountingHandler rootHandler = new EventCountingHandler(); 211 final EventCountingHandler leafHandler = new EventCountingHandler(); 212 213 final Node testLeafNode = new Rectangle(); 214 final Group testRootNode = new Group(testLeafNode); 215 final Scene testScene = new Scene(testRootNode); 216 217 setEventHandler(testScene, sceneOnHandlerPropRef, sceneHandler); 218 setEventHandler(testRootNode, nodeOnHandlerPropRef, rootHandler); 219 testLeafNode.addEventHandler(eventType, leafHandler); 220 221 testRootNode.setEventDispatcher(null); 222 223 Event.fireEvent(testLeafNode, triggeringEvent); 224 assertEquals(1, sceneHandler.getCounter()); 225 assertEquals(0, rootHandler.getCounter()); 226 assertEquals(1, leafHandler.getCounter()); 227 228 testLeafNode.setEventDispatcher(null); 229 230 Event.fireEvent(testLeafNode, triggeringEvent); 231 assertEquals(2, sceneHandler.getCounter()); 232 assertEquals(0, rootHandler.getCounter()); 233 assertEquals(1, leafHandler.getCounter()); 234 235 testScene.setEventDispatcher(null); 236 237 Event.fireEvent(testLeafNode, triggeringEvent); 238 assertEquals(2, sceneHandler.getCounter()); 239 assertEquals(0, rootHandler.getCounter()); 240 assertEquals(1, leafHandler.getCounter()); 241 } 242 243 @Test 244 public void shouldNotPropagateConsumedCapturingEvents() { 245 final EventCountingHandler sceneHandler = new EventCountingHandler(); 246 final EventCountingHandler rlNodeHandler = new EventCountingHandler(); 247 248 setEventHandler(TEST_SCENE, sceneOnHandlerPropRef, sceneHandler); 249 setEventHandler(TEST_RL_NODE, nodeOnHandlerPropRef, rlNodeHandler); 250 251 TEST_L_NODE.addEventFilter(eventType, EVENT_CONSUMING_HANDLER); 252 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 253 assertEquals(1, sceneHandler.getCounter()); 254 assertEquals(1, rlNodeHandler.getCounter()); 255 TEST_L_NODE.removeEventFilter(eventType, EVENT_CONSUMING_HANDLER); 256 257 TEST_R_NODE.addEventFilter(eventType, EVENT_CONSUMING_HANDLER); 258 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 259 assertEquals(1, sceneHandler.getCounter()); 260 assertEquals(1, rlNodeHandler.getCounter()); 261 TEST_R_NODE.removeEventFilter(eventType, EVENT_CONSUMING_HANDLER); 262 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 263 assertEquals(2, sceneHandler.getCounter()); 264 assertEquals(2, rlNodeHandler.getCounter()); 265 266 TEST_SCENE.addEventFilter(eventType, EVENT_CONSUMING_HANDLER); 267 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 268 assertEquals(2, sceneHandler.getCounter()); 269 assertEquals(2, rlNodeHandler.getCounter()); 270 TEST_SCENE.removeEventFilter(eventType, EVENT_CONSUMING_HANDLER); 271 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 272 assertEquals(3, sceneHandler.getCounter()); 273 assertEquals(3, rlNodeHandler.getCounter()); 274 275 setEventHandler(TEST_SCENE, sceneOnHandlerPropRef, null); 276 setEventHandler(TEST_RL_NODE, nodeOnHandlerPropRef, null); 277 } 278 279 @Test 280 public void shouldNotPropagateConsumedBubblingEvents() { 281 final EventCountingHandler sceneHandler = new EventCountingHandler(); 282 final EventCountingHandler rootNodeHandler = new EventCountingHandler(); 283 final EventCountingHandler rlNodeHandler = new EventCountingHandler(); 284 285 setEventHandler(TEST_SCENE, sceneOnHandlerPropRef, sceneHandler); 286 setEventHandler(TEST_ROOT_NODE, nodeOnHandlerPropRef, rootNodeHandler); 287 setEventHandler(TEST_RL_NODE, nodeOnHandlerPropRef, rlNodeHandler); 288 289 setEventHandler(TEST_L_NODE, nodeOnHandlerPropRef, 290 EVENT_CONSUMING_HANDLER); 291 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 292 assertEquals(1, sceneHandler.getCounter()); 293 assertEquals(1, rootNodeHandler.getCounter()); 294 assertEquals(1, rlNodeHandler.getCounter()); 295 setEventHandler(TEST_L_NODE, nodeOnHandlerPropRef, null); 296 297 TEST_RL_NODE.addEventHandler(eventType, EVENT_CONSUMING_HANDLER); 298 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 299 assertEquals(1, sceneHandler.getCounter()); 300 assertEquals(1, rootNodeHandler.getCounter()); 301 assertEquals(2, rlNodeHandler.getCounter()); 302 TEST_RL_NODE.removeEventHandler(eventType, EVENT_CONSUMING_HANDLER); 303 304 setEventHandler(TEST_R_NODE, nodeOnHandlerPropRef, 305 EVENT_CONSUMING_HANDLER); 306 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 307 assertEquals(1, sceneHandler.getCounter()); 308 assertEquals(1, rootNodeHandler.getCounter()); 309 assertEquals(3, rlNodeHandler.getCounter()); 310 setEventHandler(TEST_R_NODE, nodeOnHandlerPropRef, null); 311 312 TEST_ROOT_NODE.addEventHandler(eventType, EVENT_CONSUMING_HANDLER); 313 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 314 assertEquals(1, sceneHandler.getCounter()); 315 assertEquals(2, rootNodeHandler.getCounter()); 316 assertEquals(4, rlNodeHandler.getCounter()); 317 TEST_ROOT_NODE.removeEventHandler(eventType, EVENT_CONSUMING_HANDLER); 318 319 TEST_SCENE.addEventHandler(eventType, EVENT_CONSUMING_HANDLER); 320 Event.fireEvent(TEST_RL_NODE, triggeringEvent); 321 assertEquals(2, sceneHandler.getCounter()); 322 assertEquals(3, rootNodeHandler.getCounter()); 323 assertEquals(5, rlNodeHandler.getCounter()); 324 TEST_SCENE.removeEventHandler(eventType, EVENT_CONSUMING_HANDLER); 325 326 setEventHandler(TEST_SCENE, sceneOnHandlerPropRef, null); 327 setEventHandler(TEST_ROOT_NODE, nodeOnHandlerPropRef, null); 328 setEventHandler(TEST_RL_NODE, nodeOnHandlerPropRef, null); 329 } 330 331 private static final Node TEST_RL_NODE = new Rectangle(); 332 private static final Node TEST_RR_NODE = new Rectangle(); 333 private static final Node TEST_L_NODE = new Rectangle(); 334 private static final Group TEST_R_NODE = 335 new Group(TEST_RL_NODE, TEST_RR_NODE); 336 private static final Group TEST_ROOT_NODE = 337 new Group(TEST_L_NODE, TEST_R_NODE); 338 private static final Scene TEST_SCENE = new Scene(TEST_ROOT_NODE); 339 private static final Event TEST_EVENT = new Event(new EventType<Event>()); 340 341 private static final EventHandler<Event> EVENT_CONSUMING_HANDLER = 342 new EventHandler<Event>() { 343 @Override 344 public void handle(final Event event) { 345 event.consume(); 346 } 347 }; 348 349 private static final class EventCountingHandler 350 implements EventHandler<Event> { 351 private int counter; 352 353 @Override 354 public void handle(final Event event) { 355 ++counter; 356 } 357 358 public int getCounter() { 359 return counter; 360 } 361 } 362 363 private static Event createTestKeyEvent( 364 final EventType<KeyEvent> keyEventType) { 365 String character; 366 String text; 367 KeyCode keyCode; 368 if (keyEventType == KeyEvent.KEY_TYPED) { 369 character = "q"; 370 text = ""; 371 keyCode = KeyCode.UNDEFINED; 372 } else { 373 character = KeyEvent.CHAR_UNDEFINED; 374 text = KeyCode.Q.getName(); 375 keyCode = KeyCode.Q; 376 } 377 378 return new KeyEvent(keyEventType, character, text, 379 keyCode, 380 false, false, false, false); 381 } 382 383 private static Event createContextMenuEvent() { 384 return new ContextMenuEvent(ContextMenuEvent.CONTEXT_MENU_REQUESTED, 10, 10, 385 10, 10, false, null); 386 } 387 388 private static Event createSwipeEvent(final EventType<SwipeEvent> type) { 389 return new SwipeEvent( 390 type, 391 100, 100, 100, 100, 392 false, false, false, false, true, 1, null); 393 } 394 395 private static void setEventHandler( 396 final Object bean, 397 final PropertyReference handlerPropertyReference, 398 final EventHandler<? extends Event> handler) { 399 handlerPropertyReference.setValue(bean, handler); 400 } 401 }