ComboBox: support using as cell renderer (e.g. in JTable)

This commit is contained in:
Karl Tauber
2021-05-04 21:39:08 +02:00
parent 067501cbe7
commit cacf0ea987
4 changed files with 90 additions and 30 deletions

View File

@@ -5,8 +5,13 @@ FlatLaf Change Log
#### New features and improvements #### New features and improvements
- Renamed `Flat*Laf.install()` methods to `Flat*Laf.setup()` to avoid confusion
with `UIManager.installLookAndFeel(LookAndFeelInfo info)`. The old
`Flat*Laf.install()` methods are still there, but marked as deprecated. They
will be removed in a future version.
- Button and ToggleButton: Support borderless button style (set client property - Button and ToggleButton: Support borderless button style (set client property
`JButton.buttonType` to `borderless`). (PR #276) `JButton.buttonType` to `borderless`). (PR #276)
- ComboBox: Support using as cell renderer (e.g. in `JTable`).
- DesktopPane: Improved layout of iconified internal frames in dock: - DesktopPane: Improved layout of iconified internal frames in dock:
- Always placed at bottom-left in desktop pane. - Always placed at bottom-left in desktop pane.
- Newly iconified frames are added to the right side of the dock. - Newly iconified frames are added to the right side of the dock.
@@ -23,10 +28,6 @@ FlatLaf Change Log
- Use mapper function in color filter to dynamically map colors. (PR #303) - Use mapper function in color filter to dynamically map colors. (PR #303)
- Color filter supports light and dark themes. - Color filter supports light and dark themes.
- Getters for icon name, classloader, etc. - Getters for icon name, classloader, etc.
- Renamed `Flat*Laf.install()` methods to `Flat*Laf.setup()` to avoid confusion
with `UIManager.installLookAndFeel(LookAndFeelInfo info)`. The old
`Flat*Laf.install()` methods are still there, but marked as deprecated. They
will be removed in a future version.
#### Fixed bugs #### Fixed bugs

View File

@@ -141,6 +141,21 @@ public class FlatArrowButton
return FlatUIUtils.deriveColor( foreground, this.foreground ); return FlatUIUtils.deriveColor( foreground, this.foreground );
} }
/**
* Returns the color used to paint the arrow.
*
* @since 1.2
*/
protected Color getArrowColor() {
return isEnabled()
? (pressedForeground != null && isPressed()
? pressedForeground
: (hoverForeground != null && isHover()
? hoverForeground
: foreground))
: disabledForeground;
}
@Override @Override
public Dimension getPreferredSize() { public Dimension getPreferredSize() {
return scale( super.getPreferredSize() ); return scale( super.getPreferredSize() );
@@ -170,13 +185,7 @@ public class FlatArrowButton
} }
// paint arrow // paint arrow
g.setColor( deriveForeground( isEnabled() g.setColor( deriveForeground( getArrowColor() ) );
? (pressedForeground != null && isPressed()
? pressedForeground
: (hoverForeground != null && isHover()
? hoverForeground
: foreground))
: disabledForeground ) );
paintArrow( (Graphics2D) g ); paintArrow( (Graphics2D) g );
FlatUIUtils.resetRenderingHints( g, oldRenderingHints ); FlatUIUtils.resetRenderingHints( g, oldRenderingHints );

View File

@@ -42,6 +42,7 @@ import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference; 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.ComboBoxEditor; import javax.swing.ComboBoxEditor;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
import javax.swing.InputMap; import javax.swing.InputMap;
@@ -390,6 +391,15 @@ public class FlatComboBoxUI
public void update( Graphics g, JComponent c ) { public void update( Graphics g, JComponent c ) {
float focusWidth = FlatUIUtils.getBorderFocusWidth( c ); float focusWidth = FlatUIUtils.getBorderFocusWidth( c );
float arc = FlatUIUtils.getBorderArc( c ); float arc = FlatUIUtils.getBorderArc( c );
boolean paintBackground = true;
// check whether used as cell renderer
boolean isCellRenderer = c.getParent() instanceof CellRendererPane;
if( isCellRenderer ) {
focusWidth = 0;
arc = 0;
paintBackground = isCellRendererBackgroundChanged();
}
// fill background if opaque to avoid garbage if user sets opaque to true // fill background if opaque to avoid garbage if user sets opaque to true
if( c.isOpaque() && (focusWidth > 0 || arc > 0) ) if( c.isOpaque() && (focusWidth > 0 || arc > 0) )
@@ -407,27 +417,29 @@ public class FlatComboBoxUI
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight(); boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
// paint background // paint background
g2.setColor( getBackground( enabled ) ); if( paintBackground || c.isOpaque() ) {
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc ); g2.setColor( getBackground( enabled ) );
// paint arrow button background
if( enabled ) {
g2.setColor( paintButton ? buttonEditableBackground : 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 ); FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
}
// paint vertical line between value and arrow button // paint arrow button background
if( paintButton ) { if( enabled && !isCellRenderer ) {
g2.setColor( enabled ? borderColor : disabledBorderColor ); g2.setColor( paintButton ? buttonEditableBackground : buttonBackground );
float lw = scale( 1f ); Shape oldClip = g2.getClip();
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw; if( isLeftToRight )
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - 1 - (focusWidth * 2)) ); 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 button
if( paintButton ) {
g2.setColor( enabled ? borderColor : disabledBorderColor );
float lw = scale( 1f );
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - 1 - (focusWidth * 2)) );
}
} }
// avoid that the "current value" renderer is invoked with enabled antialiasing // avoid that the "current value" renderer is invoked with enabled antialiasing
@@ -554,6 +566,16 @@ public class FlatComboBoxUI
} }
} }
private boolean isCellRenderer() {
return comboBox.getParent() instanceof CellRendererPane;
}
private boolean isCellRendererBackgroundChanged() {
// parent is a CellRendererPane, parentParent is e.g. a JTable
Container parentParent = comboBox.getParent().getParent();
return parentParent != null && !comboBox.getBackground().equals( parentParent.getBackground() );
}
//---- class FlatComboBoxButton ------------------------------------------- //---- class FlatComboBoxButton -------------------------------------------
protected class FlatComboBoxButton protected class FlatComboBoxButton
@@ -580,6 +602,14 @@ public class FlatComboBoxUI
protected boolean isPressed() { protected boolean isPressed() {
return super.isPressed() || (!comboBox.isEditable() ? pressed : false); return super.isPressed() || (!comboBox.isEditable() ? pressed : false);
} }
@Override
protected Color getArrowColor() {
if( isCellRenderer() && isCellRendererBackgroundChanged() )
return comboBox.getForeground();
return super.getArrowColor();
}
} }
//---- class FlatComboPopup ----------------------------------------------- //---- class FlatComboPopup -----------------------------------------------

