support defining "defaultFont" in FlatLaf properties files (issue #384)

This commit is contained in:
Karl Tauber
2021-10-12 11:13:40 +02:00
parent ac46632e73
commit 51a90d32f8
2 changed files with 81 additions and 48 deletions

View File

@@ -44,6 +44,7 @@ import java.util.ResourceBundle;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.IntUnaryOperator;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
@@ -429,6 +430,10 @@ public abstract class FlatLaf
else else
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), addons, getAdditionalDefaults(), isDark(), defaults ); UIDefaultsLoader.loadDefaultsFromProperties( getClass(), addons, getAdditionalDefaults(), isDark(), defaults );
// setup default font after loading defaults from properties
// to allow defining "defaultFont" in properties
initDefaultFont( defaults );
// use Aqua MenuBarUI if Mac screen menubar is enabled // use Aqua MenuBarUI if Mac screen menubar is enabled
if( SystemInfo.isMacOS && Boolean.getBoolean( "apple.laf.useScreenMenuBar" ) ) { if( SystemInfo.isMacOS && Boolean.getBoolean( "apple.laf.useScreenMenuBar" ) ) {
defaults.put( "MenuBarUI", "com.apple.laf.AquaMenuBarUI" ); defaults.put( "MenuBarUI", "com.apple.laf.AquaMenuBarUI" );
@@ -519,8 +524,22 @@ public abstract class FlatLaf
} }
private void initFonts( UIDefaults defaults ) { private void initFonts( UIDefaults defaults ) {
// use active value for all fonts to allow changing fonts in all components with:
// UIManager.put( "defaultFont", myFont );
// (this is similar as in Nimbus L&F)
Object activeFont = new ActiveFont( null, -1, 0, 0, 0, 0 );
// override fonts
for( Object key : defaults.keySet() ) {
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
defaults.put( key, activeFont );
}
}
private void initDefaultFont( UIDefaults defaults ) {
FontUIResource uiFont = null; FontUIResource uiFont = null;
// determine UI font based on operating system
if( SystemInfo.isWindows ) { if( SystemInfo.isWindows ) {
Font winFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty( "win.messagebox.font" ); Font winFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty( "win.messagebox.font" );
if( winFont != null ) { if( winFont != null ) {
@@ -563,20 +582,21 @@ public abstract class FlatLaf
if( uiFont == null ) if( uiFont == null )
uiFont = createCompositeFont( Font.SANS_SERIF, Font.PLAIN, 12 ); uiFont = createCompositeFont( Font.SANS_SERIF, Font.PLAIN, 12 );
// get/remove "defaultFont" from defaults if set in properties files
// (use remove() to avoid that ActiveFont.createValue() gets invoked)
Object defaultFont = defaults.remove( "defaultFont" );
// use font from OS as base font and derive the UI font from it
if( defaultFont instanceof ActiveFont ) {
Font baseFont = uiFont;
uiFont = ((ActiveFont)defaultFont).derive( baseFont, fontSize -> {
return Math.round( fontSize * UIScale.computeFontScaleFactor( baseFont ) );
} );
};
// increase font size if system property "flatlaf.uiScale" is set // increase font size if system property "flatlaf.uiScale" is set
uiFont = UIScale.applyCustomScaleFactor( uiFont ); uiFont = UIScale.applyCustomScaleFactor( uiFont );
// use active value for all fonts to allow changing fonts in all components
// (similar as in Nimbus L&F) with:
// UIManager.put( "defaultFont", myFont );
Object activeFont = new ActiveFont( null, -1, 0, 0, 0, 0 );
// override fonts
for( Object key : defaults.keySet() ) {
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
defaults.put( key, activeFont );
}
// set default font // set default font
defaults.put( "defaultFont", uiFont ); defaults.put( "defaultFont", uiFont );
} }
@@ -1170,7 +1190,7 @@ public abstract class FlatLaf
private final float scaleSize; private final float scaleSize;
// cache (scaled/derived) font // cache (scaled/derived) font
private Font font; private FontUIResource font;
private Font lastDefaultFont; private Font lastDefaultFont;
/** /**
@@ -1204,17 +1224,13 @@ public abstract class FlatLaf
if( lastDefaultFont != defaultFont ) { if( lastDefaultFont != defaultFont ) {
lastDefaultFont = defaultFont; lastDefaultFont = defaultFont;
font = derive( defaultFont ); font = derive( defaultFont, fontSize -> UIScale.scale( fontSize ) );
// make sure that font is a UIResource for LaF switching
if( !(font instanceof UIResource) )
font = new FontUIResource( font );
} }
return font; return font;
} }
private Font derive( Font baseFont ) { FontUIResource derive( Font baseFont, IntUnaryOperator scale ) {
int baseStyle = baseFont.getStyle(); int baseStyle = baseFont.getStyle();
int baseSize = baseFont.getSize(); int baseSize = baseFont.getSize();
@@ -1227,9 +1243,9 @@ public abstract class FlatLaf
// new size // new size
int newSize = (absoluteSize > 0) int newSize = (absoluteSize > 0)
? UIScale.scale( absoluteSize ) ? scale.applyAsInt( absoluteSize )
: (relativeSize != 0) : (relativeSize != 0)
? (baseSize + UIScale.scale( relativeSize )) ? (baseSize + scale.applyAsInt( relativeSize ))
: (scaleSize > 0) : (scaleSize > 0)
? Math.round( baseSize * scaleSize ) ? Math.round( baseSize * scaleSize )
: baseSize; : baseSize;
@@ -1241,15 +1257,22 @@ public abstract class FlatLaf
for( String family : families ) { for( String family : families ) {
Font font = createCompositeFont( family, newStyle, newSize ); Font font = createCompositeFont( family, newStyle, newSize );
if( !isFallbackFont( font ) || family.equalsIgnoreCase( Font.DIALOG ) ) if( !isFallbackFont( font ) || family.equalsIgnoreCase( Font.DIALOG ) )
return font; return toUIResource( font );
} }
} }
// derive font // derive font
if( newStyle != baseStyle || newSize != baseSize ) if( newStyle != baseStyle || newSize != baseSize )
return baseFont.deriveFont( newStyle, newSize ); return toUIResource( baseFont.deriveFont( newStyle, newSize ) );
else else
return baseFont; return toUIResource( baseFont );
}
private FontUIResource toUIResource( Font font ) {
// make sure that font is a UIResource for LaF switching
return (font instanceof FontUIResource)
? (FontUIResource) font
: new FontUIResource( font );
} }
private boolean isFallbackFont( Font font ) { private boolean isFallbackFont( Font font ) {

View File

@@ -192,7 +192,15 @@ public class UIScale
if( font == null ) if( font == null )
font = UIManager.getFont( "Label.font" ); font = UIManager.getFont( "Label.font" );
float newScaleFactor; setUserScaleFactor( computeFontScaleFactor( font ), true );
}
/**
* For internal use only.
*
* @since 2
*/
public static float computeFontScaleFactor( Font font ) {
if( SystemInfo.isWindows ) { if( SystemInfo.isWindows ) {
// Special handling for Windows to be compatible with OS scaling, // Special handling for Windows to be compatible with OS scaling,
// which distinguish between "screen scaling" and "text scaling". // which distinguish between "screen scaling" and "text scaling".
@@ -204,33 +212,35 @@ public class UIScale
// - Settings > Display > Scale and layout // - Settings > Display > Scale and layout
// - Settings > Ease of Access > Display > Make text bigger (100% - 225%) // - Settings > Ease of Access > Display > Make text bigger (100% - 225%)
if( font instanceof UIResource ) { if( font instanceof UIResource ) {
if( isSystemScalingEnabled() ) { Font uiFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty( "win.messagebox.font" );
// Do not apply own scaling if the JRE scales using Windows screen scale factor. if( uiFont == null || uiFont.getSize() == font.getSize() ) {
// If user increases font size in Windows 10 settings, desktop property if( isSystemScalingEnabled() ) {
// "win.messagebox.font" is changed and FlatLaf uses the larger font. // Do not apply own scaling if the JRE scales using Windows screen scale factor.
newScaleFactor = 1; // If user increases font size in Windows 10 settings, desktop property
} else { // "win.messagebox.font" is changed and FlatLaf uses the larger font.
// If the JRE does not scale (Java 8), the size of the UI font return 1;
// (usually from desktop property "win.messagebox.font") } else {
// combines the Windows screen and text scale factors. // If the JRE does not scale (Java 8), the size of the UI font
// But the font in desktop property "win.defaultGUI.font" is only // (usually from desktop property "win.messagebox.font")
// scaled with the Windows screen scale factor. So use it to compute // combines the Windows screen and text scale factors.
// our scale factor that is equal to Windows screen scale factor. // But the font in desktop property "win.defaultGUI.font" is only
Font winFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty( "win.defaultGUI.font" ); // scaled with the Windows screen scale factor. So use it to compute
newScaleFactor = computeScaleFactor( (winFont != null) ? winFont : font ); // our scale factor that is equal to Windows screen scale factor.
Font winFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty( "win.defaultGUI.font" );
return computeScaleFactor( (winFont != null) ? winFont : font );
}
} }
} else {
// If font was explicitly set from outside (is not a UIResource)
// use it to compute scale factor. This allows applications to
// use custom fonts (e.g. that the user can change in UI) and
// get scaling if a larger font size is used.
// E.g. FlatLaf Demo supports increasing font size in "Font" menu and UI scales.
newScaleFactor = computeScaleFactor( font );
} }
} else
newScaleFactor = computeScaleFactor( font );
setUserScaleFactor( newScaleFactor, true ); // If font was explicitly set from outside (is not a UIResource),
// or was set in FlatLaf properties files (is a UIResource),
// use it to compute scale factor. This allows applications to
// use custom fonts (e.g. that the user can change in UI) and
// get scaling if a larger font size is used.
// E.g. FlatLaf Demo supports increasing font size in "Font" menu and UI scales.
}
return computeScaleFactor( font );
} }
private static float computeScaleFactor( Font font ) { private static float computeScaleFactor( Font font ) {