ComboBox (editable) and Spinner: increased size of internal text field to the component border so that it behaves like plain text field (issue #330)

This commit is contained in:
Karl Tauber
2021-07-02 18:43:37 +02:00
parent a9dcf09d13
commit 3e14f28dc2
5 changed files with 153 additions and 16 deletions

View File

@@ -13,7 +13,11 @@ FlatLaf Change Log
#### Fixed bugs
- TBD
- ComboBox (editable) and Spinner: Increased size of internal text field to the
component border so that it behaves like plain text field (mouse click to left
of text now positions caret to first character instead of opening ComboBox
popup; mouse cursor is now of type "text" within the whole component, except
for arrow buttons). (issue #330)
## 1.3

View File

@@ -133,6 +133,8 @@ public class FlatComboBoxUI
protected Color popupBackground;
protected Insets paddingUnscaled;
private MouseListener hoverListener;
protected boolean hover;
protected boolean pressed;
@@ -223,7 +225,8 @@ public class FlatComboBoxUI
comboBox.setMaximumRowCount( maximumRowCount );
// scale
padding = UIScale.scale( padding );
paddingUnscaled = padding;
padding = UIScale.scale( paddingUnscaled );
MigLayoutVisualPadding.install( comboBox );
}
@@ -276,11 +279,6 @@ public class FlatComboBoxUI
editor.setBounds( rectangleForCurrentValue() );
}
}
if( editor != null && padding != null ) {
// fix editor bounds by subtracting padding
editor.setBounds( FlatUIUtils.subtractInsets( editor.getBounds(), padding ) );
}
}
};
}
@@ -361,9 +359,16 @@ public class FlatComboBoxUI
protected void configureEditor() {
super.configureEditor();
// remove default text field border from editor
if( editor instanceof JTextField && ((JTextField)editor).getBorder() instanceof FlatTextBorder )
((JTextField)editor).setBorder( BorderFactory.createEmptyBorder() );
if( editor instanceof JTextField ) {
JTextField textField = (JTextField) editor;
// remove default text field border from editor
if( textField.getBorder() instanceof FlatTextBorder )
textField.setBorder( BorderFactory.createEmptyBorder() );
// editor padding
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, paddingUnscaled );
}
// explicitly make non-opaque
if( editor instanceof JComponent )
@@ -548,6 +553,9 @@ public class FlatComboBoxUI
ListCellRenderer<Object> renderer = comboBox.getRenderer();
uninstallCellPaddingBorder( renderer );
// update padding
padding = UIScale.scale( paddingUnscaled );
Dimension displaySize = super.getDisplaySize();
// recalculate width without hardcoded 100 under special conditions

View File

