diff --git a/CHANGELOG.md b/CHANGELOG.md index bf2d2cc5..3aad6c51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ FlatLaf Change Log #### Fixed bugs +- ComboBox and Spinner: Limit arrow button width if component has large + preferred height. (issue #361) - InternalFrame: Limit internal frame bounds to parent bounds on resize. Also honor maximum size of internal frame. (issue #362) - Popup: Fixed incorrectly placed drop shadow for medium-weight popups in diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index 876881f7..89f1a424 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -23,6 +23,7 @@ import java.awt.Component; import java.awt.ComponentOrientation; import java.awt.Container; import java.awt.Dimension; +import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; @@ -261,8 +262,12 @@ public class FlatComboBoxUI super.layoutContainer( parent ); if( arrowButton != null ) { + // limit button width to height of a raw combobox (without insets) + FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() ); + int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom ); + Insets insets = getInsets(); - int buttonWidth = parent.getPreferredSize().height - insets.top - insets.bottom; + int buttonWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth ); if( buttonWidth != arrowButton.getWidth() ) { // set width of arrow button to preferred height of combobox int xOffset = comboBox.getComponentOrientation().isLeftToRight() diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java index d7238d90..c8b4c8bb 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSpinnerUI.java @@ -21,6 +21,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; @@ -411,8 +412,12 @@ public class FlatSpinnerUI Rectangle editorRect = new Rectangle( r ); Rectangle buttonsRect = new Rectangle( r ); + // limit buttons width to height of a raw spinner (without insets) + FontMetrics fm = spinner.getFontMetrics( spinner.getFont() ); + int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom ); + // make button area square (if spinner has preferred height) - int buttonsWidth = parent.getPreferredSize().height - insets.top - insets.bottom; + int buttonsWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth ); buttonsRect.width = buttonsWidth; if( parent.getComponentOrientation().isLeftToRight() ) { diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java index ecb55f42..24ebced1 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.testing; import java.awt.Component; +import java.awt.Dimension; import java.awt.Insets; import javax.swing.*; import javax.swing.border.*; @@ -102,10 +103,18 @@ public class FlatTextComponentsTest JComboBox comboBox3 = new JComboBox<>(); JLabel spinnerLabel = new JLabel(); JSpinner spinner1 = new JSpinner(); - JSpinner spinner2 = new JSpinner(); - JSpinner spinner3 = new JSpinner(); + JLabel label2 = new JLabel(); JComboBox comboBox2 = new JComboBox<>(); + JSpinner spinner2 = new JSpinner(); + JLabel label1 = new JLabel(); + JComboBox comboBox5 = new JComboBox<>(); + JSpinner spinner4 = new JSpinner(); + JLabel label3 = new JLabel(); JComboBox comboBox4 = new JComboBox<>(); + JSpinner spinner3 = new JSpinner(); + JLabel label4 = new JLabel(); + JComboBox comboBox6 = new JComboBox<>(); + JSpinner spinner5 = new JSpinner(); JPopupMenu popupMenu1 = new JPopupMenu(); JMenuItem cutMenuItem = new JMenuItem(); JMenuItem copyMenuItem = new JMenuItem(); @@ -130,8 +139,12 @@ public class FlatTextComponentsTest "[50,fill]" + "[]" + "[]para" + + "[40]" + + "[40]" + "[]" + "[]" + + "[::14]" + + "[::14]" + "[]" + "[]")); @@ -401,23 +414,67 @@ public class FlatTextComponentsTest spinner1.setName("spinner1"); add(spinner1, "cell 1 7,growx"); - //---- spinner2 ---- - spinner2.setName("spinner2"); - add(spinner2, "cell 1 8,growx,height 40"); - - //---- spinner3 ---- - spinner3.setName("spinner3"); - add(spinner3, "cell 1 9,growx,hmax 14"); + //---- label2 ---- + label2.setText("Large row height:
(default pref height)"); + label2.setName("label2"); + add(label2, "cell 0 8,aligny top,growy 0"); //---- comboBox2 ---- comboBox2.setEditable(true); comboBox2.setName("comboBox2"); - add(comboBox2, "cell 1 10,growx,height 40"); + add(comboBox2, "cell 1 8,grow"); + + //---- spinner2 ---- + spinner2.setName("spinner2"); + add(spinner2, "cell 1 9,grow"); + + //---- label1 ---- + label1.setText("Large pref height:"); + label1.setName("label1"); + add(label1, "cell 0 10,aligny top,growy 0"); + + //---- comboBox5 ---- + comboBox5.setPreferredSize(new Dimension(60, 40)); + comboBox5.setEditable(true); + comboBox5.setName("comboBox5"); + add(comboBox5, "cell 1 10,growx"); + + //---- spinner4 ---- + spinner4.setPreferredSize(new Dimension(60, 40)); + spinner4.setName("spinner4"); + add(spinner4, "cell 1 11,growx"); + + //---- label3 ---- + label3.setText("Small row height:
(default pref height)"); + label3.setName("label3"); + add(label3, "cell 0 12 1 2,aligny top,growy 0"); //---- comboBox4 ---- comboBox4.setEditable(true); comboBox4.setName("comboBox4"); - add(comboBox4, "cell 1 11,growx,hmax 14"); + add(comboBox4, "cell 1 12,growx"); + + //---- spinner3 ---- + spinner3.setName("spinner3"); + add(spinner3, "cell 1 13,growx"); + + //---- label4 ---- + label4.setText("Small pref height:"); + label4.setName("label4"); + add(label4, "cell 0 14 1 2,aligny top,growy 0"); + + //---- comboBox6 ---- + comboBox6.setEditable(true); + comboBox6.setPreferredSize(new Dimension(60, 14)); + comboBox6.setMinimumSize(new Dimension(60, 14)); + comboBox6.setName("comboBox6"); + add(comboBox6, "cell 1 14,growx"); + + //---- spinner5 ---- + spinner5.setMinimumSize(new Dimension(60, 14)); + spinner5.setPreferredSize(new Dimension(60, 14)); + spinner5.setName("spinner5"); + add(spinner5, "cell 1 15,growx,hmax 14"); //======== popupMenu1 ======== { diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd index b8bcac13..8ea38154 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd @@ -10,7 +10,7 @@ new FormModel { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$layoutConstraints": "ltr,insets dialog,hidemode 3" "$columnConstraints": "[][][::100][100,fill][fill]" - "$rowConstraints": "[][][][50,fill][50,fill][50,fill][][]para[][][][]" + "$rowConstraints": "[][][][50,fill][50,fill][50,fill][][]para[40][40][][][::14][::14][][]" } ) { name: "this" add( new FormComponent( "javax.swing.JLabel" ) { @@ -303,15 +303,11 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 7,growx" } ) - add( new FormComponent( "javax.swing.JSpinner" ) { - name: "spinner2" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label2" + "text": "Large row height:
(default pref height)" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 8,growx,height 40" - } ) - add( new FormComponent( "javax.swing.JSpinner" ) { - name: "spinner3" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 9,growx,hmax 14" + "value": "cell 0 8,aligny top,growy 0" } ) add( new FormComponent( "javax.swing.JComboBox" ) { name: "comboBox2" @@ -320,7 +316,40 @@ new FormModel { "JavaCodeGenerator.typeParameters": "String" } }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 10,growx,height 40" + "value": "cell 1 8,grow" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner2" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 9,grow" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label1" + "text": "Large pref height:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 10,aligny top,growy 0" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox5" + "preferredSize": new java.awt.Dimension( 60, 40 ) + "editable": true + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 10,growx" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner4" + "preferredSize": new java.awt.Dimension( 60, 40 ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 11,growx" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label3" + "text": "Small row height:
(default pref height)" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 12 1 2,aligny top,growy 0" } ) add( new FormComponent( "javax.swing.JComboBox" ) { name: "comboBox4" @@ -329,11 +358,40 @@ new FormModel { "JavaCodeGenerator.typeParameters": "String" } }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 11,growx,hmax 14" + "value": "cell 1 12,growx" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner3" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 13,growx" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label4" + "text": "Small pref height:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 14 1 2,aligny top,growy 0" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox6" + "editable": true + "preferredSize": new java.awt.Dimension( 60, 14 ) + "minimumSize": new java.awt.Dimension( 60, 14 ) + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 14,growx" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner5" + "minimumSize": new java.awt.Dimension( 60, 14 ) + "preferredSize": new java.awt.Dimension( 60, 14 ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 15,growx,hmax 14" } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) - "size": new java.awt.Dimension( 530, 580 ) + "size": new java.awt.Dimension( 530, 660 ) } ) add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) { name: "popupMenu1" @@ -350,7 +408,7 @@ new FormModel { "text": "Paste" } ) }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 0, 680 ) + "location": new java.awt.Point( 0, 705 ) "size": new java.awt.Dimension( 91, 87 ) } ) }