From c141cb6c6c535b954164e1224a32ad9b28d74dc0 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 17 Dec 2019 23:24:38 +0100 Subject: [PATCH] CheckBox and RadioButton: fixed cut off outer focus border if checkbox/radiobutton border was explicitly set to a EmptyBorder --- .../flatlaf/icons/FlatCheckBoxIcon.java | 2 +- .../formdev/flatlaf/ui/FlatRadioButtonUI.java | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java index 1e492803..e54787ed 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatCheckBoxIcon.java @@ -62,7 +62,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils; public class FlatCheckBoxIcon extends FlatAbstractIcon { - protected final int focusWidth = UIManager.getInt( "Component.focusWidth" ); + public final int focusWidth = UIManager.getInt( "Component.focusWidth" ); protected final Color focusColor = FlatUIUtils.getUIColor( "CheckBox.icon.focusedColor", UIManager.getColor( "Component.focusColor" ) ); protected final int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java index 210de4f7..d248d685 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java @@ -18,7 +18,9 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; import java.awt.Color; +import java.awt.Dimension; import java.awt.Graphics; +import java.awt.Insets; import java.awt.Rectangle; import javax.swing.AbstractButton; import javax.swing.CellRendererPane; @@ -28,6 +30,8 @@ import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicRadioButtonUI; +import com.formdev.flatlaf.icons.FlatCheckBoxIcon; +import com.formdev.flatlaf.util.UIScale; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButton}. @@ -92,6 +96,26 @@ public class FlatRadioButtonUI defaults_initialized = false; } + private static Insets tempInsets = new Insets( 0, 0, 0, 0 ); + + @Override + public Dimension getPreferredSize( JComponent c ) { + Dimension size = super.getPreferredSize( c ); + + // small insets fix + int focusWidth = getIconFocusWidth( c ); + if( focusWidth > 0 ) { + // Increase preferred width and height if insets were explicitly reduced (e.g. with + // an EmptyBorder) and icon has a focus width, which is not included in icon size. + // Otherwise the component may be too small and outer focus border may be cut off. + Insets insets = c.getInsets( tempInsets ); + size.width += Math.max( focusWidth - insets.left, 0 ) + Math.max( focusWidth - insets.right, 0 ); + size.height += Math.max( focusWidth - insets.top, 0 ) + Math.max( focusWidth - insets.bottom, 0 ); + } + + return size; + } + @Override public void paint( Graphics g, JComponent c ) { // fill background even if opaque if @@ -104,6 +128,29 @@ public class FlatRadioButtonUI g.fillRect( 0, 0, c.getWidth(), c.getHeight() ); } + // small insets fix + int focusWidth = getIconFocusWidth( c ); + if( focusWidth > 0 ) { + boolean ltr = c.getComponentOrientation().isLeftToRight(); + Insets insets = c.getInsets( tempInsets ); + int leftOrRightInset = ltr ? insets.left : insets.right; + if( focusWidth > leftOrRightInset ) { + // The left (or right) inset is smaller than the focus width, which may be + // the case if insets were explicitly reduced (e.g. with an EmptyBorder). + // In this case the width has been increased in getPreferredSize() and + // here it is necessary to fix icon and text painting location. + int offset = focusWidth - leftOrRightInset; + if( !ltr ) + offset = -offset; + + // move the graphics origin to the left (or right) + g.translate( offset, 0 ); + super.paint( g, c ); + g.translate( -offset, 0 ); + return; + } + } + super.paint( g, c ); } @@ -111,4 +158,11 @@ public class FlatRadioButtonUI protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) { FlatButtonUI.paintText( g, b, textRect, text, b.isEnabled() ? b.getForeground() : disabledText ); } + + private int getIconFocusWidth( JComponent c ) { + AbstractButton b = (AbstractButton) c; + return (b.getIcon() == null && getDefaultIcon() instanceof FlatCheckBoxIcon) + ? UIScale.scale( ((FlatCheckBoxIcon)getDefaultIcon()).focusWidth ) + : 0; + } }