@@ -123,9 +123,6 @@ public class FlatSpinnerUI
buttonPressedArrowColor = UIManager.getColor( "Spinner.buttonPressedArrowColor" );
padding = UIManager.getInsets( "Spinner.padding" );
// scale
padding = scale( padding );
MigLayoutVisualPadding.install( spinner );
}
@@ -184,6 +181,7 @@ public class FlatSpinnerUI
if( textField != null )
textField.setOpaque( false );
updateEditorPadding();
updateEditorColors();
return editor;
}
@@ -194,6 +192,8 @@ public class FlatSpinnerUI
removeEditorFocusListener( oldEditor );
addEditorFocusListener( newEditor );
updateEditorPadding();
updateEditorColors();
}
@@ -209,6 +209,12 @@ public class FlatSpinnerUI
textField.removeFocusListener( getHandler() );
}
private void updateEditorPadding() {
JTextField textField = getEditorTextField( spinner.getEditor() );
if( textField != null )
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, padding );
}
private void updateEditorColors() {
JTextField textField = getEditorTextField( spinner.getEditor() );
if( textField != null ) {
@@ -373,6 +379,7 @@ public class FlatSpinnerUI
@Override
public Dimension preferredLayoutSize( Container parent ) {
Insets insets = parent.getInsets();
Insets padding = scale( FlatSpinnerUI.this.padding );
Dimension editorSize = (editor != null) ? editor.getPreferredSize() : new Dimension( 0, 0 );
// the arrows width is the same as the inner height so that the arrows area is square
@@ -397,7 +404,7 @@ public class FlatSpinnerUI
if( nextButton == null && previousButton == null ) {
if( editor != null )
editor.setBounds( FlatUIUtils.subtractInsets( r, padding ) );
editor.setBounds( r );
return;
}
@@ -417,7 +424,7 @@ public class FlatSpinnerUI
}
if( editor != null )
editor.setBounds( FlatUIUtils.subtractInsets( editorRect, padding ) );
editor.setBounds( editorRect );
int nextHeight = (buttonsRect.height / 2) + (buttonsRect.height % 2); // round up
if( nextButton != null )

View File

@@ -20,6 +20,7 @@ import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
@@ -42,9 +43,23 @@ public class FlatCustomBordersTest
} );
}
@SuppressWarnings( "unchecked" )
FlatCustomBordersTest() {
initComponents();
applyCustomBorders();
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>( new String[] {
"text",
"123",
"4567",
"abc",
"def"
} );
for( Component c : getComponents() ) {
if( c instanceof JComboBox )
((JComboBox<String>)c).setModel( model );
}
}
@Override
@@ -99,6 +114,13 @@ public class FlatCustomBordersTest
applyCustomComboBoxEditorBorderWithIcon( comboBox20 );
applyCustomComboBoxEditorBorder( comboBox21, null );
applyCustomComboBoxEditorBorder( comboBox22, null );
applyCustomComboBoxRendererBorder( comboBox23 );
applyCustomComboBoxRendererBorder( comboBox24 );
applyCustomComboBoxRendererBorderWithIcon( comboBox25 );
applyCustomComboBoxRendererBorderWithIcon( comboBox26 );
applyCustomComboBoxRendererBorder( comboBox27, null );
applyCustomComboBoxRendererBorder( comboBox28, null );
}
private void applyCustomInsideBorder( JComponent c, String uiKey ) {
@@ -129,6 +151,21 @@ public class FlatCustomBordersTest
} );
}
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox ) {
applyCustomComboBoxRendererBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 3 ) ) );
}
private void applyCustomComboBoxRendererBorderWithIcon( JComboBox<String> comboBox ) {
applyCustomComboBoxRendererBorder( comboBox, new BorderWithIcon() );
}
@SuppressWarnings( "unchecked" )
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox, Border border ) {
BasicComboBoxRenderer customRenderer = new BasicComboBoxRenderer();
customRenderer.setBorder( border );
comboBox.setRenderer( customRenderer );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
label1 = new JLabel();
@@ -152,10 +189,16 @@ public class FlatCustomBordersTest
comboBox2 = new JComboBox<>();
comboBox3 = new JComboBox<>();
comboBox4 = new JComboBox<>();
comboBox23 = new JComboBox<>();
comboBox25 = new JComboBox<>();
comboBox27 = new JComboBox<>();
comboBox5 = new JComboBox<>();
comboBox6 = new JComboBox<>();
comboBox7 = new JComboBox<>();
comboBox8 = new JComboBox<>();
comboBox24 = new JComboBox<>();
comboBox26 = new JComboBox<>();
comboBox28 = new JComboBox<>();
comboBox9 = new JComboBox<>();
comboBox10 = new JComboBox<>();
comboBox11 = new JComboBox<>();
@@ -289,6 +332,9 @@ public class FlatCustomBordersTest
add(comboBox2, "cell 2 3");
add(comboBox3, "cell 3 3");
add(comboBox4, "cell 4 3");
add(comboBox23, "cell 5 3");
add(comboBox25, "cell 6 3");
add(comboBox27, "cell 7 3");
//---- comboBox5 ----
comboBox5.putClientProperty("JComponent.roundRect", true);
@@ -306,6 +352,18 @@ public class FlatCustomBordersTest
comboBox8.putClientProperty("JComponent.roundRect", true);
add(comboBox8, "cell 4 4");
//---- comboBox24 ----
comboBox24.putClientProperty("JComponent.roundRect", true);
add(comboBox24, "cell 5 4");
//---- comboBox26 ----
comboBox26.putClientProperty("JComponent.roundRect", true);
add(comboBox26, "cell 6 4");
//---- comboBox28 ----
comboBox28.putClientProperty("JComponent.roundRect", true);
add(comboBox28, "cell 7 4");
//---- comboBox9 ----
comboBox9.setEditable(true);
add(comboBox9, "cell 1 5");
@@ -460,10 +518,16 @@ public class FlatCustomBordersTest
private JComboBox<String> comboBox2;
private JComboBox<String> comboBox3;
private JComboBox<String> comboBox4;
private JComboBox<String> comboBox23;
private JComboBox<String> comboBox25;
private JComboBox<String> comboBox27;
private JComboBox<String> comboBox5;
private JComboBox<String> comboBox6;
private JComboBox<String> comboBox7;
private JComboBox<String> comboBox8;
private JComboBox<String> comboBox24;
private JComboBox<String> comboBox26;
private JComboBox<String> comboBox28;
private JComboBox<String> comboBox9;
private JComboBox<String> comboBox10;
private JComboBox<String> comboBox11;
@@ -508,6 +572,9 @@ public class FlatCustomBordersTest
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
icon.paintIcon( c, g, x + width - icon.getIconWidth() - 2, y + ((height - icon.getIconHeight()) / 2) );
g.setColor( RED );
g.drawRect( x, y, width - 1, height - 1 );
}
@Override

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -147,6 +147,30 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox23"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox25"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox27"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 7 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox5"
"$client.JComponent.roundRect": true
@@ -183,6 +207,33 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox24"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox26"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox28"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 7 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox9"
"editable": true