public void mouseWheelMoved(MouseWheelEvent e) {
   if (isEnabled()) {
     a += (double) e.getWheelRotation() / (double) 3;
     a = (a >= 1 ? 0.9999 : a <= -1 ? -0.9999 : a);
     face.setEmotion(p, a, d, e.getX(), e.getY());
   }
   paint();
 }
    private MouseEvent transformMouseEvent(MouseEvent event) {
      if (event == null) {
        throw new IllegalArgumentException("MouseEvent is null");
      }
      MouseEvent newEvent;
      if (event instanceof MouseWheelEvent) {
        MouseWheelEvent mouseWheelEvent = (MouseWheelEvent) event;
        newEvent =
            new MouseWheelEvent(
                mouseWheelEvent.getComponent(),
                mouseWheelEvent.getID(),
                mouseWheelEvent.getWhen(),
                mouseWheelEvent.getModifiers(),
                mouseWheelEvent.getX(),
                mouseWheelEvent.getY(),
                mouseWheelEvent.getClickCount(),
                mouseWheelEvent.isPopupTrigger(),
                mouseWheelEvent.getScrollType(),
                mouseWheelEvent.getScrollAmount(),
                mouseWheelEvent.getWheelRotation());
      } else {
        newEvent =
            new MouseEvent(
                event.getComponent(),
                event.getID(),
                event.getWhen(),
                event.getModifiers(),
                event.getX(),
                event.getY(),
                event.getClickCount(),
                event.isPopupTrigger(),
                event.getButton());
      }
      if (view != null && at.getDeterminant() != 0) {
        Rectangle viewBounds = getTransformedSize();
        Insets insets = JXTransformer.this.getInsets();
        int xgap = (getWidth() - (viewBounds.width + insets.left + insets.right)) / 2;
        int ygap = (getHeight() - (viewBounds.height + insets.top + insets.bottom)) / 2;

        double x = newEvent.getX() + viewBounds.getX() - insets.left;
        double y = newEvent.getY() + viewBounds.getY() - insets.top;
        Point2D p = new Point2D.Double(x - xgap, y - ygap);

        Point2D tp;
        try {
          tp = at.inverseTransform(p, null);
        } catch (NoninvertibleTransformException ex) {
          // can't happen, we check it before
          throw new AssertionError("NoninvertibleTransformException");
        }
        // Use transformed coordinates to get the current component
        mouseCurrentComponent =
            SwingUtilities.getDeepestComponentAt(view, (int) tp.getX(), (int) tp.getY());
        if (mouseCurrentComponent == null) {
          mouseCurrentComponent = JXTransformer.this;
        }
        Component tempComponent = mouseCurrentComponent;
        if (mouseDraggedComponent != null) {
          tempComponent = mouseDraggedComponent;
        }

        Point point =
            SwingUtilities.convertPoint(view, (int) tp.getX(), (int) tp.getY(), tempComponent);
        newEvent.setSource(tempComponent);
        newEvent.translatePoint(point.x - event.getX(), point.y - event.getY());
      }
      return newEvent;
    }
  public void mouseWheelMoved(MouseWheelEvent e) {
    if (enabled && !readOnly) {
      if (timer != null && timer.isRunning()) {
        timer.stop();
      }
      if (enableMouseWheel) {
        int count = 1;
        MouseWheelEvent e2;

        long lastEventTime = e.getWhen();
        int steps = 0;
        int r;

        // This cycle is to determine multiple clicks like double wheel, triple wheel event etc.
        // We go through the vector of events and check whether there are events corresponding to
        // multiple events.
        for (int i = 0; i < events.size() && events.get(i) instanceof MouseWheelEvent; i++) {
          e2 = (MouseWheelEvent) events.get(i);

          // The events are considered to be a multiple click when:
          // 1. Coordinates are equal
          // 2. Modifiers are equal
          // 3. Both events are wheel up or down
          // 4. Delay between two subsequent clicks is lower than given number of miliseconds
          r = e2.getWheelRotation();
          if (e2.getX() == e.getX()
              && e2.getY() == e.getY()
              && e2.getModifiers() == e.getModifiers()
              && (lastEventTime - e2.getWhen() < mouseMultiDelay)
              && e2.getID() == e.getID()
              && ((r > 0 && e.getWheelRotation() > 0) || (r < 0 && e.getWheelRotation() < 0))) {
            count++;
            lastEventTime = e2.getWhen();
            steps += Math.abs(r);
          } else {
            break;
          }
        }

        steps += Math.abs(e.getWheelRotation());

        // Generate the command string
        String s =
            "Mouse "
                + (e.getWheelRotation() > 0
                    ? MouseCommand.MOUSE_WHEEL_DOWN
                    : MouseCommand.MOUSE_WHEEL_UP);

        // Insert modifiers if there are any
        String modifiers = parser.modifiersToString(e.getModifiers());
        if (modifiers.length() > 0) {
          s += " " + MouseCommand.PARAM_MODIFIER + "=" + modifiers;
        }

        // Generate the count parameter
        if (count > 1) {
          s += " " + MouseCommand.PARAM_COUNT + "=" + Math.abs(steps);
        }

        // This will determine whether this event is preceded by a mouse move command with the same
        // coordinates.
        // It will be replaced if yes.
        boolean replaceLastMove = false;
        if (enableMouseMoves) {
          if (events.size() > 0 && events.get(events.size() - 1) instanceof MouseEvent) {
            MouseEvent me = (MouseEvent) events.get(events.size() - 1);
            if (me.getID() == MouseEvent.MOUSE_MOVED
                && e.getX() == me.getX()
                && e.getY() == me.getY()) {
              replaceLastMove = true;
            }
          }
        }

        // Generate coordinates
        s += " " + MouseCommand.PARAM_TO + "=" + parser.pointToString(e.getPoint());

        // Insert the command to the current editor
        insertLine(s, count > 1 || replaceLastMove, true, false);
        dragInProgress = false;
      }
      insertEvent(e);
    }
  }