mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
ScrollPane: use smooth scrolling when rotating the mouse wheel (issue #50)
This commit is contained in:
@@ -28,8 +28,6 @@ import java.beans.PropertyChangeListener;
|
|||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.swing.BoundedRangeModel;
|
|
||||||
import javax.swing.DefaultBoundedRangeModel;
|
|
||||||
import javax.swing.InputMap;
|
import javax.swing.InputMap;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
@@ -37,7 +35,6 @@ import javax.swing.JScrollBar;
|
|||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.event.ChangeListener;
|
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicScrollBarUI;
|
import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
@@ -450,7 +447,11 @@ public class FlatScrollBarUI
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void runAndSetValueAnimated( Runnable r ) {
|
/**
|
||||||
|
* Runs the given runnable, which should modify the scroll bar value,
|
||||||
|
* and then animate scroll bar value from old value to new value.
|
||||||
|
*/
|
||||||
|
public void runAndSetValueAnimated( Runnable r ) {
|
||||||
if( !isSmoothScrollingEnabled() ) {
|
if( !isSmoothScrollingEnabled() ) {
|
||||||
r.run();
|
r.run();
|
||||||
return;
|
return;
|
||||||
@@ -459,30 +460,26 @@ public class FlatScrollBarUI
|
|||||||
if( animator != null )
|
if( animator != null )
|
||||||
animator.cancel();
|
animator.cancel();
|
||||||
|
|
||||||
int[] newValue = new int[1];
|
// if invoked while animation is running, calculation of new value
|
||||||
|
// should start at the previous target value
|
||||||
|
if( targetValue != Integer.MIN_VALUE )
|
||||||
|
scrollbar.setValue( targetValue );
|
||||||
|
|
||||||
runWithoutValueChangeEvents( scrollbar, () -> {
|
int oldValue = scrollbar.getValue();
|
||||||
// if invoked while animation is running, calculation of new value
|
|
||||||
// should start at the previous target value
|
|
||||||
if( targetValue != Integer.MIN_VALUE )
|
|
||||||
scrollbar.setValue( targetValue );
|
|
||||||
|
|
||||||
int oldValue = scrollbar.getValue();
|
r.run();
|
||||||
|
|
||||||
r.run();
|
int newValue = scrollbar.getValue();
|
||||||
|
scrollbar.setValue( oldValue );
|
||||||
|
|
||||||
newValue[0] = scrollbar.getValue();
|
setValueAnimated( newValue );
|
||||||
scrollbar.setValue( oldValue );
|
|
||||||
} );
|
|
||||||
|
|
||||||
setValueAnimated( newValue[0] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Animator animator;
|
private Animator animator;
|
||||||
private int targetValue = Integer.MIN_VALUE;
|
private int targetValue = Integer.MIN_VALUE;
|
||||||
private int delta;
|
private int delta;
|
||||||
|
|
||||||
protected void setValueAnimated( int value ) {
|
public void setValueAnimated( int value ) {
|
||||||
// create animator
|
// create animator
|
||||||
if( animator == null ) {
|
if( animator == null ) {
|
||||||
int duration = FlatUIUtils.getUIInt( "ScrollPane.smoothScrolling.duration", 200 );
|
int duration = FlatUIUtils.getUIInt( "ScrollPane.smoothScrolling.duration", 200 );
|
||||||
@@ -527,29 +524,6 @@ public class FlatScrollBarUI
|
|||||||
return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
|
return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void runWithoutValueChangeEvents( JScrollBar scrollBar, Runnable r ) {
|
|
||||||
BoundedRangeModel model = scrollBar.getModel();
|
|
||||||
if( !(model instanceof DefaultBoundedRangeModel) ) {
|
|
||||||
r.run();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultBoundedRangeModel m = (DefaultBoundedRangeModel) model;
|
|
||||||
|
|
||||||
// remove all listeners
|
|
||||||
ChangeListener[] changeListeners = m.getChangeListeners();
|
|
||||||
for( ChangeListener l : changeListeners )
|
|
||||||
m.removeChangeListener( l );
|
|
||||||
|
|
||||||
try {
|
|
||||||
r.run();
|
|
||||||
} finally {
|
|
||||||
// add all listeners
|
|
||||||
for( ChangeListener l : changeListeners )
|
|
||||||
m.addChangeListener( l );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---- class ScrollBarHoverListener ---------------------------------------
|
//---- class ScrollBarHoverListener ---------------------------------------
|
||||||
|
|
||||||
// using static field to disabling hover for other scroll bars
|
// using static field to disabling hover for other scroll bars
|
||||||
|
|||||||
@@ -135,12 +135,25 @@ public class FlatScrollPaneUI
|
|||||||
MouseWheelListener superListener = super.createMouseWheelListener();
|
MouseWheelListener superListener = super.createMouseWheelListener();
|
||||||
return e -> {
|
return e -> {
|
||||||
if( isSmoothScrollingEnabled() &&
|
if( isSmoothScrollingEnabled() &&
|
||||||
scrollpane.isWheelScrollingEnabled() &&
|
scrollpane.isWheelScrollingEnabled() )
|
||||||
e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL &&
|
|
||||||
e.getPreciseWheelRotation() != 0 &&
|
|
||||||
e.getPreciseWheelRotation() != e.getWheelRotation() )
|
|
||||||
{
|
{
|
||||||
mouseWheelMovedSmooth( e );
|
if( e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL &&
|
||||||
|
e.getPreciseWheelRotation() != 0 &&
|
||||||
|
e.getPreciseWheelRotation() != e.getWheelRotation() )
|
||||||
|
{
|
||||||
|
// precise scrolling
|
||||||
|
mouseWheelMovedPrecise( e );
|
||||||
|
} else {
|
||||||
|
// smooth scrolling
|
||||||
|
JScrollBar scrollBar = findScrollBarToScroll( e );
|
||||||
|
if( scrollBar != null && scrollBar.getUI() instanceof FlatScrollBarUI ) {
|
||||||
|
FlatScrollBarUI ui = (FlatScrollBarUI) scrollBar.getUI();
|
||||||
|
ui.runAndSetValueAnimated( () -> {
|
||||||
|
superListener.mouseWheelMoved( e );
|
||||||
|
} );
|
||||||
|
} else
|
||||||
|
superListener.mouseWheelMoved( e );
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
superListener.mouseWheelMoved( e );
|
superListener.mouseWheelMoved( e );
|
||||||
};
|
};
|
||||||
@@ -157,19 +170,16 @@ public class FlatScrollPaneUI
|
|||||||
return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
|
return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mouseWheelMovedSmooth( MouseWheelEvent e ) {
|
private void mouseWheelMovedPrecise( MouseWheelEvent e ) {
|
||||||
// return if there is no viewport
|
// return if there is no viewport
|
||||||
JViewport viewport = scrollpane.getViewport();
|
JViewport viewport = scrollpane.getViewport();
|
||||||
if( viewport == null )
|
if( viewport == null )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// find scrollbar to scroll
|
// find scrollbar to scroll
|
||||||
JScrollBar scrollbar = scrollpane.getVerticalScrollBar();
|
JScrollBar scrollbar = findScrollBarToScroll( e );
|
||||||
if( scrollbar == null || !scrollbar.isVisible() || e.isShiftDown() ) {
|
if( scrollbar == null )
|
||||||
scrollbar = scrollpane.getHorizontalScrollBar();
|
return;
|
||||||
if( scrollbar == null || !scrollbar.isVisible() )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// consume event
|
// consume event
|
||||||
e.consume();
|
e.consume();
|
||||||
@@ -262,6 +272,16 @@ public class FlatScrollPaneUI
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JScrollBar findScrollBarToScroll( MouseWheelEvent e ) {
|
||||||
|
JScrollBar scrollBar = scrollpane.getVerticalScrollBar();
|
||||||
|
if( scrollBar == null || !scrollBar.isVisible() || e.isShiftDown() ) {
|
||||||
|
scrollBar = scrollpane.getHorizontalScrollBar();
|
||||||
|
if( scrollBar == null || !scrollBar.isVisible() )
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return scrollBar;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PropertyChangeListener createPropertyChangeListener() {
|
protected PropertyChangeListener createPropertyChangeListener() {
|
||||||
PropertyChangeListener superListener = super.createPropertyChangeListener();
|
PropertyChangeListener superListener = super.createPropertyChangeListener();
|
||||||
|
|||||||
Reference in New Issue
Block a user