IntelliJ Themes: fixes for text component disabled backgrounds, button backgrounds, combobox disabled backgrounds and spinner disabled backgrounds

This commit is contained in:
Karl Tauber
2019-11-14 11:28:38 +01:00
parent 3b740cb494
commit a907cd7f46
9 changed files with 103 additions and 12 deletions

View File

@@ -126,6 +126,8 @@ public class IntelliJTheme
if( ui == null ) if( ui == null )
return; return;
defaults.put( "Component.isIntelliJTheme", true );
loadNamedColors( defaults ); loadNamedColors( defaults );
// convert Json "ui" structure to UI defaults // convert Json "ui" structure to UI defaults
@@ -229,7 +231,7 @@ public class IntelliJTheme
// (e.g. set ComboBox.buttonEditableBackground to *.background // (e.g. set ComboBox.buttonEditableBackground to *.background
// because it is mapped from ComboBox.ArrowButton.background) // because it is mapped from ComboBox.ArrowButton.background)
String km = uiKeyInverseMapping.getOrDefault( k, (String) k ); String km = uiKeyInverseMapping.getOrDefault( k, (String) k );
if( km.endsWith( tail ) ) if( km.endsWith( tail ) && !noWildcardReplace.contains( k ) )
defaults.put( k, uiValue ); defaults.put( k, uiValue );
} }
} }
@@ -312,6 +314,7 @@ public class IntelliJTheme
private static Map<String, String> uiKeyMapping = new HashMap<>(); private static Map<String, String> uiKeyMapping = new HashMap<>();
private static Map<String, String> uiKeyInverseMapping = new HashMap<>(); private static Map<String, String> uiKeyInverseMapping = new HashMap<>();
private static Map<String, String> checkboxKeyMapping = new HashMap<>(); private static Map<String, String> checkboxKeyMapping = new HashMap<>();
private static Set<String> noWildcardReplace = new HashSet<>();
static { static {
// ComboBox // ComboBox
@@ -336,6 +339,16 @@ public class IntelliJTheme
checkboxKeyMapping.put( "Checkbox.Border.Selected", "CheckBox.icon.selectedBorderColor" ); checkboxKeyMapping.put( "Checkbox.Border.Selected", "CheckBox.icon.selectedBorderColor" );
checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" ); checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" );
checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.selectedFocusedBorderColor" ); checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.selectedFocusedBorderColor" );
// because FlatLaf uses Button.background and Button.borderColor,
// but Darcula uses Button.startBackground and Button.startBorderColor,
// our default button background and border colors may be replaced by
// wildcard *.background and *.borderColor colors
noWildcardReplace.add( "Button.background" );
noWildcardReplace.add( "Button.borderColor" );
noWildcardReplace.add( "Button.default.background" );
noWildcardReplace.add( "Button.default.borderColor" );
noWildcardReplace.add( "ToggleButton.background" );
} }
//---- class ThemeLaf ----------------------------------------------------- //---- class ThemeLaf -----------------------------------------------------

View File

