void (@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()); } }); }