mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
TabbedPane: fixed scrolling tabs with touchpads and high-resolution mouse wheels
This commit is contained in:
@@ -40,6 +40,8 @@ FlatLaf Change Log
|
||||
`tab`) now respect explicitly set background color.
|
||||
- TabbedPane: Fixed `IndexOutOfBoundsException` when using tooltip text on close
|
||||
buttons and closing last/rightmost tab. (issue #235)
|
||||
- TabbedPane: Fixed scrolling tabs with touchpads and high-resolution mouse
|
||||
wheels.
|
||||
- Extras: Added missing export of package
|
||||
`com.formdev.flatlaf.extras.components` to Java 9 module descriptor.
|
||||
- JIDE Common Layer:
|
||||
|
||||
@@ -221,6 +221,8 @@ public class FlatTabbedPaneUI
|
||||
private Container leadingComponent;
|
||||
private Container trailingComponent;
|
||||
|
||||
private Dimension scrollBackwardButtonPrefSize;
|
||||
|
||||
private Handler handler;
|
||||
private boolean blockRollover;
|
||||
private boolean rolloverTabClose;
|
||||
@@ -1870,33 +1872,78 @@ public class FlatTabbedPaneUI
|
||||
lastMouseY = e.getY();
|
||||
|
||||
double preciseWheelRotation = e.getPreciseWheelRotation();
|
||||
boolean isPreciseWheel = (preciseWheelRotation != 0 && preciseWheelRotation != e.getWheelRotation());
|
||||
int amount = (int) (maxTabHeight * preciseWheelRotation);
|
||||
|
||||
// scroll at least one pixel to avoid "hanging"
|
||||
if( amount == 0 ) {
|
||||
if( preciseWheelRotation > 0 )
|
||||
amount = 1;
|
||||
else if( preciseWheelRotation < 0 )
|
||||
amount = -1;
|
||||
}
|
||||
|
||||
// compute new view position
|
||||
Point viewPosition = (targetViewPosition != null)
|
||||
? targetViewPosition
|
||||
: tabViewport.getViewPosition();
|
||||
Dimension viewSize = tabViewport.getViewSize();
|
||||
boolean horizontal = isHorizontalTabPlacement();
|
||||
int x = viewPosition.x;
|
||||
int y = viewPosition.y;
|
||||
int tabPlacement = tabPane.getTabPlacement();
|
||||
if( tabPlacement == TOP || tabPlacement == BOTTOM ) {
|
||||
if( horizontal )
|
||||
x += isLeftToRight() ? amount : -amount;
|
||||
x = Math.min( Math.max( x, 0 ), viewSize.width - tabViewport.getWidth() );
|
||||
} else {
|
||||
else
|
||||
y += amount;
|
||||
y = Math.min( Math.max( y, 0 ), viewSize.height - tabViewport.getHeight() );
|
||||
|
||||
// In case of having scroll buttons on both sides and hiding disabled buttons,
|
||||
// the viewport is moved when the scroll backward button becomes visible
|
||||
// or is hidden. For non-precise wheel scrolling (e.g. mouse wheel on Windows),
|
||||
// this is no problem because the scroll amount is at least a tab-height.
|
||||
// For precise wheel scrolling (e.g. touchpad on Mac), this is a problem
|
||||
// because it is possible to scroll by a fraction of a tab-height.
|
||||
if( isPreciseWheel &&
|
||||
getScrollButtonsPlacement() == BOTH &&
|
||||
getScrollButtonsPolicy() == AS_NEEDED_SINGLE &&
|
||||
(isLeftToRight() || !horizontal) || // scroll buttons are hidden in right-to-left
|
||||
scrollBackwardButtonPrefSize != null )
|
||||
{
|
||||
// special cases for scrolling with touchpad or high-resolution wheel:
|
||||
// 1. if view is at 0/0 and scrolling right/down, then the scroll backward button
|
||||
// becomes visible, which moves the viewport right/down by the width/height of
|
||||
// the button --> add button width/height to new view position so that
|
||||
// tabs seems to stay in place at screen
|
||||
// 2. if scrolling left/up to the beginning, then the scroll backward button
|
||||
// becomes hidden, which moves the viewport left/up by the width/height of
|
||||
// the button --> set new view position to 0/0 so that
|
||||
// tabs seems to stay in place at screen
|
||||
if( horizontal ) {
|
||||
//
|
||||
if( viewPosition.x == 0 && x > 0 )
|
||||
x += scrollBackwardButtonPrefSize.width;
|
||||
else if( amount < 0 && x <= scrollBackwardButtonPrefSize.width )
|
||||
x = 0;
|
||||
} else {
|
||||
if( viewPosition.y == 0 && y > 0 )
|
||||
y += scrollBackwardButtonPrefSize.height;
|
||||
else if( amount < 0 && y <= scrollBackwardButtonPrefSize.height )
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// limit new view position
|
||||
if( horizontal )
|
||||
x = Math.min( Math.max( x, 0 ), viewSize.width - tabViewport.getWidth() );
|
||||
else
|
||||
y = Math.min( Math.max( y, 0 ), viewSize.height - tabViewport.getHeight() );
|
||||
|
||||
// check whether view position has changed
|
||||
Point newViewPosition = new Point( x, y );
|
||||
if( newViewPosition.equals( viewPosition ) )
|
||||
return;
|
||||
|
||||
// update view position
|
||||
if( preciseWheelRotation != 0 &&
|
||||
preciseWheelRotation != e.getWheelRotation() )
|
||||
{
|
||||
if( isPreciseWheel ) {
|
||||
// do not use animation for precise scrolling (e.g. with trackpad)
|
||||
|
||||
// stop running animation (if any)
|
||||
@@ -2896,6 +2943,8 @@ public class FlatTabbedPaneUI
|
||||
moreTabsButton.setVisible( moreTabsButtonVisible );
|
||||
backwardButton.setVisible( backwardButtonVisible );
|
||||
forwardButton.setVisible( forwardButtonVisible );
|
||||
|
||||
scrollBackwardButtonPrefSize = backwardButton.getPreferredSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user