diff --git a/CHANGELOG.md b/CHANGELOG.md index e3e41270..f92609eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ FlatLaf Change Log - FileChooser: Fixed localizing special Windows folders (e.g. "Documents") and enabled hiding known file extensions (if enabled in Windows Explorer). (issue #178) +- Spinner: Fixed `NullPointerException` in case that arrow buttons were removed + to create button-less spinner. (issue #181) ## 0.42 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 c3626299..44fb16da 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 @@ -268,31 +268,34 @@ public class FlatSpinnerUI int width = c.getWidth(); int height = c.getHeight(); - Component nextButton = getHandler().nextButton; - int arrowX = nextButton.getX(); - int arrowWidth = nextButton.getWidth(); - boolean paintButton = !"none".equals( buttonStyle ); boolean enabled = spinner.isEnabled(); - boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight(); // paint background g2.setColor( getBackground( enabled ) ); FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc ); - // paint arrow buttons background - if( paintButton && enabled ) { - g2.setColor( buttonBackground ); - Shape oldClip = g2.getClip(); - if( isLeftToRight ) - g2.clipRect( arrowX, 0, width - arrowX, height ); - else - g2.clipRect( 0, 0, arrowX + arrowWidth, height ); - FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc ); - g2.setClip( oldClip ); - } + // paint button background and separator + boolean paintButton = !"none".equals( buttonStyle ); + Handler handler = getHandler(); + if( paintButton && (handler.nextButton != null || handler.previousButton != null) ) { + Component button = (handler.nextButton != null) ? handler.nextButton : handler.previousButton; + int arrowX = button.getX(); + int arrowWidth = button.getWidth(); + boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight(); - // paint vertical line between value and arrow buttons - if( paintButton ) { + // paint arrow buttons background + if( enabled ) { + g2.setColor( buttonBackground ); + Shape oldClip = g2.getClip(); + if( isLeftToRight ) + g2.clipRect( arrowX, 0, width - arrowX, height ); + else + g2.clipRect( 0, 0, arrowX + arrowWidth, height ); + FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc ); + g2.setClip( oldClip ); + } + + // paint vertical line between value and arrow buttons g2.setColor( enabled ? borderColor : disabledBorderColor ); float lw = scale( 1f ); float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw; @@ -359,7 +362,7 @@ public class FlatSpinnerUI if( nextButton == null && previousButton == null ) { if( editor != null ) - editor.setBounds( r ); + editor.setBounds( FlatUIUtils.subtractInsets( r, padding ) ); return; } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java index 88169dc1..18a184f2 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.java @@ -186,6 +186,8 @@ public class FlatComponentsTest JLabel spinnerLabel = new JLabel(); JSpinner spinner1 = new JSpinner(); JSpinner spinner2 = new JSpinner(); + FlatComponentsTest.ButtonlessSpinner buttonlessSpinner1 = new FlatComponentsTest.ButtonlessSpinner(); + FlatComponentsTest.ButtonlessSpinner buttonlessSpinner2 = new FlatComponentsTest.ButtonlessSpinner(); JComboBox comboBox7 = new JComboBox<>(); JSpinner spinner3 = new JSpinner(); JLabel textFieldLabel = new JLabel(); @@ -678,6 +680,8 @@ public class FlatComponentsTest //---- spinner2 ---- spinner2.setEnabled(false); add(spinner2, "cell 2 6,growx"); + add(buttonlessSpinner1, "cell 3 6,growx"); + add(buttonlessSpinner2, "cell 4 6,growx"); //---- comboBox7 ---- comboBox7.setEditable(true); @@ -1427,4 +1431,22 @@ public class FlatComponentsTest setBorder( null ); } } + + //---- class ButtonlessSpinner -------------------------------------------- + + private static class ButtonlessSpinner + extends JSpinner + { + @Override + public void updateUI() { + super.updateUI(); + + // remove arrow buttons + for( Component c : getComponents() ) { + String name = c.getName(); + if( "Spinner.nextButton".equals( name ) || "Spinner.previousButton".equals( name ) ) + remove( c ); + } + } + } } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd index ca3cf281..6833b3e9 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponentsTest.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -456,6 +456,16 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 2 6,growx" } ) + add( new FormComponent( "com.formdev.flatlaf.testing.FlatComponentsTest$ButtonlessSpinner" ) { + name: "buttonlessSpinner1" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 6,growx" + } ) + add( new FormComponent( "com.formdev.flatlaf.testing.FlatComponentsTest$ButtonlessSpinner" ) { + name: "buttonlessSpinner2" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 6,growx" + } ) add( new FormComponent( "javax.swing.JComboBox" ) { name: "comboBox7" "editable": true