mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 15:07:11 -06:00
Merge branch 'master' into disabledIcon
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.io.InputStream;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
/**
|
||||
* Addon for FlatLaf UI defaults.
|
||||
@@ -50,6 +52,13 @@ public abstract class FlatDefaultsAddon
|
||||
return addonClass.getResourceAsStream( propertiesName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows modifying UI defaults after loading UI defaults.
|
||||
* The default implementation does nothing.
|
||||
*/
|
||||
public void afterDefaultsLoading( LookAndFeel laf, UIDefaults defaults ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the priority used to sort addon loading.
|
||||
* The order is only important if you want overwrite UI defaults of other addons.
|
||||
|
||||
@@ -48,10 +48,10 @@ class FlatInputMaps
|
||||
modifyInputMap( defaults, "ComboBox.ancestorInputMap",
|
||||
"SPACE", "spacePopup",
|
||||
|
||||
"UP", "selectPrevious2",
|
||||
"DOWN", "selectNext2",
|
||||
"KP_UP", "selectPrevious2",
|
||||
"KP_DOWN", "selectNext2",
|
||||
"UP", mac( "selectPrevious2", "selectPrevious" ),
|
||||
"DOWN", mac( "selectNext2", "selectNext" ),
|
||||
"KP_UP", mac( "selectPrevious2", "selectPrevious" ),
|
||||
"KP_DOWN", mac( "selectNext2", "selectNext" ),
|
||||
|
||||
mac( "alt UP", null ), "togglePopup",
|
||||
mac( "alt DOWN", null ), "togglePopup",
|
||||
@@ -182,7 +182,7 @@ class FlatInputMaps
|
||||
"ctrl A", beginLineAction,
|
||||
"ctrl E", endLineAction,
|
||||
|
||||
// move caret to document begin/end (without selecting text)
|
||||
// move caret to document begin/end and select text
|
||||
"shift meta UP", selectionBeginAction,
|
||||
"shift meta DOWN", selectionEndAction,
|
||||
"shift meta KP_UP", selectionBeginAction,
|
||||
@@ -198,16 +198,6 @@ class FlatInputMaps
|
||||
"shift KP_UP", selectionBeginLineAction,
|
||||
"shift KP_DOWN", selectionEndLineAction,
|
||||
|
||||
// move caret one page (without selecting text)
|
||||
"PAGE_UP", pageUpAction,
|
||||
"PAGE_DOWN", pageDownAction,
|
||||
|
||||
// move caret one page and select text
|
||||
"shift PAGE_UP", "selection-page-up", // DefaultEditorKit.selectionPageUpAction
|
||||
"shift PAGE_DOWN", "selection-page-down", // DefaultEditorKit.selectionPageDownAction
|
||||
"shift meta PAGE_UP", "selection-page-left", // DefaultEditorKit.selectionPageLeftAction
|
||||
"shift meta PAGE_DOWN", "selection-page-right", // DefaultEditorKit.selectionPageRightAction
|
||||
|
||||
// delete previous/next word
|
||||
"ctrl W", deletePrevWordAction,
|
||||
"ctrl D", deleteNextCharAction,
|
||||
@@ -350,6 +340,12 @@ class FlatInputMaps
|
||||
"meta V", "paste",
|
||||
"meta X", "cut",
|
||||
|
||||
// let parent scroll pane do the macOS typical scrolling without changing selection
|
||||
"HOME", null,
|
||||
"END", null,
|
||||
"PAGE_UP", null,
|
||||
"PAGE_DOWN", null,
|
||||
|
||||
"ctrl A", null,
|
||||
"ctrl BACK_SLASH", null,
|
||||
"ctrl C", null,
|
||||
@@ -370,8 +366,6 @@ class FlatInputMaps
|
||||
"ctrl UP", null,
|
||||
"ctrl V", null,
|
||||
"ctrl X", null,
|
||||
"PAGE_DOWN", null,
|
||||
"PAGE_UP", null,
|
||||
"SPACE", null,
|
||||
"shift ctrl DOWN", null,
|
||||
"shift ctrl END", null,
|
||||
@@ -390,10 +384,16 @@ class FlatInputMaps
|
||||
"shift INSERT", null,
|
||||
"shift SPACE", null
|
||||
);
|
||||
|
||||
// scrollbar
|
||||
copyInputMap( defaults, "ScrollBar.ancestorInputMap", "ScrollBar.focusInputMap" );
|
||||
copyInputMap( defaults, "ScrollBar.ancestorInputMap.RightToLeft", "ScrollBar.focusInputMap.RightToLeft" );
|
||||
modifyInputMap( defaults, "List.focusInputMap.RightToLeft",
|
||||
"ctrl KP_LEFT", null,
|
||||
"ctrl KP_RIGHT", null,
|
||||
"ctrl LEFT", null,
|
||||
"ctrl RIGHT", null,
|
||||
"shift ctrl KP_LEFT", null,
|
||||
"shift ctrl KP_RIGHT", null,
|
||||
"shift ctrl LEFT", null,
|
||||
"shift ctrl RIGHT", null
|
||||
);
|
||||
|
||||
// scrollpane
|
||||
modifyInputMap( defaults, "ScrollPane.ancestorInputMap",
|
||||
@@ -410,6 +410,16 @@ class FlatInputMaps
|
||||
"ctrl PAGE_UP", null
|
||||
);
|
||||
|
||||
// tabbedpane
|
||||
modifyInputMap( defaults, "TabbedPane.ancestorInputMap",
|
||||
"ctrl UP", null,
|
||||
"ctrl KP_UP", null
|
||||
);
|
||||
modifyInputMap( defaults, "TabbedPane.focusInputMap",
|
||||
"ctrl DOWN", null,
|
||||
"ctrl KP_DOWN", null
|
||||
);
|
||||
|
||||
// table
|
||||
modifyInputMap( defaults, "Table.ancestorInputMap",
|
||||
"alt TAB", "focusHeader",
|
||||
@@ -419,6 +429,12 @@ class FlatInputMaps
|
||||
"meta V", "paste",
|
||||
"meta X", "cut",
|
||||
|
||||
// let parent scroll pane do the macOS typical scrolling without changing selection
|
||||
"HOME", null,
|
||||
"END", null,
|
||||
"PAGE_UP", null,
|
||||
"PAGE_DOWN", null,
|
||||
|
||||
"ctrl A", null,
|
||||
"ctrl BACK_SLASH", null,
|
||||
"ctrl C", null,
|
||||
@@ -476,27 +492,31 @@ class FlatInputMaps
|
||||
"RIGHT", "selectChild",
|
||||
"KP_LEFT", "selectParent",
|
||||
"KP_RIGHT", "selectChild",
|
||||
"shift LEFT", "selectParent",
|
||||
"shift RIGHT", "selectChild",
|
||||
"shift KP_LEFT", "selectParent",
|
||||
"shift KP_RIGHT", "selectChild",
|
||||
"alt LEFT", "selectParent",
|
||||
"alt RIGHT", "selectChild",
|
||||
"alt KP_LEFT", "selectParent",
|
||||
"alt KP_RIGHT", "selectChild",
|
||||
|
||||
"meta A", "selectAll",
|
||||
"meta C", "copy",
|
||||
"meta V", "paste",
|
||||
"meta X", "cut",
|
||||
|
||||
// let parent scroll pane do the macOS typical scrolling without changing selection
|
||||
"HOME", null,
|
||||
"END", null,
|
||||
"PAGE_UP", null,
|
||||
"PAGE_DOWN", null,
|
||||
|
||||
"ctrl LEFT", null,
|
||||
"ctrl RIGHT", null,
|
||||
"ctrl KP_LEFT", null,
|
||||
"ctrl KP_RIGHT", null,
|
||||
|
||||
"shift LEFT", null,
|
||||
"shift RIGHT", null,
|
||||
"shift KP_LEFT", null,
|
||||
"shift KP_RIGHT", null,
|
||||
|
||||
"alt LEFT", null,
|
||||
"alt RIGHT", null,
|
||||
"alt KP_LEFT", null,
|
||||
"alt KP_RIGHT", null,
|
||||
|
||||
"ctrl A", null,
|
||||
"ctrl BACK_SLASH", null,
|
||||
"ctrl C", null,
|
||||
@@ -513,11 +533,7 @@ class FlatInputMaps
|
||||
"ctrl UP", null,
|
||||
"ctrl V", null,
|
||||
"ctrl X", null,
|
||||
"END", null,
|
||||
"F2", null,
|
||||
"HOME", null,
|
||||
"PAGE_DOWN", null,
|
||||
"PAGE_UP", null,
|
||||
"SPACE", null,
|
||||
"shift ctrl DOWN", null,
|
||||
"shift ctrl END", null,
|
||||
@@ -540,17 +556,18 @@ class FlatInputMaps
|
||||
"LEFT", "selectChild",
|
||||
"RIGHT", "selectParent",
|
||||
"KP_LEFT", "selectChild",
|
||||
"KP_RIGHT", "selectParent"
|
||||
"KP_RIGHT", "selectParent",
|
||||
"shift LEFT", "selectChild",
|
||||
"shift RIGHT", "selectParent",
|
||||
"shift KP_LEFT", "selectChild",
|
||||
"shift KP_RIGHT", "selectParent",
|
||||
"alt LEFT", "selectChild",
|
||||
"alt RIGHT", "selectParent",
|
||||
"alt KP_LEFT", "selectChild",
|
||||
"alt KP_RIGHT", "selectParent"
|
||||
} ) );
|
||||
}
|
||||
|
||||
private static void copyInputMap( UIDefaults defaults, String srcKey, String destKey ) {
|
||||
// Note: not using `defaults.get(key)` here because this would resolve the lazy value
|
||||
Object inputMap = defaults.remove( srcKey );
|
||||
defaults.put( srcKey, inputMap );
|
||||
defaults.put( destKey, inputMap );
|
||||
}
|
||||
|
||||
private static void modifyInputMap( UIDefaults defaults, String key, Object... bindings ) {
|
||||
// Note: not using `defaults.get(key)` here because this would resolve the lazy value
|
||||
defaults.put( key, new LazyModifyInputMap( defaults.remove( key ), bindings ) );
|
||||
|
||||
@@ -31,8 +31,11 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -48,6 +51,7 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.UIDefaults.ActiveValue;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.IconUIResource;
|
||||
@@ -275,12 +279,19 @@ public abstract class FlatLaf
|
||||
initIconColors( defaults, isDark() );
|
||||
FlatInputMaps.initInputMaps( defaults );
|
||||
|
||||
// get addons and sort them by priority
|
||||
ServiceLoader<FlatDefaultsAddon> addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
|
||||
List<FlatDefaultsAddon> addons = new ArrayList<>();
|
||||
for( FlatDefaultsAddon addon : addonLoader )
|
||||
addons.add( addon );
|
||||
addons.sort( (addon1, addon2) -> addon1.getPriority() - addon2.getPriority() );
|
||||
|
||||
// load defaults from properties
|
||||
List<Class<?>> lafClassesForDefaultsLoading = getLafClassesForDefaultsLoading();
|
||||
if( lafClassesForDefaultsLoading != null )
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, defaults );
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, addons, getAdditionalDefaults(), defaults );
|
||||
else
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), defaults );
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), addons, getAdditionalDefaults(), defaults );
|
||||
|
||||
// use Aqua MenuBarUI if Mac screen menubar is enabled
|
||||
if( SystemInfo.IS_MAC && Boolean.getBoolean( "apple.laf.useScreenMenuBar" ) )
|
||||
@@ -289,19 +300,29 @@ public abstract class FlatLaf
|
||||
// initialize text antialiasing
|
||||
putAATextInfo( defaults );
|
||||
|
||||
invokePostInitialization( defaults );
|
||||
// apply additional defaults (e.g. from IntelliJ themes)
|
||||
applyAdditionalDefaults( defaults );
|
||||
|
||||
return defaults;
|
||||
}
|
||||
// allow addons modifying UI defaults
|
||||
for( FlatDefaultsAddon addon : addons )
|
||||
addon.afterDefaultsLoading( this, defaults );
|
||||
|
||||
void invokePostInitialization( UIDefaults defaults ) {
|
||||
if( postInitialization != null ) {
|
||||
postInitialization.accept( defaults );
|
||||
postInitialization = null;
|
||||
}
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
List<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
void applyAdditionalDefaults( UIDefaults defaults ) {
|
||||
}
|
||||
|
||||
protected List<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Properties getAdditionalDefaults() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -334,14 +355,22 @@ public abstract class FlatLaf
|
||||
|
||||
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( 1 );
|
||||
|
||||
// override fonts
|
||||
for( Object key : defaults.keySet() ) {
|
||||
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
|
||||
defaults.put( key, uiFont );
|
||||
defaults.put( key, activeFont );
|
||||
}
|
||||
|
||||
// use smaller font for progress bar
|
||||
defaults.put( "ProgressBar.font", UIScale.scaleFont( uiFont, 0.85f ) );
|
||||
defaults.put( "ProgressBar.font", new ActiveFont( 0.85f ) );
|
||||
|
||||
// set default font
|
||||
defaults.put( "defaultFont", uiFont );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -551,4 +580,42 @@ public abstract class FlatLaf
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//---- class ActiveFont ---------------------------------------------------
|
||||
|
||||
private static class ActiveFont
|
||||
implements ActiveValue
|
||||
{
|
||||
private final float scaleFactor;
|
||||
|
||||
// cache (scaled) font
|
||||
private Font font;
|
||||
private Font lastDefaultFont;
|
||||
|
||||
ActiveFont( float scaleFactor ) {
|
||||
this.scaleFactor = scaleFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createValue( UIDefaults table ) {
|
||||
Font defaultFont = UIManager.getFont( "defaultFont" );
|
||||
|
||||
if( lastDefaultFont != defaultFont ) {
|
||||
lastDefaultFont = defaultFont;
|
||||
|
||||
if( scaleFactor != 1 ) {
|
||||
// scale font
|
||||
int newFontSize = Math.round( defaultFont.getSize() * scaleFactor );
|
||||
font = new FontUIResource( defaultFont.deriveFont( (float) newFontSize ) );
|
||||
} else {
|
||||
// make sure that font is a UIResource for LaF switching
|
||||
font = (defaultFont instanceof UIResource)
|
||||
? defaultFont
|
||||
: new FontUIResource( defaultFont );
|
||||
}
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,19 +513,12 @@ public class IntelliJTheme
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIDefaults getDefaults() {
|
||||
UIDefaults defaults = super.getDefaults();
|
||||
void applyAdditionalDefaults( UIDefaults defaults ) {
|
||||
theme.applyProperties( defaults );
|
||||
super.invokePostInitialization( defaults );
|
||||
return defaults;
|
||||
}
|
||||
|
||||
@Override
|
||||
void invokePostInitialization( UIDefaults defaults ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||
lafClasses.add( FlatLaf.class );
|
||||
lafClasses.add( theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.BufferedReader;
|
||||
@@ -31,6 +32,7 @@ import java.util.logging.Level;
|
||||
import javax.swing.text.StyleContext;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -99,6 +101,10 @@ class LinuxFontPolicy
|
||||
}
|
||||
|
||||
private static double getGnomeFontScale() {
|
||||
// do not scale font here if JRE scales
|
||||
if( isSystemScaling() )
|
||||
return 96. / 72.;
|
||||
|
||||
// see class com.sun.java.swing.plaf.gtk.PangoFonts background information
|
||||
|
||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "gnome.Xft/DPI" );
|
||||
@@ -168,7 +174,7 @@ class LinuxFontPolicy
|
||||
|
||||
// font dpi
|
||||
int dpi = 96;
|
||||
if( forceFontDPI != null ) {
|
||||
if( forceFontDPI != null && !isSystemScaling() ) {
|
||||
try {
|
||||
dpi = Integer.parseInt( forceFontDPI );
|
||||
if( dpi <= 0 )
|
||||
@@ -247,4 +253,15 @@ class LinuxFontPolicy
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the JRE scales, which is the case if:
|
||||
* - environment variable GDK_SCALE is set and running on Java 9 or later
|
||||
* - running on JetBrains Runtime 11 or later and scaling is enabled in system Settings
|
||||
*/
|
||||
private static boolean isSystemScaling() {
|
||||
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
return UIScale.getSystemScaleFactor( gc ) > 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.UIDefaults;
|
||||
@@ -69,7 +68,9 @@ class UIDefaultsLoader
|
||||
private static final String OPTIONAL_PREFIX = "?";
|
||||
private static final String GLOBAL_PREFIX = "*.";
|
||||
|
||||
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, UIDefaults defaults ) {
|
||||
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
|
||||
Properties additionalDefaults, UIDefaults defaults )
|
||||
{
|
||||
// determine classes in class hierarchy in reverse order
|
||||
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||
for( Class<?> lafClass = lookAndFeelClass;
|
||||
@@ -79,10 +80,12 @@ class UIDefaultsLoader
|
||||
lafClasses.add( 0, lafClass );
|
||||
}
|
||||
|
||||
loadDefaultsFromProperties( lafClasses, defaults );
|
||||
loadDefaultsFromProperties( lafClasses, addons, additionalDefaults, defaults );
|
||||
}
|
||||
|
||||
static void loadDefaultsFromProperties( List<Class<?>> lafClasses, UIDefaults defaults ) {
|
||||
static void loadDefaultsFromProperties( List<Class<?>> lafClasses, List<FlatDefaultsAddon> addons,
|
||||
Properties additionalDefaults, UIDefaults defaults )
|
||||
{
|
||||
try {
|
||||
// load core properties files
|
||||
Properties properties = new Properties();
|
||||
@@ -94,15 +97,8 @@ class UIDefaultsLoader
|
||||
}
|
||||
}
|
||||
|
||||
// get addons and sort them by priority
|
||||
ServiceLoader<FlatDefaultsAddon> addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
|
||||
List<FlatDefaultsAddon> addonList = new ArrayList<>();
|
||||
for( FlatDefaultsAddon addon : addonLoader )
|
||||
addonList.add( addon );
|
||||
addonList.sort( (addon1, addon2) -> addon1.getPriority() - addon2.getPriority() );
|
||||
|
||||
// load properties from addons
|
||||
for( FlatDefaultsAddon addon : addonList ) {
|
||||
for( FlatDefaultsAddon addon : addons ) {
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
try( InputStream in = addon.getDefaults( lafClass ) ) {
|
||||
if( in != null )
|
||||
@@ -113,12 +109,16 @@ class UIDefaultsLoader
|
||||
|
||||
// collect addon class loaders
|
||||
List<ClassLoader> addonClassLoaders = new ArrayList<>();
|
||||
for( FlatDefaultsAddon addon : addonList ) {
|
||||
for( FlatDefaultsAddon addon : addons ) {
|
||||
ClassLoader addonClassLoader = addon.getClass().getClassLoader();
|
||||
if( !addonClassLoaders.contains( addonClassLoader ) )
|
||||
addonClassLoaders.add( addonClassLoader );
|
||||
}
|
||||
|
||||
// add additional defaults
|
||||
if( additionalDefaults != null )
|
||||
properties.putAll( additionalDefaults );
|
||||
|
||||
// collect all platform specific keys (but do not modify properties)
|
||||
ArrayList<String> platformSpecificKeys = new ArrayList<>();
|
||||
for( Object key : properties.keySet() ) {
|
||||
@@ -332,16 +332,17 @@ class UIDefaultsLoader
|
||||
|
||||
private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||
if( value.indexOf( ',' ) >= 0 ) {
|
||||
// top,left,bottom,right[,lineColor]
|
||||
// top,left,bottom,right[,lineColor[,lineThickness]]
|
||||
List<String> parts = split( value, ',' );
|
||||
Insets insets = parseInsets( value );
|
||||
ColorUIResource lineColor = (parts.size() == 5)
|
||||
ColorUIResource lineColor = (parts.size() >= 5)
|
||||
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true )
|
||||
: null;
|
||||
float lineThickness = (parts.size() >= 6) ? parseFloat( parts.get( 5 ), true ) : 1f;
|
||||
|
||||
return (LazyValue) t -> {
|
||||
return (lineColor != null)
|
||||
? new FlatLineBorder( insets, lineColor )
|
||||
? new FlatLineBorder( insets, lineColor, lineThickness )
|
||||
: new FlatEmptyBorder( insets );
|
||||
};
|
||||
} else
|
||||
|
||||
@@ -281,13 +281,14 @@ public class FlatComboBoxUI
|
||||
// macOS
|
||||
if( SystemInfo.IS_MAC && editor instanceof JTextComponent ) {
|
||||
// delegate actions from editor text field to combobox, which is necessary
|
||||
// because text field on macOS (based on Aqua LaF UI defaults)
|
||||
// already handle those keys
|
||||
// because text field on macOS already handle those keys
|
||||
InputMap inputMap = ((JTextComponent)editor).getInputMap();
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "UP" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_UP" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "DOWN" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_DOWN" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "HOME" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "END" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,12 +460,12 @@ public class FlatComboBoxUI
|
||||
//---- class FlatComboPopup -----------------------------------------------
|
||||
|
||||
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||
private class FlatComboPopup
|
||||
protected class FlatComboPopup
|
||||
extends BasicComboPopup
|
||||
{
|
||||
private CellPaddingBorder paddingBorder;
|
||||
|
||||
FlatComboPopup( JComboBox combo ) {
|
||||
protected FlatComboPopup( JComboBox combo ) {
|
||||
super( combo );
|
||||
|
||||
// BasicComboPopup listens to JComboBox.componentOrientation and updates
|
||||
@@ -479,13 +480,8 @@ public class FlatComboBoxUI
|
||||
|
||||
@Override
|
||||
protected Rectangle computePopupBounds( int px, int py, int pw, int ph ) {
|
||||
// get maximum display size of all items, ignoring prototype value
|
||||
Object prototype = comboBox.getPrototypeDisplayValue();
|
||||
if( prototype != null )
|
||||
comboBox.setPrototypeDisplayValue( null );
|
||||
// get maximum display size of all items
|
||||
Dimension displaySize = getDisplaySize();
|
||||
if( prototype != null )
|
||||
comboBox.setPrototypeDisplayValue( prototype );
|
||||
|
||||
// make popup wider if necessary
|
||||
if( displaySize.width > pw ) {
|
||||
|
||||
@@ -26,9 +26,9 @@ import java.awt.Insets;
|
||||
/**
|
||||
* Line border for various components.
|
||||
*
|
||||
* Paints a scaled 1px thick line around the component.
|
||||
* The line thickness is not included in the border insets.
|
||||
* The insets should be at least 1,1,1,1.
|
||||
* Paints a scaled (usually 1px thick) line around the component.
|
||||
* The line thickness is not added to the border insets.
|
||||
* The insets should be at least have line thickness (usually 1,1,1,1).
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -36,10 +36,16 @@ public class FlatLineBorder
|
||||
extends FlatEmptyBorder
|
||||
{
|
||||
private final Color lineColor;
|
||||
private final float lineThickness;
|
||||
|
||||
public FlatLineBorder( Insets insets, Color lineColor ) {
|
||||
this( insets, lineColor, 1f );
|
||||
}
|
||||
|
||||
public FlatLineBorder( Insets insets, Color lineColor, float lineThickness ) {
|
||||
super( insets );
|
||||
this.lineColor = lineColor;
|
||||
this.lineThickness = lineThickness;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +54,7 @@ public class FlatLineBorder
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
g2.setColor( lineColor );
|
||||
FlatUIUtils.paintComponentBorder( g2, x, y, width, height, 0f, scale( 1f ), 0f );
|
||||
FlatUIUtils.paintComponentBorder( g2, x, y, width, height, 0f, scale( lineThickness ), 0f );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ public class FlatUIUtils
|
||||
}
|
||||
|
||||
public static Font nonUIResource( Font font ) {
|
||||
return (font instanceof UIResource) ? new Font( font.getName(), font.getStyle(), font.getSize() ) : font;
|
||||
return (font instanceof UIResource) ? font.deriveFont( font.getStyle() ) : font;
|
||||
}
|
||||
|
||||
public static int minimumWidth( JComponent c, int minimumWidth ) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
@@ -48,12 +49,15 @@ import javax.swing.plaf.UIResource;
|
||||
*
|
||||
* 2) user scaling mode
|
||||
*
|
||||
* This mode is mainly for Java 8 compatibility, but is also used on Linux.
|
||||
* This mode is mainly for Java 8 compatibility, but is also used on Linux
|
||||
* or if the default font is changed.
|
||||
* The user scale factor is computed based on the used font.
|
||||
* The JRE does not scale anything.
|
||||
* So we have to invoke {@link #scale(float)} where necessary.
|
||||
* There is only one user scale factor for all displays.
|
||||
* The user scale factor may change if the active LaF or "Label.font" has changed.
|
||||
* The user scale factor may change if the active LaF, "defaultFont" or "Label.font" has changed.
|
||||
* If system scaling mode is available the user scale factor is usually 1,
|
||||
* but may be larger on Linux or if the default font is changed.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -61,6 +65,20 @@ public class UIScale
|
||||
{
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static PropertyChangeSupport changeSupport;
|
||||
|
||||
public static void addPropertyChangeListener( PropertyChangeListener listener ) {
|
||||
if( changeSupport == null )
|
||||
changeSupport = new PropertyChangeSupport( UIScale.class );
|
||||
changeSupport.addPropertyChangeListener( listener );
|
||||
}
|
||||
|
||||
public static void removePropertyChangeListener( PropertyChangeListener listener ) {
|
||||
if( changeSupport == null )
|
||||
return;
|
||||
changeSupport.removePropertyChangeListener( listener );
|
||||
}
|
||||
|
||||
//---- system scaling (Java 9) --------------------------------------------
|
||||
|
||||
private static Boolean jreHiDPI;
|
||||
@@ -97,7 +115,7 @@ public class UIScale
|
||||
}
|
||||
|
||||
public static double getSystemScaleFactor( GraphicsConfiguration gc ) {
|
||||
return isSystemScalingEnabled() ? gc.getDefaultTransform().getScaleX() : 1;
|
||||
return (isSystemScalingEnabled() && gc != null) ? gc.getDefaultTransform().getScaleX() : 1;
|
||||
}
|
||||
|
||||
//---- user scaling (Java 8) ----------------------------------------------
|
||||
@@ -110,27 +128,33 @@ public class UIScale
|
||||
return;
|
||||
initialized = true;
|
||||
|
||||
if( isUserScalingEnabled() ) {
|
||||
// listener to update scale factor if LaF changed or if Label.font changed
|
||||
// (e.g. option "Override default fonts" in IntelliJ IDEA)
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
String propName = e.getPropertyName();
|
||||
if( "lookAndFeel".equals( propName ) ) {
|
||||
if( !isUserScalingEnabled() )
|
||||
return;
|
||||
|
||||
// listener to update scale factor if LaF changed, "defaultFont" or "Label.font" changed
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case "lookAndFeel":
|
||||
// it is not necessary (and possible) to remove listener of old LaF defaults
|
||||
if( e.getNewValue() instanceof LookAndFeel )
|
||||
UIManager.getLookAndFeelDefaults().addPropertyChangeListener( this );
|
||||
updateScaleFactor();
|
||||
} else if( "Label.font".equals( propName ) )
|
||||
updateScaleFactor();
|
||||
}
|
||||
};
|
||||
UIManager.addPropertyChangeListener( listener );
|
||||
UIManager.getLookAndFeelDefaults().addPropertyChangeListener( listener );
|
||||
break;
|
||||
|
||||
updateScaleFactor();
|
||||
}
|
||||
case "defaultFont":
|
||||
case "Label.font":
|
||||
updateScaleFactor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
UIManager.addPropertyChangeListener( listener );
|
||||
UIManager.getDefaults().addPropertyChangeListener( listener );
|
||||
UIManager.getLookAndFeelDefaults().addPropertyChangeListener( listener );
|
||||
|
||||
updateScaleFactor();
|
||||
}
|
||||
|
||||
private static void updateScaleFactor() {
|
||||
@@ -141,7 +165,9 @@ public class UIScale
|
||||
// because even if we are on a HiDPI display it is not sure
|
||||
// that a larger font size is set by the current LaF
|
||||
// (e.g. can avoid large icons with small text)
|
||||
Font font = UIManager.getFont( "Label.font" );
|
||||
Font font = UIManager.getFont( "defaultFont" );
|
||||
if( font == null )
|
||||
font = UIManager.getFont( "Label.font" );
|
||||
|
||||
setUserScaleFactor( computeScaleFactor( font ) );
|
||||
}
|
||||
@@ -168,26 +194,17 @@ public class UIScale
|
||||
}
|
||||
|
||||
private static boolean isUserScalingEnabled() {
|
||||
if( isSystemScalingEnabled() && !SystemInfo.IS_LINUX )
|
||||
return false; // disable user scaling if JRE scales
|
||||
|
||||
// same as in IntelliJ IDEA
|
||||
String hidpi = System.getProperty( "hidpi" );
|
||||
return (hidpi != null) ? Boolean.parseBoolean( hidpi ) : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a custom scale factor given in system properties "flatlaf.uiScale"
|
||||
* or "sun.java2d.uiScale" to the given font.
|
||||
* Applies a custom scale factor given in system property "flatlaf.uiScale"
|
||||
* to the given font.
|
||||
*/
|
||||
public static FontUIResource applyCustomScaleFactor( FontUIResource font ) {
|
||||
if( UIScale.isSystemScalingEnabled() )
|
||||
return font;
|
||||
|
||||
String uiScale = System.getProperty( "flatlaf.uiScale" );
|
||||
if( uiScale == null )
|
||||
uiScale = System.getProperty( "sun.java2d.uiScale" );
|
||||
|
||||
float scaleFactor = parseScaleFactor( uiScale );
|
||||
if( scaleFactor <= 0 )
|
||||
return font;
|
||||
@@ -197,15 +214,7 @@ public class UIScale
|
||||
return font;
|
||||
|
||||
int newFontSize = Math.round( (font.getSize() / fontScaleFactor) * scaleFactor );
|
||||
return new FontUIResource( font.getFamily(), font.getStyle(), newFontSize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales the given font.
|
||||
*/
|
||||
public static FontUIResource scaleFont( FontUIResource font, float scaleFactor ) {
|
||||
int newFontSize = Math.round( font.getSize() * scaleFactor );
|
||||
return new FontUIResource( font.getFamily(), font.getStyle(), newFontSize );
|
||||
return new FontUIResource( font.deriveFont( (float) newFontSize ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,10 +254,14 @@ public class UIScale
|
||||
else // round scale factor to 1/4
|
||||
scaleFactor = Math.round( scaleFactor * 4f ) / 4f;
|
||||
|
||||
float oldScaleFactor = UIScale.scaleFactor;
|
||||
UIScale.scaleFactor = scaleFactor;
|
||||
|
||||
if( DEBUG )
|
||||
System.out.println( "HiDPI scale factor " + scaleFactor );
|
||||
|
||||
if( changeSupport != null )
|
||||
changeSupport.firePropertyChange( "userScaleFactor", oldScaleFactor, scaleFactor );
|
||||
}
|
||||
|
||||
public static float scale( float value ) {
|
||||
|
||||
@@ -178,6 +178,7 @@ ColorChooser.swatchesDefaultRecentColor=$control
|
||||
|
||||
ComboBox.border=com.formdev.flatlaf.ui.FlatRoundBorder
|
||||
ComboBox.padding=2,6,2,6
|
||||
[mac]ComboBox.showPopupOnNavigation=true
|
||||
|
||||
|
||||
#---- Component ----
|
||||
@@ -268,7 +269,6 @@ InternalFrameTitlePane.border=0,8,0,0
|
||||
|
||||
#---- List ----
|
||||
|
||||
List.border=1,0,1,0
|
||||
List.border=0,0,0,0
|
||||
List.cellMargins=1,6,1,6
|
||||
List.cellFocusColor=@cellFocusColor
|
||||
@@ -598,6 +598,7 @@ Tree.dropLineColor=@dropLineColor
|
||||
Tree.rendererFillBackground=false
|
||||
Tree.rendererMargins=1,2,1,2
|
||||
Tree.wideSelection=true
|
||||
Tree.repaintWholeRow=true
|
||||
Tree.paintLines=false
|
||||
Tree.leftChildIndent=7
|
||||
Tree.rightChildIndent=11
|
||||
|
||||
Reference in New Issue
Block a user