/**
  * Returns an {@link EventSynchronizer} for the specified {@link EventType}. The {@link
  * EventSynchronizer} is automatically registered on the {@link Scene}. Therefore, you only have
  * to fire the event and call {@link EventSynchronizer#await()} after that to wait for the event
  * processing.
  *
  * <p>For example, the following snippet waits for the processing of a MOUSE_PRESSED event to
  * finish:
  *
  * <pre>
  * // simulate mouse press
  * Robot robot = new Robot();
  * EventSynchronizer<MouseEvent> es = fxNonApplicationThreadRule.getEventSynchronizer(MouseEvent.MOUSE_PRESSED);
  * robot.mousePress(InputEvent.BUTTON1_MASK);
  * es.await();
  * </pre>
  *
  * Convenience methods are provided for standard interactions:
  *
  * <ul>
  *   <li>{@link #keyPress(Robot, int)}
  *   <li>{@link #keyRelease(Robot, int)}
  *   <li>{@link #mousePress(Robot, int)}
  *   <li>{@link #mouseRelease(Robot, int)}
  *   <li>{@link #mouseDrag(Robot, int, int)}
  *   <li>{@link #moveTo(Robot, Node, double, double)}
  * </ul>
  *
  * @param type
  * @return An {@link EventSynchronizer} that is registered for the specified {@link EventType} on
  *     the {@link Scene}.
  */
 @SuppressWarnings("unchecked")
 public <T extends Event> EventSynchronizer<T> getEventSynchronizer(EventType<T> type) {
   if (!eventSynchronizers.containsKey(type)) {
     eventSynchronizers.put(type, new EventSynchronizer<T>(scene, type));
   }
   EventSynchronizer<T> eventSynchronizer = (EventSynchronizer<T>) eventSynchronizers.get(type);
   eventSynchronizer.register();
   return eventSynchronizer;
 }
 public void moveTo(Robot robot, Node visual, double localX, double localY)
     throws InterruptedException {
   Point2D localToScene = visual.localToScene(localX, localY);
   double x = scene.getWindow().getX() + localToScene.getX();
   double y = scene.getWindow().getY() + localToScene.getY();
   EventSynchronizer<MouseEvent> synchronizer =
       new EventSynchronizer<MouseEvent>(visual, MouseEvent.MOUSE_ENTERED);
   synchronizer.register();
   robot.mouseMove((int) x, (int) y);
   synchronizer.await();
 }
 /**
  * Fires a MOUSE_RELEASED event and waits for its processing to finish.
  *
  * @param robot
  * @param keycode
  * @throws InterruptedException
  */
 public void mouseRelease(Robot robot, int buttons) throws InterruptedException {
   EventSynchronizer<MouseEvent> eventSynchronizer =
       getEventSynchronizer(MouseEvent.MOUSE_RELEASED);
   robot.mouseRelease(buttons);
   eventSynchronizer.await();
 }
 /**
  * Fires a MOUSE_PRESSED event and waits for its processing to finish.
  *
  * @param robot
  * @param keycode
  * @throws InterruptedException
  */
 public void mousePress(Robot robot, int buttons) throws InterruptedException {
   EventSynchronizer<MouseEvent> eventSynchronizer =
       getEventSynchronizer(MouseEvent.MOUSE_PRESSED);
   robot.mousePress(buttons);
   eventSynchronizer.await();
 }
 /**
  * Fires a MOUSE_DRAGGED event and waits for its processing to finish.
  *
  * @param robot
  * @param keycode
  * @throws InterruptedException
  */
 public void mouseDrag(Robot robot, int x, int y) throws InterruptedException {
   EventSynchronizer<MouseEvent> eventSynchronizer =
       getEventSynchronizer(MouseEvent.MOUSE_DRAGGED);
   robot.mouseMove(x, y);
   eventSynchronizer.await();
 }
 /**
  * Fires a KEY_RELEASED event and waits for its processing to finish.
  *
  * @param robot
  * @param keycode
  * @throws InterruptedException
  */
 public void keyRelease(Robot robot, int keycode) throws InterruptedException {
   EventSynchronizer<KeyEvent> eventSynchronizer = getEventSynchronizer(KeyEvent.KEY_RELEASED);
   robot.keyRelease(keycode);
   eventSynchronizer.await();
 }
 /**
  * Fires a KEY_PRESSED event and waits for its processing to finish.
  *
  * @param robot
  * @param keycode
  * @throws InterruptedException
  */
 public void keyPress(Robot robot, int keycode) throws InterruptedException {
   EventSynchronizer<KeyEvent> eventSynchronizer = getEventSynchronizer(KeyEvent.KEY_PRESSED);
   robot.keyPress(keycode);
   eventSynchronizer.await();
 }