@@ -70,6 +70,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Component.focusWidth int * @uiDefault Component.focusWidth int
* @uiDefault Component.arc int * @uiDefault Component.arc int
* @uiDefault Component.arrowType String triangle (default) or chevron * @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault Component.borderColor Color * @uiDefault Component.borderColor Color
* @uiDefault Component.disabledBorderColor Color * @uiDefault Component.disabledBorderColor Color
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background * @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
@@ -89,6 +90,7 @@ public class FlatComboBoxUI
protected int focusWidth; protected int focusWidth;
protected int arc; protected int arc;
protected String arrowType; protected String arrowType;
protected boolean isIntelliJTheme;
protected Color borderColor; protected Color borderColor;
protected Color disabledBorderColor; protected Color disabledBorderColor;
@@ -140,6 +142,7 @@ public class FlatComboBoxUI
focusWidth = UIManager.getInt( "Component.focusWidth" ); focusWidth = UIManager.getInt( "Component.focusWidth" );
arc = UIManager.getInt( "Component.arc" ); arc = UIManager.getInt( "Component.arc" );
arrowType = UIManager.getString( "Component.arrowType" ); arrowType = UIManager.getString( "Component.arrowType" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
borderColor = UIManager.getColor( "Component.borderColor" ); borderColor = UIManager.getColor( "Component.borderColor" );
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" ); disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
@@ -309,7 +312,7 @@ public class FlatComboBoxUI
// paint background // paint background
g2.setColor( enabled g2.setColor( enabled
? (editableBackground != null && comboBox.isEditable() ? editableBackground : c.getBackground()) ? (editableBackground != null && comboBox.isEditable() ? editableBackground : c.getBackground())
: disabledBackground ); : getDisabledBackground( comboBox ) );
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
// paint arrow button background // paint arrow button background
@@ -347,7 +350,7 @@ public class FlatComboBoxUI
boolean enabled = comboBox.isEnabled(); boolean enabled = comboBox.isEnabled();
c.setForeground( enabled ? comboBox.getForeground() : disabledForeground ); c.setForeground( enabled ? comboBox.getForeground() : disabledForeground );
c.setBackground( enabled ? comboBox.getBackground() : disabledBackground ); c.setBackground( enabled ? comboBox.getBackground() : getDisabledBackground( comboBox ) );
boolean shouldValidate = (c instanceof JPanel); boolean shouldValidate = (c instanceof JPanel);
if( padding != null ) if( padding != null )
@@ -364,10 +367,14 @@ public class FlatComboBoxUI
@Override @Override
public void paintCurrentValueBackground( Graphics g, Rectangle bounds, boolean hasFocus ) { public void paintCurrentValueBackground( Graphics g, Rectangle bounds, boolean hasFocus ) {
g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : disabledBackground ); g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : getDisabledBackground( comboBox ) );
g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height ); g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height );
} }
private Color getDisabledBackground( JComponent c ) {
return isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground;
}
@Override @Override
protected Dimension getSizeForComponent( Component comp ) { protected Dimension getSizeForComponent( Component comp ) {
Dimension size = super.getSizeForComponent( comp ); Dimension size = super.getSizeForComponent( comp );

View File

@@ -18,11 +18,14 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale; import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JEditorPane; import javax.swing.JEditorPane;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicEditorPaneUI; import javax.swing.plaf.basic.BasicEditorPaneUI;
import javax.swing.text.JTextComponent;
/** /**
* Provides the Flat LaF UI delegate for {@link javax.swing.JEditorPane}. * Provides the Flat LaF UI delegate for {@link javax.swing.JEditorPane}.
@@ -45,6 +48,7 @@ import javax.swing.plaf.basic.BasicEditorPaneUI;
* <!-- FlatEditorPaneUI --> * <!-- FlatEditorPaneUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -52,6 +56,7 @@ public class FlatEditorPaneUI
extends BasicEditorPaneUI extends BasicEditorPaneUI
{ {
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme;
private Object oldHonorDisplayProperties; private Object oldHonorDisplayProperties;
@@ -64,6 +69,7 @@ public class FlatEditorPaneUI
super.installDefaults(); super.installDefaults();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
// use component font and foreground for HTML text // use component font and foreground for HTML text
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES ); oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
@@ -95,4 +101,17 @@ public class FlatEditorPaneUI
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) ); size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
return size; return size;
} }
@Override
protected void paintBackground( Graphics g ) {
JTextComponent c = getComponent();
// for compatibility with IntelliJ themes
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
FlatUIUtils.paintParentBackground( g, c );
return;
}
super.paintBackground( g );
}
} }

View File

@@ -50,6 +50,7 @@ import com.formdev.flatlaf.util.SystemInfo;
* *
* @uiDefault Component.focusWidth int * @uiDefault Component.focusWidth int
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -58,6 +59,7 @@ public class FlatPasswordFieldUI
{ {
protected int focusWidth; protected int focusWidth;
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme;
private FocusListener focusListener; private FocusListener focusListener;
@@ -75,6 +77,7 @@ public class FlatPasswordFieldUI
focusWidth = UIManager.getInt( "Component.focusWidth" ); focusWidth = UIManager.getInt( "Component.focusWidth" );
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 ); LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
@@ -106,7 +109,7 @@ public class FlatPasswordFieldUI
@Override @Override
protected void paintSafely( Graphics g ) { protected void paintSafely( Graphics g ) {
FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth ); FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth, isIntelliJTheme );
super.paintSafely( g ); super.paintSafely( g );
} }

View File

@@ -60,6 +60,7 @@ import javax.swing.plaf.basic.BasicSpinnerUI;
* @uiDefault Component.arc int * @uiDefault Component.arc int
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.arrowType String triangle (default) or chevron * @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault Component.borderColor Color * @uiDefault Component.borderColor Color
* @uiDefault Component.disabledBorderColor Color * @uiDefault Component.disabledBorderColor Color
* @uiDefault Spinner.disabledBackground Color * @uiDefault Spinner.disabledBackground Color
@@ -81,6 +82,7 @@ public class FlatSpinnerUI
protected int arc; protected int arc;
protected int minimumWidth; protected int minimumWidth;
protected String arrowType; protected String arrowType;
protected boolean isIntelliJTheme;
protected Color borderColor; protected Color borderColor;
protected Color disabledBorderColor; protected Color disabledBorderColor;
protected Color disabledBackground; protected Color disabledBackground;
@@ -105,6 +107,7 @@ public class FlatSpinnerUI
arc = UIManager.getInt( "Component.arc" ); arc = UIManager.getInt( "Component.arc" );
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
arrowType = UIManager.getString( "Component.arrowType" ); arrowType = UIManager.getString( "Component.arrowType" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
borderColor = UIManager.getColor( "Component.borderColor" ); borderColor = UIManager.getColor( "Component.borderColor" );
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" ); disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" ); disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
@@ -261,7 +264,9 @@ public class FlatSpinnerUI
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight(); boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
// paint background // paint background
g2.setColor( enabled ? c.getBackground() : disabledBackground ); g2.setColor( enabled
? c.getBackground()
: (isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground) );
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
// paint arrow buttons background // paint arrow buttons background

View File

@@ -47,6 +47,7 @@ import javax.swing.text.JTextComponent;
* <!-- FlatTextAreaUI --> * <!-- FlatTextAreaUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault TextArea.disabledBackground Color used if not enabled * @uiDefault TextArea.disabledBackground Color used if not enabled
* @uiDefault TextArea.inactiveBackground Color used if not editable * @uiDefault TextArea.inactiveBackground Color used if not editable
* *
@@ -56,6 +57,7 @@ public class FlatTextAreaUI
extends BasicTextAreaUI extends BasicTextAreaUI
{ {
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme;
protected Color disabledBackground; protected Color disabledBackground;
protected Color inactiveBackground; protected Color inactiveBackground;
@@ -68,6 +70,7 @@ public class FlatTextAreaUI
super.installDefaults(); super.installDefaults();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" ); disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" ); inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
} }
@@ -87,9 +90,11 @@ public class FlatTextAreaUI
Color background = c.getBackground(); Color background = c.getBackground();
g.setColor( !(background instanceof UIResource) g.setColor( !(background instanceof UIResource)
? background ? background
: (!c.isEnabled() : (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
? disabledBackground ? FlatUIUtils.getParentBackground( c )
: (!c.isEditable() ? inactiveBackground : background)) ); : (!c.isEnabled()
? disabledBackground
: (!c.isEditable() ? inactiveBackground : background))) );
g.fillRect( 0, 0, c.getWidth(), c.getHeight() ); g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
} }

View File

@@ -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 java.awt.Color;
import java.awt.Container; import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
@@ -29,6 +30,7 @@ import javax.swing.JTextField;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTextFieldUI; import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
@@ -54,6 +56,7 @@ import javax.swing.text.JTextComponent;
* *
* @uiDefault Component.focusWidth int * @uiDefault Component.focusWidth int
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -62,6 +65,7 @@ public class FlatTextFieldUI
{ {
protected int focusWidth; protected int focusWidth;
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme;
private FocusListener focusListener; private FocusListener focusListener;
@@ -75,6 +79,7 @@ public class FlatTextFieldUI
focusWidth = UIManager.getInt( "Component.focusWidth" ); focusWidth = UIManager.getInt( "Component.focusWidth" );
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 ); LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
@@ -106,7 +111,7 @@ public class FlatTextFieldUI
@Override @Override
protected void paintSafely( Graphics g ) { protected void paintSafely( Graphics g ) {
paintBackground( g, getComponent(), focusWidth ); paintBackground( g, getComponent(), focusWidth, isIntelliJTheme );
super.paintSafely( g ); super.paintSafely( g );
} }
@@ -115,7 +120,7 @@ public class FlatTextFieldUI
// background is painted elsewhere // background is painted elsewhere
} }
static void paintBackground( Graphics g, JTextComponent c, int focusWidth ) { static void paintBackground( Graphics g, JTextComponent c, int focusWidth, boolean isIntelliJTheme ) {
// do not paint background if: // do not paint background if:
// - not opaque and // - not opaque and
// - border is not a flat border and // - border is not a flat border and
@@ -135,7 +140,12 @@ public class FlatTextFieldUI
float fFocusWidth = (c.getBorder() instanceof FlatBorder) ? scale( (float) focusWidth ) : 0; float fFocusWidth = (c.getBorder() instanceof FlatBorder) ? scale( (float) focusWidth ) : 0;
g2.setColor( c.getBackground() ); Color background = c.getBackground();
g2.setColor( !(background instanceof UIResource)
? background
: (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
? FlatUIUtils.getParentBackground( c )
: background) );
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), fFocusWidth, 0 ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), fFocusWidth, 0 );
} finally { } finally {
g2.dispose(); g2.dispose();

View File

@@ -18,11 +18,14 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale; import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JEditorPane; import javax.swing.JEditorPane;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTextPaneUI; import javax.swing.plaf.basic.BasicTextPaneUI;
import javax.swing.text.JTextComponent;
/** /**
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextPane}. * Provides the Flat LaF UI delegate for {@link javax.swing.JTextPane}.
@@ -45,6 +48,7 @@ import javax.swing.plaf.basic.BasicTextPaneUI;
* <!-- FlatTextPaneUI --> * <!-- FlatTextPaneUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -52,6 +56,7 @@ public class FlatTextPaneUI
extends BasicTextPaneUI extends BasicTextPaneUI
{ {
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme;
private Object oldHonorDisplayProperties; private Object oldHonorDisplayProperties;
@@ -64,6 +69,7 @@ public class FlatTextPaneUI
super.installDefaults(); super.installDefaults();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
// use component font and foreground for HTML text // use component font and foreground for HTML text
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES ); oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
@@ -95,4 +101,17 @@ public class FlatTextPaneUI
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) ); size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
return size; return size;
} }
@Override
protected void paintBackground( Graphics g ) {
JTextComponent c = getComponent();
// for compatibility with IntelliJ themes
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
FlatUIUtils.paintParentBackground( g, c );
return;
}
super.paintBackground( g );
}
} }

View File

@@ -163,6 +163,16 @@ public class FlatUIUtils
} }
} }
/**
* Gets the background color of the first opaque parent.
*/
public static Color getParentBackground( JComponent c ) {
Container parent = findOpaqueParent( c );
return (parent != null)
? parent.getBackground()
: UIManager.getColor( "Panel.background" ); // fallback, probably never used
}
/** /**
* Find the first parent that is opaque. * Find the first parent that is opaque.
*/ */