mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 15:07:11 -06:00
ComboBox: reworked uninstall of CellPaddingBorder, which is temporary used for cell renderers, to make it easier to understand and reliable
(tested using FlatCustomBordersTest, FlatNetBeansTest, etc)
This commit is contained in:
@@ -39,7 +39,6 @@ import java.awt.event.MouseEvent;
|
|||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.CellRendererPane;
|
import javax.swing.CellRendererPane;
|
||||||
@@ -139,7 +138,7 @@ public class FlatComboBoxUI
|
|||||||
protected boolean hover;
|
protected boolean hover;
|
||||||
protected boolean pressed;
|
protected boolean pressed;
|
||||||
|
|
||||||
private WeakReference<Component> lastRendererComponent;
|
private CellPaddingBorder paddingBorder;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatComboBoxUI();
|
return new FlatComboBoxUI();
|
||||||
@@ -228,6 +227,8 @@ public class FlatComboBoxUI
|
|||||||
paddingUnscaled = padding;
|
paddingUnscaled = padding;
|
||||||
padding = UIScale.scale( paddingUnscaled );
|
padding = UIScale.scale( paddingUnscaled );
|
||||||
|
|
||||||
|
paddingBorder = new CellPaddingBorder( padding );
|
||||||
|
|
||||||
MigLayoutVisualPadding.install( comboBox );
|
MigLayoutVisualPadding.install( comboBox );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +254,8 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
popupBackground = null;
|
popupBackground = null;
|
||||||
|
|
||||||
|
paddingBorder.uninstall();
|
||||||
|
|
||||||
MigLayoutVisualPadding.uninstall( comboBox );
|
MigLayoutVisualPadding.uninstall( comboBox );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,14 +479,14 @@ public class FlatComboBoxUI
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
||||||
|
paddingBorder.uninstall();
|
||||||
|
|
||||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||||
uninstallCellPaddingBorder( renderer );
|
|
||||||
if( renderer == null )
|
if( renderer == null )
|
||||||
renderer = new DefaultListCellRenderer();
|
renderer = new DefaultListCellRenderer();
|
||||||
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
|
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
|
||||||
c.setFont( comboBox.getFont() );
|
c.setFont( comboBox.getFont() );
|
||||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
uninstallCellPaddingBorder( c );
|
|
||||||
|
|
||||||
boolean enabled = comboBox.isEnabled();
|
boolean enabled = comboBox.isEnabled();
|
||||||
c.setBackground( getBackground( enabled ) );
|
c.setBackground( getBackground( enabled ) );
|
||||||
@@ -537,26 +540,20 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getDefaultSize() {
|
protected Dimension getDefaultSize() {
|
||||||
@SuppressWarnings( "unchecked" )
|
paddingBorder.uninstall();
|
||||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
|
||||||
uninstallCellPaddingBorder( renderer );
|
|
||||||
|
|
||||||
Dimension size = super.getDefaultSize();
|
Dimension size = super.getDefaultSize();
|
||||||
|
paddingBorder.uninstall();
|
||||||
uninstallCellPaddingBorder( renderer );
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getDisplaySize() {
|
protected Dimension getDisplaySize() {
|
||||||
@SuppressWarnings( "unchecked" )
|
|
||||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
|
||||||
uninstallCellPaddingBorder( renderer );
|
|
||||||
|
|
||||||
// update padding
|
// update padding
|
||||||
padding = UIScale.scale( paddingUnscaled );
|
padding = UIScale.scale( paddingUnscaled );
|
||||||
|
|
||||||
|
paddingBorder.uninstall();
|
||||||
Dimension displaySize = super.getDisplaySize();
|
Dimension displaySize = super.getDisplaySize();
|
||||||
|
paddingBorder.uninstall();
|
||||||
|
|
||||||
// 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( displaySize.width == 100 + padding.left + padding.right &&
|
||||||
@@ -570,7 +567,6 @@ public class FlatComboBoxUI
|
|||||||
displaySize = new Dimension( width, displaySize.height );
|
displaySize = new Dimension( width, displaySize.height );
|
||||||
}
|
}
|
||||||
|
|
||||||
uninstallCellPaddingBorder( renderer );
|
|
||||||
return displaySize;
|
return displaySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,14 +593,6 @@ public class FlatComboBoxUI
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uninstallCellPaddingBorder( Object o ) {
|
|
||||||
CellPaddingBorder.uninstall( o );
|
|
||||||
if( lastRendererComponent != null ) {
|
|
||||||
CellPaddingBorder.uninstall( lastRendererComponent );
|
|
||||||
lastRendererComponent = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCellRenderer() {
|
private boolean isCellRenderer() {
|
||||||
return comboBox.getParent() instanceof CellRendererPane;
|
return comboBox.getParent() instanceof CellRendererPane;
|
||||||
}
|
}
|
||||||
@@ -668,8 +656,6 @@ public class FlatComboBoxUI
|
|||||||
protected class FlatComboPopup
|
protected class FlatComboPopup
|
||||||
extends BasicComboPopup
|
extends BasicComboPopup
|
||||||
{
|
{
|
||||||
private CellPaddingBorder paddingBorder;
|
|
||||||
|
|
||||||
protected FlatComboPopup( JComboBox combo ) {
|
protected FlatComboPopup( JComboBox combo ) {
|
||||||
super( combo );
|
super( combo );
|
||||||
|
|
||||||
@@ -753,6 +739,19 @@ public class FlatComboBoxUI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getPopupHeightForRowCount( int maxRowCount ) {
|
||||||
|
int height = super.getPopupHeightForRowCount( maxRowCount );
|
||||||
|
paddingBorder.uninstall();
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintChildren( Graphics g ) {
|
||||||
|
super.paintChildren( g );
|
||||||
|
paddingBorder.uninstall();
|
||||||
|
}
|
||||||
|
|
||||||
//---- class PopupListCellRenderer -----
|
//---- class PopupListCellRenderer -----
|
||||||
|
|
||||||
private class PopupListCellRenderer
|
private class PopupListCellRenderer
|
||||||
@@ -762,22 +761,15 @@ public class FlatComboBoxUI
|
|||||||
public Component getListCellRendererComponent( JList list, Object value,
|
public Component getListCellRendererComponent( JList list, Object value,
|
||||||
int index, boolean isSelected, boolean cellHasFocus )
|
int index, boolean isSelected, boolean cellHasFocus )
|
||||||
{
|
{
|
||||||
ListCellRenderer renderer = comboBox.getRenderer();
|
paddingBorder.uninstall();
|
||||||
CellPaddingBorder.uninstall( renderer );
|
|
||||||
CellPaddingBorder.uninstall( lastRendererComponent );
|
|
||||||
|
|
||||||
|
ListCellRenderer renderer = comboBox.getRenderer();
|
||||||
if( renderer == null )
|
if( renderer == null )
|
||||||
renderer = new DefaultListCellRenderer();
|
renderer = new DefaultListCellRenderer();
|
||||||
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
|
|
||||||
if( c instanceof JComponent ) {
|
paddingBorder.install( c );
|
||||||
if( paddingBorder == null )
|
|
||||||
paddingBorder = new CellPaddingBorder( padding );
|
|
||||||
paddingBorder.install( (JComponent) c );
|
|
||||||
}
|
|
||||||
|
|
||||||
lastRendererComponent = (c != renderer) ? new WeakReference<>( c ) : null;
|
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -788,44 +780,57 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cell padding border used only in popup list.
|
* Cell padding border used only in popup list.
|
||||||
*
|
* <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.
|
||||||
*
|
* <p>
|
||||||
* The renderer border is painted on the outside of this border.
|
* The renderer border is painted on the outer side of this border.
|
||||||
*/
|
*/
|
||||||
private static class CellPaddingBorder
|
private static class CellPaddingBorder
|
||||||
extends AbstractBorder
|
extends AbstractBorder
|
||||||
{
|
{
|
||||||
private final Insets padding;
|
private final Insets padding;
|
||||||
|
private JComponent rendererComponent;
|
||||||
private Border rendererBorder;
|
private Border rendererBorder;
|
||||||
|
|
||||||
CellPaddingBorder( Insets padding ) {
|
CellPaddingBorder( Insets padding ) {
|
||||||
this.padding = padding;
|
this.padding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void install( JComponent rendererComponent ) {
|
void install( Component c ) {
|
||||||
Border oldBorder = rendererComponent.getBorder();
|
if( !(c instanceof JComponent) )
|
||||||
if( !(oldBorder instanceof CellPaddingBorder) ) {
|
|
||||||
rendererBorder = oldBorder;
|
|
||||||
rendererComponent.setBorder( this );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uninstall( Object o ) {
|
|
||||||
if( o instanceof WeakReference )
|
|
||||||
o = ((WeakReference<?>)o).get();
|
|
||||||
|
|
||||||
if( !(o instanceof JComponent) )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
JComponent rendererComponent = (JComponent) o;
|
JComponent jc = (JComponent) c;
|
||||||
Border border = rendererComponent.getBorder();
|
Border oldBorder = jc.getBorder();
|
||||||
if( border instanceof CellPaddingBorder ) {
|
if( oldBorder == this )
|
||||||
CellPaddingBorder paddingBorder = (CellPaddingBorder) border;
|
return; // already installed
|
||||||
rendererComponent.setBorder( paddingBorder.rendererBorder );
|
|
||||||
paddingBorder.rendererBorder = null;
|
// this border can be installed only at one component
|
||||||
}
|
uninstall();
|
||||||
|
|
||||||
|
// remember component where this border was installed for uninstall
|
||||||
|
rendererComponent = jc;
|
||||||
|
|
||||||
|
// remember old border and replace it
|
||||||
|
rendererBorder = oldBorder;
|
||||||
|
rendererComponent.setBorder( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall border from previously installed component.
|
||||||
|
* Because this border is installed in PopupListCellRenderer.getListCellRendererComponent(),
|
||||||
|
* there is no single place to uninstall it.
|
||||||
|
* This is the reason why this method is called from various places.
|
||||||
|
*/
|
||||||
|
void uninstall() {
|
||||||
|
if( rendererComponent == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( rendererComponent.getBorder() == this )
|
||||||
|
rendererComponent.setBorder( rendererBorder );
|
||||||
|
rendererComponent = null;
|
||||||
|
rendererBorder = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user