diff --git a/platform/util/src/com/intellij/ui/JBAutoscroller.java b/platform/util/src/com/intellij/ui/JBAutoscroller.java index cb1af49a8917..54bf0971ce35 100644 --- a/platform/util/src/com/intellij/ui/JBAutoscroller.java +++ b/platform/util/src/com/intellij/ui/JBAutoscroller.java @@ -45,19 +45,23 @@ public class JBAutoscroller implements ActionListener { private JBAutoscroller() { } - public static void installOn(@NotNull JComponent component) { - installOn(component, null); + public static void installOn(@NotNull JComponent component, @Nullable AutoscrollLocker locker) { + installOn(component, null, locker); } public static void installOn(@NotNull JComponent component, @Nullable ScrollDeltaProvider handler) { - getInstance().doInstallOn(component, handler); + installOn(component, handler, null); + } + + public static void installOn(@NotNull JComponent component, @Nullable ScrollDeltaProvider handler, @Nullable AutoscrollLocker locker) { + getInstance().doInstallOn(component, handler, locker); } private static JBAutoscroller getInstance() { return INSTANCE; } - private void doInstallOn(@NotNull JComponent component, @Nullable ScrollDeltaProvider handler) { + private void doInstallOn(@NotNull JComponent component, @Nullable ScrollDeltaProvider handler, @Nullable AutoscrollLocker locker) { component.setAutoscrolls(false); // disable swing autoscroll if (handler != null) { @@ -67,7 +71,7 @@ public class JBAutoscroller implements ActionListener { if (component instanceof JTable) { JTable t = (JTable)component; new MoveTableCellEditorOnAutoscrollFix(t); - new ScrollOnTableSelectionChangeFix(t); + new ScrollOnTableSelectionChangeFix(t, locker); } component.addMouseListener(new MouseAdapter() { @@ -190,6 +194,23 @@ public class JBAutoscroller implements ActionListener { } } + public static class AutoscrollLocker { + private boolean locked; + + public boolean locked() { + return locked; + } + + public void runWithLock(Runnable runnable) { + try { + locked = true; + runnable.run(); + } finally { + locked = false; + } + } + } + private static class SyntheticDragEvent extends MouseEvent { public SyntheticDragEvent(Component source, int id, long when, int modifiers, int x, int y, int xAbs, int yAbs, @@ -263,9 +284,11 @@ public class JBAutoscroller implements ActionListener { // Particularly, scrollRectToVisible in javax.swing.JTable#changeSelection won't be called. private static class ScrollOnTableSelectionChangeFix implements ListSelectionListener, PropertyChangeListener { private final JTable myTable; + private final AutoscrollLocker myLocker; - public ScrollOnTableSelectionChangeFix(JTable table) { + public ScrollOnTableSelectionChangeFix(JTable table, AutoscrollLocker locker) { myTable = table; + myLocker = locker; myTable.addPropertyChangeListener("selectionModel", this); myTable.addPropertyChangeListener("columnModel", this); @@ -276,7 +299,7 @@ public class JBAutoscroller implements ActionListener { @Override public void valueChanged(ListSelectionEvent e) { - if (e.getValueIsAdjusting() || getInstance().isRunningOn(myTable)) return; + if (e.getValueIsAdjusting() || getInstance().isRunningOn(myTable) || locked()) return; int row = getLeadSelectionIndexIfSelectionIsNotEmpty(getRowSelectionModel()); int col = getLeadSelectionIndexIfSelectionIsNotEmpty(getColumnSelectionModel()); @@ -286,6 +309,10 @@ public class JBAutoscroller implements ActionListener { } } + private boolean locked() { + return myLocker != null && myLocker.locked(); + } + @Override public void propertyChange(PropertyChangeEvent evt) { ListSelectionModel oldSelectionModel = null;