mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-07 06:20:53 +03:00
ComboBox (not editable):
- increased size of internal renderer pane to the component border so that it can paint within the whole component - increase combo box size if a custom renderer uses a border with insets that are larger than the default combo box padding (`2,6,2,6`)
This commit is contained in:
@@ -18,6 +18,10 @@ FlatLaf Change Log
|
|||||||
of text now positions caret to first character instead of opening ComboBox
|
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
|
popup; mouse cursor is now of type "text" within the whole component, except
|
||||||
for arrow buttons). (issue #330)
|
for arrow buttons). (issue #330)
|
||||||
|
- ComboBox (not editable): Increased size of internal renderer pane to the
|
||||||
|
component border so that it can paint within the whole component. Also
|
||||||
|
increase combo box size if a custom renderer uses a border with insets that
|
||||||
|
are larger than the default combo box padding (`2,6,2,6`).
|
||||||
- Fixed component heights at `1.25x`, `1.75x` and `2.25x` scaling factors (Java
|
- Fixed component heights at `1.25x`, `1.75x` and `2.25x` scaling factors (Java
|
||||||
8 only) so that Button, ComboBox, Spinner and TextField components (including
|
8 only) so that Button, ComboBox, Spinner and TextField components (including
|
||||||
subclasses) have same heights. This increases heights of Button and TextField
|
subclasses) have same heights. This increases heights of Button and TextField
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import static com.formdev.flatlaf.util.UIScale.unscale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.ComponentOrientation;
|
import java.awt.ComponentOrientation;
|
||||||
@@ -67,7 +68,6 @@ import javax.swing.plaf.basic.ComboPopup;
|
|||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}.
|
||||||
@@ -132,8 +132,6 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
protected Color popupBackground;
|
protected Color popupBackground;
|
||||||
|
|
||||||
protected Insets paddingUnscaled;
|
|
||||||
|
|
||||||
private MouseListener hoverListener;
|
private MouseListener hoverListener;
|
||||||
protected boolean hover;
|
protected boolean hover;
|
||||||
protected boolean pressed;
|
protected boolean pressed;
|
||||||
@@ -223,10 +221,6 @@ public class FlatComboBoxUI
|
|||||||
if( maximumRowCount > 0 && maximumRowCount != 8 && comboBox.getMaximumRowCount() == 8 )
|
if( maximumRowCount > 0 && maximumRowCount != 8 && comboBox.getMaximumRowCount() == 8 )
|
||||||
comboBox.setMaximumRowCount( maximumRowCount );
|
comboBox.setMaximumRowCount( maximumRowCount );
|
||||||
|
|
||||||
// scale
|
|
||||||
paddingUnscaled = padding;
|
|
||||||
padding = UIScale.scale( paddingUnscaled );
|
|
||||||
|
|
||||||
paddingBorder = new CellPaddingBorder( padding );
|
paddingBorder = new CellPaddingBorder( padding );
|
||||||
|
|
||||||
MigLayoutVisualPadding.install( comboBox );
|
MigLayoutVisualPadding.install( comboBox );
|
||||||
@@ -368,9 +362,6 @@ public class FlatComboBoxUI
|
|||||||
// remove default text field border from editor
|
// remove default text field border from editor
|
||||||
if( textField.getBorder() instanceof FlatTextBorder )
|
if( textField.getBorder() instanceof FlatTextBorder )
|
||||||
textField.setBorder( BorderFactory.createEmptyBorder() );
|
textField.setBorder( BorderFactory.createEmptyBorder() );
|
||||||
|
|
||||||
// editor padding
|
|
||||||
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, paddingUnscaled );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// explicitly make non-opaque
|
// explicitly make non-opaque
|
||||||
@@ -379,6 +370,7 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
|
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
|
|
||||||
|
updateEditorPadding();
|
||||||
updateEditorColors();
|
updateEditorColors();
|
||||||
|
|
||||||
// macOS
|
// macOS
|
||||||
@@ -395,6 +387,25 @@ public class FlatComboBoxUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateEditorPadding() {
|
||||||
|
if( !(editor instanceof JTextField) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
JTextField textField = (JTextField) editor;
|
||||||
|
Insets insets = textField.getInsets();
|
||||||
|
Insets pad = padding;
|
||||||
|
if( insets.top != 0 || insets.left != 0 || insets.bottom != 0 || insets.right != 0 ) {
|
||||||
|
// if text field has custom border, subtract text field insets from padding
|
||||||
|
pad = new Insets(
|
||||||
|
unscale( Math.max( scale( padding.top ) - insets.top, 0 ) ),
|
||||||
|
unscale( Math.max( scale( padding.left ) - insets.left, 0 ) ),
|
||||||
|
unscale( Math.max( scale( padding.bottom ) - insets.bottom, 0 ) ),
|
||||||
|
unscale( Math.max( scale( padding.right ) - insets.right, 0 ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, pad );
|
||||||
|
}
|
||||||
|
|
||||||
private void updateEditorColors() {
|
private void updateEditorColors() {
|
||||||
// use non-UIResource colors because when SwingUtilities.updateComponentTreeUI()
|
// use non-UIResource colors because when SwingUtilities.updateComponentTreeUI()
|
||||||
// is used, then the editor is updated after the combobox and the
|
// is used, then the editor is updated after the combobox and the
|
||||||
@@ -493,16 +504,10 @@ public class FlatComboBoxUI
|
|||||||
c.setForeground( getForeground( enabled ) );
|
c.setForeground( getForeground( enabled ) );
|
||||||
|
|
||||||
boolean shouldValidate = (c instanceof JPanel);
|
boolean shouldValidate = (c instanceof JPanel);
|
||||||
if( padding != null )
|
|
||||||
bounds = FlatUIUtils.subtractInsets( bounds, padding );
|
|
||||||
|
|
||||||
// increase the size of the rendering area to make sure that the text
|
|
||||||
// is vertically aligned with other component types (e.g. JTextField)
|
|
||||||
Insets rendererInsets = getRendererComponentInsets( c );
|
|
||||||
if( rendererInsets != null )
|
|
||||||
bounds = FlatUIUtils.addInsets( bounds, rendererInsets );
|
|
||||||
|
|
||||||
|
paddingBorder.install( c );
|
||||||
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
|
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
|
||||||
|
paddingBorder.uninstall();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -549,51 +554,35 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getDisplaySize() {
|
protected Dimension getDisplaySize() {
|
||||||
// update padding
|
|
||||||
padding = UIScale.scale( paddingUnscaled );
|
|
||||||
|
|
||||||
paddingBorder.uninstall();
|
paddingBorder.uninstall();
|
||||||
Dimension displaySize = super.getDisplaySize();
|
Dimension displaySize = super.getDisplaySize();
|
||||||
paddingBorder.uninstall();
|
paddingBorder.uninstall();
|
||||||
|
|
||||||
|
// remove padding added in super.getDisplaySize()
|
||||||
|
int displayWidth = displaySize.width - padding.left - padding.right;
|
||||||
|
int displayHeight = displaySize.height - padding.top - padding.bottom;
|
||||||
|
|
||||||
// recalculate width without hardcoded 100 under special conditions
|
// recalculate width without hardcoded 100 under special conditions
|
||||||
if( displaySize.width == 100 + padding.left + padding.right &&
|
if( displayWidth == 100 &&
|
||||||
comboBox.isEditable() &&
|
comboBox.isEditable() &&
|
||||||
comboBox.getItemCount() == 0 &&
|
comboBox.getItemCount() == 0 &&
|
||||||
comboBox.getPrototypeDisplayValue() == null )
|
comboBox.getPrototypeDisplayValue() == null )
|
||||||
{
|
{
|
||||||
int width = getDefaultSize().width;
|
displayWidth = Math.max( getDefaultSize().width, editor.getPreferredSize().width );
|
||||||
width = Math.max( width, editor.getPreferredSize().width );
|
|
||||||
width += padding.left + padding.right;
|
|
||||||
displaySize = new Dimension( width, displaySize.height );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return displaySize;
|
return new Dimension( displayWidth, displayHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getSizeForComponent( Component comp ) {
|
protected Dimension getSizeForComponent( Component comp ) {
|
||||||
|
paddingBorder.install( comp );
|
||||||
Dimension size = super.getSizeForComponent( comp );
|
Dimension size = super.getSizeForComponent( comp );
|
||||||
|
paddingBorder.uninstall();
|
||||||
// remove the renderer border top/bottom insets from the size to make sure that
|
|
||||||
// the combobox gets the same height as other component types (e.g. JTextField)
|
|
||||||
Insets rendererInsets = getRendererComponentInsets( comp );
|
|
||||||
if( rendererInsets != null )
|
|
||||||
size = new Dimension( size.width, size.height - rendererInsets.top - rendererInsets.bottom );
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Insets getRendererComponentInsets( Component rendererComponent ) {
|
|
||||||
if( rendererComponent instanceof JComponent ) {
|
|
||||||
Border rendererBorder = ((JComponent)rendererComponent).getBorder();
|
|
||||||
if( rendererBorder != null )
|
|
||||||
return rendererBorder.getBorderInsets( rendererComponent );
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCellRenderer() {
|
private boolean isCellRenderer() {
|
||||||
return comboBox.getParent() instanceof CellRendererPane;
|
return comboBox.getParent() instanceof CellRendererPane;
|
||||||
}
|
}
|
||||||
@@ -661,7 +650,7 @@ public class FlatComboBoxUI
|
|||||||
super( combo );
|
super( combo );
|
||||||
|
|
||||||
// BasicComboPopup listens to JComboBox.componentOrientation and updates
|
// BasicComboPopup listens to JComboBox.componentOrientation and updates
|
||||||
// the component orientation of the list, scroller and popup, but when
|
// the component orientation of the list, scroll pane and popup, but when
|
||||||
// switching the LaF and a new combo popup is created, the component
|
// switching the LaF and a new combo popup is created, the component
|
||||||
// orientation is not applied.
|
// orientation is not applied.
|
||||||
ComponentOrientation o = comboBox.getComponentOrientation();
|
ComponentOrientation o = comboBox.getComponentOrientation();
|
||||||
@@ -780,7 +769,7 @@ public class FlatComboBoxUI
|
|||||||
//---- class CellPaddingBorder --------------------------------------------
|
//---- class CellPaddingBorder --------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cell padding border used only in popup list.
|
* Cell padding border used in popup list and for current value if not editable.
|
||||||
* <p>
|
* <p>
|
||||||
* The insets are the union of the cell padding and the renderer border insets,
|
* The insets are the union of the cell padding and the renderer border insets,
|
||||||
* which vertically aligns text in popup list with text in combobox.
|
* which vertically aligns text in popup list with text in combobox.
|
||||||
@@ -836,6 +825,7 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||||
|
Insets padding = scale( this.padding );
|
||||||
if( rendererBorder != null ) {
|
if( rendererBorder != null ) {
|
||||||
Insets insideInsets = rendererBorder.getBorderInsets( c );
|
Insets insideInsets = rendererBorder.getBorderInsets( c );
|
||||||
insets.top = Math.max( padding.top, insideInsets.top );
|
insets.top = Math.max( padding.top, insideInsets.top );
|
||||||
|
|||||||
@@ -114,17 +114,19 @@ public class TestFlatComponentSizes
|
|||||||
void comboBox( float factor ) {
|
void comboBox( float factor ) {
|
||||||
TestUtils.scaleFont( factor );
|
TestUtils.scaleFont( factor );
|
||||||
|
|
||||||
JComboBox<String> comboBox = new JComboBox<>();
|
String[] items = { "text" };
|
||||||
JComboBox<String> comboBox2 = new JComboBox<>();
|
JComboBox<String> comboBox = new JComboBox<>( items );
|
||||||
JComboBox<String> comboBox3 = new JComboBox<>();
|
JComboBox<String> comboBox2 = new JComboBox<>( items );
|
||||||
JComboBox<String> comboBox4 = new JComboBox<>();
|
JComboBox<String> comboBox3 = new JComboBox<>( items );
|
||||||
|
JComboBox<String> comboBox4 = new JComboBox<>( items );
|
||||||
|
|
||||||
applyCustomComboBoxRendererBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 3 ) ) );
|
applyCustomComboBoxRendererBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 6 ) ) );
|
||||||
applyCustomComboBoxRendererBorder( comboBox3, new BorderWithIcon() );
|
applyCustomComboBoxRendererBorder( comboBox3, new BorderWithIcon() );
|
||||||
applyCustomComboBoxRendererBorder( comboBox4, null );
|
applyCustomComboBoxRendererBorder( comboBox4, null );
|
||||||
|
|
||||||
Dimension size = comboBox.getPreferredSize();
|
Dimension size = comboBox.getPreferredSize();
|
||||||
assertEquals( size, comboBox2.getPreferredSize() );
|
assertEquals( size.width, comboBox2.getPreferredSize().width );
|
||||||
|
assertEquals( size.height - (2 * UIScale.scale( 2 )) + (2 * UIScale.scale( 6 )), comboBox2.getPreferredSize().height );
|
||||||
assertEquals( size, comboBox3.getPreferredSize() );
|
assertEquals( size, comboBox3.getPreferredSize() );
|
||||||
assertEquals( size, comboBox4.getPreferredSize() );
|
assertEquals( size, comboBox4.getPreferredSize() );
|
||||||
|
|
||||||
@@ -143,23 +145,24 @@ public class TestFlatComponentSizes
|
|||||||
void comboBoxEditable( float factor ) {
|
void comboBoxEditable( float factor ) {
|
||||||
TestUtils.scaleFont( factor );
|
TestUtils.scaleFont( factor );
|
||||||
|
|
||||||
JComboBox<String> comboBox = new JComboBox<>();
|
String[] items = { "text" };
|
||||||
JComboBox<String> comboBox2 = new JComboBox<>();
|
JComboBox<String> comboBox = new JComboBox<>( items );
|
||||||
JComboBox<String> comboBox3 = new JComboBox<>();
|
JComboBox<String> comboBox2 = new JComboBox<>( items );
|
||||||
JComboBox<String> comboBox4 = new JComboBox<>();
|
JComboBox<String> comboBox3 = new JComboBox<>( items );
|
||||||
|
JComboBox<String> comboBox4 = new JComboBox<>( items );
|
||||||
|
|
||||||
comboBox.setEditable( true );
|
comboBox.setEditable( true );
|
||||||
comboBox2.setEditable( true );
|
comboBox2.setEditable( true );
|
||||||
comboBox3.setEditable( true );
|
comboBox3.setEditable( true );
|
||||||
comboBox4.setEditable( true );
|
comboBox4.setEditable( true );
|
||||||
|
|
||||||
applyCustomComboBoxEditorBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 3 ) ) );
|
applyCustomComboBoxEditorBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 6 ) ) );
|
||||||
applyCustomComboBoxEditorBorder( comboBox3, new BorderWithIcon() );
|
applyCustomComboBoxEditorBorder( comboBox3, new BorderWithIcon() );
|
||||||
applyCustomComboBoxEditorBorder( comboBox4, null );
|
applyCustomComboBoxEditorBorder( comboBox4, null );
|
||||||
|
|
||||||
Dimension size = comboBox.getPreferredSize();
|
Dimension size = comboBox.getPreferredSize();
|
||||||
assertEquals( size.width, comboBox2.getPreferredSize().width );
|
assertEquals( size.width, comboBox2.getPreferredSize().width );
|
||||||
assertEquals( size.height + (2 * UIScale.scale( 3 )), comboBox2.getPreferredSize().height );
|
assertEquals( size.height - (2 * UIScale.scale( 2 )) + (2 * UIScale.scale( 6 )), comboBox2.getPreferredSize().height );
|
||||||
assertEquals( size, comboBox3.getPreferredSize() );
|
assertEquals( size, comboBox3.getPreferredSize() );
|
||||||
assertEquals( size, comboBox4.getPreferredSize() );
|
assertEquals( size, comboBox4.getPreferredSize() );
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ public class FlatCustomBordersTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox ) {
|
private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox ) {
|
||||||
applyCustomComboBoxEditorBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 3 ) ) );
|
applyCustomComboBoxEditorBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyCustomComboBoxEditorBorderWithIcon( JComboBox<String> comboBox ) {
|
private void applyCustomComboBoxEditorBorderWithIcon( JComboBox<String> comboBox ) {
|
||||||
@@ -152,7 +152,7 @@ public class FlatCustomBordersTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox ) {
|
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox ) {
|
||||||
applyCustomComboBoxRendererBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 3 ) ) );
|
applyCustomComboBoxRendererBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyCustomComboBoxRendererBorderWithIcon( JComboBox<String> comboBox ) {
|
private void applyCustomComboBoxRendererBorderWithIcon( JComboBox<String> comboBox ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user