diff --git a/CHANGELOG.md b/CHANGELOG.md index f14665b9..f8f763ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ FlatLaf Change Log ## Unreleased +#### New features + +- Table: Detect whether component is used in cell editor and automatically + disable round border style and reduce cell editor outer border width (used for + focus indicator) to zero. (issue #148) +- ComboBox, Spinner and TextField: Support disabling round border style per + component, if globally enabled (set client property `JComponent.roundRect` to + `false`). (issue #148) + #### Fixed bugs - Custom window decorations: Embedded menu bar did not always respond to mouse diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 79ac1ce1..782995e0 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -314,6 +314,15 @@ public interface FlatClientProperties return (value instanceof Boolean) ? (boolean) value : defaultValue; } + /** + * Checks whether a client property of a component is a {@link Boolean} and returns its value. + * If the client property is not set, or not a {@link Boolean}, defaultValue is returned. + */ + static Boolean clientPropertyBooleanStrict( JComponent c, String key, Boolean defaultValue ) { + Object value = c.getClientProperty( key ); + return (value instanceof Boolean) ? (Boolean) value : defaultValue; + } + /** * Checks whether a client property of a component is an integer and returns its value. * If the client property is not set, or not an integer, defaultValue is returned. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java index cf75aed8..c435aed4 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java @@ -87,15 +87,14 @@ public class FlatBorder try { FlatUIUtils.setRenderingHints( g2 ); - boolean isCellEditor = isCellEditor( c ); - float focusWidth = isCellEditor ? 0 : scale( (float) getFocusWidth( c ) ); + float focusWidth = scale( (float) getFocusWidth( c ) ); float borderWidth = scale( (float) getBorderWidth( c ) ); - float arc = isCellEditor ? 0 : scale( (float) getArc( c ) ); + float arc = scale( (float) getArc( c ) ); Color outlineColor = getOutlineColor( c ); // paint outer border if( outlineColor != null || isFocused( c ) ) { - float innerWidth = !isCellEditor && !(c instanceof JScrollPane) + float innerWidth = !isCellEditor( c ) && !(c instanceof JScrollPane) ? (outlineColor != null ? innerOutlineWidth : innerFocusWidth) : 0; @@ -204,8 +203,7 @@ public class FlatBorder @Override public Insets getBorderInsets( Component c, Insets insets ) { - boolean isCellEditor = isCellEditor( c ); - float focusWidth = isCellEditor ? 0 : scale( (float) getFocusWidth( c ) ); + float focusWidth = scale( (float) getFocusWidth( c ) ); float ow = focusWidth + scale( (float) getLineWidth( c ) ); insets = super.getBorderInsets( c, insets ); @@ -214,7 +212,7 @@ public class FlatBorder insets.bottom = Math.round( scale( (float) insets.bottom ) + ow ); insets.right = Math.round( scale( (float) insets.right ) + ow ); - if( isCellEditor ) { + if( isCellEditor( c ) ) { // remove top and bottom insets if used as cell editor insets.top = insets.bottom = 0; @@ -232,6 +230,9 @@ public class FlatBorder * Returns the (unscaled) thickness of the outer focus border. */ protected int getFocusWidth( Component c ) { + if( isCellEditor( c ) ) + return 0; + return focusWidth; } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java index 5fc802d4..d379c177 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonBorder.java @@ -141,6 +141,9 @@ public class FlatButtonBorder @Override protected int getArc( Component c ) { + if( isCellEditor( c ) ) + return 0; + switch( FlatButtonUI.getButtonType( c ) ) { case FlatButtonUI.TYPE_SQUARE: return 0; case FlatButtonUI.TYPE_ROUND_RECT: return Short.MAX_VALUE; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java index 58d90230..3703be9c 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRoundBorder.java @@ -33,6 +33,10 @@ public class FlatRoundBorder @Override protected int getArc( Component c ) { - return FlatUIUtils.isRoundRect( c ) ? Short.MAX_VALUE : arc; + if( isCellEditor( c ) ) + return 0; + + Boolean roundRect = FlatUIUtils.isRoundRect( c ); + return roundRect != null ? (roundRect ? Short.MAX_VALUE : 0) : arc; } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextBorder.java index 2ff587cb..b57a1088 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextBorder.java @@ -33,6 +33,10 @@ public class FlatTextBorder @Override protected int getArc( Component c ) { - return FlatUIUtils.isRoundRect( c ) ? Short.MAX_VALUE : arc; + if( isCellEditor( c ) ) + return 0; + + Boolean roundRect = FlatUIUtils.isRoundRect( c ); + return roundRect != null ? (roundRect ? Short.MAX_VALUE : 0) : arc; } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index a7f5c8c7..6c706b24 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -37,6 +37,7 @@ import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.util.function.Consumer; import javax.swing.JComponent; +import javax.swing.JTable; import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.UIManager; @@ -137,11 +138,21 @@ public class FlatUIUtils } public static boolean isCellEditor( Component c ) { - // check whether used as cell editor in file chooser - // Tree.cellEditor is set in sun.swing.FilePane.editFileName() + // check whether used in cell editor (check 3 levels up) + Component c2 = c; + for( int i = 0; i <= 2 && c2 != null; i++ ) { + Container parent = c2.getParent(); + if( parent instanceof JTable && ((JTable)parent).getEditorComponent() == c2 ) + return true; + + c2 = parent; + } + + // check whether used as cell editor // Table.editor is set in JTable.GenericEditor constructor + // Tree.cellEditor is set in sun.swing.FilePane.editFileName() String name = c.getName(); - if( "Tree.cellEditor".equals( name ) || "Table.editor".equals( name ) ) + if( "Table.editor".equals( name ) || "Tree.cellEditor".equals( name ) ) return true; // for using combo box as cell editor in table @@ -159,9 +170,11 @@ public class FlatUIUtils keyboardFocusManager.getActiveWindow() == SwingUtilities.windowForComponent( c ); } - public static boolean isRoundRect( Component c ) { - return c instanceof JComponent && FlatClientProperties.clientPropertyBoolean( - (JComponent) c, FlatClientProperties.COMPONENT_ROUND_RECT, false ); + public static Boolean isRoundRect( Component c ) { + return (c instanceof JComponent) + ? FlatClientProperties.clientPropertyBooleanStrict( + (JComponent) c, FlatClientProperties.COMPONENT_ROUND_RECT, null ) + : null; } /**