private void doInstallOn(@NotNull JComponent component, @Nullable ScrollDeltaProvider handler, @Nullable AutoscrollLocker locker) {
    component.setAutoscrolls(false); // disable swing autoscroll

    if (handler != null) {
      component.putClientProperty(SCROLL_HANDLER_KEY, handler);
    }

    if (component instanceof JTable t) {
      new MoveTableCellEditorOnAutoscrollFix(t);
      new ScrollOnTableSelectionChangeFix(t, locker);
    }

    component.addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
        start();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
        stop();
      }
    });
    component.addMouseMotionListener(new MouseMotionAdapter() {
      @Override
      public void mouseDragged(MouseEvent e) {
        if (e instanceof SyntheticDragEvent) return;

        JComponent c = (JComponent)e.getComponent();
        ScrollDeltaProvider handler = (ScrollDeltaProvider)c.getClientProperty(SCROLL_HANDLER_KEY);
        handler = ObjectUtils.notNull(handler, myDefaultAutoScrollHandler);

        myVerticalScrollDelta = handler.getVerticalScrollDelta(e);
        myHorizontalScrollDelta = handler.getHorizontalScrollDelta(e);
        myLatestDragEvent = new SyntheticDragEvent(c, e.getID(), e.getWhen(), e.getModifiersEx(),
                                                   c.getX(), c.getY(), e.getXOnScreen(), e.getYOnScreen(),
                                                   e.getClickCount(), e.isPopupTrigger(), e.getButton());
      }
    });
  }
private void doInstallOn(@NotNull JComponent component, @Nullable ScrollDeltaProvider handler, @Nullable AutoscrollLocker locker)