ScrollBar:

- added `ScrollBar.minimumButtonSize` to specify minimum scroll arrow button size
- center and scale arrows in scroll up/down buttons

(issue #493)
This commit is contained in:
Karl Tauber
2022-03-13 10:50:49 +01:00
parent ab58101ce3
commit 99f7b9ad84
15 changed files with 74 additions and 19 deletions

View File

@@ -9,6 +9,19 @@ FlatLaf Change Log
`JFrame.setDefaultLookAndFeelDecorated(true)` and
`JDialog.setDefaultLookAndFeelDecorated(true)` before creating a window.
(issue #482)
- ScrollBar: Added UI value `ScrollBar.minimumButtonSize` to specify minimum
scroll arrow button size (if shown). (issue #493)
#### Fixed bugs
- ScrollBar: Center and scale arrows in scroll up/down buttons (if shown).
(issue #493)
#### Incompatibilities
- Method `FlatUIUtils.paintArrow()` (and class `FlatArrowButton`) now paints
arrows one pixel smaller than before. To fix this, increase parameter
`arrowSize` by one.
## 2.0.2

View File

@@ -37,7 +37,7 @@ public class FlatArrowButton
extends BasicArrowButton
implements UIResource
{
public static final int DEFAULT_ARROW_WIDTH = 8;
public static final int DEFAULT_ARROW_WIDTH = 9;
protected boolean chevron;
protected Color foreground;
@@ -211,6 +211,6 @@ public class FlatArrowButton
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron, arrowWidth, xOffset, yOffset );
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron, getArrowWidth(), getXOffset(), getYOffset() );
}
}

View File

@@ -57,6 +57,7 @@ import com.formdev.flatlaf.util.UIScale;
*
* <!-- FlatScrollBarUI -->
*
* @uiDefault ScrollBar.minimumButtonSize Dimension
* @uiDefault ScrollBar.trackInsets Insets
* @uiDefault ScrollBar.thumbInsets Insets
* @uiDefault ScrollBar.trackArc int
@@ -83,6 +84,7 @@ public class FlatScrollBarUI
// overrides BasicScrollBarUI.supportsAbsolutePositioning (which is private)
@Styleable protected boolean allowsAbsolutePositioning;
/** @since 2.1 */ @Styleable protected Dimension minimumButtonSize;
@Styleable protected Insets trackInsets;
@Styleable protected Insets thumbInsets;
@Styleable protected int trackArc;
@@ -142,6 +144,7 @@ public class FlatScrollBarUI
allowsAbsolutePositioning = super.getSupportsAbsolutePositioning();
minimumButtonSize = UIManager.getDimension( "ScrollBar.minimumButtonSize" );
trackInsets = UIManager.getInsets( "ScrollBar.trackInsets" );
thumbInsets = UIManager.getInsets( "ScrollBar.thumbInsets" );
trackArc = UIManager.getInt( "ScrollBar.trackArc" );
@@ -171,6 +174,7 @@ public class FlatScrollBarUI
protected void uninstallDefaults() {
super.uninstallDefaults();
minimumButtonSize = null;
trackInsets = null;
thumbInsets = null;
hoverTrackColor = null;
@@ -451,7 +455,6 @@ public class FlatScrollBarUI
super( direction, type, foreground, disabledForeground,
hoverForeground, hoverBackground, pressedForeground, pressedBackground );
setArrowWidth( FlatArrowButton.DEFAULT_ARROW_WIDTH - 2 );
setFocusable( false );
setRequestFocusEnabled( false );
}
@@ -461,6 +464,18 @@ public class FlatScrollBarUI
null, hoverButtonBackground, null, pressedButtonBackground );
}
@Override
public int getArrowWidth() {
// scale arrow size depending on scroll bar width
// (6 is default arrow width; 10 is base scroll bar width)
int arrowWidth = Math.round( 6 * (scrollBarWidth / 10f) );
// compute arrow size that leaves equal space on both sides (arrow is centered)
arrowWidth = scrollBarWidth - (((scrollBarWidth - arrowWidth) / 2) * 2);
return arrowWidth;
}
@Override
protected Color deriveBackground( Color background ) {
return FlatUIUtils.deriveColor( background, scrollbar.getBackground() );
@@ -469,8 +484,9 @@ public class FlatScrollBarUI
@Override
public Dimension getPreferredSize() {
if( isShowButtons() ) {
int w = UIScale.scale( scrollBarWidth );
return new Dimension( w, w );
int w = UIScale.scale( Math.max( scrollBarWidth, (minimumButtonSize != null) ? minimumButtonSize.width : 0 ) );
int h = UIScale.scale( Math.max( scrollBarWidth, (minimumButtonSize != null) ? minimumButtonSize.height : 0 ) );
return new Dimension( w, h );
} else
return new Dimension();
}

View File

@@ -1841,7 +1841,7 @@ public class FlatTabbedPaneUI
super( direction, arrowType,
FlatTabbedPaneUI.this.foreground, FlatTabbedPaneUI.this.disabledForeground,
null, buttonHoverBackground, null, buttonPressedBackground );
setArrowWidth( 10 );
setArrowWidth( 11 );
}
protected void updateStyle() {

View File

@@ -786,13 +786,15 @@ public class FlatUIUtils
int direction, boolean chevron, int arrowSize, float xOffset, float yOffset )
{
// compute arrow width/height
int aw = UIScale.scale( arrowSize + (chevron ? 0 : 1) );
int ah = UIScale.scale( (arrowSize / 2) + (chevron ? 0 : 1) );
// - make chevron arrows one pixel smaller because coordinates are based on center of pixels (0.5/0.5)
// - make triangle arrows one pixel taller (and round height up) to make them look stronger
float aw = UIScale.scale( arrowSize + (chevron ? -1 : 0) );
float ah = chevron ? (aw / 2) : UIScale.scale( (arrowSize / 2) + 1 );
// rotate arrow width/height for horizontal directions
boolean vert = (direction == SwingConstants.NORTH || direction == SwingConstants.SOUTH);
if( !vert ) {
int temp = aw;
float temp = aw;
aw = ah;
ah = temp;
}
@@ -804,19 +806,19 @@ public class FlatUIUtils
// compute arrow location
float ox = ((width - (aw + extra)) / 2f) + UIScale.scale( xOffset );
float oy = ((height - (ah + extra)) / 2f) + UIScale.scale( yOffset );
int ax = x + ((direction == SwingConstants.WEST) ? -Math.round( -ox ) : Math.round( ox ));
int ay = y + ((direction == SwingConstants.NORTH) ? -Math.round( -oy ) : Math.round( oy ));
float ax = x + ((direction == SwingConstants.WEST) ? -Math.round( -(ox + aw) ) - aw : Math.round( ox ));
float ay = y + ((direction == SwingConstants.NORTH) ? -Math.round( -(oy + ah) ) - ah : Math.round( oy ));
// paint arrow
g.translate( ax, ay );
/*debug
debugPaintArrow( g, Color.red, vert, aw + extra, ah + extra );
debugPaintArrow( g, Color.red, vert, Math.round( aw + extra ), Math.round( ah + extra ) );
debug*/
Shape arrowShape = createArrowShape( direction, chevron, aw, ah );
if( chevron ) {
Stroke oldStroke = g.getStroke();
g.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
g.draw( arrowShape );
drawShapePure( g, arrowShape );
g.setStroke( oldStroke );
} else {
// triangle
@@ -892,6 +894,23 @@ debug*/
return path;
}
/**
* Draws the given shape with disabled stroke normalization.
* The x/y coordinates of the shape are translated by a half pixel.
*
* @since 2.1
*/
public static void drawShapePure( Graphics2D g, Shape shape ) {
Object oldStrokeControl = g.getRenderingHint( RenderingHints.KEY_STROKE_CONTROL );
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
g.translate( 0.5, 0.5 );
g.draw( shape );
g.translate( -0.5, -0.5 );
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, oldStrokeControl );
}
/**
* Draws the given string at the specified location.
* The provided component is used to query text properties and anti-aliasing hints.

View File

@@ -555,6 +555,7 @@ RootPane.honorDialogMinimumSizeOnResize = true
#---- ScrollBar ----
ScrollBar.width = 10
ScrollBar.minimumButtonSize = 12,12
ScrollBar.minimumThumbSize = 10,10
ScrollBar.maximumThumbSize = 100000,100000
ScrollBar.trackInsets = 0,0,0,0

View File

@@ -539,6 +539,7 @@ public class TestFlatStyleableInfo
"maximumThumbSize", Dimension.class,
"allowsAbsolutePositioning", boolean.class,
"minimumButtonSize", Dimension.class,
"trackInsets", Insets.class,
"thumbInsets", Insets.class,
"trackArc", int.class,

View File

@@ -684,6 +684,7 @@ public class TestFlatStyling
ui.applyStyle( "maximumThumbSize: 1,2" );
ui.applyStyle( "allowsAbsolutePositioning: true" );
ui.applyStyle( "minimumButtonSize: 1,2" );
ui.applyStyle( "trackInsets: 1,2,3,4" );
ui.applyStyle( "thumbInsets: 1,2,3,4" );
ui.applyStyle( "trackArc: 5" );

View File

@@ -217,8 +217,8 @@ public class FlatTaskPaneUI
Graphics2D g2 = (Graphics2D) g;
// scale chevron size
float cw = scale( 6f );
float ch = scale( 3f );
float cw = scale( 7f );
float ch = scale( 3.5f );
// create arrow shape
int direction = group.isCollapsed() ? SwingConstants.SOUTH : SwingConstants.NORTH;
@@ -237,9 +237,9 @@ public class FlatTaskPaneUI
// paint
g2.translate( cx, cy );
g2.draw( arrowShape );
FlatUIUtils.drawShapePure( g2, arrowShape );
g2.translate( 0, offset );
g2.draw( arrowShape );
FlatUIUtils.drawShapePure( g2, arrowShape );
g2.translate( -cx, -(cy + offset) );
}

View File

@@ -862,6 +862,7 @@ ScrollBar.hoverThumbColor #6e767a HSL 200 5 45 com.formdev.flatlaf.u
ScrollBar.hoverThumbWithTrack false
ScrollBar.hoverTrackColor #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(4%)
ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumButtonSize 12,12 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.pressedButtonBackground #54595c HSL 203 5 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10%)
ScrollBar.pressedThumbColor #7a8387 HSL 198 5 50 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15%)

View File

@@ -867,6 +867,7 @@ ScrollBar.hoverThumbColor #c3c3c3 HSL 0 0 76 com.formdev.flatlaf.u
ScrollBar.hoverThumbWithTrack false
ScrollBar.hoverTrackColor #ededed HSL 0 0 93 com.formdev.flatlaf.util.DerivedColor [UI] darken(3%)
ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumButtonSize 12,12 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.pressedButtonBackground #d9d9d9 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(10%)
ScrollBar.pressedThumbColor #a9a9a9 HSL 0 0 66 com.formdev.flatlaf.util.DerivedColor [UI] darken(20%)

View File

@@ -874,6 +874,7 @@ ScrollBar.hoverThumbColor #ff0000 HSL 0 100 50 javax.swing.plaf.Colo
ScrollBar.hoverThumbWithTrack false
ScrollBar.hoverTrackColor #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumButtonSize 12,12 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.pressedThumbWithTrack false
ScrollBar.showButtons false

View File

@@ -673,7 +673,7 @@ public class FlatPaintingTest
panel5.add(arrowSizeLabel, "cell 0 2");
//---- arrowSizeSpinner ----
arrowSizeSpinner.setModel(new SpinnerNumberModel(8, 2, null, 1));
arrowSizeSpinner.setModel(new SpinnerNumberModel(9, 2, null, 1));
arrowSizeSpinner.addChangeListener(e -> arrowSizeChanged());
panel5.add(arrowSizeSpinner, "cell 1 2");

View File

@@ -564,7 +564,7 @@ new FormModel {
name: "arrowSizeSpinner"
"model": new javax.swing.SpinnerNumberModel {
minimum: 2
value: 8
value: 9
}
auxiliary() {
"JavaCodeGenerator.variableLocal": false

View File

@@ -658,6 +658,7 @@ ScrollBar.hoverThumbColor
ScrollBar.hoverThumbWithTrack
ScrollBar.hoverTrackColor
ScrollBar.maximumThumbSize
ScrollBar.minimumButtonSize
ScrollBar.minimumThumbSize
ScrollBar.pressedButtonBackground
ScrollBar.pressedThumbColor