View File

@@ -134,6 +134,7 @@ public class FlatComponents2Test
"January", "February", "March", "April", "May", "June", "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" "July", "August", "September", "October", "November", "December"
}; };
cm.getColumn(2).setCellRenderer( new TestComboBoxTableCellRenderer() );
cm.getColumn(2).setCellEditor( new DefaultCellEditor( new JComboBox<>( months ) ) ); cm.getColumn(2).setCellEditor( new DefaultCellEditor( new JComboBox<>( months ) ) );
JComboBox<String> editableComboBox = new JComboBox<>( months ); JComboBox<String> editableComboBox = new JComboBox<>( months );
editableComboBox.setEditable( true ); editableComboBox.setEditable( true );
@@ -1219,4 +1220,23 @@ public class FlatComponents2Test
return this; return this;
} }
} }
//---- class TestComboBoxTableCellRenderer --------------------------------
private static class TestComboBoxTableCellRenderer
extends JComboBox<String>
implements TableCellRenderer
{
@Override
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column )
{
setModel( new DefaultComboBoxModel<>( new String[] { String.valueOf( value ) } ) );
setBackground( isSelected ? table.getSelectionBackground() : table.getBackground() );
setForeground( isSelected ? table.getSelectionForeground() : table.getForeground() );
setBorder( null );
return this;
}
}
} }