mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-07 14:30:56 +03:00
Slider: fixed painting issues:
- needle of directional thumb was not painted while dragging - artifacts on HiDPI screen while dragging - cut off focus indicator on HiDPI screen
This commit is contained in:
@@ -30,9 +30,11 @@ import java.awt.geom.RoundRectangle2D;
|
|||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JSlider;
|
import javax.swing.JSlider;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicSliderUI;
|
import javax.swing.plaf.basic.BasicSliderUI;
|
||||||
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -286,74 +288,95 @@ debug*/
|
|||||||
public static void paintThumb( Graphics g, JSlider slider, Rectangle thumbRect, boolean roundThumb,
|
public static void paintThumb( Graphics g, JSlider slider, Rectangle thumbRect, boolean roundThumb,
|
||||||
Color thumbColor, Color thumbBorderColor, Color focusedColor, int focusWidth )
|
Color thumbColor, Color thumbBorderColor, Color focusedColor, int focusWidth )
|
||||||
{
|
{
|
||||||
int fw = UIScale.scale( focusWidth );
|
double systemScaleFactor = UIScale.getSystemScaleFactor( (Graphics2D) g );
|
||||||
int x = thumbRect.x + fw;
|
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
|
||||||
int y = thumbRect.y + fw;
|
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
|
||||||
int width = thumbRect.width - fw - fw;
|
HiDPIUtils.paintAtScale1x( (Graphics2D) g, thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height,
|
||||||
int height = thumbRect.height - fw - fw;
|
(g2d, x2, y2, width2, height2, scaleFactor) -> {
|
||||||
|
paintThumbImpl( g, slider, x2, y2, width2, height2,
|
||||||
|
roundThumb, thumbColor, thumbBorderColor, focusedColor,
|
||||||
|
(float) (focusWidth * scaleFactor) );
|
||||||
|
} );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
paintThumbImpl( g, slider, thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height,
|
||||||
|
roundThumb, thumbColor, thumbBorderColor, focusedColor, focusWidth );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void paintThumbImpl( Graphics g, JSlider slider, int x, int y, int width, int height,
|
||||||
|
boolean roundThumb, Color thumbColor, Color thumbBorderColor, Color focusedColor, float focusWidth )
|
||||||
|
{
|
||||||
|
int fw = Math.round( UIScale.scale( focusWidth ) );
|
||||||
|
int tx = x + fw;
|
||||||
|
int ty = y + fw;
|
||||||
|
int tw = width - fw - fw;
|
||||||
|
int th = height - fw - fw;
|
||||||
boolean focused = FlatUIUtils.isPermanentFocusOwner( slider );
|
boolean focused = FlatUIUtils.isPermanentFocusOwner( slider );
|
||||||
|
|
||||||
if( roundThumb ) {
|
if( roundThumb ) {
|
||||||
// paint thumb focus border
|
// paint thumb focus border
|
||||||
if( focused ) {
|
if( focused ) {
|
||||||
g.setColor( focusedColor );
|
g.setColor( focusedColor );
|
||||||
((Graphics2D)g).fill( createRoundThumbShape( thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height ) );
|
((Graphics2D)g).fill( createRoundThumbShape( x, y, width, height ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( thumbBorderColor != null ) {
|
if( thumbBorderColor != null ) {
|
||||||
// paint thumb border
|
// paint thumb border
|
||||||
g.setColor( thumbBorderColor );
|
g.setColor( thumbBorderColor );
|
||||||
((Graphics2D)g).fill( createRoundThumbShape( x, y, width, height ) );
|
((Graphics2D)g).fill( createRoundThumbShape( tx, ty, tw, th ) );
|
||||||
|
|
||||||
// paint thumb background
|
// paint thumb background
|
||||||
float lw = UIScale.scale( 1f );
|
float lw = UIScale.scale( 1f );
|
||||||
g.setColor( thumbColor );
|
g.setColor( thumbColor );
|
||||||
((Graphics2D)g).fill( createRoundThumbShape( x + lw, y + lw,
|
((Graphics2D)g).fill( createRoundThumbShape( tx + lw, ty + lw,
|
||||||
width - lw - lw, height - lw - lw ) );
|
tw - lw - lw, th - lw - lw ) );
|
||||||
} else {
|
} else {
|
||||||
// paint thumb background
|
// paint thumb background
|
||||||
g.setColor( thumbColor );
|
g.setColor( thumbColor );
|
||||||
((Graphics2D)g).fill( createRoundThumbShape( x, y, width, height ) );
|
((Graphics2D)g).fill( createRoundThumbShape( tx, ty, tw, th ) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
try {
|
try {
|
||||||
g2.translate( thumbRect.x, thumbRect.y );
|
g2.translate( x, y );
|
||||||
if( slider.getOrientation() == JSlider.VERTICAL ) {
|
if( slider.getOrientation() == JSlider.VERTICAL ) {
|
||||||
if( slider.getComponentOrientation().isLeftToRight() ) {
|
if( slider.getComponentOrientation().isLeftToRight() ) {
|
||||||
g2.translate( 0, thumbRect.height );
|
g2.translate( 0, height );
|
||||||
g2.rotate( Math.toRadians( 270 ) );
|
g2.rotate( Math.toRadians( 270 ) );
|
||||||
} else {
|
} else {
|
||||||
g2.translate( thumbRect.width, 0 );
|
g2.translate( width, 0 );
|
||||||
g2.rotate( Math.toRadians( 90 ) );
|
g2.rotate( Math.toRadians( 90 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
int temp = width;
|
// rotate thumb width/height
|
||||||
width = height;
|
int temp = tw;
|
||||||
height = temp;
|
tw = th;
|
||||||
|
th = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// paint thumb focus border
|
// paint thumb focus border
|
||||||
if( focused ) {
|
if( focused ) {
|
||||||
g2.setColor( focusedColor );
|
g2.setColor( focusedColor );
|
||||||
g2.fill( createDirectionalThumbShape( 0, 0,
|
g2.fill( createDirectionalThumbShape( 0, 0,
|
||||||
width + fw + fw, height + fw + fw + (fw * 0.4142f), fw ) );
|
tw + fw + fw, th + fw + fw + (fw * 0.4142f), fw ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( thumbBorderColor != null ) {
|
if( thumbBorderColor != null ) {
|
||||||
// paint thumb border
|
// paint thumb border
|
||||||
g2.setColor( thumbBorderColor );
|
g2.setColor( thumbBorderColor );
|
||||||
g2.fill( createDirectionalThumbShape( fw, fw, width, height, 0 ) );
|
g2.fill( createDirectionalThumbShape( fw, fw, tw, th, 0 ) );
|
||||||
|
|
||||||
// paint thumb background
|
// paint thumb background
|
||||||
float lw = UIScale.scale( 1f );
|
float lw = UIScale.scale( 1f );
|
||||||
g2.setColor( thumbColor );
|
g2.setColor( thumbColor );
|
||||||
g2.fill( createDirectionalThumbShape( fw + lw, fw + lw,
|
g2.fill( createDirectionalThumbShape( fw + lw, fw + lw,
|
||||||
width - lw - lw, height - lw - lw - (lw * 0.4142f), 0 ) );
|
tw - lw - lw, th - lw - lw - (lw * 0.4142f), 0 ) );
|
||||||
} else {
|
} else {
|
||||||
// paint thumb background
|
// paint thumb background
|
||||||
g2.setColor( thumbColor );
|
g2.setColor( thumbColor );
|
||||||
g2.fill( createDirectionalThumbShape( fw, fw, width, height, 0 ) );
|
g2.fill( createDirectionalThumbShape( fw, fw, tw, th, 0 ) );
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
@@ -404,6 +427,32 @@ debug*/
|
|||||||
return !slider.getPaintTicks() && !slider.getPaintLabels();
|
return !slider.getPaintTicks() && !slider.getPaintLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setThumbLocation( int x, int y ) {
|
||||||
|
if( !isRoundThumb() ) {
|
||||||
|
// the needle of the directional thumb is painted outside of thumbRect
|
||||||
|
// --> must increase repaint rectangle
|
||||||
|
|
||||||
|
// set new thumb location and compute union of old and new thumb bounds
|
||||||
|
Rectangle r = new Rectangle( thumbRect );
|
||||||
|
thumbRect.setLocation( x, y );
|
||||||
|
SwingUtilities.computeUnion( thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height, r );
|
||||||
|
|
||||||
|
// increase union rectangle for repaint
|
||||||
|
int extra = (int) Math.ceil( UIScale.scale( focusWidth ) * 0.4142f );
|
||||||
|
if( slider.getOrientation() == JSlider.HORIZONTAL )
|
||||||
|
r.height += extra;
|
||||||
|
else {
|
||||||
|
r.width += extra;
|
||||||
|
if( !slider.getComponentOrientation().isLeftToRight() )
|
||||||
|
r.x -= extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
slider.repaint( r );
|
||||||
|
} else
|
||||||
|
super.setThumbLocation( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatTrackListener --------------------------------------------
|
//---- class FlatTrackListener --------------------------------------------
|
||||||
|
|
||||||
protected class FlatTrackListener
|
protected class FlatTrackListener
|
||||||
|
|||||||
Reference in New Issue
Block a user