mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-10 22:17:13 -06:00
more fixes for AWT components on macOS (issue #583)
- use light theme for AWT components if dark FlatLaf theme is active (AWT is always light) - made AWT peer background compatible with Aqua Laf
This commit is contained in:
@@ -181,7 +181,7 @@ public class FlatButtonUI
|
||||
private AtomicBoolean borderShared;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return FlatUIUtils.canUseSharedUI( c )
|
||||
return FlatUIUtils.canUseSharedUI( c ) && !FlatUIUtils.needsLightAWTPeer( c )
|
||||
? FlatUIUtils.createSharedUI( FlatButtonUI.class, () -> new FlatButtonUI( true ) )
|
||||
: new FlatButtonUI( false );
|
||||
}
|
||||
@@ -193,6 +193,13 @@ public class FlatButtonUI
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||
else
|
||||
installUIImpl( c );
|
||||
}
|
||||
|
||||
private void installUIImpl( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
installStyle( (AbstractButton) c );
|
||||
|
||||
@@ -43,7 +43,7 @@ public class FlatCheckBoxUI
|
||||
extends FlatRadioButtonUI
|
||||
{
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return FlatUIUtils.canUseSharedUI( c )
|
||||
return FlatUIUtils.canUseSharedUI( c ) && !FlatUIUtils.needsLightAWTPeer( c )
|
||||
? FlatUIUtils.createSharedUI( FlatCheckBoxUI.class, () -> new FlatCheckBoxUI( true ) )
|
||||
: new FlatCheckBoxUI( false );
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ public class FlatComboBoxUI
|
||||
@Styleable protected String arrowType;
|
||||
protected boolean isIntelliJTheme;
|
||||
|
||||
private Color background;
|
||||
@Styleable protected Color editableBackground;
|
||||
@Styleable protected Color focusedBackground;
|
||||
@Styleable protected Color disabledBackground;
|
||||
@@ -165,6 +166,13 @@ public class FlatComboBoxUI
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||
else
|
||||
installUIImpl( c );
|
||||
}
|
||||
|
||||
private void installUIImpl( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
installStyle();
|
||||
@@ -227,6 +235,7 @@ public class FlatComboBoxUI
|
||||
arrowType = UIManager.getString( "Component.arrowType" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
|
||||
background = UIManager.getColor( "ComboBox.background" );
|
||||
editableBackground = UIManager.getColor( "ComboBox.editableBackground" );
|
||||
focusedBackground = UIManager.getColor( "ComboBox.focusedBackground" );
|
||||
disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" );
|
||||
@@ -259,6 +268,7 @@ public class FlatComboBoxUI
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
background = null;
|
||||
editableBackground = null;
|
||||
focusedBackground = null;
|
||||
disabledBackground = null;
|
||||
@@ -632,7 +642,7 @@ public class FlatComboBoxUI
|
||||
protected Color getBackground( boolean enabled ) {
|
||||
if( enabled ) {
|
||||
if( FlatUIUtils.isAWTPeer( comboBox ) )
|
||||
return UIManager.getColor( "ComboBox.background" );
|
||||
return background;
|
||||
|
||||
Color background = comboBox.getBackground();
|
||||
|
||||
|
||||
@@ -90,6 +90,13 @@ public class FlatListUI
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||
else
|
||||
installUIImpl( c );
|
||||
}
|
||||
|
||||
private void installUIImpl( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
installStyle();
|
||||
|
||||
@@ -83,7 +83,7 @@ public class FlatRadioButtonUI
|
||||
private Map<String, Object> oldStyleValues;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return FlatUIUtils.canUseSharedUI( c )
|
||||
return FlatUIUtils.canUseSharedUI( c ) && !FlatUIUtils.needsLightAWTPeer( c )
|
||||
? FlatUIUtils.createSharedUI( FlatRadioButtonUI.class, () -> new FlatRadioButtonUI( true ) )
|
||||
: new FlatRadioButtonUI( false );
|
||||
}
|
||||
@@ -95,6 +95,13 @@ public class FlatRadioButtonUI
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||
else
|
||||
installUIImpl( c );
|
||||
}
|
||||
|
||||
private void installUIImpl( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
if( FlatUIUtils.isAWTPeer( c ) )
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
@@ -37,11 +38,13 @@ import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
@@ -230,6 +233,24 @@ public class FlatScrollBarUI
|
||||
}
|
||||
SwingUtilities.replaceUIInputMap( scrollbar, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap );
|
||||
break;
|
||||
|
||||
case "ancestor":
|
||||
// check whether scroll bar is used as AWT peer on macOS and
|
||||
// dark theme is active --> reinstall using light theme
|
||||
if( SystemInfo.isMacOS && FlatLaf.isLafDark() ) {
|
||||
Container p = scrollbar.getParent();
|
||||
for( int i = 0; i < 2 && p != null; i++, p = p.getParent() ) {
|
||||
if( FlatUIUtils.isAWTPeer( p ) ) {
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> {
|
||||
JScrollBar scrollbar = this.scrollbar;
|
||||
uninstallUI( scrollbar );
|
||||
installUI( scrollbar );
|
||||
} );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,6 +87,13 @@ public class FlatScrollPaneUI
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||
else
|
||||
installUIImpl( c );
|
||||
}
|
||||
|
||||
private void installUIImpl( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
|
||||
@@ -86,6 +86,13 @@ public class FlatTextAreaUI
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||
else
|
||||
installUIImpl( c );
|
||||
}
|
||||
|
||||
private void installUIImpl( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
installStyle();
|
||||
|
||||
@@ -128,6 +128,13 @@ public class FlatTextFieldUI
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||
else
|
||||
installUIImpl( c );
|
||||
}
|
||||
|
||||
private void installUIImpl( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class );
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.SystemColor;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
@@ -45,16 +46,22 @@ import java.util.WeakHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.util.DerivedColor;
|
||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||
@@ -257,13 +264,38 @@ public class FlatUIUtils
|
||||
(window != null && window.getType() == Window.Type.POPUP && window.getOwner() == activeWindow);
|
||||
}
|
||||
|
||||
static boolean isAWTPeer( JComponent c ) {
|
||||
static boolean isAWTPeer( Component c ) {
|
||||
// on macOS, Swing components are used for AWT components
|
||||
if( SystemInfo.isMacOS )
|
||||
return c.getClass().getName().startsWith( "sun.lwawt.LW" );
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether component is used as peer for AWT (on macOS) and
|
||||
* whether a dark FlatLaf theme is active, which requires special handling
|
||||
* because AWT always uses light colors.
|
||||
*/
|
||||
static boolean needsLightAWTPeer( JComponent c ) {
|
||||
return FlatUIUtils.isAWTPeer( c ) && FlatLaf.isLafDark();
|
||||
}
|
||||
|
||||
private static UIDefaults lightAWTPeerDefaults;
|
||||
|
||||
static void runWithLightAWTPeerUIDefaults( Runnable runnable ) {
|
||||
if( lightAWTPeerDefaults == null ) {
|
||||
FlatLaf lightLaf = UIManager.getInt( "Component.focusWidth" ) >= 2
|
||||
? new FlatIntelliJLaf()
|
||||
: new FlatLightLaf();
|
||||
lightAWTPeerDefaults = lightLaf.getDefaults();
|
||||
}
|
||||
|
||||
FlatLaf.runWithUIDefaultsGetter( key -> {
|
||||
Object value = lightAWTPeerDefaults.get( key );
|
||||
return (value != null) ? value : FlatLaf.NULL_VALUE;
|
||||
}, runnable );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given component is in a window that is in full-screen mode.
|
||||
*/
|
||||
@@ -694,7 +726,17 @@ public class FlatUIUtils
|
||||
// parent.getBackground() may return null
|
||||
// (e.g. for Swing delegate components used for AWT components on macOS)
|
||||
Color background = (parent != null) ? parent.getBackground() : null;
|
||||
return (background != null) ? background : UIManager.getColor( "Panel.background" );
|
||||
if( background != null )
|
||||
return background;
|
||||
|
||||
if( isAWTPeer( c ) ) {
|
||||
// AWT peers usually use component background, except for TextField and ScrollPane
|
||||
return c instanceof JTextField || c instanceof JScrollPane || c.getBackground() == null
|
||||
? SystemColor.window
|
||||
: c.getBackground();
|
||||
}
|
||||
|
||||
return UIManager.getColor( "Panel.background" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user